refactor(replan): unify typed history triggers and count logical turns - #4902
huangruiteng wants to merge 4 commits into
Conversation
…turns Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…sent Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…owner Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
Request changes conclusion (author-owned PR; GitHub blocks formal self-review)
评审目标:#4902,exact head 1182f7c6ef448e621d84d359dc56b40cde256975,base c41e09473a9ab883c53b077a73e47ee4eda78816。
动机
现有历史 replan 由几段 Python 扫描分别决定 typed progress、Monitor 重复和定期审查;同一逻辑 Turn 的重试记录可能被重复计数,已接受 ACK 没有一致地截断进度窗口,中性额度记账也可能遮住重复停滞。把这组共享规则收敛为一个决策边界是有价值的完整增量;它不等于整个 Goal authority 的 TS promote。
改动思路
现有 status/quota 路径从持久化 Run 与 Todo 投影取得事实;replan_history_codec.py 仅沿用旧指纹、时间及 Turn ID 解码,向 effect runtime 发送有限 typed facts;replan_history.ts 先按 agent 划分历史,再按 accepted ACK 截断、中性分类过滤、逻辑 Turn 去重,依原优先级产生 progress、Monitor 或 periodic trigger。后续仍由 Python 建立原有 obligation,前端与 Lark 无新字段。Future-due Monitor 的判断复用现有 TS Todo resume planner,未另建 Todo 权威状态。
具体改动
关键代码讲解
replan_history.ts的historyWindow保证 peer ACK 不清除当前 lane,distinctTurns仅对有可信 Turn ID 的有效证据去重;进度、Monitor 和定期审查共用这个窗口。replan_history_codec.py的project_replan_history对旧 Run 做兼容解码并调用work_item.replan_history.project;autonomous_replan_obligation.py/progress_observation.py删除原来的独立选择循环,保留 obligation 形状。effect_runtime_handlers.ts注册纯决策方法;autonomous_replan_ack.py为局部整理;status.py和 status projection 改为引用共享中性分类。三组新测试覆盖 typed 负例、重试和 File/SQLite 实际调用;双语 RFC 检查点和协议文档披露默认行为改变及 promote 边界。
对主干的风险
**[P1,阻塞] loopx/status.py:10 的公开兼容导出未满足现有审计契约。**本 PR 将 REPLAN_HISTORY_NEUTRAL_CLASSIFICATIONS 以 AUTONOMOUS_RUN_HISTORY_NEUTRAL_CLASSIFICATIONS 别名导入公开 facade,但 _PUBLIC_COMPAT_REEXPORTS 没有相应、可审计的 canonical 绑定。仓库既有 tests/architecture/test_control_plane_import_boundaries.py::test_public_facade_import_only_reexports_match_the_audited_allowlist 在 base 通过,在当前 head 失败,唯一多出的绑定就是该别名。请让 facade 导出符合现有审计契约;如果选择去掉公开别名,先核实外部兼容性。修后重跑该架构测试及聚焦 status/quota 路径。
本地验证:新增 TS 测试 21/21 通过,聚焦 Python 行为及真实 File/SQLite consumer 14/14 通过,control-plane typecheck 与 git diff --check 通过;上述必需架构测试 1 项失败。它说明行为测试全绿仍不能证明公开 facade 兼容性。该 PR 没有默认关闭路径,文档已明确这次修正对既有 lane 默认生效,且把 replan 描述为机器执行条件而非建议。未做整个 Goal 的迁移验收;作者声明的 PostgreSQL 适配范围也不是本 slice。
语义与 CI 对齐
这次选择是复用现有 replan / Todo 语义词汇,而非创建新 authority 或 actor 生命周期。status.py 的新增导出违反现行公开 facade import-only allowlist,必须修复并通过同一条架构测试,不能用新行为用例替代。这里只依据上述本地复现作出结论。
我的整体评价
规则归属、重试计数和负例设计总体合理,文件规模与要消除的重复决策相称;没有发现需要扩大成另一个框架的理由。但当前 exact head 的仓库必需测试出现明确的 base→head 回归,故结论为 REQUEST_CHANGES。修好 facade 审计后,再按新 head 复核完整 PR、真实 consumer 和必需测试。此改动属于 control-plane,仍应由 maintainer 合并。
English verdict: REQUEST_CHANGES - At head 1182f7c6ef448e621d84d359dc56b40cde256975, the new public status.py alias breaks the audited import-only facade contract (base test passes, head test fails). The focused TS (21) and Python/File/SQLite (14) tests and typecheck pass; repair the facade binding and rerun the architecture gate before re-review.
History-triggered replanning used separate Python scans, so retries could prematurely trigger periodic/Monitor review, accepted ACKs could leave typed-progress stalls active, and neutral accounting could hide repetition. This PR makes the existing status/quota callers share one TypeScript history policy and removes the replaced Python decisions.
Refs #4574. The TS and shared-authority RFC ledgers record this T3 decision-family closure and the conditional 5–8 remaining default-adoption packages. This does not flip provider defaults or qualify whole-Goal promotion. Frontend/Lark keep consuming the existing obligation contract; there is no new setting or capability.
Validation: 164 Python cases, 34 TypeScript cases, control-plane typecheck, configured mypy, focused ruff, docs governance and public-boundary checks. The status facade retains five baseline-only F401 diagnostics with no new lint findings. A read-only real-source rehearsal used 345 active Todos / 600 history rows / five lanes: all lane results matched baseline, and isolated File/SQLite readback plus quota CLI passed without a display or source mutation. Full archive capture independently remains blocked by an incomplete archived dependency role/class; this read-path evidence does not discharge that migration hold. PostgreSQL storage was not changed or qualified by this slice.
The first semantic-vocabulary check reported 44/43 same-basename Python/TS pairs. The historical compatibility module is explicitly named
replan_history_codec.py: it owns encoding and the single RPC, with no Python trigger fallback. The unchanged check now reports 43/43; no budget, scan scope or fixture population was increased/reduced. Python product code shrinks by 253 lines overall. Updated on mainc41e09473, including #4886 and #4887. Scope: 17 files, +1005 / -445 lines.Final qualification: standard premerge canary passed (19 selected checks, zero failures); exact-head change-quality receipt
cqr_5d9f098e704637b5aff1is valid for head1182f7c6e/ basec41e09473. Scope fingerprint:5d9f098e704637b5aff1cbad31ba361686faacb1928693f9220a940478b1a201. No unresolved quality blockers.Maintainer merge required for this control-plane change.