Skip to content

Commit 07d4aed

Browse files
committed
fix(heartbeat): carry the closeout vision decision in the writeback guidance
The vision checkpoint contract already requires a per-agent vision decision at a material closeout, but the guidance injected into every wake said only `material->actual outcome`. A lane that followed it recorded the segment with a `missing_required` checkpoint and paid for the decision on the next wake, which opened on a checkpoint-missing replan obligation and spent itself reconstructing facts that were in hand at closeout time. The guidance now states the contract the product actually implements: a material closeout - a material `delivery_outcome` on the agent lane, or a durable `## Next Action` update - carries its own vision decision in the same `refresh-state` call, an omission is repaired on the original turn through the repair command the CLI returns, the goal cannot reach its terminal no-follow-up state before the decision satisfies the checkpoint, and a segment does not record an `unchanged` reason it did not earn. The sentence stays inside both agent-facing budgets: the prompt body keeps its per-mode character allowance and the hot-path interface envelope stays inside its 4800-character json budget. The record-and-repair contract is deliberately untouched. An input-boundary refusal was proposed earlier in this PR and withdrawn: it removed the recorded-then-repaired path that the shipped host completion, same-turn supplement, idempotent replay and external-delivery resume confirmation all depend on, and 15 tests encode that path (they now stay green). Fixing the guidance removes the waste at its source without retiring the recovery mechanism. Verified: tests/test_host_vision_recovery.py, tests/control_plane/test_refresh_checkpoint_recovery.py, tests/control_plane/test_refresh_checkpoint_isolation.py and tests/test_state_refresh_agent_lane_action.py 64 passed; tests/control_plane/test_cli_output_budget.py and tests/control_plane/test_heartbeat_prompt_support.py 58 passed; hot-path-interface-budget, heartbeat-prompt, goal-vision-refresh-state-budget, goal-vision-replan-contract, blocker-push-runtime and docs-governance smokes ok. Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
1 parent 3ca8681 commit 07d4aed

4 files changed

Lines changed: 32 additions & 6 deletions

File tree

‎docs/development/control-plane-course/08-evidence-refresh-and-self-repair.md‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,15 +312,18 @@ if total_usage > GOAL_VISION_TOTAL_LIMIT:
312312
第二份 transcript。`examples/project/goal-vision-refresh-state-budget-smoke.py`
313313
同时验证写入正确性、预算与 repair delta。
314314

315-
当 material refresh 没有 vision patch 或 unchanged reason 时,CLI 会产生 `vision_checkpoint_missing` acceptance gap。Todo 即使完成,也不能直接 terminal。
315+
正常调用应当在同一次写回里带上这个决定。当 agent lane 的 material closeout 没有 vision
316+
patch 或 unchanged reason 时,CLI 会记录 segment 并把 checkpoint 标成
317+
`vision_checkpoint_missing`,同时返回一条可直接执行的修复命令:在原 turn 用它补齐决定,
318+
settlement identity 不变、不会再花一次 spend。补齐之前,Todo 即使完成也不能宣告 terminal。
316319

317-
修复选择有三种:
320+
要满足这个决定,路径仍是三种:
318321

319322
1. 写一个 bounded vision patch;
320323
2. 明确记录 vision unchanged reason;
321324
3. 用 evidence 关闭或 supersede 该 vision frontier。
322325

323-
不要为了消除 warning 随便写“unchanged”。Reason 必须与本轮 acceptance 事实一致。
326+
不要为了消除这个提示自动填一个空泛的“unchanged”。Reason 必须与本轮 acceptance 事实一致。
324327

325328
## Signal、Anchor 与 Feedback 不直接变成 Todo Truth
326329

‎docs/reference/protocols/goal-vision-replan-contract-v0.md‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,22 @@ Valid checkpoint decisions are:
232232
- `not_required`: no material closeout trigger was present, including a valid
233233
typed in-flight continuation.
234234

235+
The closeout is where this requirement is met, so the writeback guidance every
236+
wake receives states it: a material closeout -- a material `delivery_outcome` on
237+
the agent lane, or a durable `## Next Action` update -- carries its own vision
238+
decision in the same `refresh-state` call, and does not record an `unchanged`
239+
reason the segment did not earn.
240+
241+
An omission is recorded, not discarded, and is repaired in the same turn:
242+
`refresh-state` writes the segment with a `missing_required` checkpoint and
243+
returns the repair command that repeats the original invocation with the missing
244+
decision. The goal cannot reach its terminal no-follow-up state until that
245+
decision satisfies the checkpoint, and the same-turn supplement applies it to the
246+
original settlement identity rather than to a new one, so the repair neither
247+
re-authors the segment nor spends a second time. An in-flight continuation owes
248+
no decision, and neither does a closeout that carries no `agent_id`, because a
249+
per-agent decision requires an agent to make it.
250+
235251
`missing_required` is not a chat reminder. Status keeps it in compact run
236252
history, quota filters it by current `agent_id`, and goal-frontier projection
237253
turns it into `acceptance_gaps[]`. If the current agent has no runnable

‎examples/control_plane/heartbeat-prompt-smoke.py‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,10 @@ def user_output_policy(task_body: str, *, mode: str) -> dict[str, str]:
8585
def assert_sole_notification_authority(task_body: str, *, mode: str) -> None:
8686
body = normalized(task_body)
8787
assert "no-change=`surface_only`/no spend; unchanged->" in body, mode
88-
assert "`--vision-unchanged-reason`; material->actual outcome." in body, mode
88+
assert (
89+
"`--vision-unchanged-reason`; material closeout->actual outcome"
90+
"+vision决定; 缺则按返回命令同turn补齐,补齐前不terminal"
91+
) in body, mode
8992

9093
if mode == "full":
9194
assert (
@@ -714,7 +717,10 @@ def main() -> int:
714717
):
715718
assert "no-change=`surface_only`/no spend" in task, label
716719
assert "`--vision-unchanged-reason`" in task, label
717-
assert "material->actual outcome" in task, label
720+
assert "material closeout->actual outcome" in task, label
721+
assert "同turn补齐" in task, label
722+
assert "补齐前不terminal" in task, label
723+
assert "勿空填unchanged" in task, label
718724
assert "if absent say" not in thin_task, thin_task
719725
assert "If false/0: quiet/no-user-todo" not in thin_task, thin_task
720726

‎loopx/control_plane/heartbeat/rules.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
)
2424
HEARTBEAT_VISION_WRITEBACK_RULE_SHORT = (
2525
"writeback: no-change=`surface_only`/no spend; "
26-
"unchanged->`--vision-unchanged-reason`; material->actual outcome."
26+
"unchanged->`--vision-unchanged-reason`; material closeout->actual outcome"
27+
"+vision决定; 缺则按返回命令同turn补齐,补齐前不terminal;勿空填unchanged."
2728
)
2829
REWARD_MEMORY_OUTCOME_RULE = (
2930
"`reward_memory_recall.experiment.automatic_ingest=true`: reusable Todo outcomes "

0 commit comments

Comments
 (0)