From b14ae68551e50ab63627e3c49b846e7de72af281 Mon Sep 17 00:00:00 2001 From: LoopX Agent <337587101+loopx-agent@users.noreply.github.com> Date: Sun, 4 Oct 2026 20:20:19 +0800 Subject: [PATCH 1/2] fix(goals): align checkpoint repair guidance with vision validation Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com> --- .../control_plane/goals/vision_checkpoint.ts | 19 +++++-- .../test_refresh_checkpoint_recovery.py | 54 ++++++++++--------- .../vision_checkpoint.test.ts | 38 +++++++++++++ 3 files changed, 83 insertions(+), 28 deletions(-) diff --git a/loopx/control_plane/goals/vision_checkpoint.ts b/loopx/control_plane/goals/vision_checkpoint.ts index da01ba10fb..175b762a13 100644 --- a/loopx/control_plane/goals/vision_checkpoint.ts +++ b/loopx/control_plane/goals/vision_checkpoint.ts @@ -24,6 +24,8 @@ const GOAL_VISION_BUDGET_ERROR = "vision_budget_exceeded"; const GOAL_VISION_TOTAL_LIMIT = 1_800; const GOAL_VISION_ADVANCEMENT_POLICIES = ["as_needed", "repeat_until_closed"] as const; const VISION_UNCHANGED_REASON_LIMIT = 240; +const VISION_TODO_DELTA_ENTRY_LIMIT = 8; +const VISION_TODO_DELTA_TEXT_LIMIT = 80; const VISION_BUDGET_SUGGESTION_LIMIT = 96; const GOAL_VISION_FIELD_LIMITS = { @@ -66,7 +68,14 @@ const GOAL_PATH_DELTA_LIST_LIMITS = { export function visionAuthoringContract(): JsonObject { return { schema_version: GOAL_VISION_REPLAN_SCHEMA_VERSION, - fields: {state: "lifecycle token", vision_patch: {...GOAL_VISION_FIELD_LIMITS}}, + fields: { + state: "lifecycle token", + vision_patch: {...GOAL_VISION_FIELD_LIMITS}, + todo_delta: { + max_retained_items: VISION_TODO_DELTA_ENTRY_LIMIT, + max_item_chars: VISION_TODO_DELTA_TEXT_LIMIT, + }, + }, common_states: ["vision_patch_proposed", "vision_closed", "no_followup"], advancement_policies: [...GOAL_VISION_ADVANCEMENT_POLICIES], minimal_example: {schema_version: GOAL_VISION_REPLAN_SCHEMA_VERSION, state: "vision_patch_proposed", vision_patch: { @@ -618,8 +627,8 @@ function prepareVisionRefresh(request: VisionRefreshPrepareRequest): JsonObject const todoDelta: string[] = []; if (Array.isArray(updatePacket.todo_delta)) { - for (const item of updatePacket.todo_delta.slice(0, 8)) { - const text = boundedPublicText("todo_delta", item, 80); + for (const item of updatePacket.todo_delta.slice(0, VISION_TODO_DELTA_ENTRY_LIMIT)) { + const text = boundedPublicText("todo_delta", item, VISION_TODO_DELTA_TEXT_LIMIT); if (text) todoDelta.push(text); } } @@ -883,7 +892,9 @@ export function buildVisionCheckpoint(value: unknown): JsonObject { } if (!satisfied) { checkpoint.required_resolution = ["write_vision_patch"]; - if (checkpoint.missing_baseline !== true) { + if (request.existing_agent_vision === null) { + checkpoint.missing_baseline = true; + } else { (checkpoint.required_resolution as string[]).push( "record_unchanged_reason", ); diff --git a/tests/control_plane/test_refresh_checkpoint_recovery.py b/tests/control_plane/test_refresh_checkpoint_recovery.py index 6ea9324edc..2758720e9f 100644 --- a/tests/control_plane/test_refresh_checkpoint_recovery.py +++ b/tests/control_plane/test_refresh_checkpoint_recovery.py @@ -15,10 +15,8 @@ AGENT_ID, REPO_ROOT, GOAL_ID, - SELECTED_REPLAN_TODO_ID, TODO_ID, TURN_ID, - _configure_selected_todo_replan_fixture, _initialize_git_checkout, _run_cli, _write_fixture, @@ -306,30 +304,21 @@ def test_checkpoint_only_recovery_bypasses_open_todo_completion_validation( tmp_path: Path, ) -> None: project, runtime, registry = _write_fixture(tmp_path) - _configure_selected_todo_replan_fixture(project, registry) _initialize_git_checkout(project) state_path = project / f".codex/goals/{GOAL_ID}/ACTIVE_GOAL_STATE.md" state_text = state_path.read_text(encoding="utf-8") selected_marker = ( - f"todo_id={SELECTED_REPLAN_TODO_ID} status=open " + f"todo_id={TODO_ID} status=open " "task_class=advancement_task action_kind=validate " - f"claimed_by={AGENT_ID} -->" + "-->" ) assert selected_marker in state_text - state_path.write_text( - state_text.replace( - selected_marker, - selected_marker.replace(" -->", " validation_command=pytest -->"), - 1, - ), - encoding="utf-8", - ) turn_id = "turn-checkpoint-open-validator" binding = ( "--agent-id", AGENT_ID, "--todo-id", - SELECTED_REPLAN_TODO_ID, + TODO_ID, "--turn-instance-id", turn_id, ) @@ -341,17 +330,14 @@ def test_checkpoint_only_recovery_bypasses_open_todo_completion_validation( "--codex-app", "--goal-id", GOAL_ID, - "--agent-id", - AGENT_ID, - "--turn-instance-id", - turn_id, + *binding, "--scan-path", str(project), cwd=project, ) assert rc == 0, guard - assert guard["decision"] == "autonomous_replan_required" - assert guard["selected_todo"]["todo_id"] == SELECTED_REPLAN_TODO_ID + assert guard["decision"] == "run" + assert guard["selected_todo"]["todo_id"] == TODO_ID delivery = ( "refresh-state", @@ -360,6 +346,8 @@ def test_checkpoint_only_recovery_bypasses_open_todo_completion_validation( *binding, "--classification", "validated_progress", + "--progress-scope", + "goal", "--delivery-batch-scale", "implementation", "--delivery-outcome", @@ -378,15 +366,33 @@ def test_checkpoint_only_recovery_bypasses_open_todo_completion_validation( "--suppress-external-sinks", ) mutations = ( - "--autonomous-replan-recorded", - "--repair-delta-kind", - "successor_or_supersede", + "--next-action", + "Inspect the remaining checkpoint recovery scope.", ) rc, first = _run_cli(registry, runtime, *delivery, *mutations, cwd=project) assert rc == 0, first assert first["appended"] is True assert first["vision_checkpoint"]["decision"] == "missing_required" + checkpoint = first["vision_checkpoint"] + assert checkpoint["missing_baseline"] is True + assert checkpoint["required_resolution"] == ["write_vision_patch"] + instructions = render_state_refresh_markdown(first) + _assert_checkpoint_instructions(instructions) + assert "No persisted vision baseline is available" in instructions + assert "--vision-unchanged-reason" not in instructions + + # A controller may install completion validation before checkpoint repair. + # The supplement repairs the existing receipt while the Todo remains open. + state_path.write_text( + state_path.read_text(encoding="utf-8").replace( + selected_marker, + selected_marker.replace(" -->", " validation_command=pytest -->"), + 1, + ), + encoding="utf-8", + ) + vision = ( "--vision-summary", "Continue the accepted checkpoint recovery scope.", @@ -403,7 +409,7 @@ def test_checkpoint_only_recovery_bypasses_open_todo_completion_validation( ) wrong_binding = list(delivery) - wrong_todo_index = wrong_binding.index(SELECTED_REPLAN_TODO_ID) + wrong_todo_index = wrong_binding.index(TODO_ID) wrong_binding[wrong_todo_index] = "todo_chain_000000000001" rc, wrong_identity = _run_cli( registry, runtime, *wrong_binding, *vision, cwd=project diff --git a/tests/control_plane_ts/vision_checkpoint.test.ts b/tests/control_plane_ts/vision_checkpoint.test.ts index a52cac96f3..21dae12135 100644 --- a/tests/control_plane_ts/vision_checkpoint.test.ts +++ b/tests/control_plane_ts/vision_checkpoint.test.ts @@ -5,6 +5,7 @@ import { buildVisionCheckpoint, VISION_REFRESH_PREPARED_SCHEMA_VERSION, VISION_REFRESH_REQUEST_SCHEMA, + visionAuthoringContract, } from "../../loopx/control_plane/goals/vision_checkpoint.ts"; function finalizeRequest(overrides: Record = {}) { @@ -412,11 +413,48 @@ test("semantic closeout retains the strict material vision checkpoint", () => { assert.equal(result.required, true); assert.equal(result.satisfied, false); assert.equal(result.decision, "missing_required"); + assert.equal(result.missing_baseline, true); + assert.deepEqual(result.required_resolution, ["write_vision_patch"]); assert.deepEqual(result.triggers, [ { kind: "material_delivery_outcome", delivery_outcome: "outcome_progress" }, ]); }); +test("missing checkpoint offers unchanged only with a persisted vision", () => { + const baseline = {state: "vision_active", generated_at: "2026-09-01T10:00:00Z"}; + const missing = buildVisionCheckpoint(finalizeRequest({ + existing_agent_vision: baseline, + })); + assert.equal(missing.satisfied, false); + assert.deepEqual(missing.required_resolution, [ + "write_vision_patch", "record_unchanged_reason", + ]); + assert.equal("missing_baseline" in missing, false); + assert.equal(buildVisionCheckpoint(finalizeRequest({ + existing_agent_vision: baseline, + vision_unchanged_reason: "The verified scope is still current.", + })).satisfied, true); + const rejected = buildVisionCheckpoint(finalizeRequest({ + vision_unchanged_reason: "The verified scope is still current.", + })); + assert.equal(rejected.satisfied, false); + assert.equal(rejected.missing_baseline, true); + assert.deepEqual(rejected.required_resolution, ["write_vision_patch"]); +}); + +test("advertised Todo delta limits match retained items and item validation", () => { + const fields = visionAuthoringContract().fields as Record; + assert.deepEqual(fields.todo_delta, {max_retained_items: 8, max_item_chars: 80}); + const packet = (todo_delta: string[]) => prepareRequest({ + agent_vision_packet: {vision_summary: "Deliver the scoped result.", todo_delta}, + }); + const deltas = Array.from({length: 9}, (_, index) => String(index).repeat(80)); + const vision = buildVisionCheckpoint(packet(deltas)).agent_vision as Record; + assert.deepEqual(vision.todo_delta, deltas.slice(0, 8)); + assert.throws(() => buildVisionCheckpoint(packet(["x".repeat(81)])), + /todo_delta uses 81 chars; limit is 80/); +}); + test("a bounded blocked retry does not invent a vision change", () => { const blockedRetry = { schema_version: "quota_blocked_retry_v0", From d8d49d7e43e11bb61497c1028d6c1956085002c2 Mon Sep 17 00:00:00 2001 From: LoopX Agent <337587101+loopx-agent@users.noreply.github.com> Date: Sun, 4 Oct 2026 20:20:35 +0800 Subject: [PATCH 2/2] docs(rfc): record truthful checkpoint repair authoring boundary Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com> --- .../rfcs/typescript-control-plane-migration-v0.md | 9 +++++++++ .../rfcs/typescript-control-plane-migration-v0.zh-CN.md | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/docs/architecture/rfcs/typescript-control-plane-migration-v0.md b/docs/architecture/rfcs/typescript-control-plane-migration-v0.md index 8fa226d176..49f1a21ba0 100644 --- a/docs/architecture/rfcs/typescript-control-plane-migration-v0.md +++ b/docs/architecture/rfcs/typescript-control-plane-migration-v0.md @@ -1230,6 +1230,15 @@ Goal prose, acceptance and vision basis. A display limit must never become a settlement limit. Retain the current complete read until that parity and stale- head recovery are qualified on legacy, File and SQLite backends. +**Checkpoint repair authoring.** The existing TS vision owner must project only +repair choices the validator accepts: without a persisted vision, a missing +checkpoint requires a vision patch; unchanged reasoning is available only with +that baseline. The authoring contract shares the validator's `todo_delta` +limits: retain the first eight entries, with at most 80 characters per retained +entry. Isolated real CLI recovery must preserve the original settlement identity +and replay fences. This closes a recovery-guidance correctness gap; it does not +qualify lower context, IO or latency costs. + **Recovery boundary (2026-09-22).** The [authority archive command](../../reference/authority-archive.md) places retained history validation, delta reconstruction and resumable restore in the existing diff --git a/docs/architecture/rfcs/typescript-control-plane-migration-v0.zh-CN.md b/docs/architecture/rfcs/typescript-control-plane-migration-v0.zh-CN.md index 42db11d366..1cd2cd1bb2 100644 --- a/docs/architecture/rfcs/typescript-control-plane-migration-v0.zh-CN.md +++ b/docs/architecture/rfcs/typescript-control-plane-migration-v0.zh-CN.md @@ -851,6 +851,12 @@ codec;较大的完整事实快照通过私有临时文件和摘要绑定的引 内存,也不证明分布式执行。游标/checkpoint 归约保留为以测量驱动、完整源语义一致 为前提的后续工作,不再造 Python 规则。见[历史决策证据](ledger/typescript-control-plane-migration-v0/2026-09-22-replan-history-policy.zh-CN.md)。 +**Checkpoint 恢复编写契约。** 现有 TS vision owner 只能投影校验器接受的恢复 +选项:没有持久 vision 时,缺失的 checkpoint 必须提交 vision patch;有该基线时 +才提供 unchanged reason。Authoring 契约复用校验器的 `todo_delta` 限制:保留前 +八项,每个保留项至多 80 字符。隔离的真实 CLI 恢复必须保持原结算身份和 replay +约束。这闭合恢复指引的正确性缺口,不代表上下文、IO 或延迟成本已降低。 + **恢复边界(2026-09-22)。** [authority archive 命令](../../reference/authority-archive.md) 由现有 TS coordination owner 负责历史校验、状态 delta 重建和可重入恢复;Python 只解析 CLI 路径、传递请求并展示紧凑结果。复用 state-log codec,避免各 provider