refactor(authority): move shadow drain recovery planning into TypeScript - #4920
Conversation
…eScript Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…on gates 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) for exact head 16c2b577a56de386c470dcf77435bdd629d9fae5.
动机
现有 File shadow drain 先由 TS 证明完整 lineage,再把历史事务送回 Python,由 Python 第二次解释回执连续性、游标锚点、恢复预算和 ACK。这造成规则双所有者及随历史增长的 RPC 负担;另外,证明后若 outbox JSON 只变更排版,旧路径可能先推进游标、后在删除时才发现字节变化。本 PR 针对 TS T3/shared-authority L7 交付一个可回滚的完整恢复规则迁移;它不宣称整 Goal 迁移或默认 provider 切换已完成。
改动思路
继续使用既有 coordination/File shadow 权威边界:Python 在维护锁下采集 binding、游标、目录和原始字节摘要;TS 从真实 File provider 读取并验证完整 proof,单独决定 checkpoint、replay、reclaim 和 pending;Python 重新持锁核对完整观测后才执行游标写入和文件删除。这样 TS 成为回执恢复规则的唯一所有者,Python 保留源读回、锁及文件效果;计划本身不是脱锁删除许可。
具体改动
local_authority_shadow_adapter.py 删除原 _proof、_partition_history、_check_file 和 Python 决策分支,改为调用新的内部 plan_drain effect。local_authority_shadow_outbox.py 抽出完整字节复核并放在游标效果之前;effect_runtime_handlers.ts 注册新路由。新增 TS planner、Python/TS 定向与真实 File 集成测试,并同步 T3/L7 中英文 RFC ledger;未新增 CLI 参数、持久格式、配置入口或默认开启行为。
关键代码讲解
readShadowDrainPlan(shadow_drain_plan.ts第 185 行)只从真实 File verifier 获取 proof,不信任调用方提供历史;返回紧凑 plan。planShadowDrain(同文件第 115 行)集中验证回执序列、游标锚点、ACK 与预算外损坏尾部,再推导 replay/reclaim/pending。_PartitionDrainer._reconcile(local_authority_shadow_adapter.py第 517 行)只传文件观测,重新加锁核对 binding、游标、目录与所有原始字节,然后实施计划。verify_observed_files(local_authority_shadow_outbox.py第 379 行)复用删除前的字节规则,并把检查提前到任何游标写入之前。
对主干的风险
未发现阻断项。最危险的反例是 proof 后文件排版变化却先推进游标:新 Python 测试在 cursor、entry byte、new entry 三种交错下断言失败时游标和残留不变;伪造 ACK、损坏尾部与预算耗尽也由原生 TS 和真实 File 测试覆盖。旧 base 23edcb19c 与此 head 运行同一组未修改 File drain/adversarial/e2e 测试,均 49 项通过;head 另有 19 项 Python 和 47 项 TS 定向测试通过,typecheck、Ruff 和风险 canary 重跑通过。首次 canary 因隔离 worktree 未安装 Node 依赖失败,补齐依赖后重跑通过。未独立重跑 PR 作者声称的 PostgreSQL 集成和私有快照演练;本 diff 不改 PostgreSQL store/selector,不能把那些陈述算作本评审的自有证据。10,000 事务验证上限与长期迁移资格也没有被本 PR 放宽。
语义与 CI 对齐
内部 request/result v0 扩展的是既有 runtime-shadow coordination 词汇;持久 schema、公共 CLI 与 File/SQLite/PostgreSQL 晋升条件未改。语义词汇 smoke 在补齐 Node 依赖后通过。按 Goal packet 的 wait_for_ci=false,本评审没有抓取或等待远端 CI;维护者合并前仍须对未变 head 独立运行 merge-readiness。
我的整体评价
APPROVE:这是有实际调用方的规则去重和相邻正确性修复,而非为未来迁移搭空框架;生产侧约新增 202 行 TS planner,同时删除 Python 历史解释约 224 行。File shadow 真实入口、失败恢复及无副作用边界有对应验证。剩余 L2/L3、L5/D1、SQLite D2、L7/L8 和 L9 仍按现有 RFC/Goal 的条件路径推进;本批准不等于 provider 晋升或控制面自合并许可。
English verdict: APPROVE - exact head 16c2b57 centralizes File shadow recovery in TS and rejects post-proof byte changes before checkpoint effects; 49 shared base/head File tests, 19 Python, 47 TS, typecheck, Ruff, and the risk canary passed.
Keep both new effect-runtime routes: the native shadow drain planner added by this branch and the automation cadence handlers added by main. Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
The branch removes Python's drain decision branches, so six bounded-regression cases drifted off their locators. Re-home each case on the owner that now holds the same rule: the native planner's cursor, receipt-byte and replay decisions, and the reconciled adapter's verified-commit recording. Oracle tests and case names are unchanged, and every case is still killed by its own oracle. Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Removing the Python drain decision branches shifted two codec-read sites in local_authority_shadow_adapter.py. Regenerated with scripts/generate_project_registry_io_manifest.py; no sites added or removed. Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…ged base The merged main still carried stale codec-read anchors for todo.py, history.py, feedback.py and goal_admit_goal_amendment_proposal.py, and this branch shifts two local_authority_shadow_adapter.py anchors by deleting Python drain decisions. Regenerated with scripts/generate_project_registry_io_manifest.py; sites are unchanged (224) and no direct site is unclassified. 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) for exact head fc9b00d65516afdf772600d5ef29c2b8baa614cf.
本 head 相对上一次评审的变化只有两类:与最新 main 的合并(git diff 87ba2b4e1..HEAD -- <本 PR 的生产/测试文件> 为空,PR 自身表面没有改动),以及为合并后的树重新生成 project-registry I/O census。PR 本体的判断与上一次评审一致,下面是完整证据。
动机
File shadow drain 原先由 TS 证明完整 lineage,却把整个事务历史送回 Python,由 Python 第二次解释回执连续性、游标锚点、恢复预算与 ACK;同时证明之后若 outbox JSON 只变更排版,旧路径可能先推进游标、后在删除阶段才发现字节变化。受影响入口是 authority-shadow drain CLI 与写入后的 inline drain,两者都不需要新增配置。
交付判断是 justified_increment:这是针对 TS T3/shared-authority L7 的一个可独立评审、可回滚的完整恢复规则迁移——删除 Python 侧重复规则、由既有 coordination owner 决策——但不宣称整 Goal 迁移或默认 provider 切换。L2/L3 caller 采纳与 fence、L5/D1 canonical 消费者、SQLite D2 elapsed soak、L7/L8 连续性与受审 cohort、L9 默认与退役仍按现有 RFC/Goal 条件路径推进。
改动思路
入口是 _PartitionDrainer.run → _reconcile:它在维护锁下采集 binding、游标、目录与全部原始字节摘要,再调用 effect 路由 coordination.runtime_shadow.plan_drain。TS readShadowDrainPlan 只从真实 File verifier 取 proof,planShadowDrain 在纯决策边界推导 checkpoint、replay、reclaim 与 pending;Python 之后重新持锁核对完整观测,才执行游标写入与残留删除。计划本身不是脱锁删除许可,删除仍受锁、完整字节复核与既有预算约束。
复用的是既有 coordination/File shadow 权威边界:没有新增 capability、provider 或持久状态,旧的 Python 规则组是被删除而不是包了一层。与 main 的两次合并都只涉及 effect_runtime_handlers.ts 的 import 区(本分支的 readShadowDrainPlan 与 main 新增的 automation cadence 处理器并存,两条路由都在同一 handler 表中注册)以及生成物 census。
具体改动
生产侧 4 个文件:local_authority_shadow_adapter.py 删除 Python 的证明/历史解释与决策分支,改为调用新 effect;新增 shadow_drain_plan.ts 原生 planner;local_authority_shadow_outbox.py 抽出完整字节复核并前置到任何游标效果之前;effect_runtime_handlers.ts 注册新路由。测试侧新增 Python 原生 plan 用例、TS 单元与真实 File 集成用例,并把 6 个有界回归变异用例重新挂到新所有者。文档侧为 4 份中英 RFC ledger,另加 census manifest 的行锚点刷新。整份 diff 为 13 个文件、+928/−248(相对合并后的 main)。
关键代码讲解
planShadowDrain(loopx/control_plane/coordination/shadow_drain_plan.ts):回执恢复规则的唯一所有者。它验证分区历史连续性、游标锚点、ACK 与预算之外的损坏尾部,再推导 replay/reclaim/pending;损坏尾部即使超出预算也会整体拒绝,预算只影响效果选择。partitionDigest与同文件末尾的cursor_update计算:settled no-op 只推进位置、绝不合成 baseline digest,映射runtime_shadow既有的 applied-marker 语义;_reconcile直接消费该结果写游标。_PartitionDrainer._reconcile(loopx/control_plane/coordination/local_authority_shadow_adapter.py):只把文件观测交给原生 planner,然后在维护锁与 primary 锁下重新核对 binding、游标、目录列表与所有原始字节,之后才写游标并按 plan 删除已核对残留。verify_observed_files(loopx/control_plane/coordination/local_authority_shadow_outbox.py):复用删除阶段原有的字节规则,并把检查提前到任何游标写入之前,关闭"先推进游标、后拒绝字节"的窗口。examples/shared-goal-authority-e2e/mutants.py:cursor_baseline_digest、cursor_digest_unchecked、receipt_bytes、cursor_regression、replay_counted_as_delivery、cleanup_hides_verified_commit六个用例原先定位在已被本 PR 删除的 Python 分支上;现在改挂在持有同一规则的新所有者(原生 planner 与协调后的 adapter),用例名与 oracle 测试保持不变,本 head 逐项复验仍为 assertion kill。
对主干的风险
最强的反例仍是"proof 之后字节只变排版却先推进游标":现在 verify_observed_files 在任何游标写入前完整复核观测批次,测试在 cursor、entry byte、new entry 三种交错下断言失败时游标与残留都不变。其余强反例——伪造 ACK、损坏历史与预算外损坏尾部、清理权限失败后仍须报告已证提交——由重新挂接的变异用例、真实 File 集成用例和既有 adversarial 用例覆盖。
验证矩阵:
- Python:
tests/control_plane/test_shadow_drain_native_plan.py、test_shadow_drain_adversarial.py、test_shadow_drain_e2e.py、test_shadow_cursor_recovery_e2e.py共52 passed;本 head 上tests/architecture/test_project_registry_io_census.py与test_goal_instance_binding_inventory.py共9 passed。 - 变异 lane:完整 54 例在本机 GREEN/RED 全通过,
stage2c (mutants 0)在 CI 上对本 PR 的87ba2b4e1通过;6 个重新挂接的用例在本 head 再次逐项复验。 - TypeScript:
npm run typecheck:control-plane通过;npm run test:control-plane在本 head 为2870 passed / 1 failed,唯一失败是tests/control_plane_ts/authority_source.test.ts的todo_terminal_lifecycle_request生成契约文案断言,该失败在未包含本 PR 的origin/main上可 1:1 复现,与本 diff 无关。配置范围内的python -m ruff check与python -m mypy(22 个模块)通过。 - CI 对本 head 的
87ba2b4e1:stage2c (mutants 0)与postgresql-authority (real server)通过;test-shard (3)的失败已定位为origin/main自身 stale 的 census 锚点(todo.py、history.py、feedback.py、goal_amendment_proposal.py共 11 处),本 head 已随合并一起重新生成并本地复验。未在本机独立复跑私有快照演练;10,000 事务验证上限与长期迁移资格没有被放宽。 - 观察到的预算压力:Node 26 前向兼容 lane(
continue-on-error: true)在本 PR 的前一 head 上超过其 20 分钟预算被取消,而 main 最近一次成功记录为 16m24s;新增的 TS 用例让这个咨询型 lane 更接近上限,属于需要后续关注的预算压力,不是本 PR 的阻塞项。
语义与 CI 对齐
内部 request/result v0 扩展的是既有 runtime-shadow coordination 词汇;持久 schema、公共 CLI 与 File/SQLite/PostgreSQL 晋升条件未改。按 Goal packet 的 wait_for_ci=false,本评审不抓取、不等待远端 CI,结论来自未变 head 上的本地验证与已完成的同内容 CI lane;维护者合并前仍须对未变 head 独立运行 merge-readiness。另需记录:origin/main 当前在 census 与 authority_source.test.ts 两处为红,本 PR 顺带修复了前者,后者超出本 PR 边界,保持未修。
我的整体评价
APPROVE:这是有实际调用方的规则去重与相邻正确性修复,而不是为未来迁移搭空框架;File shadow 的真实入口、失败恢复与无副作用边界都有对应验证,上一轮暴露的"变异 oracle 仍指向已删除代码"与 stale census 也已修复,且本 head 的 PR 自身文件与已充分验证的 87ba2b4e1 逐字相同。剩余 L2/L3、L5/D1、SQLite D2、L7/L8、L9 仍按现有 RFC/Goal 条件路径推进;本批准不等于 provider 晋升或控制面自合并许可。
English verdict: APPROVE - exact head fc9b00d65516afdf772600d5ef29c2b8baa614cf centralizes File shadow drain recovery in the native TypeScript planner, rejects post-proof byte changes before any checkpoint effect, and re-homes the six bounded-regression mutants onto the owners that now hold those rules; the merged head only adds the latest main plus the regenerated project-registry census, with 52 focused Python tests, 9 architecture census tests, typecheck, Ruff, mypy, the full 54-case mutation lane and the CI stage2c mutants job passing.
|
Merged decision record (admin-bypass merge, maintainer-authorized).
Changed surfaces and validation:
|
Problem and result
Shadow drain asked TS to verify the File lineage, transported the entire compact transaction history to Python, then interpreted receipt recovery a second time. Drain now sends filesystem identities/digests to a native TS planner and receives only checkpoint, reclamation, replay and pending-work decisions. Python keeps source readback, locks and filesystem effects; persisted formats, CLI flags and provider defaults stay compatible.
The refactor also fixes checkpoint ordering: a formatting-only change to an outbox JSON file after proof must reject before either cursor advancement or deletion. Complete byte revalidation is shared with the existing reclamation check. Budget selection still follows validation of every residue, no-op receipts preserve the last applied digest, and lost ACKs recover without duplicate mutations.
Delivery context: #4574; TS T3 and shared-authority L7. This is the existing coordination/File-shadow owner, not a new capability. Paired RFC ledger entries retain the conditional 5–8-package default-on plan. This slice does not claim whole-Goal migration completion, change provider defaults, or replace SQLite D2's elapsed soak. The native 10,000-transaction history ceiling remains unchanged; backlog-sized plans and verifier cost remain bounded by their existing contracts.
Validation
Entry points:
authority-shadow drainand inline post-write drain. Existing CLI results/readback are exercised. No frontend configuration change is required because there is no new setting or user action. The related refactor removes Python history interpretation and shares byte validation. Runtime/control-plane change: maintainer merge required.