fix(smokes): restore the two public smoke contracts broken on main - #4681
Conversation
`main` (d8e7af1) fails Full Public Smokes in two shards, both from a contract and its guard drifting apart, not from a flaky job. Reproduced on a clean `origin/main` worktree. - `examples/project/goal-vision-replan-contract-smoke.py` requires the protocol doc to state that a bounded loop's look-back stays explicit "without adding more inline CLI flags or expanding the heartbeat prompt". The Path Delta rewrite in 77798d5 replaced that paragraph and dropped the sentence, so the guard lost its contract. Restore it where the rewritten section now describes the same boundary (`--agent-vision-json`). - `examples/blocker-push-runtime-smoke.py` pinned the ASCII form `unchanged->`--vision-unchanged-reason``. 67fcd01 moved the shipped writeback sentence to `unchanged→真实`--vision-unchanged-reason`` and updated `examples/control_plane/heartbeat-prompt-smoke.py` for it, but not this sibling, so the blocker-runtime path still asserted retired text. Both smokes now pass on this head, and `loopx canary premerge --from-git-diff` reports 0 failures / 0 advisories (with the repository's TypeScript deps linked locally, which `semantic-vocabulary-drift-smoke` needs). Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
Reviewed exact head: e2bf3a9a48540ea01119053103a354d3763f5a15.
loopx pr-review --check-result on the matching packet returned ok: true with no approval_blockers; all 8 evidence rows for this docs/example plan are verified.
动机
main(d8e7af141)的 Full Public Smokes 在两个分片上红,两条都不是 flaky,而是契约与它的守卫被同一次改动拆开。它们挡着所有开放 PR 的必过检查,因此必须先修好。
| Smoke | 根因 | 修法 |
|---|---|---|
examples/project/goal-vision-replan-contract-smoke.py(shard 4) |
77798d5a8 重写 Path Delta 段时,把原来那句「bounded loop 的 look-back 保持显式,without adding more inline CLI flags or expanding the heartbeat prompt」丢掉了,而守卫仍在要求它 |
在改写后的同一段里恢复这句约束(它正是该段现在描述的 --agent-vision-json 边界) |
examples/blocker-push-runtime-smoke.py(shard 0) |
67fcd01fa 把已发货的写回句改成 unchanged→真实--vision-unchanged-reason``,并同步了 examples/control_plane/heartbeat-prompt-smoke.py,漏了这个兄弟 smoke,它还断言退役的 ASCII 形式 |
断言改回已发货文本,并加一行注释指向已同步的兄弟 smoke |
同一 run 里第三个失败 job smoke-fleet-health 是聚合 job:它自己的 smoke-fleet-health-smoke 在同一份日志里报 ok inventory=520 owners=337 owner_gaps=183。
这个 PR 的价值:把 main 的必过门从「两条常红」恢复到可判读,同时把 look-back 的边界约束重新写回协议文档——而不是为了变绿去删守卫。
改动思路
两条修复都遵循同一个原则:先判断哪一侧才是权威,再补缺失的一侧。
- 对 shard 4:文档是权威(它成文地声明约束),smoke 是守卫。维护者
#4637的关闭说明只提到保留 same-turn 指引与 record-and-repair 生命周期,没有任何放宽 look-back 边界的意图,所以正确修法是补回契约句,而不是删掉期望。这也避免落入「为了让 CI 过而降低门禁」。 - 对 shard 0:已发货的 prompt 文本是权威(
loopx/control_plane/heartbeat/rules.py产出,67fcd01fa有意改成混合语言句式,并已同步 sibling smoke),因此把兄弟 smoke 的字面量对齐,而不是回退 prompt。
两处都保持单处表述:文档把句子放回 Path Delta 段(不另起一段重复),smoke 用注释显式指向已同步的兄弟,降低再次漏改的概率。
具体改动
2 个文件、+7/-2,都不触碰 loopx/** 运行时:
docs/reference/protocols/goal-vision-replan-contract-v0.md(+3/-1):在 Path Delta 段恢复 look-back 边界句,并说明它走的是既有--agent-vision-json边界。examples/blocker-push-runtime-smoke.py(+4/-1):断言改为unchanged→真实--vision-unchanged-reason``,加一行注释说明与examples/control_plane/heartbeat-prompt-smoke.py同源。
关键内容讲解
恢复的那句在文档里承担的是一个可执行的边界声明,而不是修饰语:
The look-back rides the existing `--agent-vision-json`
boundary, so it stays explicit without adding more inline CLI flags or expanding
the heartbeat prompt.
它约束的是实现方式:vision look-back 只能复用既有 packet 边界,不得为了它新增内联 CLI flag,也不得为了它扩张 heartbeat prompt。这正是守卫 require(protocol, [...]) 里那一条期望所保护的内容,也是 loopx canary premerge 的 catalog canary 会间接依赖的表述。
smoke 侧的改动则只是把守卫的观测点对齐到已发货文本:
assert "unchanged→真实`--vision-unchanged-reason`" in compact_prompt, promptsibling smoke 早在 67fcd01fa 里就断言同一句,因此这不是放宽,而是让两个调用方一致。
对主干的风险
改动只落在文档与示例,不改变运行时、权限、状态或 CLI 契约。主要风险是相反的:用「删期望」的方式让门禁变绿,从而让边界从守卫里静默消失——本 PR 明确避免,期望列表 diff 只有断言文本与注释(+4/-1),没有任何删项。
在本 head 上实测:
env -u PYTHONPATH uv run --extra test python examples/project/goal-vision-replan-contract-smoke.py→ okenv -u PYTHONPATH uv run --extra test python examples/blocker-push-runtime-smoke.py→ ok- 基线对照:同一台机器上的干净
origin/mainworktree(d8e7af141)两条都 exit 1,错误串与 CI run 35277850079 日志中的 AssertionError 完全一致;从该 run 的失败清单逐条解析,失败项恰好只有这两条 smoke。 - 相邻覆盖:
heartbeat-prompt-smoke、docs-governance-smoke、goal-vision-path-delta-smoke、smoke-fleet-health-smoke全部 ok。 env -u PYTHONPATH uv run --extra test loopx canary premerge --from-git-diff→ 0 failures / 0 advisories(catalog canaries 5/5、risk-profile smokes 8/8、public boundary clean)。
未验证 / 如实标注:本机未运行完整 Full Public Smokes 套件,「main 全绿」的最终证据仍在 CI;semantic-vocabulary-drift-smoke 需要仓库 TypeScript 依赖(裸 checkout 上以解析器错误退出,属既有本地环境限制),链接本地依赖后通过。文档约束句的恢复依据是 77798d5a8 的 diff 与 #4637 的关闭说明;若该约束其实已被有意放宽,正确做法是先改文档里的约束声明并说明原因,而不是删除守卫。
边界声明:本 PR 只改公开文档与一个公开 smoke 示例,不含 loopx/** 行为改动。
我的整体评价
两条红项的根因定位到具体 commit,修的是缺失的一侧而不是放宽断言,改动量与问题规模相称(+7/-2)。无阻断性发现。
一点给维护者留意:同一句 heartbeat 写回文本目前由两个 smoke 各自维护字面量,67fcd01fa 就已漏改一个。若这类文本后续还会调整,值得由产出方(heartbeat rules)在改动时同时更新消费者 smoke,或加一条轻量清单断言,避免同类漏改反复发生。
English verdict: APPROVE - reviewed at exact head e2bf3a9: both Full Public Smokes failures on main (d8e7af1) are a contract and its guard drifting apart, and this PR repairs the missing side of each rather than loosening an assertion. 77798d5 rewrote the Path Delta section and dropped the sentence that says a bounded loop's look-back stays explicit "without adding more inline CLI flags or expanding the heartbeat prompt", so the smoke that requires it lost its contract; the sentence is restored inside the rewritten paragraph, where it describes the same --agent-vision-json boundary. 67fcd01 moved the shipped writeback sentence to the mixed-language form and updated the sibling heartbeat-prompt-smoke but missed blocker-push-runtime-smoke, which still asserted the retired ASCII literal; it now asserts the shipped text with a comment naming the sibling. Both smokes failed on a clean main worktree with exactly the CI error strings and now pass here; the adjacent heartbeat, docs-governance, path-delta and fleet-health smokes pass, and loopx canary premerge --from-git-diff reports 0 failures / 0 advisories. The change is docs plus one public example smoke, with no runtime, permission, state or CLI-contract change. Unverified and disclosed: the full suite's green evidence remains CI, and semantic-vocabulary-drift-smoke needs the repository's TypeScript deps (a pre-existing local gap). No blocking finding.
What this repairs
main(d8e7af141) fails Full Public Smokes in two shards. Both failures are a contract and its guard drifting apart after a recent merge — not flaky jobs. I reproduced both on a cleanorigin/mainworktree and traced each to the commit that moved one side.mainexamples/project/goal-vision-replan-contract-smoke.py(shard 4)--agent-vision-json).examples/blocker-push-runtime-smoke.py(shard 0)unchanged→真实\--vision-unchanged-reason`and updatedexamples/control_plane/heartbeat-prompt-smoke.py` for it, but not this sibling smoke, which kept asserting the retired ASCII form.The third failing job in that run (
smoke-fleet-health) is the meta job that aggregates the shards;smoke-fleet-health-smokeitself reportsok inventory=520 owners=337 owner_gaps=183in the same log.Validation
python3 examples/project/goal-vision-replan-contract-smoke.py— ok (failed before withmissing ['without adding more inline CLI flags or expanding the heartbeat prompt']).python3 examples/blocker-push-runtime-smoke.py— ok (failed before withAssertionErroron the retired literal).python3 examples/control_plane/heartbeat-prompt-smoke.py,python3 examples/canary/smoke-fleet-health-smoke.py,python3 examples/project/goal-vision-path-delta-smoke.py,python3 examples/docs-governance-smoke.py— all ok.loopx canary premerge --from-git-diff— 0 failures / 0 advisories (catalog canaries 5/5, risk-profile smokes 8/8, public boundary clean).semantic-vocabulary-drift-smokeneeds the repository's TypeScript deps; with them linked locally it passes, and its absence on a bare checkout is the same pre-existing local gap reported in earlier reviews.Boundary
Docs plus one public example smoke, no runtime, permission, state or CLI-contract change.
loopx/control-planeexecution surfaces are untouched.