feat(monitor): bind leased observations to crash-safe quota settlement - #4672
Conversation
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
Reviewed exact head: 980f3a103b9d210abb7b8f6192b21d0d9dc7a8df.
未发现阻塞问题。结论适用于本次 leased Monitor observation → canonical transaction → quota settlement 的完整阶段;不代表 provider 默认切换或整 Goal 晋升已完成。
动机
按 #4574、TS T2 和 shared-authority L4 判断交付:旧 canonical Monitor 拒绝所有 retained lease,status 又抑制其调度;hard mode 下没有 lease 反而可能通过。业务提交后若进程退出,新 successor 改变实时调度决定,还会让后续 quota 结算重新准入失败。
这不是单纯参数缺失。只删除拒绝分支会放过旧执行者;只增加 proof 传输仍会留下崩溃恢复缺口。本 PR 在现有 owner 内交付一个可独立验证的端到端增量。#4669 acquire/reclaim、#4224 SQLite D2、其余 L2/event callers 和默认切换保持各自边界。
改动思路
当前执行权限与历史提交证据分开:新观察在 canonical revision 上校验 actor、claim、binding、exclusion 和当前 lease,再以同一 CAS 提交 observation、generation、独立 successor 和 receipt。既有 receipt 优先重放,因此释放/过期/归档不会把已经提交的观察重新执行。
Quota 与业务 store 仍是两个真实的持久化边界。Preflight 先保存原始 admitted decision 和 provider plan;恢复用这份历史依据构造记录,并核对同一 proof 的业务回执。保留原有 quota-index CAS,而非新增跨 store 事务框架。
具体改动
task_lease_proof.ts严格解析 execution key 和正安全整数 version,并复用todo_lifecycle_decision.ts的现有 fence。todo_update.ts和todo_monitor_poll.ts共用该边界;返回值剥离终结操作的 release proposal,关闭自动 acquire/delegation。租约有效性取 runtime 时间,不接受调用方用旧观察时间延长权限。local_authority_runtime.ts/todo_monitor_poll.ts接受带 proof 的 v1 请求,保留无 proof 的 v0 identity。原生 Monitor 沿用monitor_metadata.ts、state_transition_rules.ts、monitor_successor.ts、CoordinationCommandReceipt与各 store,实现当前执行者写入和历史 receipt 重放;不更改 lease。- Python CLI、quota facade、
monitor_poll.py和 scheduler/provider adapter 将两个 proof 参数送达原生 owner,并把 diagnostic code 回传 CLI。未晋升 Goal 携带 proof 会明确失败,不进入 legacy writer。active_state_todos.py删除统一 unsupported 标记,使 canonical due Monitor 可被选中;调度选择不授予租约。 monitor_poll_commit.ts新增有明确版本的 pending admission,buildRecord接受已验证 admission,去除再次读取当前准入的重复规则。Pending plan、request digest、business receipt 核对原 proof。已完成 v0 receipt 和无 proof 的请求 digest 保留;旧 pending 缺乏历史依据时返回legacy_monitor_admission_unavailable,保留证据。- 扩展现有 native/imported 复杂 fixture,验证 generation 4→5 通过既有 resume reducer 真正解除已有依赖等待,且完整非目标状态和 lease 不变。补充真实 CLI 进程退出、release 后恢复、CAS renewal race、丢响应、归档后 replay、错误 proof 和 pending schema 负例。复用 source rehearsal 对照冻结基线及真实 File/SQLite/service-opened PostgreSQL;同步双语 RFC 和操作/降级协议。
全 diff 为 27 文件:生产代码 +265/−60,验证与 fixture +651/−5,文档 +140/−20。新增生产模块有两个现有 caller;没有新增未使用的 provider/coordinator。未来维护整理已应用于共同 lease proof 和 record admission;不扩大为另一套 Monitor 引擎。
对主干的风险
两个默认行为修正已经披露:canonical due Monitor 恢复调度可见性;hard-mode 无 proof 写入被拒绝。新 pending receipt 的版本变化也适用于无 proof 的新事务。它不是仅靠新增 flag 激活的独立 capability,不能声称内部 journal 形状完全不变。
兼容与恢复限制明确:旧 v0 pending 不能凭空补造原准入;降级前须完成 v1 pending;若有其他 quota-index 写入,仍会明确冲突。历史 receipt 只支持既有操作结算,不授权新观察。未增加跨 owner claim、lease lifecycle、provider promotion 或 quota spend。错误和状态判定使用 typed schema/enum/transition,没有添加文本启发式或把强制约束称为 guidance。
验证结果:
- 全量 TS 控制平面 1,867 passed,0 failed、0 skipped;含真实隔离 PostgreSQL 16.15 store/service,以及 File/SQLite/NoKV。
- 105 项相邻 Python 检查及 21 项 leased CLI/status 检查通过;最终 wheel、sdist 各 6 项真实安装 CLI 语义探针通过。实际进程在业务提交后退出,再释放 lease、恢复、重放,仅产生一个 successor 集和一个 quota record。
- 冻结
8330a974cc2631ffd006d1fb7bd1627d2d690e85与本 head 的 12 组成对 CLI 用例:legacy 完整规范化结果一致;canonical 完整业务写回/Todo 一致,调度差异明确保留。仅规范化时钟、生成 ID 和临时目录。删除 expiry 比较的独立 mutation 会让同一真实 runtime rehearsal 的过期执行 oracle 失败;本 head 通过。 - 只读源快照在临时 runtime/隔离 tenant 中复演,源及所有非目标记录不变,三个 candidate provider 最终业务状态相同。
- 打包 HTTP 入口可服务;status 回读提交后的 Monitor generation 和 successor,零 contract error;Goal Channel compact projection 按既有优先级展示独立 advancement successor。无布局或配置编辑器变化,proof 是执行输入。
- TS typecheck、配置内 22 文件 mypy、scoped Ruff、maintainability ratchet、DCO 和 public/private scan 通过。精确 quality receipt
cqr_eea3514390e4862050c8有效;一次 bounded safe-fix,零 blocker/warning/advisory。Premerge direct checks 和 19/19 canary 通过,无失败、跳过或人工 hold。 - 64 组交错真实完整 CLI 测量:baseline p50/p95 6,275.82/8,304.07 ms,candidate 6,205.86/7,753.22 ms;p95 −6.63%,未触发回退门槛。内部非持久转换 p95 0.044 ms,未增加跨 runtime 调用次数。共享机器负载限制了绝对耗时的推广价值,不据此声称普遍提速。
本次按配置使用精确 head 本地证据,未获取或等待远端 CI。未覆盖跨 host PostgreSQL 部署、真实外部网络轮询和长期 soak;这些是明确的后续资格,不冒充已通过。
我的整体评价
APPROVE:这是对原目标有实际收益、可独立回滚的 L4/T2 增量。最重要的收益是恢复语义闭合、当前权限校验归一、调度到真实写入的路径连通,而非代码量或测试数量。现有 suite、真实进程故障、成对基线和 mutation 足以支持所声明范围。控制平面变更仍交维护者合并,本评审不授予自合并或 provider 启用权限。
English verdict: APPROVE - Exact head 980f3a1. Current lease proof fences canonical Monitor writes; frozen admission lets historical business receipts settle after process loss without repeating effects. Full TS (1,867, zero skipped), real File/SQLite/PostgreSQL, installed CLI crash recovery, paired baseline/mutation, static/package checks and 19 premerge canaries pass. Existing index-CAS, old-pending/downgrade and rollout limitations remain explicit; maintainer merge required.
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…aries Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
980f3a1 to
11487a6
Compare
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机
这属于 #4574(S2/R5 可恢复工作)与 #3225/#3245,实现共享权威 L4 / TS T2 里的"带 lease 的 Monitor 观测与结算"切片。改动前的三条事实放在一起看才是问题:
- 规范路径拒绝一切保留中的 lease(
Monitor observation with a lease is not supported)——合法情形被挡住了; - 于是 hard mode 下没有 lease 的 Monitor 反而能写——非法情形被放过去了;
- 规范 status 抑制了到期 Monitor 的选择,而进程若在业务写之后丢失,结算会被"重新读一遍已经变化的调度状态"带偏,导致配额结算搁浅。
这个 head 把三件事一起纠正,并把"原始准入"冻结下来,使进程丢失后结算依据的是当时真正获准的决定。
改动思路
- 复用已有 fence,不新增决策者:把既有的"非终局当前执行证明"(
evaluateCanonicalTaskLeaseProof)接进 Monitor 写入路径;lease 的 acquire/renew/release 语义一字未动。 - 证明贯穿整笔事务:v1 请求把 lease proof 带进 observation、provider plan 与商业回执,plan 与 receipt 之间再做一次规范哈希比对;
expected_version走 CAS,所以不会续租、不会释放。 - 时间取权威时钟:过期判断用运行时传入的
now,不用 observation.generated_at,杜绝"用观测时间复活 lease"。 - 冻结准入:新 pending receipt(
quota_monitor_poll_pending_admission_v1)保存admitted_decision,恢复时从中物化结算,历史结算永不授权新的观测。 - 兼容与破坏面都写清:无 proof 的 v0 请求/回执、legacy 与 soft-claim 的无 lease 观测保持兼容;同时明确标注这是破坏性变更(hard mode 无 fence 写入现在被拒),并给出降级顺序:先把 v1 pending 结算完再降级。
具体改动
关键代码讲解
todo_monitor_poll.ts:planWriteback改为"有 lease / hard mode / 带 proof"时走 fence,outcome !== "apply"即整笔拒绝;soft_claim明确禁止带 lease 观测;monitorReceipt还会校验回执里的 proof 与本次输入一致。monitor_poll_commit.ts:新增 v1 请求常量与双向校验(v1 必须有 proof,有 proof 必须是 v1)、monitor_poll_todo_provider_plan_v1、pending receipt 的admitted_decision,以及"pending-admission 回执不得被当作已完成结算"这一条。scheduler/monitor_poll_writeback.py/provider_monitor_poll.py:带 proof 时只走已 promote 的规范权威,绝不回落到 legacy writer;无目标即报错。cli_commands/quota_request.py:两个新 flag 只在monitor-poll且必须成对出现、版本为正的安全整数。- 文档:
docs/reference/protocols/quota-monitor-observation-receipt-v0.md新增"规范 lease 观测与恢复"一节(含 CLI 示例与硬模式漏洞的说明),两个 RFC 镜像同步更新行。
我实跑的结果
python -m pytest tests/control_plane/test_leased_monitor_poll.py \
tests/control_plane/test_native_monitor_poll.py \
tests/control_plane/test_canonical_status_todos.py -q → 30 passed
node --test tests/control_plane_ts/todo_monitor_poll.test.ts \
tests/control_plane_ts/quota_monitor_poll_commit.test.ts → 27 passed, 0 skipped
gh checks @ head(读取时):20 项成功、0 失败,1 个 test shard 仍在跑,mergeStateStatus=BEHIND
反向用例确实存在且覆盖到位:保留 lease + 陈旧观测不得改动任一半、hard mode 不能用缺 lease 绕过、soft mode 不能接受外部 proof、--material-change 必须在两个活跃 monitor 之间消歧而不是猜、以及"原子观测并创建工作但不续租/释放 lease"。
对主干的风险
没有阻塞发现。一条 P3:
- [P3] 描述里的 "Tested revision" 不在本分支。
980f3a103b9d…不是 head 的祖先,只存在于本地分支codex/authority-foundations-20260918,因此描述里那套完整证据(1,867 用例全过、rehearsal、打包安装、性能对)无法直接对应到本 head。风险其实很小:我把两边 patch 里loopx/、tests/、examples/的代码 hunk 做了逐行比对,完全相同,只有文档行上下文与 hunk 偏移不同。但在一个把 exact-head 证据当规矩的仓库里,建议把验证表面绑到 head(或给出等价的内容标识),我是按自己在 head 上的运行与代码阅读下的结论。
另外说明我的证据边界:我没有复现完整 1,867 用例套件、rehearsal、打包安装与性能对;这一轮我跑的是 monitor 相关 Python/TS 套件,并逐段读了事务代码。破坏性变更本身我认为披露完整:body 勾了 breaking change、给出降级顺序(先结清 v1 pending 再降级),协议文档与两个 RFC 镜像都写了新的硬模式行为。
我的整体评价
这是"把 fence 接进应有位置"的正例,而且接得克制:没有新造决策者、没有把 lease 生命周期搅进来、proof 只作为一次调用的执行凭据,opto-in 到单次请求。几条细节我尤其认可——过期看权威时钟而不是观测时间戳;plan/receipt 之间再比对一次 proof;pending 回执不能冒充已完成结算;以及"选择到期 Monitor ≠ 授予 lease"这句被同时写进代码与文档。
唯一要收尾的是证据绑定:把验证表绑到 head(或等价内容标识)。代码侧我没有其它阻塞项。
English verdict: APPROVE (author-owned PR; published as a COMMENTED review because GitHub blocks formal self-approval) - head 11487a6 closes a real hard-mode hole (a leased Monitor observation was refused while a lease-free hard-mode write was admitted), binds the caller's current execution proof through one canonical observation/generation/successor CAS, freezes the granted admission in a new quota_monitor_poll_pending_admission_v1 pending receipt so a process lost after the business commit cannot strand or fabricate settlement, and restores canonical due-Monitor selection while explicitly stating that selection is not a lease grant; the schema discipline is enforced in both directions (v1 exactly when a proof exists, provider plan and receipt must agree, a pending-admission receipt cannot stand in for a completed settlement), expiry uses the authority clock rather than the observation timestamp, the lease is read but never mutated, and a proof-carrying writeback can never fall back to the legacy writer; I ran 30 Python monitor/canonical-status tests and the two TypeScript monitor suites (27 passed, 0 skipped) and inspected the transaction code, with one P3 recorded - the body's "Tested revision" 980f3a1 is not an ancestor of this head (it lives on codex/authority-foundations-20260918), so the validation table is not literally bound to the reviewed head even though the code hunks are byte-identical between the two, and I did not reproduce the full-suite, rehearsal, packaged-install or performance rows.
check_rfc_ledger_entries accepted only the literal heading "Appendix A: Execution ledger", so an RFC already using Appendix A for other evidence could not adopt per-file entries without renumbering its appendices across both language files -- a mechanical diff that itself forces rework on the branches the convention exists to spare. The heading is now matched for any appendix letter, and the READMEs stop hardcoding how many RFCs carry one. shared-goal-authority-state-provider-v0 records each delivery as a dated subsection at the end of one large file, which is why loopx-project#3820, loopx-project#4061 and loopx-project#4672 all collided there per loopx-project#4677. New records move to ledger/shared-goal-authority-state-provider-v0/ as dated files with Chinese mirrors; existing dated subsections stay as append-only history. Refs loopx-project#4677 Signed-off-by: DJC1412 <108855841+DJC1412@users.noreply.github.com>
check_rfc_ledger_entries accepted only the literal heading "Appendix A: Execution ledger", so an RFC already using Appendix A for other evidence could not adopt per-file entries without renumbering its appendices across both language files -- a mechanical diff that itself forces rework on the branches the convention exists to spare. The heading is now matched for any appendix letter, and the READMEs stop hardcoding how many RFCs carry one. shared-goal-authority-state-provider-v0 records each delivery as a dated subsection at the end of one large file, which is why loopx-project#3820, loopx-project#4061 and loopx-project#4672 all collided there per loopx-project#4677. New records move to ledger/shared-goal-authority-state-provider-v0/ as dated files with Chinese mirrors; existing dated subsections stay as append-only history. Refs loopx-project#4677 Signed-off-by: DJC1412 <108855841+DJC1412@users.noreply.github.com>
check_rfc_ledger_entries accepted only the literal heading "Appendix A: Execution ledger", so an RFC already using Appendix A for other evidence could not adopt per-file entries without renumbering its appendices across both language files -- a mechanical diff that itself forces rework on the branches the convention exists to spare. The heading is now matched for any appendix letter, and the READMEs stop hardcoding how many RFCs carry one. shared-goal-authority-state-provider-v0 records each delivery as a dated subsection at the end of one large file, which is why #3820, #4061 and #4672 all collided there per #4677. New records move to ledger/shared-goal-authority-state-provider-v0/ as dated files with Chinese mirrors; existing dated subsections stay as append-only history. Refs #4677 Signed-off-by: DJC1412 <108855841+DJC1412@users.noreply.github.com>
Goal And Delivered Outcome
Related to #4574 (S2 / R5, recoverable G2 work), #3225 and #3245. Implements the leased Monitor observation/settlement slice of shared-authority L4 and TS T2; base:
main.Previously, canonical Monitor writeback rejected every retained lease, hard mode could admit a lease-free Monitor, and canonical status suppressed due Monitor selection. A process lost after business commit could also strand quota settlement by rechecking the changed scheduling state. The public CLI now carries current execution proof into one canonical observation/generation/successor CAS, and the original admitted quota decision survives process loss. Historical settlement never authorizes a new observation.
Scope And Continuation
Validation
8330a974cc2631ffd006d1fb7bd1627d2d690e85baseline: 12 paired CLI cases across legacy/File/SQLite; business writeback and full Todo readback match. Canonical due-scheduling differences are explicitly retained. Same public runtime rehearsal detects a deliberately removed expiry check.examples/control_plane/authority-monitor-poll-rehearsal.py: read-only source cloned into disposable runtimes, baseline plus File/SQLite/service-opened PostgreSQL, equal candidate heads, unchanged source/non-target records. Private source is not included; the reusable synthetic conformance fixture is public.cqr_29831cd43a3cea91e872verified for the rebased head; no additional safe-fix pass; no blockers/warnings/advisories. Premerge direct checks plus 19 selected canaries pass, no failures/skips/manual holds. Runtime PR remains for maintainer merge.Coverage includes wrong/missing/stale proof, expiry, hard/soft mode, malformed versions, historical replay, duplicate/no-change observations, CAS renewal races, lost acknowledgements, pending schema/scope corruption and old receipt compatibility. External network polling remains caller-owned; no live network poll, provider promotion or long-duration soak was performed.
Frontend / Visual Evidence
Type of Change
LoopX Area
Technical Direction
Shared Goal Authority and TS control-plane T2 / L4. Future-facing pass: reuse the established lifecycle fence and resume-condition reducer, remove duplicate lease fact projection and repeated live admission during event construction. No speculative provider abstraction added.
Shared-authority RFC fixture impact
loopx_coordination_production_scale_fixture_v0; existingproductionScaleCoordinationFixturewith native/imported projection variants;productionScaleLeasedMonitorFixtureadds prior observations and a generation-bound dependent.Boundary Checklist
Runtime observations: managed startup p50/p95 210.29/333.71 ms (16 samples), warm RPC preview 8.94/10.91 ms (128 samples), and RSS 106.98 MiB idle / 114.69 MiB after 256 requests. RPC timings include transport and source checks; the internal-transition budget is measured separately.