refactor(todos): import the Todo task-class vocabulary from its owner - #4608
huangruiteng merged 7 commits into
Conversation
Track A for loopx-project#4447. TODO_TASK_CLASS_ADVANCEMENT was restated as a literal in three modules that each classify a Todo, and TODO_TASK_CLASS_MONITOR in one of them, while control_plane/todos/contract.py already owns both and already exports the closed set they belong to. A literal copy cannot be caught by reading either module: the values match today, so nothing fails, and a future change has three places to land. Import the owner's names instead; every module that restates them already imports from the todos layer, so no dependency direction moves. Semantic same-runtime forks 18 -> 16; budgets and the smoke anchor move together. Refs loopx-project#4447 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: song <song@users.noreply.github.com>
动机Track A(减少已测量的语义债)第三项。 代价不是当前行为错——四处值逐字相同,今天读起来一致。代价是未来:改一处不会被另三处发现。这种复制还无法通过阅读任一模块察觉,因为没有东西会失败。 实测澄清了一个此前的隐含预期:这批残留的语义"分叉"里 0 个是同名不同值,全部是同值多份定义。所以"保留有理由的独立契约"这一判定,在这批上的答案是"一个都不需要保留"。 更小的替代修法不足:只删副本会让这三个模块的既有调用点( 改动思路入口是四个常量声明,出口是三个模块的使用点。权威状态只有 关键前提是依赖方向:三个复制模块本来就在从 todos 层导入—— 复用既有机制:没有新增词汇表条目、没有新增校验分支、没有改 具体改动5 文件、+23/−12:
关键代码讲解
预算锚定: 对主干的风险无阻塞项。
那 1 个 FAIL 是 负向走查(触发状态 → 观察结果 → 最小修复):在任一模块重新声明 变更体量相称:净减 4 处重复声明,机制成本为零(无新依赖、无新检查、无新 schema)。 English verdict: APPROVE — exact head Refs #4447 🤖 Generated with Claude Code |
exact-head 复核(
|
long_todo_chain.py restated TODO_TASK_CLASS_ADVANCEMENT but never used it, so importing the owner's name left an unused import and F401 failed the test-suite lint. No module imports the constant from here, so the fix is to remove the import rather than keep a dead re-export. Verified with ruff's rule: the module no longer binds the name and the drift smoke still reports same_runtime_forks=23 with the owner as the only definition site. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: song <22676124+songoow@users.noreply.github.com>
…ource-todo-task-class Signed-off-by: song <22676124+songoow@users.noreply.github.com>
91da927 to
e614af4
Compare
修复
|
…ource-todo-task-class Both sides tightened the semantic ratchets in the same two anchored places. Resolved by taking the tighter side of each, the only resolution budgets_only_decrease allows: - same_runtime_forks_semantic 18 -> 16, from this branch: importing the Todo task-class vocabulary from its owner removes two semantic forks. - conflicting_values_semantic 2 -> 0, from loopx-project#4603 on main. Registry and BUDGET_ANCHOR carry the same pair. Measured after the merge: same_runtime_forks_semantic=16/16, conflicting_values_semantic=0/0. Note for merge order: loopx-project#4606 resolves the same anchor to 13. Whichever of the two lands second has to lower the anchor again in that merge, because each branch only counts the forks it removes. Signed-off-by: song <22676124+songoow@users.noreply.github.com>
exact-head 复核(
|
| 锚点 | 本分支 | main | 解析 |
|---|---|---|---|
same_runtime_forks_semantic |
18 → 16(从 owner 导入 Todo task-class 词表消掉两个分叉) | 18 | 取 16 |
conflicting_values_semantic |
2 | 2 → 0(#4603) | 取 0 |
合并顺序耦合:#4606 把同一锚点解到 13。两者互不冲突但共享这一个数字,后合并的那个必须在合并提交里再降一次。
验证:semantic-vocabulary-drift-smoke: ok,same_runtime_forks_semantic=16/16、conflicting_values_semantic=0/0。合并提交带 DCO 签名。
合并顺序:与 4606 共享三个棘轮锚点我对全部 8 个在开 PR 做了两两试合并,唯一会撞的就是 #4606 × #4608(其余 27 对全部干净)。两者改的是同一组锚点的不同数字,因为每个分支只统计自己消掉的分叉:
后合并的那个需要在它的合并提交里把这三个数改成最右列,registry 与 这不是估算:我在本地把两个 head 都合到 main 上,解成上表数字后跑 smoke,得到 |
…ource-todo-task-class Signed-off-by: song <22676124+songoow@users.noreply.github.com>
本 PR 在 #4447 计划中的位置issue #4447 现在有一节统一协调(中英双语),把这 13 个在开 PR 作为一个计划列出:各自修什么、为何必要、以及实测出的合并顺序。 冲突实测:对全部 78 对做了试合并,9 对冲突,分四簇,每一处都是文本相邻,没有一处是语义分歧。
建议顺序(代价从低到高):#4628 → #4625、#4626 → #4627 → #4619、#4621 → #4630 → #4614 → #4631 → #4629 → #4617 → #4606 → #4608。四个棘轮 PR 放最后,因为每落地一个,下一个的数字就从估算变成确定值。 全部 13 个 PR 现已同步到 |
huangruiteng
left a comment
There was a problem hiding this comment.
详细评审 — exact head 5c99c7610e74683a113f7541dab54f5f758c7d92
动机
Track A(#4447):TODO_TASK_CLASS_ADVANCEMENT 在三个模块里被重复成字面量、TODO_TASK_CLASS_MONITOR 在一个模块里重复,而 control_plane/todos/contract.py 本来就拥有这两个名字。作者的理由准确:字面量复制无法靠读任一模块发现——今天值相同,什么都不会失败,只是未来改动有三个落点。
改动思路
直接用 owner 的导入替换复制,不新增机制、不移动依赖方向(三个模块本来就已经从 todos 层导入)。第二个提交做收尾:long_todo_chain.py 里那份字面量其实从未被使用,导入 owner 名字会留下未使用导入并让 F401 失败,因此选择删掉这个绑定而不是保留死再导出。这个判断需要证据支撑,我单独核过(见下)。
具体改动
loopx/control_plane/goals/goal_frontier/__init__.py(+10/-3):从...todos.contract导入TODO_TASK_CLASS_ADVANCEMENT、TODO_TASK_CLASS_MONITOR,删除两个字面量;包对外仍可通过属性访问取到这两个名字。loopx/control_plane/todos/frontier_revision.py(+9/-2):从.contract导入TODO_TASK_CLASS_ADVANCEMENT,删除字面量。loopx/control_plane/goals/goal_frontier/long_todo_chain.py(+4/-? 后 -3):先改为导入,再在收尾提交中删除这个从未使用的绑定。examples/semantic-vocabulary-drift-smoke.py、loopx/semantics/vocabulary_v0.json:锚点与inventory_ratchets从 25/58/18 降到 23/52/16。
验证(都在本 head):goal_frontier.TODO_TASK_CLASS_ADVANCEMENT、frontier_revision.TODO_TASK_CLASS_ADVANCEMENT 与 owner 同名常量都解析为 advancement_task(continuous_monitor 同理);全仓库只剩 contract.py:72-73 两处定义;long_todo_chain 已不再绑定该名字(hasattr 为 False)。测试:test_control_plane_import_boundaries.py、test_semantic_vocabulary_drift.py、test_semantic_production.py、test_canonical_frontier_revision.py、test_goal_frontier_replan_rules.py、test_frontier_revision_scope.py → 158 passed;drift smoke ok 且实测 same_runtime_forks=23/23、same_runtime_fork_definitions=52/52、same_runtime_forks_semantic=16/16。
对主干的风险
唯一对外的可见变化是 long_todo_chain.py 不再绑定 TODO_TASK_CLASS_ADVANCEMENT,所以我逐一把该模块的导入方都查了:ack_policy.py 导入的是 LONG_TODO_CHAIN_TRIGGER 等三个名字,包 __init__.py 导入的是 LONG_TODO_CHAIN_TRIGGER 与 evaluate_long_todo_chain,测试里导入的是 evaluate_long_todo_chain——没有任何地方导入被删掉的名字,且这些模块在本 head 都能正常导入。值没有变化,依赖方向没有变化(都原本就依赖 todos 层),drift 锚点下调方向是收紧而非放松。
我的整体评价
APPROVE。 典型的"删重复、留单一 owner"改动:范围小、可逆、验证可在本地复算,并且它让 drift 预算朝好的方向移动了 2 个名字/6 个定义/2 个语义 fork。第二个提交体现的是对 lint 的正确反应(删死代码而不是保留死再导出),且删得有据。合并权仍在维护者。
English verdict: APPROVE - reviewed exact head 5c99c76. The Todo task-class vocabulary now has a single owner in loopx/control_plane/todos/contract.py: goal_frontier/init.py imports both names instead of restating them, frontier_revision.py imports the advancement name, and the second commit removes the copy long_todo_chain.py never used. I verified the removal is safe by checking every importer of that module (ack_policy.py, the package init and the tests import LONG_TODO_CHAIN_TRIGGER, evaluate_long_todo_chain and the revision helpers, never the deleted name) and by importing the modules at this head; the owner is now the only definition site and both package attributes still resolve to advancement_task / continuous_monitor. Validation at this head: 158 passed across the import-boundary, semantic-drift, semantic-production, canonical-frontier-revision, replan-rule and frontier-revision-scope suites, and the drift smoke reports same_runtime_forks=23/23, same_runtime_fork_definitions=52/52 and same_runtime_forks_semantic=16/16, exactly the lowered anchors (25/58/18 before).
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
动机
精确评审 head:7cf8631804d39a5d4e976e49a1eedafdb19a5164;比较基线:0a4917956dd25ca73050b99dfb7ab8af6a8992cf。依据 #4447 Track A、语义收敛 RFC 与总路线图的 S2:按实际语义复用已有 owner。本 PR 完成 Todo task-class 重复定义的维护修复,不代表整个语义收敛计划完成。当前值原本一致;价值在于消除后续修改时多个分类器各自维护同一知识的风险。
改动思路
复用 todos/contract.py 已有闭集;两个实际消费者改为导入,long_todo_chain.py 删除无人使用的旧绑定。两处原本就依赖 Todo contract,没有新增依赖方向、状态字段或框架。TypeScript 继续拥有前沿选择、revision 和长链 checkpoint 规则,Python 仍只适配输入。
正向链路已走通:真实 FileAuthorityStore → active_state_todo_fields → revision adapter → TypeScript runtime → evaluate_long_todo_chain → quota should-run。超出紧凑展示范围的可执行任务发生实质变化会重新触发规划,被排除的任务修改不会;移除排除条件后会重新触发,缺失的展示文件不会被写回。
具体改动
5 文件,+20/−12。三个 Python 文件收敛绑定;registry 与既有 drift smoke 同步收紧三个预算。已合入最新基线并保留 #4606 的独立收敛,预算从主干的 20/47/13 降为 18/41/11。
关键代码讲解
frontier_revision.py:59,frontier_source_facts:仍用既有 normalizer 将 Todo 类型转成传给 TS 的advancement事实;比较值现在来自 canonical contract,筛选和序列化没有改动。goal_frontier/__init__.py:578,_summary_task_counts:推进任务、监控任务及 watch-only 排除分支保持原样,只替换常量来源。goal_frontier/__init__.py:637,_monitor_no_change_streak_trigger:仍检查 open、所属 agent、watch-only 和连续无变化阈值;统一 monitor 值来源,不改变重规划优先级。
对主干的风险
没有剩余阻塞项。最强反例是把推进任务误当监控,导致可执行前沿变化后旧 ACK 仍然有效。在隔离进程里故意替换该分类值,真实文件/TS 路径的独立重规划断言失败;未修改的 head 通过。仓库搜索也确认被删的 long-chain 常量没有导入或属性访问方。
验证:针对 import boundary、semantic inventory/production、canonical frontier、replan ordering、revision scope 的 161 项通过;相同运行时测试在主干基线 52 项通过。真实调用完整输出在仅归一化临时路径、观测时间及时间派生 event id 后一致。仓库 lint、mypy(22 个模块)、语义 drift、CLI output budget、todo-first-open-summary 均通过;旧评论中的 first-open 失败已不再复现。公共边界扫描覆盖最终 5 文件并通过。
语义与 CI 对齐
结论是 reuse_existing。没有用改名、扩大预算或缩窄扫描范围隐藏债务;减少的是同一 Todo slot 的真实重复定义。预算和 anchor 一致,其他 RFC 尚未实现的证明能力不计作本 PR 已完成。没有新增 opt-in、权限、actor lifecycle、默认行为、产品专用规则或“guidance”与强制义务混淆。CLI 是本次受影响的验证入口;前端、Lark、配置和打包资源没有改动,也没有新增用户交互需要配套。
按已解析的 wait_for_ci=false,未查询或等待远端 CI,不把它记作通过。必要本地验证与精确 head 评审仍然执行。
我的整体评价
APPROVE。 这是完整且可独立回滚的维护修复,复用了最近的 owner,机制成本与问题相称。面向后续重构的检查已落实为删除死绑定、保留 TS 决策所有权;这里不需要额外迁移框架。
canary premerge --from-git-diff:19/19 项通过,另有 4 项 diff/编译直接检查通过;0 failure、0 skip、0 manual hold。严格质量凭据 cqr_b0e23cea5e5d51fc84d3 对最终 5 文件有效,scope fingerprint:b0e23cea5e5d51fc84d39f37519c986d314161c7ee3b2076f8f265363c3f3604。质量审查允许一次 safe-fix,本轮未额外应用;blocker/warning/advisory 均为 0。
维护者已明确授权本 PR 自合并;合并前仍须通过能力的精确 head readiness 检查。无人工 hold;回滚不涉及数据迁移。
English verdict: APPROVE — head 7cf8631804d39a5d4e976e49a1eedafdb19a5164. Reuses the canonical Todo vocabulary, deletes the unused binding, and preserves combined main ratchets. 161 focused tests, 52 baseline runtime tests, real file/TypeScript caller parity, mutation sensitivity and local quality checks passed. No runtime-default or authority change; remote CI intentionally not consulted.
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
动机
精确评审 head:03f1b041e004498dedf6a0e06711c859a41d9329;比较基线:e1a97c2fd2e4ff98d3e0a2bf997bd461c0314cee。依据 #4447 Track A、语义收敛 RFC 与总路线图的 S2:按实际语义复用已有 owner。本 PR 完成 Todo task-class 重复定义的维护修复,不代表整个语义收敛计划完成。当前值原本一致;价值在于消除后续修改时多个分类器各自维护同一知识的风险。
改动思路
复用 todos/contract.py 已有闭集;两个实际消费者改为导入,long_todo_chain.py 删除无人使用的旧绑定。两处原本就依赖 Todo contract,没有新增依赖方向、状态字段或框架。TypeScript 继续拥有前沿选择、revision 和长链 checkpoint 规则,Python 仍只适配输入。
正向链路已走通:真实 FileAuthorityStore → active_state_todo_fields → revision adapter → TypeScript runtime → evaluate_long_todo_chain → quota should-run。超出紧凑展示范围的可执行任务发生实质变化会重新触发规划,被排除的任务修改不会;移除排除条件后会重新触发,缺失的展示文件不会被写回。
具体改动
5 文件,+20/−12。三个 Python 文件收敛绑定;registry 与既有 drift smoke 同步收紧三个预算。已合入最新基线并保留 #4606 和 #4617 的独立收敛,预算从主干的 20/47/13 降为 18/41/11。
关键代码讲解
frontier_revision.py:59,frontier_source_facts:仍用既有 normalizer 将 Todo 类型转成传给 TS 的advancement事实;比较值现在来自 canonical contract,筛选和序列化没有改动。goal_frontier/__init__.py:578,_summary_task_counts:推进任务、监控任务及 watch-only 排除分支保持原样,只替换常量来源。goal_frontier/__init__.py:637,_monitor_no_change_streak_trigger:仍检查 open、所属 agent、watch-only 和连续无变化阈值;统一 monitor 值来源,不改变重规划优先级。
对主干的风险
没有剩余阻塞项。最强反例是把推进任务误当监控,导致可执行前沿变化后旧 ACK 仍然有效。在隔离进程里故意替换该分类值,真实文件/TS 路径的独立重规划断言失败;未修改的 head 通过。仓库搜索也确认被删的 long-chain 常量没有导入或属性访问方。
验证:针对 import boundary、semantic inventory/production、canonical frontier、replan ordering、revision scope 的 161 项通过;相同运行时测试在主干基线 52 项通过。真实调用完整输出在仅归一化临时路径、观测时间及时间派生 event id 后一致。仓库 lint、mypy(22 个模块)、语义 drift、CLI output budget、todo-first-open-summary 均通过;旧评论中的 first-open 失败已不再复现。公共边界扫描覆盖最终 5 文件并通过。
语义与 CI 对齐
结论是 reuse_existing。没有用改名、扩大预算或缩窄扫描范围隐藏债务;减少的是同一 Todo slot 的真实重复定义。预算和 anchor 一致,其他 RFC 尚未实现的证明能力不计作本 PR 已完成。没有新增 opt-in、权限、actor lifecycle、默认行为、产品专用规则或“guidance”与强制义务混淆。CLI 是本次受影响的验证入口;前端、Lark、配置和打包资源没有改动,也没有新增用户交互需要配套。
按已解析的 wait_for_ci=false,未查询或等待远端 CI,不把它记作通过。必要本地验证与精确 head 评审仍然执行。
我的整体评价
APPROVE。 这是完整且可独立回滚的维护修复,复用了最近的 owner,机制成本与问题相称。面向后续重构的检查已落实为删除死绑定、保留 TS 决策所有权;这里不需要额外迁移框架。
canary premerge --from-git-diff:19/19 项通过,另有 4 项 diff/编译直接检查通过;0 failure、0 skip、0 manual hold。严格质量凭据 cqr_8703730d50e8844caafe 对最终 5 文件有效,scope fingerprint:8703730d50e8844caafe6f62e7a4a9c018c10075e21bd1e6926fee4793d4d6e6。质量审查允许一次 safe-fix,本轮未额外应用;blocker/warning/advisory 均为 0。
维护者已明确授权本 PR 自合并。本地质量门无 hold;GitHub 的 require_last_push_approval 另要求最后推送者以外的审批。此次修复推送与评审为同一维护者账号,能力的 readiness 仍需如实检查该审批状态,不能把 APPROVE 或本地通过写成已获远端合并放行。回滚不涉及数据迁移。
English verdict: APPROVE — head 03f1b041e004498dedf6a0e06711c859a41d9329. Reuses the canonical Todo vocabulary, deletes the unused binding, and preserves combined main ratchets. 161 focused tests, 52 baseline runtime tests, real file/TypeScript caller parity, mutation sensitivity and local quality checks passed. No runtime-default or authority change; remote CI intentionally not consulted.
…odo-header-markers loopx-project#4608 merged while this branch was open and both sides edit the same anchored ratchet block. Resolved by taking the tighter side of each, as budgets_only_decrease requires: - same_runtime_forks_semantic 13 -> 11 from main, which loopx-project#4608 earned by importing the Todo task-class vocabulary from its owner. - multi_value_forks 4 -> 2, multi_value_forks_semantic 3 -> 1 and multi_value_fork_definitions 10 -> 6 from this branch, which are the two undeclared forks the marker copies were. Registry and BUDGET_ANCHOR carry the same values. Measured after the merge: every counter is at budget, with multi_value_forks=2/2, multi_value_forks_semantic=1/1 and multi_value_fork_definitions=6/6. Signed-off-by: song <22676124+songoow@users.noreply.github.com>
…ratchets loopx-project#4608 merged after the previous sync, lowering the same anchored block again. Resolved by taking the tighter side of each, as budgets_only_decrease requires: - same_runtime_forks 20 -> 18 and same_runtime_fork_definitions 47 -> 41 from main. - conflicting_values 16 and conflicting_definitions 55 from this branch, which is what it exists to lock. Measured after the merge: conflicting_values=16/16 and conflicting_definitions=55/55, both exactly at budget. Signed-off-by: song <22676124+songoow@users.noreply.github.com>
Problem and result
Refs #4447 (Track A). Todo frontier consumers duplicated task-class values already owned by
control_plane/todos/contract.py, making future changes prone to drift. This PR imports the existing owner in the two active consumers and removes the unused binding inlong_todo_chain.py.No task-class values, runtime decisions, persisted schemas or CLI defaults change. TypeScript retains frontier selection and revision ownership. This completes the scoped duplication repair, not the wider semantic-convergence roadmap.
Integration and validation
Integrated main
e1a97c2fd; retained #4606 and #4617's independent convergence. The registry and smoke anchors now agree atsame_runtime_forks=18,same_runtime_fork_definitions=41,same_runtime_forks_semantic=11(main: 20/47/13).Reviewed source:
03f1b041e004498dedf6a0e06711c859a41d9329.quota should-rundiagnostics; eligible edits outside the compact display rearm, excluded edits do not, and missing display Markdown stays absent.todo-first-open-summarysmokes passed. The previously reported first-open failure no longer reproduces.