Skip to content

feat(authority): add local post-commit observation capture - #3818

Merged
huangruiteng merged 9 commits into
mainfrom
codex/local-authority-shadow-product-path
Sep 3, 2026
Merged

huangruiteng merged 9 commits into
mainfrom
codex/local-authority-shadow-product-path

Conversation

@wchwawa

@wchwawa wchwawa commented Sep 1, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Add the default-off Stage 2C observation foundation: existing local writers remain canonical and a file candidate captures best-effort post-commit snapshots.
  • Wire product CLI Todo, task-lease, handoff, and migration paths through the existing coordination owner without reading the candidate for decisions.
  • Expose machine-readable evidence that this is capture only, not parity or promotion evidence.

@huangruiteng This PR is the first half of Stage 2C, not Stage 3 remote parity or Stage 4 canary work.

Issue Or Task

  • Implements the local post-commit observation slice of the Shared Goal Authority RFC.
  • Contributor task ID: stage-2c-local-post-commit-observation

Validation

  • Focused Python suite: 20 passed
  • TypeScript observation contract: 8 passed
  • Subprocess CLI E2E: configure, Todo write, task-lease write, candidate readback, disable, and default-off isolation
  • Candidate-failure E2E: the primary local commit remains successful
  • POSIX SIGKILL E2E: proves the commit-to-observer loss window and later full-snapshot refresh
  • npm run typecheck:control-plane
  • loopx canary premerge --from-git-diff --git-diff-base origin/main (18/18, no warnings or holds)

Type of Change

  • New feature
  • Refactoring (behavior-preserving outside the explicit opt-in)
  • Documentation update
  • Test update

LoopX Area

  • Control plane (goals, todos, quota, scheduler, registry, runtime)
  • Public docs or presentation surface (README, protocols, dashboard)

Technical Direction

  • Shared Goal Authority and cross-host coordination

  • Target base branch: main

  • Direction tracker or promotion unit: Stage 2C local observation foundation

observation_trigger is diagnostic context, not source transaction identity. Every result states source_transaction_correlated=false, durable_source_outbox=false, source_candidate_compared=false, and parity_verdict=not_evaluated.

This PR does not add an outbox, compare source and candidate, issue a parity verdict, fence legacy writers, or promote FileAuthorityStore. The RFC also records that #3669's historical “Stage 3” name maps to the current RFC Stage 0 foundation, not current Stage 3 remote shadow parity.

Known Debt Carried Into the Second Half of Stage 2C

These are measured on this head and are deliberately not fixed here. Each one blocks the parity and promotion half of Stage 2C, not this observation slice, and each is listed so the promotion review does not inherit it silently.

  • Full-snapshot rewrite growth. Every observation captures the complete current projection as a new retained FileAuthorityStore transaction, and the file provider rewrites the whole document. Observed on a fixture with 100 Todos: 200 lease renewals grew one candidate file to 2.79 MB (+10.9 KB per renewal) and raised renewal latency from 0.18 s to 0.54 s. Cumulative cost is quadratic in the number of observations until compaction or delta capture exists.
  • Observation lock on the primary write path. Observations of one Goal serialize behind a 1.0 s exclusive_file_lock. Under contention a primary write waits up to that full second, and an observation that cannot take the lock is dropped and reported as unavailable; with four concurrent writers, 1 of 24 observations was dropped. The evidence stays typed, but capture is best-effort by construction.
  • Two runtime roots under --runtime-root. Fixed in round 3 (see below): every hook now consumes one effective runtime root, and a subprocess E2E pins the single lineage.

Round 3 (exact head ea15267fe)

Rebased onto main at fe80aecd7. The only conflict was the tsconfig.control-plane.json include list shared with #3819 and #3832; it is resolved as the union.

Fix for the P1 on 422757dd9:

  • local_authority_shadow_adapter.effective_runtime_root is the one resolver every observation hook consumes: the CLI --runtime-root override when given, otherwise the registry common_runtime_root, with a relative value anchored at the registry's project root instead of the caller's working directory. runtime_root_from_registry anchors the same way, so lease files and observations of one goal share one root.
  • Todo add/update/complete/supersede/archive-completed, capture_followup_todos, and set_goal_handoff_mode accept runtime_root_arg; the CLI passes its override through, and each writer hands the resolved root to its ownership gate, lease fence, and post-commit observation. Non-CLI callers keep the registry-root default.
  • New subprocess E2E test_product_cli_runtime_root_override_keeps_one_candidate_lineage: with common_runtime_root != --runtime-root, todo add, task-lease acquire, todo update, capture-followups, and a leased completion produce exactly one store identity; the head holds both todos and the released lease; the registry root gains neither authority-shadow/ nor a lease directory. test_relative_common_runtime_root_resolves_against_the_project_root_for_every_hook pins the anchoring from a foreign working directory.
  • SonarCloud: explicit comparator instead of the default sort() in local_authority_shadow.ts; set_goal_handoff_mode and execute_native_task_lease_acquire split into helpers below the cognitive-complexity limit; the configure-goal exception test has exactly one raising call.
  • loopx/todos.py sits exactly at its maintainability ceiling, so a separate pure-move commit relocates the todo list projection into loopx/control_plane/todos/goal_todo_projection.py before the threading lands. No caller outside loopx/todos.py used the moved helpers.

Behavior disclosure: a relative common_runtime_root now resolves against the registry's project root for the task-lease verbs and every observation hook; previously the lease verbs resolved it against the caller's working directory. Absolute roots and the default (no override) path are unchanged.

Validation on this head:

  • Full pytest -n 4: 5161 passed, 12 skipped; the 12 failures in this environment are the same git-hook install, doctor runtime-readiness, and pydantic/fastmcp-dependent MCP tests that fail identically on main here.
  • TypeScript control plane: 463 passed, 1 PostgreSQL integration skipped; npm run typecheck:control-plane clean.
  • Ruff, configured mypy, maintainability ratchet, visible-governance and CLI help smokes: clean.
  • loopx canary premerge --from-git-diff --git-diff-base origin/main: standard tier, 4/4 direct checks, 18/18 catalog canaries executed with 0 failures and 0 warnings, full-public risk profile ok, premerge-public-boundary clean, 0 manual holds.

Still not in this PR, per the previous verdict: durable outbox, source/candidate compare, parity verdict, legacy writer fencing, promotion. Those follow in the Stage 2C second-half PRs stacked on this branch.

Boundary Checklist

  • I did not commit .loopx/, .codex/goals/, live ACTIVE_GOAL_STATE.md, credentials, private benchmark traces, verifier output, raw agent sessions, internal document links, or local machine paths.
  • I did not duplicate maintainer-owned benchmark work unless a maintainer split out a public issue for it.
  • I kept the change scoped to the linked issue/task.
  • Every commit includes a DCO Signed-off-by trailer (git commit -s).

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

动机

这个方向本身贴合 RFC:Stage 2C 的前半段确实需要一个默认关闭的本地 shadow,把 legacy Markdown/task-lease 的提交结果投影到 FileAuthorityStore,同时保持 legacy writer 为唯一 authority,候选失败也不能反向推翻主写。

改动思路

实现采用 post-commit observer:各 Todo/lease/handoff/migration 写路径完成后,重新读取完整本地 projection,计算 digest,再通过 TypeScript AuthorityStore 写入 file candidate;candidate 永不参与执行决策。这个边界和 default-off/failure-isolation 原则是对的。

具体改动

  • 增加显式的 --local-authority-shadow-file 配置与关闭入口;
  • 为 Todo、follow-up、task lease lifecycle、handoff mode、state migration 接入提交后观察;
  • 用 operation_id + source_digest 在 FileAuthorityStore 中保留 observation receipt;
  • 增加冲突重试、迁移新 lineage、provider failure 不影响主写等测试。

对主干的风险

当前实现能证明的是“某次主写之后采样到的一份完整快照,被候选持久化了”,还不能称为 parity evidence 或 Stage 2C qualification:

  1. observer 在主写提交后重新采样整个 source,和原事务之间没有 durable outbox/锁内 receipt 绑定。并发写可能让 source_operation=A 对应到已经包含 B 的快照;进程在 commit 与 observer 之间崩溃也会丢失该 observation。RFC 文档承认了 crash gap,但 catalog 和 PR 描述仍把结果称作 parity evidence / exact durable receipt,容易让后续 promotion 错用这份证据。
  2. 当前没有 source-vs-candidate readback compare,也没有 parity verdict。候选返回 advanced 只证明 candidate commit 成功,不证明两个 authority view 相等。
  3. default-off 时执行语义基本隔离,但 configure-goal summary 与 capability catalog 仍新增了字段,因此“默认模式零可观察变化”也应收窄为“默认关闭时不执行 shadow、不改变 lifecycle 决策”。

请在合入前完成至少一种收敛:

  • 若本 PR 只交付 plumbing:把标题、PR body、catalog display/consider_when 和 evidence 说明统一改成 “post-commit shadow observation/capture”,明确它不是 parity verdict,也不能单独作为 promotion evidence;最好把 source_operation 改成不暗示精确事务绑定的 observation_trigger,或同等清晰的语义。
  • 若要保留 parity/transaction evidence 的声明:必须把 observation 绑定到主写的 durable transaction identity(outbox 或等价机制),并增加 candidate readback compare/typed parity result。

我的整体评价

架构方向正确,作为 Stage 2C 前半段的 observation foundation 有价值;但当前命名和资格声明高于实际保证,会污染后续 authority promotion 的证据链,因此先 Request changes。调整声明边界后,不要求这个 PR 一次完成 durable outbox 和完整 promotion gate。

English verdict: Request changes. The default-off post-commit observation plumbing aligns with the first half of Stage 2C, but it does not yet provide transaction-correlated shadow delivery or a source/candidate parity verdict. Reframe the contract and UI as observation capture, or add durable transaction binding plus explicit parity readback before claiming qualification evidence.

@wchwawa
wchwawa force-pushed the codex/local-authority-shadow-product-path branch from 80764e8 to 422757d Compare September 2, 2026 07:03
@wchwawa wchwawa changed the title feat(authority): add local post-commit shadow feat(authority): add local post-commit observation capture Sep 2, 2026
@wchwawa

wchwawa commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator Author

@huangruiteng Addressed the change request:

  • recast the feature as Stage 2C best-effort post-commit observation, not parity or promotion evidence;
  • renamed source-facing identity to observation_trigger / observation_id;
  • made the missing transaction correlation, outbox, comparison, and parity verdict explicit in every evidence result and in the catalog;
  • added real subprocess CLI and SIGKILL E2E for enable/write/readback/disable, failure isolation, and the known capture-loss window.

The RFC now also disambiguates #3669's historical Stage 3 label from the current stage map. Please re-review exact head after the force-push.

@wchwawa

wchwawa commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator Author

@huangruiteng One addition to the PR body only, no code change on head 422757d: a new section "Known Debt Carried Into the Second Half of Stage 2C" lists three measured limits of this observation slice so the parity/promotion review does not inherit them silently: full-snapshot rewrite growth (100 Todos + 200 renewals grew one candidate file to 2.79 MB and renewal latency from 0.18 s to 0.54 s), the 1.0 s observation lock on the primary write path (1 of 24 observations dropped as typed unavailable under four concurrent writers), and the two candidate lineages produced when Todo hooks resolve the registry runtime root while task-lease hooks receive a --runtime-root override. They are prerequisites for the parity and promotion half, not for this capture slice.

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Findings

[P1] --runtime-root 会把同一 Goal 的成功 observation 分裂成两个 store lineage

触发条件是 registry 的 common_runtime_root 与本次 CLI 的 --runtime-root override 不同。Todo/follow-up 路径在 local_authority_shadow_adapter.py:447-450 固定传入 runtime_root=None,因此回退到 registry root;task-lease 路径在 task_lease_acquire_adapter.py:54-57 传入调用方的 override。两边都会返回 outcome=captured,但实际写入两个不同的 store_identity:Todo store 的 head 没有刚 acquire 的 lease,lease store 又是另一条 authority history。这样一来,当前 opt-in capture 自身就无法形成一份 Goal 级完整观察;这不只是后续 parity/promotion 阶段的性能债务,而是成功证据与实际 lineage 不一致。

最小修复是让所有 post-commit writer hook 消费同一个已解析的 effective runtime root(不能一部分重新从 registry 推导、一部分沿用 CLI override),并增加真实 subprocess E2E:令 common_runtime_root != --runtime-root,依次执行 Todo add 与 task-lease acquire,断言只产生一个 store identity,且同一个 head 同时包含 Todo 和 lease。当前 head 上我独立复现到:两个调用均返回 captured,但生成两个不同 identity,Todo-side head 的 lease 数为 0、override-side head 的 lease 数为 1。

动机

这个 PR 试图补齐 Shared Goal Authority Stage 2C 的第一段产品路径:现有 Markdown Todo、handoff mode 与本地 task-lease writer 仍是唯一 canonical authority;在主写提交后,把当前完整本地 projection 以默认关闭、显式 opt-in 的方式交给 FileAuthorityStore 保存。旧行为没有可从真实 CLI writer 进入的 observation seam,因而即使 file provider 已有 conformance contract,也无法观察 Todo/lease 的实际组合状态。单独给某一个 writer 加 hook 不足以覆盖 Goal coordination 的真实写面,所以覆盖 Todo、follow-up、handoff、lease lifecycle 与 migration 是合理的最小产品边界;本 PR明确不承担 durable outbox、source/candidate compare、parity verdict、legacy writer fencing 或 authority promotion。

改动思路

入口由 configure-goal --local-authority-shadow-file 控制。Python adapter 读取闭合的 file_one_way 配置,在 primary commit 之后连续采样本地 Todo、handoff mode 与 lease projection,计算稳定 digest 和 observation id,再调用 TypeScript effect handler。TypeScript 侧只负责把 snapshot、event 与 receipt 通过 FileAuthorityStore 的 revision/CAS 合同写入 candidate;candidate 永不回流到 lifecycle 决策。正向路径是“enable -> legacy writer commit -> sample -> candidate commit -> typed captured evidence”;负向路径是 provider construction/read/commit、lock timeout 或 protocol mismatch 均降级为 failed/unavailable 等 observation evidence,已完成的 primary write不回滚。迁移路径刻意不复制旧 candidate identity,而在目标 runtime 从迁移后的 canonical state 建立新 lineage。

原 review 关于 authority 语义的 blocker 已基本解决:source_operation/operation_id 已收窄为 observation_trigger/observation_id,所有 evidence 都明确声明 source_transaction_correlated=false、durable_source_outbox=false、source_candidate_compared=false、parity_verdict=not_evaluated;RFC、CLI help 与 catalog 也不再把它称为 parity/promotion evidence。

具体改动

Exact head 422757dd9f56f2543708a35ff44c04445ad96068 相对 PR base 共 23 个文件、+2796/-34:production +1151/-27,tests +1565/-0,docs +77/-7,build/config +3/-0。生产面包括配置归一化与 catalog、Python observation adapter、TypeScript store handler、Todo/follow-up/handoff/task-lease hooks、migration seed,以及 wheel/tsconfig 打包入口;测试面覆盖配置、真实 CLI、runtime failure/retry、migration 新 lineage 和 TypeScript receipt/CAS;中英文 RFC 同步收窄了 observation 的能力边界。

关键代码讲解

  • observe_local_authority_commit:以 registry config 为 gate,采样并 canonicalize Goal projection,生成 digest/observation id,在 provider revision conflict 后重新采样;异常只生成 typed evidence。当前 runtime-root 分裂也发生在这个 symbol 的调用参数边界。
  • recordLocalAuthorityShadow:TypeScript-owned candidate commit seam;校验闭合 request/projection schema,通过 FileAuthorityStore 做 CAS,并仅在可读回同一 observation receipt 时把 ambiguous/replay 判为已捕获。
  • _attach_local_authority_shadow:把真实 task-lease acquire/renew/transfer/release 的 committed result 接到 observer;它传入 caller runtime root,与 Todo hook 的 registry-root 选择不一致,是本次 blocker 的另一半。
  • seed_migrated_authority_shadows:迁移完成后从目标 canonical files 生成 fresh candidate lineage,避免复制旧 store identity/revision;失败被压缩为 public-safe migration evidence,不推翻已经完成的迁移。
  • apply_local_authority_shadow_change / local_authority_shadow_summary:用闭合 schema 管理 enable/disable 与 readback,默认不配置时不进入 TypeScript candidate runtime。

对主干的风险

最强回归场景是用户通过受支持的全局 --runtime-root 隔离运行时:Todo 与 task-lease 都表面成功,candidate 却被拆成两个互不相干的 store。它的 blast radius 限于显式启用该实验功能的 Goal,不改变 legacy primary authority,但会让 observation consumer、后续 parity 工作或人工排障读到不完整 head;现有 evidence 没有暴露 lineage split,因此可观察性不足。修复后应以上述不同-root E2E作为回归门禁。

其余边界验证较扎实:默认关闭时没有 candidate effect 或目录,provider failure 不反转主写,SIGKILL 测试诚实展示 commit-to-observer loss window,迁移不复制旧 lineage。仍需保留的 residual risk 包括 full-snapshot history 的二次增长、1 秒 observation lock 对 opt-in 主写响应时间的影响,以及无 durable outbox 导致的单次漏采;这些已经在 PR body/RFC 中披露,可留给 Stage 2C 后半段,但不能用来豁免当前的双-lineage 正确性问题。配置 catalog/readback 在 feature disabled 时仍有加法式 schema 可见变化,因此这里证明的是 lifecycle/decision isolation,而不是整个 CLI 输出逐字节不变。

验证结果:focused Python 20 passed;TypeScript control plane 394 passed, 1 PostgreSQL integration skipped;npm run typecheck:control-plane 通过;Ruff 与 git diff --check 通过;风险型 premerge gate 18/18 通过;public-boundary scan 24 files clean。GitHub pytest/DCO/build 等通过,但 SonarCloud Quality Gate 仍为 ERROR(new reliability rating D;当前公开 API 返回 5 个 open issues),远端 merge state 仍是 BLOCKED。合入前还需要把该 check 处理到绿色或给出仓库策略认可的等价处置。

我的整体评价

这个 exact head 已正确修复上一轮最关键的“把 observation 冒充 parity/transaction evidence”问题,TypeScript/Python ownership、failure isolation、migration lineage 与文档非目标也比旧 head 清晰。代码量虽然大,但大部分来自真实 writer 覆盖和系统级负向测试,修复 single-runtime-root 以后整体 scope 可以保持在本 PR 内,不需要为了形式拆散。不过当前支持的 CLI override 会制造两个都声称 captured 的 store,因而 change proportionality 与 authority observation 的完整性尚不能通过 completion gate;结论为 Request changes。请统一 effective runtime root、补上不同-root E2E,并清理失败的 SonarCloud gate 后再复审;无需在本 PR 扩展 durable outbox 或实现 parity promotion。

English verdict: Request changes on exact head 422757dd9f56f2543708a35ff44c04445ad96068. The earlier parity/transaction overclaim is now correctly resolved, and the focused/runtime/premerge validation is strong. However, a supported --runtime-root override makes Todo and task-lease hooks write two distinct FileAuthorityStore lineages while both report captured; route every writer through one effective runtime root, add a mismatched-root subprocess E2E, and clear the failing SonarCloud quality gate before re-review.

Signed-off-by: wchwawa <wch19961116@gmail.com>
Signed-off-by: wchwawa <wch19961116@gmail.com>
Signed-off-by: wchwawa <wch19961116@gmail.com>
Signed-off-by: wchwawa <wch19961116@gmail.com>
Signed-off-by: wchwawa <wch19961116@gmail.com>
Signed-off-by: wchwawa <wch19961116@gmail.com>
loopx/todos.py sits exactly at its maintainability ceiling (2285 lines), so
threading one effective runtime root through the writer hooks cannot land
there without growing the module. Move the todo list projection block
(filtered summaries, the Markdown/event merge, and goal_todo_summaries) into
loopx/control_plane/todos/goal_todo_projection.py; list_goal_todos keeps its
behaviour and delegates to the new module.

Pure move: no call site outside loopx/todos.py used the moved helpers, and the
todo list, thin/explicit-limit, and agent-lane projection suites are unchanged.

Signed-off-by: wchwawa <wch19961116@gmail.com>
…ntime root

Review finding on the previous head: with `common_runtime_root` different from
the CLI `--runtime-root` override, Todo and follow-up hooks resolved the
registry root while task-lease hooks used the override, so one goal produced
two FileAuthorityStore lineages that both reported `captured`. The Todo-side
head had no lease and the lease-side head had no Todo.

- local_authority_shadow_adapter.effective_runtime_root resolves the one root
  of a CLI call: the override when given, else `common_runtime_root`, with a
  relative value anchored at the registry's project root instead of the
  caller's working directory. runtime_root_from_registry now anchors the same
  way, so lease files and observations of one goal share one root.
- Todo add/update/complete/supersede/archive, follow-up capture, and
  handoff-mode set accept `runtime_root_arg`; the CLI passes its override
  through, and each writer hands the resolved root to its ownership gate,
  lease fence, and post-commit observation. Non-CLI callers keep the
  registry-root default.
- E2E: a subprocess run with `common_runtime_root != --runtime-root` drives
  todo add, task-lease acquire, todo update, capture-followups, and a leased
  completion; exactly one store identity exists, the head holds both the
  todos and the released lease, and the registry root gains no lineage and no
  lease directory. A second test pins the relative-root anchoring for every
  hook from a foreign working directory.
- SonarCloud: replace the default sort in local_authority_shadow.ts with an
  explicit comparator; split set_goal_handoff_mode and
  execute_native_task_lease_acquire into smaller helpers to bring their
  cognitive complexity under the limit; hoist the fixture out of the
  configure-goal exception test so only one call can raise.

Signed-off-by: wchwawa <wch19961116@gmail.com>
@wchwawa
wchwawa force-pushed the codex/local-authority-shadow-product-path branch from 422757d to ea15267 Compare September 3, 2026 01:28
@wchwawa

wchwawa commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator Author

@huangruiteng Round 3 on exact head ea15267fe addresses the P1 and the SonarCloud items; the new "Round 3" section of the PR body has the details. The branch is rebased onto current main.

  • changed_surfaces: coordination adapter (effective_runtime_root, observe_todo_local_authority_commit); Todo, follow-up, and handoff-mode writers plus their CLI wiring; task-lease fences and runtime_root_from_registry; local_authority_shadow.ts request decoding; new loopx/control_plane/todos/goal_todo_projection.py (pure move out of loopx/todos.py); shadow runtime, CLI E2E, and config tests.
  • direct_checks: git diff --check (committed, staged, unstaged) and py_compile on every changed Python file: 4/4 passed.
  • catalog_canaries: 18 selected, 18 executed, 0 failures, 0 warnings, 0 advisory failures.
  • risk_profile_smokes: full-public suite ok at the standard tier.
  • public_private_boundary: premerge-public-boundary clean.
  • failures_or_skips: none in the gate. Full pytest on this head: 5161 passed, 12 skipped, and the 12 environment-only failures (git-hook install, doctor runtime readiness, MCP tests needing pydantic/fastmcp) fail identically on main in the same environment. TypeScript: 463 passed, 1 PostgreSQL integration skipped.
  • manual_holds: none. SonarCloud can only be confirmed by the CI run on this head.
  • merge_decision: ready for re-review. Still no outbox, parity verdict, writer fencing, or promotion in this PR; the mismatched-root subprocess E2E is the regression gate you asked for.

@wchwawa

wchwawa commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator Author

Note on the pytest check on ea15267fe: the job was cancelled by the workflow's 15-minute timeout-minutes, not by a test failure (15m02s; the same job on current main runs take 14m38s to 14m44s, and the identical suite passed on the stacked #3870 in 13m03s). I re-ran the cancelled job. If the suite stays this close to the limit, the timeout is worth raising or the job worth splitting; that is a workflow decision, so I have not touched it in this PR.

huangruiteng
huangruiteng previously approved these changes Sep 3, 2026

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

详细中文评审

Exact head: ea15267fed1b0f37274931aaacc2d32be60c17a6

动机

这份 PR 补的是 Shared Goal Authority Stage 2C 的前半段:现有 Markdown Todo、handoff mode 和本地 task lease writer 仍是唯一权威,但系统需要从真实产品写路径采集一份默认关闭、显式 opt-in 的 file candidate observation,才能在后续独立阶段验证 parity、设计 durable outbox,并最终讨论 promotion。此前只有 AuthorityStore/provider 基础合同,没有覆盖 Todo、follow-up、lease lifecycle、handoff 与 migration 的真实入口;仅给一个 writer 加 hook 会得到不完整的 Goal coordination 视图,因此覆盖这些相邻写面是合理的最小产品切片。

这次复审的原始 blocker 是:--runtime-root override 与 registry common_runtime_root 不一致时,不同 writer 会把同一个 Goal 投影到两个 store lineage,同时都声称 captured。最新 head 把 effective runtime root 统一向所有 hook 传递,并用跨进程 E2E 固化了单 lineage。更早一轮关于语义过度声明的问题也保持修复:公开合同明确这是 post-commit snapshot capture,不是 source transaction receipt、parity verdict 或 promotion evidence。

改动思路

配置入口是 configure-goal --local-authority-shadow-file。Python adapter 先读取闭合的 file_one_way 配置;未配置时直接返回且不创建 lock/provider 目录。启用后,各 legacy writer 在主提交完成后使用同一个 effective runtime root,连续采样 Todo、handoff mode 与 lease,直到得到稳定的完整 projection;随后以 observation_trigger + source_digest 生成 observation identity,调用 TypeScript effect handler。TypeScript 只通过 FileAuthorityStore 做 candidate-side CAS、receipt readback 和 ambiguous outcome reconciliation,candidate 不进入任何 Todo/lease/调度决策。

正向路径是:显式启用 → legacy Todo/lease/handoff 写入成功 → 从同一 runtime root 采样完整快照 → candidate commit → 返回 typed captured/replayed evidence。负向路径是:配置非法、provider construction/read/commit 失败、1 秒 observation lock 超时、协议不匹配或进程在 source commit 后、observer 前被杀死;这些情况只返回 failed/unavailable/ambiguous_unproved 等 observation evidence,不回滚已经完成的 primary write。迁移也不会复制旧 provider identity,而是从目标端 canonical state 建立 fresh lineage。

具体改动

  • 配置与公开面:configuration_catalog.py、configure_goal.py 和 registry-admin CLI 增加闭合、默认关闭的 observation 配置、preview/execute/clear 与 readback;中英文 RFC 同步声明 crash gap、无 durable outbox、无 source/candidate compare、无 promotion authority。
  • Python observation owner:local_authority_shadow_adapter.py 负责配置 gate、紧凑 Todo/lease projection、稳定采样、digest/observation identity、冲突后重采样和 typed failure isolation。
  • TypeScript candidate owner:local_authority_shadow.ts 通过统一 AuthorityStore contract 持久化 projection/event/receipt;operation replay 和 response-loss ambiguity 必须由 exact receipt readback 证明,不能仅凭异常猜测成功。
  • 产品接线:Todo add/update/complete/supersede/archive、follow-up capture、handoff mode、task-lease acquire/renew/transfer/release 与 state migration 都在成功提交后调用 observer。goal_todo_projection.py 是从 todos.py 纯移动出的确定性读模型,用来守住原文件 maintainability ceiling。
  • runtime-root 修复:CLI 将 runtime_root_arg 传入每个 Todo/follow-up/handoff 路径;effective_runtime_root() 让显式 override 优先,否则将相对 common_runtime_root 锚定到 registry project root。lease fence、quiescence scan 与 observation 因而共享一条 root。

关键代码讲解

  1. effective_runtime_root() 是这次复审最关键的身份边界:同一 CLI 调用的 writer、lease fence 和 observer 都消费同一个已解析 Path,避免再次从 cwd 或 registry 产生第二 lineage。
  2. observe_local_authority_commit() 只在 opt-in 后采样;observation_trigger 被明确标为诊断上下文,快照可以包含 trigger 后并发落地的提交。它在 revision conflict 后重新采样,不用旧 projection 重试,也始终输出 source_transaction_correlated=false、durable_source_outbox=false、parity_verdict=not_evaluated。
  3. recordLocalAuthorityShadow() 是唯一 candidate commit seam:先验证 request/projection/goal identity,再用 store revision CAS 提交;operation_id_exists 与 ambiguous result 都要读回匹配 receipt,缺失或不匹配则 fail closed。
  4. set_goal_handoff_mode() 与 Todo/task-lease 调用链把同一 effective root同时用于 quiescence/lease 检查和 post-commit capture;因此 snapshot 中的 Todo 与 lease 不再来自不同运行目录。
  5. seed_migrated_authority_shadows() 在迁移完成后从目标 canonical state 重建 observation,旧 candidate directory/store identity 不会被复制到新 runtime root。

对主干的风险

我没有发现最新 exact head 上仍然存在的代码 blocker。上轮双-lineage 问题已由真实 subprocess E2E覆盖:common_runtime_root != --runtime-root 时依次执行 Todo add、lease acquire、Todo update、follow-up capture 和带 lease completion,五个结果拥有同一 store_identity,同一 head 同时包含两个 Todo 与 released lease,registry root 不产生 shadow 或 lease 目录。相对路径从 foreign cwd 运行时也固定锚定 registry project root。

default-off counterfactual 已验证:相同 legacy writer 在未配置时不调用 Effect runtime、不创建 candidate/lock,Todo/lease lifecycle 结果保持原权威;启用后的 candidate failure 也不改变 primary commit。SIGKILL E2E 诚实证明 commit-to-observer loss window,后续一次完整 snapshot 能恢复当前 head,但不能补造丢失的 source transaction receipt。命名与实际 authority 对齐:这是本地 observation candidate,不是 peer agent、shared authority 或 parity owner;typed evidence 也明确区分 advisory observation 与未来 machine-enforced promotion gate。

残余风险仍包括 PR 已披露的 full-snapshot/history 二次增长、1 秒 observation lock 对 opt-in writer latency 的影响,以及没有 durable outbox 时的单次漏采。这些会阻止后续 parity/promotion,但不否定当前明确限定为 best-effort observation foundation 的价值。规模为 28 files、+3489/-344,其中 production +1673/-337、tests +1736、docs +77/-7;测试量与跨多个真实 writer/failure seam 相称,且没有在当前 PR 引入 read authority、promotion CLI 或第二套语义 reducer,整体 proportionality 可接受。

独立验证:focused Python/真实 CLI/migration suite 22 passed;TypeScript control plane 463 passed, 1 个显式 PostgreSQL live integration skipped;npm run typecheck:control-plane、changed-file Ruff、git diff --check 通过。远端 exact head 的 DCO、dependency review、pytest、Windows、release build 与 SonarCloud Code Analysis 均成功。直接对文件运行 mypy 会递归进入当前主干并报告数千条既有错误,不是可归因的本 PR 信号;我没有把它计作通过或回归。当前 GitHub mergeStateStatus=DIRTY,合并前仍需基于最新 main 解冲突并保持 head 上述验证,但这不是当前 diff 的行为 blocker。

我的整体评价

结论是 APPROVE。最新 head 同时解决了两轮核心问题:observation 不再冒充 transaction/parity evidence;所有产品 writer 也不再因为 runtime-root 解析分裂 candidate lineage。默认关闭、失败隔离、response-loss readback、迁移新 lineage 和 crash gap 都有明确合同与实测,future-facing work 被克制地留在 durable outbox、parity compare 和 separately reviewed promotion 阶段。请在合并前解决与最新 main 的冲突并重跑相应门禁;若冲突修改上述 authority/runtime-root 边界,需要按新 head 重新审查。

English verdict: APPROVE

Exact head ea15267fed1b0f37274931aaacc2d32be60c17a6. The previous split-lineage blocker is fixed by routing Todo, follow-up, handoff, lease, and observation paths through one effective runtime root, with a real mismatched-root CLI E2E proving one store identity and complete Todo/lease head. The contract also remains honestly bounded to default-off best-effort post-commit capture: no durable source outbox, parity verdict, decision read, or promotion authority is claimed. Focused Python (22 passed), TypeScript (463 passed, 1 gated skip), typecheck, Ruff, diff checks, and remote required checks pass. The branch is currently conflict-dirty against latest main and must be refreshed before merge; re-review is required if conflict resolution changes these boundaries.

Signed-off-by: huangruiteng <huangrt01@163.com>

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Findings

没有发现新 blocker。复审绑定 exact head b6d493ac26900473817f65e60611d663a2767e8f。该 head 将最新 main 合入贡献分支;唯一人工冲突位于 tsconfig.control-plane.json,解决方式是保留 PR 的 local_authority_shadow.test.ts,同时保留主干新增的 coordination runtime/projection/local-authority tests,未改动 PR 的 runtime、配置、writer hook 或 authority 语义。

动机

本 PR 为 Shared Goal Authority Stage 2C 增加默认关闭、显式 opt-in 的 post-commit observation:现有 Markdown Todo、handoff 与本地 task lease 继续是 canonical authority,而 FileAuthorityStore 只保存从真实 writer 路径采集的 candidate snapshot。这样后续可以验证 parity 和设计 durable outbox,又不会让 observation 提前成为 read authority、settlement owner 或 promotion verdict。

此前 blocker 是 common_runtime_root 与 CLI --runtime-root 不同时,各 writer 会形成两个都声称 captured 的 store lineage。贡献者已用统一的 effective runtime root 修复,并补了跨进程 E2E;本次 main 合并没有改变这个边界。

改动思路

配置通过 configure-goal --local-authority-shadow-file 显式开启。Python adapter 在 primary commit 后从同一 effective runtime root 稳定采样 Todo、handoff 和 lease projection,生成 observation identity;TypeScript effect handler 使用 FileAuthorityStore revision/CAS 写 candidate 并做 receipt readback。provider 失败、lock timeout、协议错误或 response loss 都只产生 typed observation evidence,不回滚主写,也不把 candidate 回流到 lifecycle decision。

正向路径是 opt-in → legacy writer commit → 同 root 完整快照 → candidate CAS → captured/replayed receipt。负向路径保持 fail-isolated;迁移从目标 canonical state 建立新 lineage,不复制旧 provider identity。Todo completion、lease、调度和 settlement authority 始终留在既有 owner。

具体改动

  • local_authority_shadow_adapter.py 与 effective_runtime_root() 统一 Todo、follow-up、handoff、lease fence 和 observation 的 runtime-root 解析;显式 override 优先,相对 registry root 稳定锚定 project root。
  • local_authority_shadow.ts 是唯一 candidate commit seam,以 store revision/CAS 和 exact receipt readback处理 replay/ambiguous outcome。
  • Todo add/update/complete/supersede/archive、follow-up capture、handoff mode、task-lease lifecycle 和 migration 都在成功主提交后接入 observer;失败不反转 canonical write。
  • 配置 catalog、CLI/RFC 和 tests 明确 source_transaction_correlated=false、无 durable outbox、无 parity verdict、无 promotion authority。
  • 本次冲突解决仅更新 tsconfig.control-plane.json 的 include 集合:PR 自有 test 与最新 main 的三组 coordination tests 全部保留,使 typecheck/test runner继续覆盖两侧代码。

对主干的风险

残余风险是 opt-in full-snapshot/history 增长、1 秒 observation lock 的延迟,以及无 durable outbox 时 source commit 到 observer 之间可能漏采一次;PR 已明确披露,并且这些风险不会改变 primary authority。最新 main 带来的 coordination runtime/promotion代码与本 PR 的 observation-only seam 在同一 TypeScript编译/测试集合中通过,没有发现双 owner 或旧 writer fallback 被意外放宽。

合并后独立验证:focused Python suite 22 passed;control-plane TypeScript typecheck通过;TypeScript suite 492 passed, 1 个需要 LOOPX_TEST_POSTGRES_URL 的显式 live integration skipped;risk-based premerge 18/18 passed,包括 Python compile、diff hygiene、control-plane canaries、risk-profile smokes和 27-file public-boundary scan。GitHub 新 head checks 已触发,最终 merge 仍等待这些 required checks 通过。

我的整体评价

整体结论为 APPROVE。PR 的 observation contract 保持 default-off、best-effort、candidate-only,统一 runtime-root 的修复有真实多 writer E2E保护;冲突解决没有扩大产品 scope,只让 TypeScript验证清单保留两侧新增测试。future-facing 工作仍克制地留在 durable outbox、parity compare 和独立 promotion 阶段。待 GitHub exact-head required checks 全绿后可以合并。

English verdict: APPROVE

Exact head b6d493ac26900473817f65e60611d663a2767e8f. The conflict resolution merges current main and preserves the union of the PR's local-authority-shadow test with main's new coordination tests; it does not alter runtime or authority behavior. The prior split-lineage fix remains intact. Validation: 22 focused Python tests, TypeScript typecheck, 492 TypeScript tests with one explicitly gated PostgreSQL live skip, and all 18 risk-based premerge checks passed. Merge only after the new exact-head required checks are green.

@huangruiteng
huangruiteng merged commit 581c5df into main Sep 3, 2026
11 checks passed
@huangruiteng
huangruiteng deleted the codex/local-authority-shadow-product-path branch September 3, 2026 15:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants