test(authority): execute the Stage 2C parity-half ladder rows - #4167
Conversation
Replace the nine pending `s2c2.*` declarations with executable ladder rows that drive one explicitly enabled `coordination.runtime_shadow` goal through the public CLI and assert only through `authority-shadow status|drain`, `coordination-shadow bootstrap|inspect|qualify|read-candidate|rollback` and `migrate-state`, reading history through the TypeScript shadow read over the retained store. A tenth row pins the event-only Todo source hold and its recovery. The rows carry the `stage2c_e2e` marker so CI runs them in the stage2c correctness job next to the other real-CLI and process-death suites. Two declarations stay pending: the >=10-day soak owned by RFC section 7.2, and a capture gap the parity row exposed. `todo archive-completed` on a Todo that holds a released lease record keeps that lease in the candidate head while the source projection drops the orphaned lease, so bounded qualification reports `shadow_projection_drift`; the parity row therefore archives nothing and the gap stays visible as `s2c2.archive_after_leased_completion_parity`. Three negative controls remove one operator-visible truth each and turn the corresponding row red. The new module joins the strict mypy file list. Signed-off-by: wchwawa <wch19961116@gmail.com>
huangruiteng
left a comment
There was a problem hiding this comment.
动机
这个 PR 把 Stage 2C2 authority parity-half ladder 从待办声明转成可执行的真实 CLI 端到端验证,覆盖 outbox、drain、崩溃窗口、回滚、漂移、迁移与增长测量。审阅绑定 exact head b2c6e8e292171d45fa6f9d5d68cf51979dbc2320。
改动思路
新增可安装的测试编排模块,所有状态决策、写入与回读都走公开 CLI 和生产 TypeScript authority store;测试只在时序屏障处注入控制,不替换产品结果。九项 Stage 2C2 声明被落成十行可执行 ladder,同时保留两个确实尚不能证明的 typed pending obligation:leased completion 的 archive capture 缺口,以及不少于十天的持续 soak。
具体改动
- 增加 prepared/committed outbox、bounded/idle/replay drain、SIGKILL primary/drain 窗口、rollback/rebootstrap、mixed-writer parity、direct drift、event-only source hold、migration refusal/rollback/new lineage 与 growth measurement 的真实 CLI 行。
- 更新 ladder registry、pytest markers、mutants、双语 RFC/README/correctness 文档及 strict mypy 纳入范围。
- 继续使用 disposable synthetic goals;默认关闭,不提升、改写或复用活跃 goal/registry/todo/lease 状态。
关键代码讲解
关键设计是把故障注入限制在“何时暂停/杀掉进程”,而不是伪造 authority 结论:worker 仍调用生产符号,随后由独立 CLI 进程读取落盘状态并判定。迁移与 event-only 行还验证了拒绝、回滚和新 lineage,而不仅仅检查快乐路径输出。
对主干的风险
我在 exact head 上运行 Stage 2C2 E2E,10/10 通过(364.28s);在最新 main 的合成合并树上再次 10/10 通过(368.53s),并额外通过 22 个 writer-fence caller-parity 测试。exact head 与合成合并树上的 Ruff、strict mypy 和 diff check 均通过。
远端四个红项已逐项归因:一个是与本 PR 无关的真实 git pull 网络失败,两个是当时 main 上已修复的 writer-fence 路径文本基线,另一个是聚合 merge-gate。当前 main 合成树的对应 parity 已通过,未发现 PR-owned failure;但合并前仍应更新分支并让远端检查重新跑绿,这是 merge readiness 要求,不是代码结论阻塞。
非阻塞 P2:新模块约 1,142 行,整体是完成 RFC 矩阵所需的跨接口编排,范围仍然成组且可回滚;其中约 50 行 crash worker 与 shadow_e2e_fixture 重复。建议下次任一 fault window 变化时,把共同 installable worker/builder 收敛到现有 control_plane.testing 边界并让两套套件复用,当前无需先造更宽的框架。
我的整体评价
这个 PR 把“计划中的可靠性证明”变成走真实生产入口的可复现证据,同时明确保留尚未满足的长期义务,没有用 mock 或文字声明冒充完成。代码量较大但与一组完整的 E2E 合约相称;future-facing 检查给出了有界后续而不扩张本 PR。结论:APPROVE。
English verdict: APPROVE for exact head b2c6e8e292171d45fa6f9d5d68cf51979dbc2320. The ten Stage 2C2 rows exercise the real CLI and production TypeScript authority store on disposable goals; exact-head and current-main integration runs both passed. Rebase/update and rerun remote checks before merge, and treat crash-worker deduplication as a bounded non-blocking P2 for the next fault-window change.
Summary
Execute the Stage 2C parity half of the shared-goal-authority ladder (lane C, "qualify the implementation merged in #3870"). The nine
s2c2.*declarations that were pending since #3869 become executable rows, plus one row for the event-only Todo source hold. Every row drives one explicitly enabledcoordination.runtime_shadowgoal through the realpython -m loopx.cliand asserts only through the shipped operator interfaces:authority-shadow status|drain,coordination-shadow bootstrap|inspect|qualify|read-candidate|rollback,migrate-state. History is read through the TypeScript shadow read (readLocalAuthorityShadow) in an independent node process; the rows add no product path and never read the candidate for a decision.s2c2.outbox_prepared_then_committed_entries,s2c2.drain_idempotent: a held maintenance lock defers the Python Todo writer's and the TypeScript lease writer's drains (drain_lock_busy);statusshows one committed entry per partition with its prepared record and committed marker; one drain delivers both once; bounded drains are cumulative, an idle drain changes nothing, a same-key re-acquire mints no entry.s2c2.sigkill_between_primary_write_and_drain,s2c2.sigkill_mid_drain: a real CLI process is SIGKILLed atbefore_replace,after_replace,before_markerand atbefore_commit,after_commit,after_cursor,between_unlinks; drain settles prepared-only entries asabandonedorcommitted_proven_by_readbackand recovers mid-drain deaths from exact receipts without a second delivery.s2c2.rollback_with_pending_entries: exact-revision rollback archives the outbox with its pending entries, marker, cursor and manifest; capture then reportsbootstrap_requiredwhile primary writes continue; a rebootstrap starts a new lineage from the current primary and the historical rollback replays against it.s2c2.parity_equal: three cycles interleave Python Markdown writers (add, note update plus a no-change repeat, explicit exclusion set/clear plus a no-change repeat, leased complete, supersede, capture-followups) with TypeScript lease writers (acquire, renew, transfer, fence close): 43 deliveries, 37 writer calls, 6 no-change writes, 9 write classes; every boundedqualifyisqualifiedwithoperation_countequal to the deliveries andsustained_parity_verdict=not_evaluated.s2c2.parity_divergent_detects_foreign_edit,s2c2.event_only_todo_source_holds: a direct primary edit reportsshadow_projection_driftand a later write holds onsource_partition_continuity_unproved; an event-only Todo source holdsinspect,qualify,read-candidatewithevent_log_writer_not_bound; restoring bytes or removing the event source never requalifies, only rollback plus rebootstrap does.s2c2.migration_seeds_and_drains:migrate-statepreviews an actively captured goal without writing and refuses--executewithshadow_source_replacement_requires_rebootstrap(also with capture merely disabled); after rollback the migrated goal carries its disabled configuration, requires its own bootstrap, then drains and qualifies on its first write.s2c2.growth_measurement_gate: ten fixed-size writes; cursor advances by one each time,store_bytesgrows monotonically, per-transaction growth accelerates by at most one live record, every retained transaction carries its complete projection; the report carries final/cumulative publication bytes and claims no capacity horizon.Two declarations stay pending and are documented in the README,
correctness.mdand both RFC languages:s2c2.archive_after_leased_completion_parity: a capture gap the parity row exposed.todo archive-completedon a Todo that holds a released lease record keeps that lease in the candidate head while the source snapshot drops the orphaned lease (the rule pinned bytest_source_snapshot_preserves_inventory_without_projecting_orphan_leases), soinspectreportsshadow_projection_drift. Unleased archives stay matched. The parity row therefore archives nothing rather than hide it; the fix belongs to the archive writer's capture and is not attempted here.s2c2.sustained_parity_soak: the >=10-day synthetic-goal soak owned by RFC section 7.2 / lane L.The
s2c2.*rows carry thestage2c_e2emarker, so CI runs them in the stage2c correctness job (about 130 s serial on one file-grouped worker) instead of the pytest shards. Three negative controls (status_hides_prepared_only,qualification_ignores_drift,replay_counted_as_delivery) each remove one operator-visible truth and turn the matching row red. The new module joins the strict mypy file list.Not in scope: no provider, promotion, projection or capture-kernel change; the RFC edits record executable evidence only and change no normative text.
Issue Or Task
Lane C remainder of the shared-goal-authority RFC (Appendix C, "finish sustained mixed-writer parity, explicit-clear/omission coverage, and event-only Todo recovery evidence"); D3 card "audit sustained mixed-writer and event-only coverage against the final command matrix". Follow-up of #3869 / #3870 / #3985.
Validation
b2c6e8e29(based on mainf38847b1c).python examples/shared-goal-authority-e2e/ladder.py --stage 2c2 --allow-pending: 10 pass, 0 fail, 2 pending, 0 privacy violations, exit 0; run under node 24.11.1 and 26.4.0 (about 125 s each).python -m pytest -q -n 4 --dist loadfile -m stage2c_e2e: 223 passed (213 existing + 10 new rows) in 4 min 3 s; the only error istests/test_kiro_cli_host_surface.pycollection (No module named 'yaml', local environment).python -m pytest -q -n 2 --dist loadfile tests/control_plane/test_shared_goal_authority_e2e.py: 22 passed, 8 skipped (5 twin-covered s2c1 rows, 3 environment-gated live rows).python examples/shared-goal-authority-e2e/mutants.py --case status_hides_prepared_only --case qualification_ignores_drift --case replay_counted_as_delivery: 3 selected, 3 executed, 3 killed by assertion; controls green.python -m pytest -q -n 2 -m "not stage2c_e2e"(kiro host-surface module ignored for the missing localyaml): 7078 passed, 33 skipped, 12 failed; the 12 are the known environment-only set (9 git-hooktest_repository_change_window.pycases, doctor runtime readiness, doctor installation scope, the CI shard test needingpytest-split) and none touches the ladder, capture or documentation surfaces changed here.npm run test:control-planeunder node 24.11.1: 908 passed; the 2 failures (quota_monitor_poll_commit.test.ts,monitor_successor.test.ts, Node assert message type) reproduce identically on the untouched basef38847b1c; no TypeScript file changes here.npm run typecheck:control-plane;python -m mypy(22 source files, new module included);ruff check tests loopx/canary loopx/control_plane loopx/domain_packs loopx/presentationwith ruff 0.15.22;scripts/generate_coordination_state_contract.py --check;examples/control_plane/cli-output-budget-regression-smoke.py.loopx --format json canary premerge --from-git-diff: tier standard, 17 checks selected, 0 failures (diff checks, python compile, risk-profile smokes, public boundary).python -m build(build 1.6.0, disposable environment) thenexamples/shared-goal-authority-e2e/installed.pyfor the wheel and the sdist: bothstatus=passed, 5 stages each, 0 unverified.Known local-only failures unrelated to this change (same on main):
tests/test_python_ci_workflow.py::test_two_shards_execute_each_test_once_and_merge_portable_coverage(needspytest-split), git-hook and doctor environment tests.