Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/project/goal-vision-refresh-state-budget-smoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ def run_quota(registry_path: Path, runtime: Path) -> dict:
"json",
"quota",
"should-run",
"--context-delivery",
"off",
"--goal-id",
GOAL_ID,
"--agent-id",
Expand Down
3 changes: 3 additions & 0 deletions loopx/cli_commands/quota_capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,9 @@ def fits() -> bool:
if initial_read_pointers:
overview = result.pop("overview")
instruction = result["instruction"]
if any(pointer.endswith("/vision_authoring/rule") for pointer in initial_read_pointers):
instruction = ("Before composing a Vision, select the complete vision_authoring object "
"at the displayed step in this capture. " + instruction)
result["instruction"] = ("Start with first_read_command for current facts and source navigation from this capture, "
"without reading an older baseline. "
"Read each complete optional attachment from its captured step before using it. " + instruction)
Expand Down
9 changes: 9 additions & 0 deletions loopx/control_plane/quota/progressive_context.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/** Native model presentation: requirements stay inline, supporting material is
* addressed in the immutable source. This plan changes no canonical state. */
import {isDeepStrictEqual} from "node:util";
import {visionAuthoringContract} from "../goals/vision_checkpoint.ts";
import type {JsonObject} from "../effect_program.ts";
import {jsonObject, requireJsonObject} from "../runtime_decode.ts";
import {GOAL_OUTCOMES_SCHEMA, OUTCOME_CONTEXT_NAVIGATION_SCHEMA} from "../goals/outcome_requirements.ts";
Expand Down Expand Up @@ -312,6 +314,13 @@ export function initialContextReadPointers(context: JsonObject, decisionFields:
const step = object(value), stepPath = [...planPath, "ordered_steps", stepIndex];
if (!step) { include(...stepPath); return; }
for (const field of Object.keys(step)) {
if (field === "vision_authoring" && step.kind === "durable_writeback"
&& [false, true].some(replan => isDeepStrictEqual(step[field], visionAuthoringContract(replan)))) {
// Keep the decision and continuation policy at admission. Field limits
// and worked examples are read from this step when writing the Vision.
for (const key of ["schema_version", "rule", "continuation_review"]) include(...stepPath, field, key);
continue;
}
if (field !== "optional_attachments" || !Array.isArray(step[field])) { include(...stepPath, field); continue; }
step[field].forEach((attachment, attachmentIndex) => {
const path = [...stepPath, field, attachmentIndex];
Expand Down
19 changes: 18 additions & 1 deletion tests/control_plane/test_context_first_read.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,9 @@ def test_advertised_native_reader_keeps_the_complete_current_contract_across_pag
monkeypatch.delenv("CODEX_THREAD_ID", raising=False)
project, runtime, registry = _write_fixture(tmp_path)
_initialize_fixture_authority(project, runtime, provider=provider, handoff_mode="hard_lease")
code, claim = _run_cli(registry, runtime, "todo", "claim", "--goal-id", GOAL_ID,
"--todo-id", TODO_ID, "--agent-id", AGENT_ID, "--claimed-by", AGENT_ID, cwd=project)
assert code == 0 and claim["ok"], claim
state = project / f".codex/goals/{GOAL_ID}/ACTIVE_GOAL_STATE.md"
original_state = state.read_bytes()
turn_id = "native-first-read"
Expand All @@ -295,7 +298,21 @@ def test_advertised_native_reader_keeps_the_complete_current_contract_across_pag
words = shlex.split(page["next_command"])
assert page["eof"] and len(content) > 1
values = selected_context_values("".join(content))
assert values["/interaction_contract/cli_channel"] == source["interaction_contract"]["cli_channel"]
cli_path = "/interaction_contract/cli_channel"
expected_cli = selected_context_values(json.dumps({"selections": [
{"pointer": cli_path, "value": source["interaction_contract"]["cli_channel"]}]}))
vision_path = next(path for path in expected_cli if path.endswith("/vision_authoring"))
# Every CLI leaf outside the authoring reference must still be delivered.
for path, item in expected_cli.items():
if path.startswith(vision_path + "/") or (isinstance(item, (dict, list)) and item):
continue
assert values[path] == item
assert values[vision_path + "/rule"] == expected_cli[vision_path]["rule"]
code, detail = _run_cli(registry, runtime, "quota", "context-read", "--reference-file",
view["recovery"]["reference_file"], "--select", vision_path, "--page-bytes", "8000",
"--max-page-output-bytes", "9000", cwd=project)
assert code == 0 and detail["eof"]
assert selected_context_values(detail["content"])[vision_path] == expected_cli[vision_path]
assert values["/heartbeat_receipt"] == source["heartbeat_receipt"]
assert values["/selected_todo"] == source["selected_todo"]
assert _heartbeat_receipt_count(runtime, turn_id) == 1 and _spend_run_count(runtime) == 0
Expand Down
18 changes: 18 additions & 0 deletions tests/control_plane_ts/progressive_context.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import assert from "node:assert/strict";
import test from "node:test";
import {visionAuthoringContract} from "../../loopx/control_plane/goals/vision_checkpoint.ts";
import {initialContextReadPointers, progressiveContextPlan} from "../../loopx/control_plane/quota/progressive_context.ts";
import {FULL_OUTCOME_READ_GUIDANCE, PROGRESSIVE_OUTCOME_READ_GUIDANCE} from "../../loopx/control_plane/work_items/interaction_contract.ts";

Expand Down Expand Up @@ -91,3 +92,20 @@ test("exact repeated Todo rows preserve membership without collapsing distinct e
assert.equal(progressiveContextPlan({surface: "quota_packet", payload: {...payload,
contract_binding: {signature: "signed"}}}).references, undefined);
});

test("first read keeps decision rules and preserves nonstandard Vision obligations whole", () => {
const base = "/interaction_contract/cli_channel/settlement_plan/ordered_steps/0/vision_authoring";
for (const replan of [true, false]) {
const schema = visionAuthoringContract(replan);
const required = {kind: "durable_writeback", precondition: "Verify current evidence first.", vision_authoring: schema};
const context = {interaction_contract: {schema_version: "loopx_interaction_contract_v0", cli_channel: {
settlement_plan: {schema_version: "quota_settlement_plan_v1", ordered_steps: [required]},
}}};
const pointers = initialContextReadPointers(context, []);
assert.ok(pointers.includes(base + "/rule"));
assert.equal(pointers.includes(base + "/continuation_review"), Object.hasOwn(schema, "continuation_review"));
assert.ok(!pointers.includes(base));
required.vision_authoring = {...schema, new_stop: "Keep this changed policy visible."};
assert.ok(initialContextReadPointers(context, []).includes(base));
}
});
Loading