Skip to content

test(control-plane): let the blocked-priority smoke read the shipped notice - #4622

Merged
huangruiteng merged 1 commit into
mainfrom
codex/stale-blocked-priority-smoke
Sep 17, 2026
Merged

huangruiteng merged 1 commit into
mainfrom
codex/stale-blocked-priority-smoke

Conversation

@huangruiteng

Copy link
Copy Markdown
Collaborator

What this repairs

examples/control_plane/todo-first-open-summary-smoke.py has been red on main since the fallback notice shipped:

File "examples/control_plane/todo-first-open-summary-smoke.py", line 228, in assert_blocked_priority_fallback_visible
    assert fallback["notify_user"] is False, fallback
AssertionError: {'...': 'notify_user': True, 'requires_user_action': False,
                  'reason': 'a higher-priority agent todo is blocked before the selected
                             executable fallback; the fallback continues and no owner
                             action is required'}

The shipped behavior is deliberate, not a regression: informing the owner and requiring owner action are different decisions, and only the first one changed. A higher-priority Agent Todo that is blocked, or that waits on an unsatisfied resume condition, now sets notify_user: True while requires_user_action stays False, so the heartbeat refinement raises NOTIFY and the owner learns why the priority work is not moving without being asked to act. A Todo that is merely scheduled for a future monitor window stays a silent deferral.

So the smoke was encoding the previous default, which is the case the repository's own guidance covers: rename the smoke that encoded the old default and update the docs/disclosure.

What changed

One file, one commit, test-only — no runtime behavior changes. assert_blocked_priority_fallback_visible becomes assert_blocked_priority_fallback_notice_visible (so the old default cannot be read back out of the test name) and now asserts the shipped contract on both sides of the distinction:

  • notify_user is True, requires_user_action is False;
  • heartbeat_recommendation.notify is NOTIFY and interaction_contract.user_channel.notify is NOTIFY with action_required still False;
  • the user-channel reason and the markdown readback both say "no owner action is required";
  • the markdown line reads blocked_priority_fallback: notify_user=True, and the blocked item and selected fallback rows are still rendered;
  • should_run is still True with the fallback selected, so the notice never gates delivery.

A future change that turns the notice into a gate, or drops it back to silence, now fails here. The scheduled-future-monitor deferral branch is already pinned by tests/control_plane/test_blocked_priority_fallback_notice.py (added with the notice) and is not duplicated in the public smoke.

Validation

  • python3 examples/control_plane/todo-first-open-summary-smoke.py — fails on pristine main with the assertion above, passes on this head.
  • pytest tests/control_plane/test_blocked_priority_fallback_notice.py tests/presentation/test_quota_markdown_boundary.py tests/control_plane/test_quota_settlement_cli.py -q — 70 passed, 2 failed. Both failures are the pre-existing test_prior_host_closeout_survives_hidden_todo_lifecycle[0-sqlite] / [6-sqlite] Node.js fixture failures that reproduce on an unchanged origin/main worktree, and are unrelated to this file.
  • loopx canary premerge --from-git-diff — 5/5 catalog canaries passed, 0 failures, public-boundary scan passed.

Boundary: test-only change under examples/; it changes no runtime behavior, permission, persisted contract, or public evidence policy.

Context

main's public smoke suite is red for several independent reasons and gates every open PR. #4620 restores five of them (chat stream throughput, managed turn operator flow, operator provider credential, extension entrypoint surface, cli help manpage). This PR is the sixth. #4593 owns the seventh group.

One correction worth recording

While diagnosing the last red smoke I proved that examples/auto-research-rollout-readpath-smoke.py is not an independent cause and needs no design decision: the live frontier refuses to project when quota.ok is false, and that smoke's collect_status(scan_roots=[Path.cwd()]) scans the repository root, where the seven tracked-fixture public_boundary_violation hits make the contract unhealthy. On #4593's head that smoke exits 0, as do repository-hygiene-smoke and canary-promotion-readiness-smoke (which fails in CI because its inner loopx check --scan-path <repo> step exits 1 on the same seven hits). So after #4620, this PR and #4593, the suite's red list is empty.

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

详细中文评审 — PR #4622 test(control-plane): let the blocked-priority smoke read the shipped notice

评审对象为精确 head a7fdfd2847de03f43d213255785eb06430ba91b5(1 个 commit,1 个文件,+16/−6)。基线 origin/main a921f01c7。这是测试专用改动(examples/),不改动任何产品行为。

动机

main 的 public smoke 套件是 checks / pytest / merge-gate 的依赖,因此它每多红一条,所有 open PR 都要多背一次失败。examples/control_plane/todo-first-open-summary-smoke.py 自「blocked priority 通知」上线后一直红在 assert fallback["notify_user"] is False:

AssertionError: {'notify_user': True, 'requires_user_action': False,
                 'reason': 'a higher-priority agent todo is blocked before the selected
                            executable fallback; the fallback continues and no owner
                            action is required'}

关键判断:这是产品有意为之的新默认,不是回归。「通知业主」与「要求业主行动」是两个不同决定,这次只改了前者——被阻塞(或 resume 条件未满足)的高优 Agent Todo 现在 notify_user: True 而 requires_user_action 保持 False,于是 heartbeat 提升为 NOTIFY、业主知道高优工作为何不动,却不被要求做事;而只是排在未来 monitor 窗口的 Todo 仍然是静默 deferral。旧 smoke 固化的是上一个默认,正是仓库规范覆盖的情形(应重命名那个固化旧默认的 smoke)。

改前/改后:改前该 smoke 退出非零并打印上述断言;改后输出 todo-first-open-summary-smoke ok 且退出 0。受益者是所有被这条 required check 卡住的贡献者,以及任何高优 Todo 阻塞但仍继续 fallback 的 goal 的业主。

改动思路

进入点:CI 以进程方式调用该 smoke;它守护的行为在运维侧对应 loopx quota should-run、heartbeat 建议、交互式 user channel 与 markdown 读回。

权威输入是 smoke 构造的合成 status payload(高优项 blocked + open fallback),决策归 build_quota_should_run,notify_user 由 should_run_prepare._blocked_priority_fallback 拥有,heartbeat 映射由 heartbeat_recommendation 拥有,渲染由 quota_markdown 拥有。本次改动只动测试,不触碰任何拥有者。

复用而非重造:未来 monitor 窗口的静默分支已由 tests/control_plane/test_blocked_priority_fallback_notice.py 的四个用例固化(含 test_scheduled_future_monitor_stays_a_silent_deferral),因此这里不重复实现;本 smoke 只补上投影链路那一层——单元测试只看 fallback 对象,看不到 heartbeat、interaction contract 与 markdown 三处一致性。

具体改动

测试专用:assert_blocked_priority_fallback_visible 重命名为 assert_blocked_priority_fallback_notice_visible(让旧默认无法再从测试名里被读出来),并同时断言这条区分的两侧:

  1. notify_user is True、requires_user_action is False;
  2. heartbeat_recommendation.notify == "NOTIFY"、interaction_contract.user_channel.notify == "NOTIFY" 且 action_required is False;
  3. user channel 的 reason 与 markdown 读回都含 "no owner action is required";
  4. markdown 行读作 blocked_priority_fallback: notify_user=True,且 blocked item 行与 selected fallback 行仍在;
  5. should_run is True 且 fallback 仍被选中——通知永远不会变成 gate。

这样任何一个方向的回归(把通知退化成静默,或把通知升级成 gate)都会在这里失败;此前该文件只有单侧断言,两个方向都漏过。

对主干的风险

最强回归场景:产品把 blocked-priority 通知退回静默,或把它变成阻塞 fallback 的门;触发态是「高优 Agent Todo 为 blocked(或 resume 条件未满足)而 fallback 仍可执行」。允许/阻断它的代码路径是 _blocked_priority_fallback → heartbeat 映射 → markdown 渲染三处,本 smoke 现在同时断言三处与两个非门禁标志。

爆炸半径:仅测试文件。若本 PR 写错,后果是 smoke 误过或误红,不是产品行为。

反例覆盖:现有单元测试只断言 fallback 对象上的 notify_user,即使 heartbeat 映射或 markdown 渲染丢掉了通知它依然会通过;本 smoke 正是覆盖端到端投影的反例。真实边界:smoke 用合成 payload 调真实投影与渲染函数,不跑真实 agent turn——对投影契约来说这是正确的边界;未覆盖的是前端自己渲染通知的那一层。

可观测性:smoke 自身输出与断言消息(断言消息会打印整个 fallback payload)。回退:还原即恢复旧断言与红灯,无需迁移状态。

验证矩阵(本 head 实跑):改前在 pristine 文件上实测失败并打印 shipped payload,改后 todo-first-open-summary-smoke ok;loopx canary premerge --from-git-diff 5/5 catalog canary 通过、0 failures、边界扫描通过;pytest tests/control_plane/test_blocked_priority_fallback_notice.py tests/presentation/test_quota_markdown_boundary.py tests/control_plane/test_quota_settlement_cli.py -q = 70 passed / 2 failed,两个失败是 test_prior_host_closeout_survives_hidden_todo_lifecycle[0-sqlite] / [6-sqlite] 的既有 Node.js fixture 失败,在未改动的 origin/main worktree 上同样复现,与本文件无关。CI 在本 head 尚在 pending,按既有规则未等待。

我的整体评价

结论:批准(APPROVE),无阻断性问题。 这是一个小而正确的修复:它没有放宽任何 guard,而是让一条 stale guard 重新对齐已发布的产品语义,并且顺带把它从单侧断言升级为双向断言——通知既不能被悄悄丢弃,也不能变成门。文件已存在的多投影覆盖说明把这条断言放进该 smoke 比新开文件更薄,符合「compress rather than append」。

不保留阻断意见。残余风险:本 smoke 覆盖投影与两个消费者表面,不覆盖真实 agent turn 与前端渲染;test_quota_settlement_cli 的两个既有 Node fixture 失败与本改动无关。

English verdict: APPROVE - exact head a7fdfd2; the stale blocked-priority smoke now asserts the shipped notice contract (notify_user true, heartbeat and user-channel NOTIFY, no owner action required, requires_user_action/action_required still false, should_run true) instead of the pre-notice default, so it fails for either regression direction; test-only, single file, repair of an existing public guard rather than a new artifact; validated by the smoke failing on the pristine file and passing on this head, a canary premerge with 0 failures, and 70 passing tests with only the two pre-existing Node fixture failures.

…notice

`blocked_priority_fallback` now sets `notify_user: True` when a higher-priority
Agent Todo is blocked, or waits on an unsatisfied resume condition, while an
executable fallback continues: informing the owner and requiring owner action
are different decisions, and only the first one changed. The public smoke still
asserted the previous silent default, so `todo-first-open-summary-smoke` has
been red on main since that change:

    assert fallback["notify_user"] is False
    AssertionError: {... 'notify_user': True, 'requires_user_action': False ...}

The smoke now states the shipped contract on both sides of that distinction,
which is what makes it worth keeping: `notify_user` is True, the heartbeat
recommendation and the interactive user channel both say NOTIFY, the reason and
the markdown readback both say no owner action is required, and
`requires_user_action` / `action_required` stay False with the fallback still
selected and `should_run` still True. A future change that turns the notice into
a gate, or drops it back to silence, now fails here.

The helper is renamed to `assert_blocked_priority_fallback_notice_visible` so
the old default cannot be read back out of the test name. The scheduled
future-monitor deferral branch stays a silent deferral and is already pinned by
`tests/control_plane/test_blocked_priority_fallback_notice.py`.

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
@huangruiteng
huangruiteng force-pushed the codex/stale-blocked-priority-smoke branch from a7fdfd2 to 6083a76 Compare September 17, 2026 04:28

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

详细中文评审 — PR #4622 test(control-plane): let the blocked-priority smoke read the shipped notice

评审对象为精确 head 6083a7683e208979231b6512c2660c8a759fd055(1 个 commit,1 个文件,+16/−6),已 rebase 到 origin/main a921f01c7 之上。这是测试专用改动(examples/),不改动任何产品行为。

动机

main 的 public smoke 套件是 checks / pytest / merge-gate 的依赖,因此它每多红一条,所有 open PR 都要多背一次失败。examples/control_plane/todo-first-open-summary-smoke.py 自「blocked priority 通知」上线后一直红在 assert fallback["notify_user"] is False:

AssertionError: {'notify_user': True, 'requires_user_action': False,
                 'reason': 'a higher-priority agent todo is blocked before the selected
                            executable fallback; the fallback continues and no owner
                            action is required'}

关键判断:这是产品有意为之的新默认,不是回归。「通知业主」与「要求业主行动」是两个不同决定,这次只改了前者——被阻塞(或 resume 条件未满足)的高优 Agent Todo 现在 notify_user: True 而 requires_user_action 保持 False,于是 heartbeat 提升为 NOTIFY、业主知道高优工作为何不动,却不被要求做事;而只是排在未来 monitor 窗口的 Todo 仍然是静默 deferral。旧 smoke 固化的是上一个默认,正是仓库规范覆盖的情形(应重命名那个固化旧默认的 smoke)。

改前/改后:改前该 smoke 退出非零并打印上述断言;改后输出 todo-first-open-summary-smoke ok 且退出 0。受益者是所有被这条 required check 卡住的贡献者,以及任何高优 Todo 阻塞但仍继续 fallback 的 goal 的业主。

改动思路

进入点:CI 以进程方式调用该 smoke;它守护的行为在运维侧对应 loopx quota should-run、heartbeat 建议、交互式 user channel 与 markdown 读回。

权威输入是 smoke 构造的合成 status payload(高优项 blocked + open fallback),决策归 build_quota_should_run,notify_user 由 should_run_prepare._blocked_priority_fallback 拥有,heartbeat 映射由 heartbeat_recommendation 拥有,渲染由 quota_markdown 拥有。本次改动只动测试,不触碰任何拥有者。

复用而非重造:未来 monitor 窗口的静默分支已由 tests/control_plane/test_blocked_priority_fallback_notice.py 的四个用例固化(含 test_scheduled_future_monitor_stays_a_silent_deferral),因此这里不重复实现;本 smoke 只补上投影链路那一层——单元测试只看 fallback 对象,看不到 heartbeat、interaction contract 与 markdown 三处一致性。

具体改动

测试专用:assert_blocked_priority_fallback_visible 重命名为 assert_blocked_priority_fallback_notice_visible(让旧默认无法再从测试名里被读出来),并同时断言这条区分的两侧:

  1. notify_user is True、requires_user_action is False;
  2. heartbeat_recommendation.notify == "NOTIFY"、interaction_contract.user_channel.notify == "NOTIFY" 且 action_required is False;
  3. user channel 的 reason 与 markdown 读回都含 "no owner action is required";
  4. markdown 行读作 blocked_priority_fallback: notify_user=True,且 blocked item 行与 selected fallback 行仍在;
  5. should_run is True 且 fallback 仍被选中——通知永远不会变成 gate。

这样任何一个方向的回归(把通知退化成静默,或把通知升级成 gate)都会在这里失败;此前该文件只有单侧断言,两个方向都漏过。

对主干的风险

最强回归场景:产品把 blocked-priority 通知退回静默,或把它变成阻塞 fallback 的门;触发态是「高优 Agent Todo 为 blocked(或 resume 条件未满足)而 fallback 仍可执行」。允许/阻断它的代码路径是 _blocked_priority_fallback → heartbeat 映射 → markdown 渲染三处,本 smoke 现在同时断言三处与两个非门禁标志。

爆炸半径:仅测试文件。若本 PR 写错,后果是 smoke 误过或误红,不是产品行为。

反例覆盖:现有单元测试只断言 fallback 对象上的 notify_user,即使 heartbeat 映射或 markdown 渲染丢掉了通知它依然会通过;本 smoke 正是覆盖端到端投影的反例。真实边界:smoke 用合成 payload 调真实投影与渲染函数,不跑真实 agent turn——对投影契约来说这是正确的边界;未覆盖的是前端自己渲染通知的那一层。

可观测性:smoke 自身输出与断言消息(断言消息会打印整个 fallback payload)。回退:还原即恢复旧断言与红灯,无需迁移状态。

验证矩阵(本 head 实跑):改前在 pristine 文件上实测失败并打印 shipped payload,改后 todo-first-open-summary-smoke ok;loopx canary premerge --from-git-diff 5/5 catalog canary 通过、0 failures、边界扫描通过;pytest tests/control_plane/test_blocked_priority_fallback_notice.py tests/presentation/test_quota_markdown_boundary.py tests/control_plane/test_quota_settlement_cli.py -q = 70 passed / 2 failed,两个失败是 test_prior_host_closeout_survives_hidden_todo_lifecycle[0-sqlite] / [6-sqlite] 的既有 Node.js fixture 失败,在未改动的 origin/main worktree 上同样复现,与本文件无关。CI 在本 head 尚在 pending,按既有规则未等待。

我的整体评价

结论:批准(APPROVE),无阻断性问题。 这是一个小而正确的修复:它没有放宽任何 guard,而是让一条 stale guard 重新对齐已发布的产品语义,并且顺带把它从单侧断言升级为双向断言——通知既不能被悄悄丢弃,也不能变成门。文件已存在的多投影覆盖说明把这条断言放进该 smoke 比新开文件更薄,符合「compress rather than append」。

不保留阻断意见。残余风险:本 smoke 覆盖投影与两个消费者表面,不覆盖真实 agent turn 与前端渲染;test_quota_settlement_cli 的两个既有 Node fixture 失败与本改动无关。

English verdict: APPROVE - exact head 6083a76; the stale blocked-priority smoke now asserts the shipped notice contract (notify_user true, heartbeat and user-channel NOTIFY, no owner action required, requires_user_action/action_required still false, should_run true) instead of the pre-notice default, so it fails for either regression direction; test-only, single file, repair of an existing public guard rather than a new artifact; validated by the smoke failing on the pristine file and passing on this head, a canary premerge with 0 failures, and 70 passing tests with only the two pre-existing Node fixture failures.

@huangruiteng

Copy link
Copy Markdown
Collaborator Author

Merge decision (author-owned self-merge, test-only surface).

  • Changed surface: one file, examples/control_plane/todo-first-open-summary-smoke.py (+16/-6). Test-only; no runtime, permission, persisted-state, CLI, benchmark or public-evidence-policy change.
  • Exact head: 6083a7683e208979231b6512c2660c8a759fd055, rebased onto main a921f01c7. loopx pr-review --check-merge-readiness 4622@6083a7683 returns ready=true with no blockers, and the published exact-head review on this commit is the approval record (author-owned COMMENTED approval; GitHub blocks formal self-approval).
  • Checks run: smoke fails on the pristine file and passes on this head; loopx canary premerge --from-git-diff 0 failures with the public-boundary scan passing; the notice unit test and the quota markdown boundary test pass. All required repository checks are green on this head.
  • Failures / skips / manual holds: none blocking. tests/control_plane/test_quota_settlement_cli.py::test_prior_host_closeout_survives_hidden_todo_lifecycle[0-sqlite] and [6-sqlite] fail with Node.js fixture errors, reproducing on an unchanged origin/main worktree and unrelated to this file.
  • Why the coverage is enough: the change touches no product behavior; it aligns an existing public guard with the shipped semantics and now asserts both directions of the notify-versus-gate distinction, so a wrong assertion fails locally rather than in production. Authorized by the repository's self-merge policy for narrow test-side cleanup with an exact-head review.

@huangruiteng
huangruiteng merged commit 3ca8681 into main Sep 17, 2026
2 checks passed
@huangruiteng
huangruiteng deleted the codex/stale-blocked-priority-smoke branch September 17, 2026 04:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant