From 32b6417153ca3e9a7b5b439e9df8d02cc66d0acb Mon Sep 17 00:00:00 2001 From: "lusendong.6789" Date: Wed, 30 Sep 2026 20:20:29 +0800 Subject: [PATCH] docs(rfc): define quota action authority and contention follow-ups Signed-off-by: lusendong.6789 Co-authored-by: TRAE CLI --- docs/architecture/rfcs/README.md | 8 + docs/architecture/rfcs/STATUS.md | 3 +- docs/architecture/rfcs/STATUS.zh-CN.md | 3 +- .../rfcs/quota-action-authority-v0.md | 258 ++++++++++++++++++ .../rfcs/quota-action-authority-v0.zh-CN.md | 231 ++++++++++++++++ 5 files changed, 501 insertions(+), 2 deletions(-) create mode 100644 docs/architecture/rfcs/quota-action-authority-v0.md create mode 100644 docs/architecture/rfcs/quota-action-authority-v0.zh-CN.md diff --git a/docs/architecture/rfcs/README.md b/docs/architecture/rfcs/README.md index 2afd0d4e35..fc450376b1 100644 --- a/docs/architecture/rfcs/README.md +++ b/docs/architecture/rfcs/README.md @@ -116,6 +116,14 @@ failure leaves the generated files untouched. ## Control-Plane Kernel, State, And Migration +- [Quota Action Authority v0](quota-action-authority-v0.md) + ([中文版](quota-action-authority-v0.zh-CN.md)) + - **Delivery on `main`:** Design only; final action projection and bounded + canonical claim retry remain unimplemented. + - **Current boundary:** Unifies action-bearing quota output while preserving + recommendation, Turn binding, execution admission and receipt recovery. + Includes contention evidence and ROI; no ranking or provider default change. + - [Monorepo Distribution Split v0](monorepo-distribution-split-v0.md) ([中文版](monorepo-distribution-split-v0.zh-CN.md)) - **Delivery on `main`:** Proposal only; tracking [#5072](https://github.com/loopx-project/loopx/issues/5072). diff --git a/docs/architecture/rfcs/STATUS.md b/docs/architecture/rfcs/STATUS.md index 49573b7832..6c31bcdcc7 100644 --- a/docs/architecture/rfcs/STATUS.md +++ b/docs/architecture/rfcs/STATUS.md @@ -18,7 +18,7 @@ appendix may keep dated history, but no dated log heading may precede it. [中文版](STATUS.zh-CN.md) is the semantic mirror of this file. -## Accepted (41) +## Accepted (42) | RFC | Header status | Supersedes / closes | Ledger | | --- | --- | --- | --- | @@ -57,6 +57,7 @@ appendix may keep dated history, but no dated log heading may precede it. | [RFC: Provider-side authorization at effect acceptance (v0)](provider-effect-acceptance-v0.md) | Accepted | none | — | | [RFC: Provider-Neutral Post-Writeback Capability Hooks v0](provider-neutral-post-writeback-capability-hooks-v0.md) | Accepted | none | — | | [RFC: Provider-Neutral Turn-Start Inbox Hook v0](provider-neutral-turn-start-inbox-hook-v0.md) | Accepted | none | — | +| [RFC: Quota Action Authority (v0)](quota-action-authority-v0.md) | Accepted | none | — | | [RFC: Research Exploration Control Plane v0](research-exploration-control-plane-v0.md) | Accepted | none | — | | [RFC: Semantic Vocabulary Convergence and Commit-Time Drift Checks (v0)](semantic-vocabulary-convergence-v0.md) | Accepted | none | [5 entries](ledger/semantic-vocabulary-convergence-v0/) | | [RFC: Shared Goal Alignment and Governed Amendment Protocol (v0)](shared-goal-alignment-and-governed-amendment-v0.md) | Accepted | none | [2 entries](ledger/shared-goal-alignment-and-governed-amendment-v0/) | diff --git a/docs/architecture/rfcs/STATUS.zh-CN.md b/docs/architecture/rfcs/STATUS.zh-CN.md index b54d7fa5c3..c2fe7a47e9 100644 --- a/docs/architecture/rfcs/STATUS.zh-CN.md +++ b/docs/architecture/rfcs/STATUS.zh-CN.md @@ -15,7 +15,7 @@ [English](STATUS.md) 与本文互为语义镜像。 -## 已接受 (41) +## 已接受 (42) | RFC | 头部状态 | 替代 / 关闭 | Ledger | | --- | --- | --- | --- | @@ -54,6 +54,7 @@ | [RFC:Provider 在效果接受点执行授权(v0)](provider-effect-acceptance-v0.zh-CN.md) | 已接受 | 无 | — | | [RFC:Provider-Neutral Post-Writeback Capability Hooks v0](provider-neutral-post-writeback-capability-hooks-v0.zh-CN.md) | 已接受 | 无 | — | | [RFC: Provider-Neutral Turn-Start Inbox Hook v0](provider-neutral-turn-start-inbox-hook-v0.md) | 已接受 | none | — | +| [RFC:Quota 动作权威(v0)](quota-action-authority-v0.zh-CN.md) | 已接受 | 无 | — | | [RFC:研究型探索控制面 v0](research-exploration-control-plane-v0.zh-CN.md) | 已接受 | 无 | — | | [RFC:语义词表收敛与提交期漂移检查(v0)](semantic-vocabulary-convergence-v0.zh-CN.md) | 已接受 | 无 | [5 条](ledger/semantic-vocabulary-convergence-v0/) | | [RFC:共享 Goal 对齐与受治理 Amendment 协议(v0)](shared-goal-alignment-and-governed-amendment-v0.zh-CN.md) | 已接受 | 无 | [2 条](ledger/shared-goal-alignment-and-governed-amendment-v0/) | diff --git a/docs/architecture/rfcs/quota-action-authority-v0.md b/docs/architecture/rfcs/quota-action-authority-v0.md new file mode 100644 index 0000000000..e0e815521e --- /dev/null +++ b/docs/architecture/rfcs/quota-action-authority-v0.md @@ -0,0 +1,258 @@ +# RFC: Quota Action Authority (v0) + +- **RFC status:** Accepted +- **Supersedes / closes:** none +- **Delivery maturity:** Proposal +- **Authors / owners:** LoopX control-plane maintainers +- **Created:** 2026-09-30 +- **Last normative revision:** 2026-09-30 +- **Implementation baseline:** `b79bcb1949e470aac3fcee416e96f2f4c468f926` +- **Related contracts:** [Effect interpreter](agent-loop-effect-interpreter-v0.md), [Shared authority](shared-goal-authority-state-provider-v0.md), [TypeScript migration](typescript-control-plane-migration-v0.md) +- **Language mirror:** [中文版](quota-action-authority-v0.zh-CN.md) + +## Document map and maintenance contract + +Sections 1–10 define the design and acceptance contract; section 11 defines +delivery gates; section 12 records unresolved choices. Appendix A is evidence, +not a delivery claim. Merge accepts this design basis; it does not ship runtime +behavior, change defaults, activate a provider, or approve promotion. +The English and Chinese documents are semantic mirrors; normative changes +must update both. + +## 1. Decision summary + +Resolve each executable quota action once in the existing TypeScript quota +boundary, after eligibility and selection are known. Derive action-bearing +presentation from that result. Keep recommendation, receipt-bound selection, +current execution admission, and historical settlement as distinct facts. + +Start with the inconsistent scoped-gate action projection. Preserve existing +wire fields and receipt identities. A whole quota pipeline rewrite, new +scheduler, and implicit task reservation are outside this decision. + +## 2. Problem and motivation + +A quota packet can tell an Agent to work on two different Todos. With a user +gate scoped to a peer, a P0 Todo requiring shell and network, a P1 Todo requiring +only shell, and only shell available, the audited builder returns: + +| Surface | Observed action | +| --- | --- | +| `selected_todo.todo_id` | P1 shell Todo | +| `interaction_contract.agent_channel.primary_action` | P1 shell Todo | +| `agent_scoped_user_gate_override.selected_action` | P0 network Todo | + +The override chooses text from an earlier executable summary before capability +filtering. Packet assembly retains both results. This is a reproducible +presentation inconsistency; the probe does not prove an actual unauthorized +execution or quantify its frequency. P0 here denotes work priority, not a +security severity rating. + +### Invariants + +- Every action presented as executable refers to the same final action identity. +- Recommendations never grant ownership, capabilities, permission, or a lease. +- An existing Turn receipt keeps its original Todo and settlement identity. +- Current gates can stop new execution without erasing historical recovery. +- No eligible action means no action-bearing override revives an earlier Todo. + +## 3. Scope and non-goals + +In scope: final quota action projection, compatibility consumers, and the +handoff from a recommendation to existing Todo claim/admission mechanisms. +Non-goals: change ranking policy, remove wire fields, reserve work during a +status read, redesign storage, add a capability/provider, or migrate all Python +orchestration in one batch. Contention work in section 6 is a separate bounded +follow-up under the existing shared-authority contract. + +## 4. Current-system contract + +- [`agent_scope.py`](../../../loopx/control_plane/agents/agent_scope.py) + `_agent_scoped_user_todo_override` chooses its own `selected_action`. +- [`should_run_prepare.py`](../../../loopx/control_plane/quota/should_run_prepare.py) + computes that override before the capability gate; explicit selection and + receipt recovery have later precedence. +- [`should_run_packet.py`](../../../loopx/control_plane/quota/should_run_packet.py) + attaches the override separately from `selected_todo` and interaction output. +- [`quota_selection.ts`](../../../loopx/control_plane/todos/quota_selection.ts) + already owns typed eligibility/ranking facts. Identical profiles and the same + unclaimed queue can recommend the same first Todo to multiple Agents. +- [`todo_claim.ts`](../../../loopx/control_plane/coordination/todo_claim.ts) + owns canonical claim plus optional hard lease. Its receipt helper recovers + accepted operations but does not replan a rejected CAS write. + +[PR #4061](https://github.com/loopx-project/loopx/pull/4061) concerns the snapshot +for fallback declarations and their direct dependencies. It explicitly does +not provide an atomic snapshot of the entire quota/status packet. This RFC +complements that work; neither needs to absorb the other's implementation. + +## 5. Proposed architecture + +### Ownership and placement + +Keep final action meaning in `control_plane/quota`, composing existing typed +Todo selection and gate rules. Python may gather facts and render compatibility +output; it must not rank or select a second executable action. Claim/lease +admission stays in `control_plane/coordination` and `control_plane/work_items`. +Capability id: no new capability. Provider id: existing configured authority +provider. Delivery: built-in control-plane implementation, no extension. + +### State and identity + +Use a small internal discriminated result at final packet composition: + +| Kind | Meaning | Action-bearing output | +| --- | --- | --- | +| Recommendation | Eligible candidate, no durable Turn selection | Explicitly advisory candidate | +| Selected | Existing selection contract binds the Turn to a Todo | That exact Todo; execution still needs current admission | +| Settlement | Recover or finish an existing receipt | Original receipt identity and permitted recovery steps | +| Gated | No currently admitted delivery action | Typed reason and allowed resolution; no stale work instruction | + +These are proposed internal states, not new wire enums or persisted fields. +Preserve all `quota_selected_todo_v0` fields, override schemas, source labels, +selection markers, and settlement receipts. Derive legacy `selected_action` +text from the resolved action when present. When absent, follow the existing +schema's optional-field behavior; if a consumer requires nonempty text, define +its compatible gated representation before implementation. Never substitute a +new Todo merely to make old receipt fields match current recommendations. + +The owner must retain legitimate distinctions: a preferred candidate can +coexist with an unbound Turn, and a completed Todo can still need settlement. +Identity comparison must use the existing structured identity, never action +text, display index, or a substring classification rule. + +### Lifecycle and effects + +Observation produces recommendations without mutation. Explicit selection +binds the existing Turn identity. Claim and current permission/capability/lease +checks admit execution. Validation, writeback, and spend use the bound identity. +Replay consults the original receipt and separately validates any present-tense +execution proof. A gate appearing between these stages stops new work through +the current admission owner; it does not delete an accepted result. + +This is a coherence boundary, not a claim that all facts came from one database +transaction. Each effect continues to revalidate the facts it owns. + +## 6. Alternatives, contention, and ROI + +Copying the final action text into one override is the cheapest repair, but +needs a shared final projection rule to cover explicit selection, empty +candidates, and receipt replay. Replacing the entire quota pipeline has a much +larger compatibility surface and no measured incremental benefit yet. + +Todo contention has separate causes and remedies: + +| Observation or risk | Bounded response | Evidence boundary | +| --- | --- | --- | +| Two equal-profile Agents see the same first unclaimed Todo | Claim before work; after a definitive competing-owner rejection, refresh eligibility and select another candidate through the existing selection contract | Confirmed synthetic recommendation collision; no production rate measured | +| Independent canonical claims expose provider CAS conflict | At the typed claim owner, re-read receipt/head, revalidate relevant facts, rebuild the mutation and retry within a bound | Confirmed command-level File/SQLite interleaving; same-root local CLI writer lock can serialize this case | +| Same Todo or overlapping required write scopes | Preserve ownership/lease rejection; do not retry into a takeover | Same-Todo exclusion confirmed; overlap is a required acceptance row | +| Different sessions reuse one Agent id | Retain execution-key/lease-generation checks; inspect session binding before attributing duplication to ranking | Diagnostic hypothesis, not established incident cause | + +The shared-authority RFC already requires Todo-scoped semantic conflicts. +Implement its remaining canonical claim adoption locally. Do not put domain +retry rules in the generic receipt helper or weaken provider CAS. Check receipt +recovery before a replan; preserve request identity, source authorization, +explicit revision/transfer preconditions, dependencies, gates, and write scopes. +An ambiguous commit is recovered by the same operation identity, not by picking +a new Todo. A definitive no-write rejection can permit reselection; a bound +Turn must first use its existing reconciliation contract, never silent retargeting. + +Equal-rank distribution, jitter, or a new atomic claim-next API should wait for +measurements showing that refresh/reselection remains costly. Hashing across +priority classes or randomizing every poll would silently alter scheduling. + +The following are planning estimates, not measured labor or production savings: + +| Slice | Estimated effort including focused regression review | Expected ROI | Decision | +| --- | --- | --- | --- | +| Final action projection plus compatibility matrix | 1–3 engineer-days | High: removes a reproduced contradiction with a small ownership change | Implement first | +| Canonical claim revalidation/retry | 2–4 engineer-days | Medium to high for independent cross-runtime writers; smaller with one serialized local writer | Separate PR after negative/replay fixtures | +| Ranking distribution or claim-next API | Unestimated until contention measurements | Unknown; adds fairness, selection and recovery semantics | Defer | +| Whole quota orchestration rewrite | Multi-week change | Unproven over the bounded slice | Defer | + +Evaluate savings as avoided failed attempts × average recovery time plus avoided +wrong-action recovery, against implementation and ongoing maintenance cost. +Collect rates and p50/p95 time-to-success before claiming a payback period. + +## 7. Safety, privacy, and compatibility + +Status remains read-only. No default changes to authority provider, hard-lease +mode, Agent identity, scheduling, permissions, or capability activation are +approved. Existing readers must keep parsing existing fields. Disclose the +intentional correction to contradictory action text in the implementation PR +and release notes; do not call changed output universally behavior-preserving. +Use synthetic Todo ids and aggregate counters in public evidence. Private +Goal contents, host paths, raw logs, and credentials are excluded. + +## 8. Migration and rollback + +No persisted-state migration is planned. First characterize existing legal +selection/replay cases, then replace one action projection and its active +consumers. Compare compatibility output before widening adoption. Revert that +bounded projection change if the matrix fails; receipts and provider state +remain readable. Claim retries ship independently and can be reverted without +changing stored operation or lease identities. + +## 9. Validation and acceptance + +| Claim | Test or evidence | Required result | Boundary | +| --- | --- | --- | --- | +| One executable action | Peer-scoped gate × missing/full capabilities × empty candidates × explicit selection | All executable surfaces resolve to the final identity; no stale action | Current mismatch is known failing behavior | +| Recovery identity survives gates | Bound Turn, completed Todo, capability loss, settled/unsettled replay | Original settlement identity retained; no newly granted execution | Must be added before runtime delivery | +| Independent claims progress | Barrier before provider commit; two distinct Todos and operation ids | Both succeed after bounded internal revalidation | File/SQLite first; other profiles retain qualification gates | +| Same-target exclusion | Same Todo, foreign owner, overlapping write scopes, changed authorization/dependency | One winner or typed rejection; no unauthorized receipt | Not satisfied by success-only retry tests | +| Recovery is idempotent | Lost acknowledgement, found/missing/unavailable receipt, request drift | Original accepted receipt recovered; ambiguity never becomes a new claim | Generic receipt semantics unchanged | +| Compatibility | Existing quota smoke, focused tests, mixed legacy consumers | Wire shape retained; documented correction only | Green existing tests alone do not close the mismatch | + +All rows are implementation gates, not claims that this documentation PR has +passed runtime qualification. + +## 10. Operational contract + +Use existing diagnostic/evidence surfaces to distinguish recommendation +collision, competing owner, provider-head contention, exhausted retry, and +ambiguous receipt recovery. Count attempts per successful claim and latency; +avoid a new telemetry subsystem. Never present a failed claim as execution +admission. The host consumes the existing typed recovery path rather than +looping on the same stale first candidate. + +## 11. Normative delivery plan + +| Milestone | Shipped behavior | Entry gate | Exit evidence | Rollback | +| --- | --- | --- | --- | --- | +| M0 | Coherent final action projection | Consumer inventory and characterization matrix | Mismatch fixed; negative/selection/replay cases and quota checks pass | Revert projection slice | +| M1 | Independent claims absorb unrelated CAS misses | Existing shared-authority rules; fixtures before code movement | Bounded retry, same-Todo/scope exclusion, current gates and lost-response recovery | Revert retry slice | +| M2 | Optional collision reduction, only if justified | Measured residual collision cost and agreed fairness policy | Better attempts/latency without starvation or priority inversion | Restore ranking policy | + +M0 and M1 are independent reviewable changes. M2 requires a new explicit design +decision; this RFC does not approve an API or default-ranking change. + +## 12. Open decisions + +1. Quota maintainers choose the smallest internal result shape and compatible + representation for absent action text before M0, based on actual consumer + inventory. Recommendation: reuse current codecs and omit only already + optional fields; no public-field removal. +2. Coordination maintainers choose the retry/time budget before M1, based on + forced interleavings and provider latency. Recommendation: bounded retry + with typed exhaustion and unchanged operation identity; no unbounded loop. +3. Maintainers decide whether M2 is justified after observing residual failed + attempts and fairness. Recommendation: defer without measured evidence. + +## Appendix A: Evidence registry (non-normative) + +All observations use the implementation baseline in the header and synthetic +inputs; they establish mechanisms, not incidence in a deployed Goal. + +| Evidence | Setup and result | Limit | +| --- | --- | --- | +| Action projection | `build_quota_should_run` with the section 2 fixture: shell-only selects P1 but override names P0; adding network removes that mismatch | No live action executed | +| Existing regression | `uv run --extra test python examples/control_plane/quota-agent-scoped-user-gate-smoke.py` passes while the combined fixture fails identity coherence | Demonstrates missing combined coverage | +| Recommendation | `projectQuotaSelection`: two unclaimed equal-rank rows, same profile, Agent A/B both get the first row | Recommendation is not reservation | +| Claim interleaving | Real File and SQLite stores; native two-Todo head in hard-lease mode; distinct operations/lease keys; barrier before `commitAuthority`: independent targets produce applied/conflict, same-operation retry applies | Bypasses outer local writer serialization; no deployed throughput claim | +| Exclusion control | Same setup with the same target: one applied, one conflict; same-operation retry yields `claim_owner_mismatch` | No evidence of double ownership | + +Keep temporary probes outside the product surface. Promote their semantic +cases into the existing focused suites with M0/M1; do not preserve raw logs or +an experiment-specific runner as a permanent smoke. diff --git a/docs/architecture/rfcs/quota-action-authority-v0.zh-CN.md b/docs/architecture/rfcs/quota-action-authority-v0.zh-CN.md new file mode 100644 index 0000000000..27989ed452 --- /dev/null +++ b/docs/architecture/rfcs/quota-action-authority-v0.zh-CN.md @@ -0,0 +1,231 @@ +# RFC:Quota 动作权威(v0) + +- **RFC 状态:** 已接受 +- **替代 / 关闭:** 无 +- **交付成熟度:** 仅提案,尚未实现 +- **作者 / 负责人:** LoopX 控制面维护者 +- **创建日期:** 2026-09-30 +- **最近规范修订:** 2026-09-30 +- **实现基线:** `b79bcb1949e470aac3fcee416e96f2f4c468f926` +- **相关契约:** [Effect interpreter](agent-loop-effect-interpreter-v0.zh-CN.md)、[共享权威](shared-goal-authority-state-provider-v0.zh-CN.md)、[TypeScript 迁移](typescript-control-plane-migration-v0.zh-CN.md) +- **语言镜像:** [English](quota-action-authority-v0.md) + +## 文档地图与维护约定 + +第 1–10 节定义设计与验收契约,第 11 节定义交付门禁,第 12 节记录待决事项。 +附录 A 是证据,不代表交付。合并接受此设计依据,不代表运行时实现已上线、 +默认值已改变、provider 已启用或 promotion 已获批准。 +中英文文档互为语义镜像;规范性变更必须同步修改两份文档。 + +## 1. 决策摘要 + +在既有 TypeScript quota 边界内,等待 eligibility 和 selection 确定后, +统一解析可执行动作,再从该结果生成包含动作的展示。 +推荐、receipt 绑定的选择、当前执行准入、历史结算仍是不同事实。 + +先修 scoped-gate 动作投影的不一致,保留现有 wire 字段与 receipt identity。 +本决策不包含整个 quota pipeline 重写、新 scheduler 或隐式任务预占。 + +## 2. 问题与动机 + +同一 quota packet 可能告诉 Agent 执行两个不同 Todo。复现场景是: +User gate 只约束另一个 Agent;P0 Todo 需要 shell 和 network; +P1 Todo 只需要 shell;当前仅具备 shell。被审计的 builder 输出为: + +| 输出面 | 实际观察到的动作 | +| --- | --- | +| `selected_todo.todo_id` | P1 shell Todo | +| `interaction_contract.agent_channel.primary_action` | P1 shell Todo | +| `agent_scoped_user_gate_override.selected_action` | P0 network Todo | + +override 在 capability 过滤前从较早的 executable summary 选出文本, +packet assembly 又同时保留两套结果。这是可复现的展示不一致; +实验没有证明发生了越权执行,也没有测量其频率。此处 P0 是工作优先级, +不是安全严重性评级。 + +### 不变量 + +- 所有标为可执行的动作必须指向同一最终动作身份。 +- 推荐不授予所有权、能力、权限或 lease。 +- 已有 Turn receipt 保留原 Todo 和结算身份。 +- 当前门禁可以阻止新执行,但不能抹去历史恢复依据。 +- 没有 eligible action 时,override 不能重新带回早先的 Todo。 + +## 3. 范围与非目标 + +范围包含最终 quota 动作投影、兼容消费者,以及从推荐到既有 Todo +claim/admission 机制的衔接。不改变排序策略、不删除 wire 字段、不在 status +读取中预占工作、不重做存储、不新增 capability/provider,也不一次迁移全部 +Python 编排。第 6 节的争抢工作属于既有共享权威契约下的独立有界后续变更。 + +## 4. 当前系统契约 + +- [`agent_scope.py`](../../../loopx/control_plane/agents/agent_scope.py) 中的 + `_agent_scoped_user_todo_override` 自行选出 `selected_action`。 +- [`should_run_prepare.py`](../../../loopx/control_plane/quota/should_run_prepare.py) + 在 capability gate 前计算 override;显式选择与 receipt 恢复在后续具有更高优先级。 +- [`should_run_packet.py`](../../../loopx/control_plane/quota/should_run_packet.py) + 将 override 与 `selected_todo`、interaction 输出分别附加。 +- [`quota_selection.ts`](../../../loopx/control_plane/todos/quota_selection.ts) + 已拥有 typed eligibility/ranking 事实。相同 profile 和未认领队列, + 可以让多个 Agent 同时收到同一个首选 Todo。 +- [`todo_claim.ts`](../../../loopx/control_plane/coordination/todo_claim.ts) + 拥有 canonical claim 和可选 hard lease。receipt helper 恢复已接受的操作, + 不会为遭到 CAS 拒绝的写入重新规划。 + +[PR #4061](https://github.com/loopx-project/loopx/pull/4061) 处理 fallback +声明及直接依赖的快照,并明确不提供整个 quota/status packet 的原子快照。 +本 RFC 与它互补,双方不需要吸收对方的实现。 + +## 5. 建议架构 + +### 所有权与放置 + +最终动作语义放在 `control_plane/quota`,组合已有 typed Todo selection +和 gate 规则。Python 可以收集事实、呈现兼容输出,但不能再排序或选出第二个 +可执行动作。claim/lease 准入仍归 `control_plane/coordination` 和 +`control_plane/work_items`。Capability id:不新增;provider id:既有已配置的 +权威 provider;交付形式:内建控制面实现,无 extension。 + +### 状态与身份 + +在最终 packet composition 使用一个小型内部判别结果: + +| Kind | 含义 | 包含动作的输出 | +| --- | --- | --- | +| Recommendation | Eligible 候选,尚无持久化 Turn 选择 | 明确标注为建议的候选 | +| Selected | 既有 selection 契约将 Turn 绑定到 Todo | 精确绑定的 Todo;执行仍需当前准入 | +| Settlement | 恢复或完成既有 receipt | 原 receipt identity 和允许的恢复步骤 | +| Gated | 当前没有获准的交付动作 | Typed 原因及允许的解决路径,不含旧工作指令 | + +这些是建议的内部状态,不是新增 wire enum 或持久化字段。 +保留 `quota_selected_todo_v0` 全部字段、override schema、source label、 +selection marker 和 settlement receipt。有最终动作时,由它生成兼容的 +`selected_action` 文本;没有时遵守既有 schema 的可选字段规则。 +如果消费者要求非空文本,必须在实现前定义兼容的 gated 表达。 +不能为了让旧 receipt 字段与当前推荐一致而替换 Todo。 + +必须保留合法区别:preferred candidate 可以与未绑定 Turn 共存, +已完成 Todo 仍可能需要结算。身份比较使用既有结构化 identity, +不用动作文本、展示 index 或 substring 分类规则。 + +### 生命周期与副作用 + +观察只产生推荐,不修改状态。显式选择绑定既有 Turn identity。 +claim 与当前 permission/capability/lease 检查准入执行。 +validation、writeback、spend 使用绑定身份。重放读取原 receipt, +并独立验证任何当前执行证明。阶段之间出现新 gate 时,当前准入 owner +阻止新工作,但不删除已接受结果。 + +这是投影一致性边界,不意味着所有事实来自同一个数据库事务。 +各个 effect 仍须重新验证自己拥有的事实。 + +## 6. 备选方案、争抢与 ROI + +将最终动作文本复制回某个 override 是最便宜的修复,但还需要共享的最终投影 +规则,覆盖显式选择、空候选和 receipt 重放。重写整个 quota pipeline +涉及更大的兼容面,目前没有证明额外收益。 + +Todo 争抢需要区分原因和处理方式: + +| 观察或风险 | 有界处理 | 证据边界 | +| --- | --- | --- | +| 两个同 profile Agent 看到同一未认领首项 | 先 claim 再工作;确定因其他 owner 被拒绝后,刷新 eligibility,通过既有 selection 契约选择其他候选 | 已确认合成推荐碰撞,未测量生产频率 | +| 独立 canonical claim 暴露 provider CAS 冲突 | Typed claim owner 重读 receipt/head,重验相关事实,重建 mutation,有限重试 | 已确认 File/SQLite 命令层交错;同 root 本地 CLI 写锁可能将其串行化 | +| 同 Todo 或 required write scope 重叠 | 保留 ownership/lease 拒绝,不通过重试接管 | 已确认同 Todo 排他;scope 重叠仍是必需验收项 | +| 不同 session 复用同一 Agent id | 保留 execution key/lease generation 检查,先查 session binding 再归因排序 | 诊断假设,尚未确认是实际事故原因 | + +共享权威 RFC 已要求 Todo 级语义冲突,应在 canonical claim 的既有 owner +补齐采用。不要把领域重试规则放进通用 receipt helper,也不要弱化 provider CAS。 +重新规划前先查 receipt 恢复;保留 request identity、source authorization、 +显式 revision/transfer 前置条件、依赖、gate 和 write scope。 +模糊提交必须用原 operation identity 恢复,不能换 Todo。 +确定未写入的拒绝可以允许重选;已有绑定的 Turn 必须先走既有 reconciliation +契约,禁止悄悄更换目标。 + +同 rank 分流、jitter 或新增原子 claim-next API,应等待测量证明刷新/重选仍然 +代价较高。跨优先级 hash 分配或每次 poll 随机排序会隐式改变调度。 + +以下是规划估计,不是已测量的工时或生产收益: + +| 交付切片 | 含聚焦回归评审的工作量估计 | 预期 ROI | 建议 | +| --- | --- | --- | --- | +| 最终动作投影和兼容矩阵 | 1–3 工程人日 | 高:小范围所有权调整即可消除已复现矛盾 | 优先实施 | +| Canonical claim 重验/重试 | 2–4 工程人日 | 独立跨 runtime writer 下中高;单个串行本地 writer 下较小 | 先补负例/重放 fixture,再独立 PR | +| 排序分流或 claim-next API | 获得争抢测量前不估算 | 未知;会增加公平性、选择和恢复语义 | 暂缓 | +| 完整 quota 编排重写 | 数周级变更 | 相比有界切片的增益尚未证明 | 暂缓 | + +收益可按“减少的失败尝试次数 × 平均恢复时间,加上减少的错误动作恢复”评估, +再与实现及持续维护成本比较。对外声称回本周期前,需要收集频率和 +成功 claim 耗时的 p50/p95。 + +## 7. 安全、隐私与兼容 + +status 保持只读。本设计不批准 authority provider、hard-lease 模式、 +Agent identity、调度、权限或能力启用的默认变化。已有 reader 继续解析现有字段。 +实现 PR 和 release notes 必须披露矛盾动作文本的有意修正,不能将输出变化 +笼统宣称为行为完全不变。公开证据使用合成 Todo id 和汇总计数, +不包含私有 Goal 内容、host 路径、原始日志或凭据。 + +## 8. 迁移与回滚 + +没有持久化状态迁移计划。先刻画合法的 selection/replay 行为,再替换一个动作 +投影及其实际消费者。扩大采用前比较兼容输出。矩阵失败时回滚该有界投影变更, +receipt 和 provider 状态仍可读取。claim 重试独立交付,回滚时不改变已存储的 +operation 或 lease identity。 + +## 9. 验证与验收 + +| 主张 | 测试或证据 | 必需结果 | 边界 | +| --- | --- | --- | --- | +| 唯一可执行动作 | Peer-scoped gate × 能力缺失/齐全 × 空候选 × 显式选择 | 所有 executable 输出指向最终身份,无旧动作 | 当前反例属于已知失败行为 | +| Gate 不破坏恢复身份 | 绑定 Turn、已完成 Todo、能力丢失、已结算/未结算重放 | 保留原结算 identity,不新增执行授权 | 运行时交付前必须补齐 | +| 独立 claim 可推进 | Provider commit 前 barrier,两个不同 Todo 和 operation id | 有界内部重验后均成功 | 先 File/SQLite,其他 profile 保留资格门禁 | +| 同目标排他 | 同 Todo、foreign owner、write scope 重叠、授权/依赖改变 | 唯一胜者或 typed 拒绝,无未授权 receipt | 仅测试成功重试不够 | +| 恢复幂等 | 响应丢失、receipt 存在/缺失/不可读、request drift | 恢复原已接受 receipt,ambiguity 不能成为新 claim | 不改变通用 receipt 语义 | +| 兼容性 | 现有 quota smoke、聚焦测试、混合 legacy 消费者 | 保留 wire shape,仅发生已披露修正 | 现有测试全绿不能单独关闭反例 | + +这些都是实现门禁,不表示本文档 PR 已完成运行时资格验证。 + +## 10. 运行约定 + +利用现有诊断/证据面区分推荐碰撞、其他 owner、provider-head 竞争、 +重试耗尽和模糊 receipt 恢复。统计每次成功 claim 的尝试次数和延迟, +不另建遥测系统。失败 claim 不能显示为执行准入。 +Host 消费既有 typed 恢复路径,不应循环尝试同一个过时首项。 + +## 11. 规范性交付计划 + +| 阶段 | 交付行为 | 进入门禁 | 退出证据 | 回滚 | +| --- | --- | --- | --- | --- | +| M0 | 最终动作投影一致 | 消费者清单和 characterization 矩阵 | 修复反例;负例/selection/replay 和 quota 检查通过 | 回滚投影切片 | +| M1 | 独立 claim 吸收无关 CAS miss | 既有共享权威规则;移动代码前补 fixture | 有界重试、同 Todo/scope 排他、当前 gate 和丢响应恢复 | 回滚重试切片 | +| M2 | 有证据时才减少残余碰撞 | 残余成本测量及已同意的公平策略 | 尝试次数/延迟改善,无饥饿或优先级反转 | 恢复排序策略 | + +M0 和 M1 是独立可评审变更。M2 需要新的显式设计决策; +本 RFC 不批准新增 API 或默认排序变化。 + +## 12. 待决事项 + +1. Quota 维护者在 M0 前根据真实消费者清单确定最小内部结果形状和空动作文本的 + 兼容表达。建议复用现有 codec,只省略本来可选的字段,不删除 public 字段。 +2. Coordination 维护者在 M1 前根据强制交错和 provider 延迟决定次数/时间预算。 + 建议有限重试、typed 耗尽、保持 operation identity,不使用无限循环。 +3. 维护者观察残余失败次数及公平性后,决定是否启动 M2。 + 建议在缺少测量证据时暂缓。 + +## 附录 A:证据登记(非规范) + +全部观察使用头部所列实现 baseline 和合成输入,证明机制,不证明部署中 +某个 Goal 的发生频率。 + +| 证据 | 设置与结果 | 限制 | +| --- | --- | --- | +| 动作投影 | `build_quota_should_run` 使用第 2 节 fixture:仅 shell 时选择 P1、override 指向 P0;加入 network 后此矛盾消失 | 未执行真实动作 | +| 现有回归 | `uv run --extra test python examples/control_plane/quota-agent-scoped-user-gate-smoke.py` 通过,同时组合 fixture 不满足身份一致性 | 表明组合覆盖缺失 | +| 推荐 | `projectQuotaSelection` 输入两个未认领、同 rank Todo 和相同 profile,Agent A/B 都得到首项 | 推荐不是 reservation | +| Claim 交错 | 真实 File 和 SQLite store;native 双 Todo head、hard-lease 模式、不同 operation/lease key;`commitAuthority` 前 barrier:独立目标得到 applied/conflict,用同 operation 重试成功 | 绕过外层本地 writer 串行锁,不证明部署吞吐 | +| 排他对照 | 相同设置改为同一目标:一个 applied、一个 conflict;同 operation 重试得到 `claim_owner_mismatch` | 没有双重所有权证据 | + +临时 probe 留在产品面之外。随 M0/M1 将对应语义案例纳入现有聚焦 suite, +不把原始日志或实验专用 runner 固化成永久 smoke。