Skip to content

Migrate governed capability lifecycle validation to TypeScript - #3706

Merged
huangruiteng merged 2 commits into
huangruiteng:mainfrom
hhyykk:codex/governed-capability-lifecycle-reducer
Sep 1, 2026
Merged

Migrate governed capability lifecycle validation to TypeScript#3706
huangruiteng merged 2 commits into
huangruiteng:mainfrom
hhyykk:codex/governed-capability-lifecycle-reducer

Conversation

@hhyykk

@hhyykk hhyykk commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add a versioned whole-journal lifecycle reducer to the existing governed_capability.validate_result TypeScript operation.
  • Move start admission, journal invariants, provider-result validation, callback validation, terminal-state checks, and public receipt projection into the TypeScript control plane.
  • Keep locking, atomic journal I/O, provider execution, transition materialization, writeback, and quota effects in Python while removing duplicate Python lifecycle and receipt authority.
  • Preserve the existing request contract and the public Python validation adapter.

Migration economics:

Path Before After
Preview runtime calls 1 1
Execute-start runtime calls 2 2
Terminal reconcile runtime calls 5 4
Committed replay runtime calls 3 1

The Python authority file changes by +195/-235 (net -40). The overall product delta is net +377, primarily the new typed lifecycle owner in TypeScript.

Issue Or Task

  • Closes: N/A
  • Contributor task ID: N/A (contributor-initiated RFC migration slice)

Validation

  • python3 -m py_compile loopx/*.py (covered by compile-all verification for the changed Python module)
  • loopx check --scan-root . (exact changed-file public/private scan: 0 errors, 0 warnings)
  • Other:
    • npm run test:control-plane — 203 passed
    • Relevant Python test sweep — 197 passed
    • Focused governed-capability suites — 14 TypeScript and 14 Python tests passed
    • Built-wheel content and installed-wheel runtime smoke test passed
    • LoopX premerge qualification — 9/9 selected canaries passed

Known baseline findings outside this diff:

  • Control-plane typecheck still reports three existing TestContext errors in unrelated tests.
  • Ruff still reports two existing TRY004 findings on untouched lines in the Python module.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Refactoring (no functional changes)
  • Documentation update
  • Test update

LoopX Area

  • Control plane (goals, todos, quota, scheduler, registry, runtime)
  • Benchmark boundary (adapters, runners, verifiers, scoring, evidence)
  • Capability or extension (providers, adapters, skills)
  • Public docs or presentation surface (README, protocols, dashboard)
  • Build, packaging, installer, or CI
  • Host or runtime integration

Technical Direction

  • Core control-plane hardening

  • Long-horizon benchmark evidence

  • Operator surface and IM integration

  • Shared Goal Authority and cross-host coordination

  • Architecture and research incubator

  • Target base branch: main

  • Direction tracker or promotion unit: TypeScript control-plane migration RFC

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
Owner

Choose a reason for hiding this comment

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

评审 exact head:c149372181ae39b1e2c7524c25b3cf3ac41f9b06

动机

这个 PR 想把 governed external capability 的生命周期判断从 Python 搬到既有 TypeScript control-plane owner:不仅校验单次 provider result,还一次解释 admission、journal identity、request digest、provider 状态、settlement callback、terminal state,并由 TypeScript 投影 public receipt。Python 继续负责文件锁、原子 journal I/O、provider 执行、transition proposal 落盘、writeback 和 quota spend。这个方向符合仓库“typed TypeScript boundary owns state/effect authority”的约束,也试图减少 reconcile/replay 的 managed-runtime 往返次数。

改动思路

loopx/control_plane/governed_capability.ts 新增 versioned lifecycle packet/reduction、稳定 JSON digest、journal status 枚举、whole-journal reducer 和 receipt projection;旧的 standalone validateGovernedCapabilityResult 入口仍兼容原 provider-result adapter。loopx/extensions/governed_capability_execution.py 将原来的 Python _validate_journal/_public_receipt 改成一次 governed_capability.validate_result lifecycle 调用,并只在本地 overlay Python 实际完成的 I/O effects。测试同时覆盖 TS reducer、Python 端到端运行、runtime-call 数量和 legacy adapter。

正向路径完整:selected Todo admission → prepare request/journal → TS inspect → provider start → TS observe_result → transition settlement → reconcile provider → durable writeback → quota spend → committed receipt。负向路径也覆盖了 request lifecycle/digest 篡改、callback identity/digest 篡改、provider result/receipt 矛盾和非法 transition proposal,均在 typed boundary fail closed。

具体改动

  • governed_capability.tsreduceGovernedCapabilityLifecycle 绑定 transaction settlement identity、request authority、start idempotency key、operation profile 和 journal/provider 状态;validateStoredSettlementCallback 再验证 writeback/quota receipts;lifecyclePublicReceipt 统一生成公开 receipt。
  • governed_capability_execution.py_reduce_governed_capability_journal 负责跨运行时适配,_receipt_with_local_effects 反映 Python-owned durable effects;start/reconcile/replay 都复用 lifecycle reduction,仍保留文件锁、0600 journal、atomic replace、transition proposal settlement 和 writeback-before-spend。
  • TypeScript 14 个 focused tests 与完整 203 个 control-plane tests 通过;Python governed-capability 14 个 tests 通过;control-plane typecheck、Python compileall、ruff、git diff --check 均通过;loopx check --scan-root . 公私边界扫描无 error(3 个 warning 为仓库/registry 既有状态,与本 diff 无关)。SonarCloud 远端检查为 success。

[P1] Existing-journal replay 绕过了 operation 的 selected-Todo action/target 授权

start_governed_external_capability 的 existing-path 分支中,_require_admission 已不再接收 todo_contract,随后 _reduce_governed_capability_journal(... phase="inspect") 也没有传 admission。因此这个分支只校验 heartbeat settlement identity,不再校验 selected_todo.action_kind / target_key 是否属于 operation profile。新增的 test_material_start_recovers_an_existing_journal_without_new_run_authority 还把 should_run 设为 false、删除 selected_todo 并要求 replay 成功,说明这是可观察的默认行为变化,但 PR 同时声明 “no functional changes”。

这不只是只读 readback:当 journal 已有 provider result 时,该 replay 分支会调用 _settle_journal_transition_proposals,可创建、更新或完成 LoopX monitor Todo。于是一个仅携带旧 exact settlement identity、但当前没有被选择且没有 action/target authorization 的 admission,可以重新触发 control-plane writes。此前每次 start/replay 都通过 validate_admission 校验 operation todo contract。

请保留 typed migration,但恢复 side-effecting replay 的 selected-Todo operation authorization;或者把纯 receipt readback 与需要恢复 transition writes 的路径拆开,只有后者要求新的 runnable/authorized admission。同时把这个恢复语义作为行为变化明确写入 PR,并增加 negative test:缺失或不匹配的 selected Todo 不得触发 transition settlement。

对主干的风险

主要风险在授权边界,不在 reducer 的基本状态机:TypeScript whole-journal validation、writeback-before-spend、terminal receipt binding 本身是清晰的,Python/TypeScript 数字 canonicalization 差异也通过本地 provider-result digest overlay 被显式处理。但当前 replay 放宽会让“相同 effect identity”被误当成“当前仍有 operation authority”,把幂等恢复与新一轮 control-plane write 授权混为一谈。这个变化涉及 Todo/transition authority,不能以 refactor-only 合并。除此之外,public receipt 仍需 Python overlay 实际 I/O 结果,是合理的 provider boundary,而不是第二套生命周期规则。

我的整体评价

整体架构方向正确:它把重复的 journal/result/settlement 判断收敛到 typed TypeScript owner,Python 保留 effect adapters,测试覆盖和运行时调用经济性也扎实;bounded future-facing pass 在正确边界上实施,无需再扩展新抽象。但 exact head 目前存在一个可执行 side effect 的 replay 授权回归,并且 PR 元数据未披露该默认行为变化。结论:CHANGES_REQUESTED。修复 replay authorization、补 negative coverage 并更新行为披露后,可以重新评审;当前不要合并。

English verdict: CHANGES_REQUESTED for exact head c149372181ae39b1e2c7524c25b3cf3ac41f9b06. The TypeScript lifecycle-owner migration is well structured and the focused TS/Python, full control-plane, typecheck, compile, lint, diff, and boundary checks pass, but existing-journal replay now accepts a non-runnable admission with no selected Todo and can still settle transition proposals. Restore action/target authorization for side-effecting replay (or split read-only replay from authorized recovery), add a negative regression test, and disclose this default behavior change before merge.

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

结论:REQUEST_CHANGES。评审 exact head:c149372181ae39b1e2c7524c25b3cf3ac41f9b06

阻塞项(P1):existing-journal replay 丢失了 operation 的 selected-Todo action/target 授权。start_governed_external_capability 的已有 journal 分支只用 _require_admission 校验 settlement identity,随后调用 _reduce_governed_capability_journal(..., phase="inspect") 时没有传入 admission;当 journal 已有 provider result 时,该分支仍会调用 _settle_journal_transition_proposals。因此,携带旧 settlement identity、但当前 should_run=false 且没有 selected_todo 的调用,仍可恢复并写入 monitor Todo transition。最低修复是恢复 side-effecting replay 的 operation todo-contract 校验,或把纯 receipt readback 与会落 transition 的 recovery 分成两个路径并只授权后者;同时补一条缺失/不匹配 selected Todo 不得写 transition 的负向测试,并把这个默认行为变化从“no functional changes”中明确披露出来。

动机

这个 PR 试图把 governed external capability 的整段生命周期判定从 Python 收敛到既有 TypeScript control-plane owner。旧实现由 Python 同时解释 admission、journal identity、provider result、settlement callback、terminal state 和 public receipt;新实现希望让 TypeScript 一次读取 whole-journal lifecycle packet,负责 typed state 与合法迁移,Python 只保留文件锁、原子 journal I/O、provider 调用、transition materialization、writeback 和 quota spend 等 effect adapter。这个方向能减少 Python 与 managed runtime 的重复权威,也把 committed replay 的 runtime 调用从 3 次降到 1 次。非目标是改变现有 operation 授权、provider request 合同或 writeback-before-spend 语义;正因为 PR 自称 refactor-only,replay 权限放宽不能被当作迁移细节带入主干。

改动思路

入口仍是 governed_capability.validate_result,但 validateGovernedCapabilityResult 会按 schema 分派:legacy provider-result 继续走 validateProviderResult,新的 lifecycle packet 走 reduceGovernedCapabilityLifecycle。reducer 以 settlement identity、canonical request digest、operation profile、journal status、provider result、writeback/quota receipts 为权威输入,返回 canonical journal status、validated provider result 与 public receipt。Python 的 _reduce_governed_capability_journal 负责组包并调用 typed runtime,_receipt_with_local_effects 再覆盖只有 Python 才能证明的本地 I/O effects。

正向路径是:selected Todo admission → prepare request/journal → TypeScript inspect → provider start → TypeScript observe_result → transition settlement → reconcile provider → durable writeback → quota spend → committed receipt。负向路径对 request lifecycle/digest 篡改、provider result/receipt 矛盾、callback identity/digest 篡改、quota-before-writeback 和非法 journal status 都会 fail closed。架构边界整体合理:状态机与 receipt 判定在 TypeScript,副作用执行和持久化在 Python;不需要再新增 capability 或抽象层。

具体改动

  • loopx/control_plane/governed_capability.ts(+418/-1)新增 lifecycle packet/reduction/run/receipt schema、stable JSON digest、JOURNAL_STATUSES、whole-journal reducer 与 receipt projection;legacy standalone result adapter 保持可用。
  • loopx/extensions/governed_capability_execution.py(+195/-235)删除重复的 Python _validate_journal / _public_receipt 权威,统一经 TypeScript reduction 解释 start、reconcile 和 replay;文件锁、0600 journal、atomic replace、transition proposal settlement、writeback-before-spend 仍由 Python 执行。
  • tests/control_plane_ts/governed_capability.test.ts(+152)增加 observed-result、committed replay、request/callback tamper 等 reducer 覆盖。
  • tests/extensions/test_governed_capability_execution.py(+88/-3)覆盖 runtime 调用次数、legacy adapter、Python digest overlay、replay 与 settlement;其中 test_material_start_recovers_an_existing_journal_without_new_run_authority 明确把 should_run 设为 false、删除 selected_todo 后仍期待 replay 成功,证明授权变化是当前实现的可观察合同,而不是推测。

关键代码讲解

  1. reduceGovernedCapabilityLifecycle(TypeScript 第 605 行)是新的状态权威:它校验 exact packet fields、settlement identity、request authority/lifecycle/digest、operation profile、provider result、writeback/quota callback 和 terminal receipts。未执行 provider 时只有在 packet 携带 admission 的情况下才会调用 validateGovernedCapabilityAdmission;provider result 存在后则强制 admission 为 null。
  2. lifecyclePublicReceipt(TypeScript 第 542 行)从 typed journal 投影 provider/transition/writeback/quota 状态;_receipt_with_local_effects(Python 第 294 行)仅覆盖 Python 实际落盘和 effect adapter 能证明的字段。这是合理的 provider boundary,不构成第二套生命周期规则。
  3. _reduce_governed_capability_journal(Python 第 207 行)构造 lifecycle packet、调用 managed runtime、检查 reduction schema/status,并在 inspect 时验证返回的 provider result 与 journal 一致;EffectRuntimeRejected 只在无 admission 的 inspect 路径转成 ValueError,其他路径保持 fail closed。
  4. start_governed_external_capability(Python 第 359 行)在新 journal 路径会把 admission 传给 reducer,因此 action/target 合同仍生效;但 existing-journal 路径不传 admission,却在 provider result 存在时继续执行 _settle_journal_transition_proposals,这里把幂等 identity 与当前 operation authority 混为一谈,是本次阻塞项的具体位置。
  5. reconcile_governed_external_capability(Python 第 537 行)先 inspect journal,再按 provider running/terminal 状态执行 observe_result、transition、writeback、spend 与 committed checkpoint;失败时保留 typed settlement failure,重试不会重复已提交 writeback。

对主干的风险

最高风险不是 reducer 的 typed state 设计,而是授权边界:同一个 effect identity 只能证明“这是同一笔恢复”,不能证明“当前仍允许此 operation 对 LoopX Todo 产生新副作用”。在 provider result 已经写入、transition receipt 尚未 checkpoint 的 crash 窗口里,无 selected Todo 的 replay 会进入 _settle_journal_transition_proposals,可能创建、更新或完成 continuous monitor。影响面覆盖所有采用该 governed material capability adapter 的 operation;错误可在 Todo 历史中观察并可依靠 journal/receipt 恢复,但在写入发生后才可见,不能靠幂等性替代前置授权。

Typed-state lens 方面,journal status、phase 和 transition kinds 都使用闭集/typed helper,没有 substring denylist;domain-neutrality 方面新增错误文本保持 goal/provider-neutral;guidance-vs-obligation 方面没有把强制 flag 描述成建议。不过 behavior-change disclosure 不满足:PR 勾选“Refactoring (no functional changes)”,而测试和代码实际允许无 runnable selected Todo 的 replay。除这个 P1 外,我没有发现新的 blocker。最小回归测试应模拟 provider result 已写入但 transition receipt 未落盘的 crash,然后用缺失或 action/target 不匹配的 admission replay,断言 transition setter 未被调用且 monitor 未写入。

独立验证:focused TypeScript 14/14 通过;focused Python 14/14 通过;完整 control-plane 203/203 通过;Python compileall、ruff changed-file scan、git diff --check 均通过;public/private boundary scan 0 error(3 个 warning 为现有 registry/history 状态,不来自本 diff);远端 SonarCloud 为 success。绿测证明迁移主体稳定,但当前测试把授权放宽编码成成功路径,因此不能消除上述风险。

我的整体评价

整体架构方向正确,代码量与迁移范围基本匹配:TypeScript 成为 whole-journal typed owner,Python 收缩成 effect adapter,legacy adapter、positive/negative state paths 和运行时调用经济性都有覆盖;bounded future-facing pass 已落在相邻且正确的 ownership boundary,无需再扩展框架。当前 exact head 仍有一个 side-effecting replay 的 P1 authorization regression,并且默认行为变化没有披露,所以正式结论是 REQUEST_CHANGES,当前不要合并。修复 replay authorization(或拆分只读/有副作用恢复)、补负向 crash-window coverage 并更新 PR 描述后再复审。

English verdict: REQUEST_CHANGES for exact head c149372181ae39b1e2c7524c25b3cf3ac41f9b06. The TypeScript lifecycle-owner migration is coherent and focused TS/Python, full control-plane, compile, lint, diff, boundary, and remote checks pass, but existing-journal replay accepts a non-runnable admission with no selected Todo and can still settle transition proposals. Restore action/target authorization for side-effecting replay (or split read-only replay from authorized recovery), add a negative crash-window regression test, and disclose this behavior change before merge.

hhyykk and others added 2 commits September 2, 2026 02:44
Signed-off-by: hyk <4408344+hhyykk@users.noreply.github.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
@huangruiteng
huangruiteng force-pushed the codex/governed-capability-lifecycle-reducer branch from ee90211 to 18bcf9b Compare September 1, 2026 18:49

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

评审 exact head:18bcf9b7f01658eb2d6742efac5fc4bae0360041未发现新的 blocker。 上一轮 P1 已修复:已有 journal 只有在仍存在未结算的 continuous_monitor_upsert 时才重新要求 should_run=true 和当前 selected Todo 的 action/target 授权;纯 committed/readback 路径仍保持幂等,不会因为没有新 run authority 而失败。缺失 selected Todo、should_run=false、action 不匹配都会在任何 transition 写入前 fail closed,并且不会重复调用 provider。

动机与架构判断

这个 PR 把 governed external capability 的 whole-journal 生命周期判断收敛到既有 TypeScript control-plane owner,Python 继续只负责文件锁、原子 journal I/O、provider 调用、transition materialization、writeback 和 quota spend。这个 ownership 划分解决了 Python/TypeScript 双重解释状态的问题,也保留了 provider/effect boundary;没有新增不必要的 capability 或 speculative abstraction。对用户和 operator 的主要收益是 crash/replay/reconcile 在同一个 typed contract 下 fail closed,同时减少 managed-runtime 往返。主要风险仍是 recovery authority 与幂等 readback 被混淆,而当前修复已把两者按“是否尚有可写 transition”明确分开。

Refine 结果

本轮在贡献者 fork 分支上完成 rebase 和 bounded refine。TypeScript reducer 现在允许 inspect 阶段携带 admission 并复用 operation profile 的 todo_contract 验证;Python 只在检测到未结算 monitor transition 时传入 admission,已经结算的 journal 不增加无意义授权要求。新增 TS contract test 与 Python crash-window tests 同时证明:合法 authority 可补写 receipt,三种无效 authority 都保持 journal 字节不变且 provider 调用次数不增加。这个 companion change 位于相邻 ownership boundary,后续无需再扩展框架。

验证

本地 Python governed-capability focused tests 18/18、TypeScript focused tests 15/15、完整 TypeScript control-plane tests 320/320(1 个 environment skip)、TypeScript typecheck、ruff、repository mypy、git diff --check 均通过。LoopX exact-scope change-quality 覆盖 4 个文件,fingerprint 464a56993657c4c500625d61990dd5dbb69e0c701b766312efd15ccbb687510b,receipt cqr_464a56993657c4c50062 验证有效;premerge 9/9 通过,无 manual hold。GitHub DCO、dependency review、build、Python/PowerShell tests 与 Sonar checks 全部通过。

合并决定

先前 changes-requested 的唯一授权 blocker 已在 exact head 上关闭,改动保持单一目的、DCO 完整、公私边界干净,验证覆盖正常路径、负向授权与恢复窗口。结论:APPROVE,并按 owner 授权自合并。

English verdict: APPROVED for exact head 18bcf9b7f01658eb2d6742efac5fc4bae0360041. The prior P1 is fixed by requiring fresh runnable selected-Todo action/target authority only when replay can still settle a monitor transition, while pure committed readback remains idempotent. Negative crash-window tests prove invalid authority performs no journal write and no provider retry; focused/full TS and Python validation, type/lint/mypy/diff checks, exact-scope quality receipt, premerge, and all required GitHub checks pass. Self-merge is authorized.

@huangruiteng
huangruiteng merged commit 7de2f04 into huangruiteng:main Sep 1, 2026
9 checks passed
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