Preserve ready work and back off peer coordination - #4845
huangruiteng wants to merge 5 commits into
Conversation
b168e3a to
6403d38
Compare
|
补充 exact-head 行为证据与 TS 边界判断(head 为什么是 backoff,而不是 stop
同一份真实 Finance 这既消除了 base 的“保持活跃 + 停止宿主”矛盾,也保留了异步恢复观察面。 被隐藏 ready Todo 的 base/head 对照同一个 typed resume-planning fixture 中, 因此修复保留候选真相,同时不放大展示窗口。 TS 重构裁决没有新建 leaf-only TS reducer。该 PR 让 peer wait 复用现有 验证:408 个相关 Python tests、13 个 TS tests、两个 control-plane smoke、control-plane typecheck、Ruff 0.15.22、 |
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
6403d38 to
216fc90
Compare
|
Rebased onto current The base/head Finance replay remains unchanged:
Post-rebase validation: 528 Python tests, 13 TS tests, two smokes, control-plane typecheck, Ruff and diff check all pass. Independent review and refreshed required checks remain outstanding; no self-merge. |
huangruiteng
left a comment
There was a problem hiding this comment.
Request changes conclusion (author-owned PR; GitHub blocks formal self-review)
Exact head reviewed: 216fc90ccba0ddca0db3ada99ced2bfced74aed9
动机
这次修复的主问题成立,而且优先级高:当宿主传入运行时 capability 时,旧路径只从有界展示 lane 重算,可能丢掉只存在于 deferred_resume_candidates 的 ready Todo;随后产生的 peer_coordination_blocked 又会被不同投影当成终止状态,最终把本来可恢复的工作搁置。把 ready candidate 保留下来、把 peer coordination 改成 no-spend 的可恢复等待,是正确的产品方向。
改动思路
整体架构选择是对的:
- readiness 继续由 TypeScript 的 typed resume-condition owner 决定;
- Python 只消费 typed effective action,不复制第二套状态机;
- scheduler 复用现有 stateful transition owner,按 10/20/30/60 分钟回退;
- peer/config/reassignment/local frontier 变化会重置 cadence;
goal_stopped、quota_paused、validated terminal no-followup 仍是停止边界。
但 deferredPlan 把“同一个 Todo 共享 readiness identity”和“两个 projection 共享同一个 payload”混成了一件事。前者应该共享,后者不应该共享。
具体改动
我确认以下意图已实现并通过验证:candidate-only 的 ready Todo 不再被有界展示 lane 擦掉;peer_coordination_blocked 会保持 automation active、禁止 pause、且不消费 quota;scheduler backoff 复用现有 typed transition 和 ack/reset identity。
有一个阻塞问题:
- [P1] compact display payload 被 lossless candidate 替换。
deferredPlan先做unique([...projectedCandidates, ...deferredItems]),candidate 在前,因此同一todo_id时 lossless candidate 成为唯一 winner。后面的displayIdentities只检查 identity,又把这个 winner 当成deferredItems返回。结果是deferred_lanes.deferred_items和capacity_fields.deferred_items都带上 lossless payload,破坏了有界 compact projection,可能放大 quota/status/heartbeat 热路径 JSON,也可能暴露原本刻意从展示 row 省略的字段。
我用 production projectTodoResumePlanning 做了一个反例:同一 Todo 的展示 row 文本为 Compact display copy、candidate row 文本为 Lossless candidate copy;当前 head 的 candidate 输出正确保留 lossless 文本,但两个 display 输出也错误变成了 lossless 文本。现有新测试只断言 candidate lane,因此没有捕获 display lane 的语义漂移。
最小修复建议:仍然对 canonical Todo id 做一次去重并计算 readiness/condition,然后按 Todo id 把这个决定分别应用回原始 compact deferredItems 和原始 lossless projectedCandidates;不要让一个 Item 实例同时拥有两个 projection。把现有 same-Todo 回归补成配对断言:candidate 必须保持 Lossless candidate copy,而 deferred_lanes.deferred_items 与 capacity_fields.deferred_items 必须保持 Compact display copy;最好再放一个 oversized candidate 覆盖 packet budget。
对主干的风险
本地验证结果:
resume_planning.test.ts:6 passed;- scheduler arbitration/execution-context/backoff/transition/runtime/ack matrix:275 passed;
task-orchestration-smoke.py:passed;automation-liveness-state-machine-smoke.py:passed;- changed Python Ruff:passed;
git diff --check:passed;- 上述 compact-vs-lossless 反例:failed,稳定复现 P1。
作者在审阅期间把分支 rebase 到最新 main;我核对了新旧 head,PR 自身的 runtime diff 与上述 finding 没有变化,并在新 exact head 上再次稳定复现。新的 DCO、dependency review、Frontstage Pages、PostgreSQL authority 与 release-artifact checks 在我读取时仍处于 queued,merge state 是 BLOCKED;因此即使修复 finding,仍需等待新 head 的最终 required CI。
我的整体评价
这是一个边界合理、架构方向正确的 liveness 修复,typed authority、no-spend backoff 和终止条件都比旧行为更清楚;我不建议拆掉这些部分。当前不能通过的原因很集中:canonical identity 的复用越过了 projection payload 边界。修复映射并补上双 projection 回归后,再跑 focused TypeScript、orchestration/liveness、quota/status output-budget 与 required CI,我会基于新 exact head 复审。
English verdict: REQUEST_CHANGES
|
CI note for exact head |
A ready deferred Todo could disappear when the host supplied runtime capabilities: resume planning recomputed candidates from the bounded display lane and dropped ready rows retained only in the dedicated candidate lane. The resulting false
peer_coordination_blockedstate could strand work. Its scheduler and automation projections also disagreed about whether the recurring heartbeat should remain alive.This change:
peer_coordination_blockedas a recoverable wait instead of a terminal stop;Goal stopped, quota paused, and validated terminal no-follow-up remain the stop cases. The TypeScript migration RFC is already in its transaction-payoff phase, so this PR reuses the existing coarse scheduler transition owner and removes the special Python stop path instead of adding another leaf reducer or bridge.
A replay of the captured
finance-research-goalsnapshot against base61b8311b7and head216fc90ccverifies both defects: the ready candidate remains selectable when runtime capabilities are supplied, and the blocked coordination response now projectskeep_active=true,pause_allowed=false,backoff_until_reassigned, cadence classpeer_coordination_wait, and 10/20/30/60 stateful backoff.Validation:
task-orchestration-smoke.pypassed.automation-liveness-state-machine-smoke.pypassed.Entry points:
No local runtime state, credentials, logs, or private research artifacts are included.
Closes #4843