diff --git a/docs/architecture/rfcs/ledger/semantic-vocabulary-convergence-v0/2026-09-20-staged-tracker-acceptance.md b/docs/architecture/rfcs/ledger/semantic-vocabulary-convergence-v0/2026-09-20-staged-tracker-acceptance.md new file mode 100644 index 000000000..fe6e9f4db --- /dev/null +++ b/docs/architecture/rfcs/ledger/semantic-vocabulary-convergence-v0/2026-09-20-staged-tracker-acceptance.md @@ -0,0 +1,57 @@ +# Staged tracker acceptance and conditional field retirement + +Status: **proposal**, not a completed migration or approval record. Baseline: +`36134771355f05c9bcc5657ce739bb86426383dc`. Delivery status and the ordered +work plan belong to [#4447](https://github.com/loopx-project/loopx/issues/4447); +[discussion #4738](https://github.com/loopx-project/loopx/discussions/4738) +provides the slice specifications and corrections. Section 11 carries the +proposed M3 contract change; this ledger is its evidence record. + +The previous tracker required deletion of a first field as proof of usefulness. +That confuses a means with an outcome. At this baseline, +`protocol_action_packet` still has live writers and compatibility consumers; +[#4794](https://github.com/loopx-project/loopx/pull/4794) now implements the +writer retirement but is not merged into this baseline. Its semantic-field +projection remains necessary for Envelope/signature compatibility. A low +syntactic reader count proves neither that the field is redundant nor that +historical readers can be removed. A derived compatibility projection can be +retained while duplicated construction or independent decision authority is +eliminated. + +The proposed tracker stages are: + +1. Verify the shipped guard boundaries and the selected production-path + simplifications on an integrated tree. Fresh packet construction must not be + duplicated: when the PR-05 migration is adopted, new quota/live/paused/recovery + outputs carry no packet while the historical v0 reader and signature projection + remain; without that migration, the retained field is rendered at most once at + the final live stage. Settled work must not be reconstructed or spent again, + unadmitted selection must not acquire settlement capability, and inbox source + precedence must remain intact. Preserve legitimate workspace repair and + independent capability effects. Local branch tests do not certify the + integrated result. +2. Close sources for the 26 registered vocabularies without pretending every + value originates in an internal producer. On the baseline, six runtime + producer entries plus one compatibility-only entry account for the reported + F1/F2 7/26; 19 cross-runtime vocabularies remain outside that verification. + Trace settlement/receipt, workspace/Todo, then the remaining bounded owners. + Internal production needs a real witness; external input needs decoder + acceptance/rejection evidence; compatibility needs retained scope and exit + conditions. A local-only classification needs proof it does not cross the + boundary. Labels alone, or renaming unknown entries, earn no evidence credit. +3. Review the same final revision, record passed/failed/untested boundaries and + close only after the revised acceptance is approved and its evidence is met. + Exact protocol formats and signatures stay protected. Whole-program analysis, + all-field deletion, F6-wide persistence proof and unregistered vocabulary + governance are outside this bounded delivery tracker. + +This does not change F1/F2 formulas or enforcement domains, add a source schema, +lower budgets, or declare the 19 entries verified. Source classification and +production verification must remain separate claims. Implementing any new +source-evidence contract needs its own review and negative cases; the already +merged settlement-binding witness is one pilot, not the whole second stage. + +M3 remains available when an actual consumer/authority simplification justifies +it and a versioned compatibility plan exists. Until then, retain the field and +its checks. Do not keep the tracker open solely to reach zero field names, and +do not close it by relabeling missing source evidence as documentation work. diff --git a/docs/architecture/rfcs/ledger/semantic-vocabulary-convergence-v0/2026-09-20-staged-tracker-acceptance.zh-CN.md b/docs/architecture/rfcs/ledger/semantic-vocabulary-convergence-v0/2026-09-20-staged-tracker-acceptance.zh-CN.md new file mode 100644 index 000000000..b267b6815 --- /dev/null +++ b/docs/architecture/rfcs/ledger/semantic-vocabulary-convergence-v0/2026-09-20-staged-tracker-acceptance.zh-CN.md @@ -0,0 +1,40 @@ +# Tracker 阶段验收与有条件字段退役 + +状态:**提案**,不是迁移完成或批准记录。基线: +`36134771355f05c9bcc5657ce739bb86426383dc`。 +交付状态与有序工作计划归 [#4447](https://github.com/loopx-project/loopx/issues/4447) +维护;[讨论 #4738](https://github.com/loopx-project/loopx/discussions/4738) +提供切片规格及纠正。第 11 节承载 M3 契约修改提案,本条目记录其证据。 + +旧 tracker 要求删除第一个字段以证明有用,把手段当成了结果。在本基线上, +`protocol_action_packet` 仍有现行 writer 和兼容消费者; +[#4794](https://github.com/loopx-project/loopx/pull/4794) 已实现 writer 退休, +但尚未合入本基线。其语义字段投影仍承担 Envelope/签名兼容职责。句法 reader +数少既不能证明字段冗余,也不能授权删除历史读取。可以保留派生兼容投影,同时 +消除重复构造或独立决策权威。 + +建议的 tracker 阶段为: + +1. 在集成树上验证已交付的守卫边界和选定的生产路径简化。fresh packet 构造不得 + 重复:采用 PR-05 迁移时,新 quota/live/paused/recovery 输出不携带 packet, + 同时保留历史 v0 reader 与签名投影;未采用迁移时,保留字段最多在最终 live + 阶段渲染一次。已结算工作不得重复构造/花费,未准入选择不能获得结算能力, + inbox 来源优先级保持不变。保留合法 workspace repair 和独立 capability effect。 + 单分支本地测试不能认证集成结果。 +2. 对 26 个已登记词表闭合来源,不假装每个值都来自内部 producer。基线上,六个 + runtime producer 条目与一个 compatibility-only 条目构成报告中的 F1/F2 7/26; + 仍有 19 个 cross-runtime 词表不在该验证范围内。按 settlement/receipt、 + workspace/Todo、其余有界 owner 的顺序追踪。内部生产需要真实见证,外部输入 + 需要 decoder 合法/非法输入证据,兼容项需要保留范围和退出条件。local-only + 分类必须证明不跨边界。只贴标签或给 unknown 改名不能获得证据信用。 +3. 在同一最终版本上复审,记录通过/失败/未测试边界;修订的验收范围获准且证据 + 满足后才能关闭。协议格式和签名继续受保护。全程序分析、所有字段删除、F6 + 全面持久兼容证明和未登记词表治理不属于这个有限交付 tracker。 + +本提案不修改 F1/F2 公式或强制执行域、不增加来源 schema、不降低预算,也不宣称 +19 项已验证。来源分类与生产验证必须保持为两种声明。任何新的来源证据契约实现 +都需要单独评审及负例;已合并的 settlement-binding 见证只是 pilot,不是第二阶段全部。 + +当实际消费者/权威简化收益和版本化兼容方案具备时,仍可启动 M3。在此之前保留字段 +及其检查。不要仅为了字段名归零而保持 tracker 打开,也不要把缺失的来源证据改名为 +文档工作后关闭。 diff --git a/docs/architecture/rfcs/semantic-vocabulary-convergence-v0.md b/docs/architecture/rfcs/semantic-vocabulary-convergence-v0.md index 8740a867d..8c62e357e 100644 --- a/docs/architecture/rfcs/semantic-vocabulary-convergence-v0.md +++ b/docs/architecture/rfcs/semantic-vocabulary-convergence-v0.md @@ -979,11 +979,19 @@ with `npm ci --ignore-scripts` before running the TypeScript production scan. | M0.5b | `producers` and `compatibility_only` on `kernel` vocabularies; production-form scan with the two role checks (I12, I13); retirement budgets counted by identifier with all six anchors lowered in one diff (Q11); merge-order rule from Q9 written into Section 10 | M0.5a complete; Q9 decided or its interim rule accepted | Smoke green with I11 to I14 enforced; `skip` resolved; Section 9 producer rows green; `turn_route` persistence answered for Q2 | Remove producer fields and role checks; budgets return to the pre-M0.5b anchors | | M1 | `EffectiveAction` typed enum in one owner module; the replay observation and frontier slots split off (Q6); producers and consumers import it; registry `literal_scan` tightened to the enum | M0.5 merged; owner module chosen (Q3); slot split decided (Q6) | Smoke green; zero bare `effective_action` literals outside the owner; parity fixtures for status/should-run unchanged | Revert to literals; registry keeps the set | | M2 | Route-to-disposition projection, the `decide_loop_disposition` decision table, and the cross-runtime sets published through a shared contract with generated Python and TypeScript bindings, following the coordination contract generator | M1 merged; Q2 and Q7 decided | Generator `--check` and smoke green; `settlement.ts` and `transaction.py` read the generated set | Regenerate from prior contract | -| M3 | Per-field retirement of legacy should-run fields, one field per PR, budgets lowered to zero and the field removed | Field's migration surface is emptied module by module, and the residual unresolved and dynamic-key evidence is reviewed; a zero count is not by itself the gate | Schema-reduction record per `AGENTS.md`; Appendix B entry | Restore field from the last writer | +| M3 | Conditional per-field retirement where removing a field eliminates demonstrated duplicate authority or unnecessary consumer maintenance; a derived compatibility projection may remain | Document net benefit, target version, consumers, historical formats/signatures and rollback window; review unresolved and dynamic-key evidence before stopping writes | Approved migration, new-output and historical-read/rejection tests, actual removal of replaced code, and updated budgets for the approved surface; retaining a useful projection is not a failed migration | Restore the approved writer within the declared compatibility window | | M4 | Twin budget lowered with each replacement-first cutover from the migration RFC | Each cutover PR | Budget edit in the same diff | None needed; budget follows code | -A ratchet without a target is a direction, not a plan. The table below is the -state at which this RFC is complete; each row is a registry budget or a +**Staged acceptance proposal for #4447.** This RFC's long-range milestones are +not all prerequisites for closing one delivery tracker. The staged proposal in +[#4447](https://github.com/loopx-project/loopx/issues/4447), informed by +[discussion #4738](https://github.com/loopx-project/loopx/discussions/4738), separates +verified guard adoption, bounded production-path simplification, and source +evidence closure. Maintainer acceptance of that scope is required before tracker +closure; this proposal does not certify delivery or change any runtime check. + +The table below records long-range targets, not an unconditional deletion quota +or the acceptance checklist for #4447; each row is a registry budget or a vocabulary property the smoke can check. Rows marked *open* wait on a Section 12 decision and are the reason the plan is a skeleton until those are recorded. @@ -996,7 +1004,7 @@ vocabulary property the smoke can check. Rows marked *open* wait on a Section | Conflicting values, semantic | 2 names | `semantic-vocabulary-drift-smoke.py`: `conflicting_values_semantic` | 0 | baseline PRs | | Multi-value forks | 4 (1 misclassified) | `semantic-vocabulary-drift-smoke.py`: `multi_value_forks` and `multi_value_forks_semantic`. Only the count is printed today; #4614 adds `divergent_value_sets` to name the surviving forks | 0 after `scope` declares bounded-context names | M0.5 + baseline PRs | | Multi-value twins | 19 | `semantic-vocabulary-drift-smoke.py`: `multi_value_twins` | 0 | baseline PRs | -| Legacy should-run fields | 6 fields, 124 py / 10 ts module mentions | `semantic-vocabulary-drift-smoke.py`: one `.py` / `.ts` pair per field for the token count; one `retirement_role:` line per field and runtime under `--report` for the migration surface and its five roles | 0 fields | M3, gated on emptying the B3 migration surface; the token count stays budgeted until Q11 | +| Legacy should-run fields | 6 fields, 124 py / 10 ts module mentions | `semantic-vocabulary-drift-smoke.py`: one `.py` / `.ts` pair per field for the token count; one `retirement_role:` line per field and runtime under `--report` for the migration surface and its five roles | No unneeded independent authority in approved migration surfaces; retained derived/compatibility fields remain visible | M3 only when benefit and compatibility justify retirement; budgets stay enforced until a reviewed change | | Merge-candidate groups | 32 unreviewed | `merge_candidate_groups()` in `loopx/semantics/inventory.py`; no command prints it today, and #4630 adds the CLI line. Read the reviewable count, not the raw one -- a registered cross-runtime vocabulary owns both its Python and TypeScript symbols, so those pairs are required by I3 rather than debt | every group classified; only `same_semantics` groups merged | classification PR, then per-group PRs | | Control-plane py/ts twins | 43 | `semantic-vocabulary-drift-smoke.py`: `independently_maintained` | follows the TypeScript migration RFC; no target here | M4 | diff --git a/docs/architecture/rfcs/semantic-vocabulary-convergence-v0.zh-CN.md b/docs/architecture/rfcs/semantic-vocabulary-convergence-v0.zh-CN.md index 489d7e40f..a3b20b464 100644 --- a/docs/architecture/rfcs/semantic-vocabulary-convergence-v0.zh-CN.md +++ b/docs/architecture/rfcs/semantic-vocabulary-convergence-v0.zh-CN.md @@ -791,10 +791,16 @@ TypeScript effective-action 绑定与[术语表](../../reference/glossary.md)通 | M0.5b | `kernel` 词表的 `producers` 与 `compatibility_only`;带两条角色检查(I12、I13)的生产形式扫描;退休预算改按标识符计数并在一个 diff 里调整六个锚点(Q11);Q9 的合并序规则写入第 10 节 | M0.5a 完成;Q9 已决或其临时规则被接受 | smoke 在 I11 到 I14 强制下全绿;`skip` 已处理;第 9 节生产者行全绿;为 Q2 回答 `turn_route` 是否持久化 | 删除生产者字段和角色检查;预算回到 M0.5b 前的锚点 | | M1 | 单一 owner 模块中的 `EffectiveAction` 类型化枚举;replay observation 与 frontier 槽位拆出(Q6);生产者与消费者 import 它;注册表 `literal_scan` 收紧到枚举 | M0.5 合入;owner 模块已定(Q3);槽位拆分已决(Q6) | smoke 绿;owner 之外零裸 `effective_action` 字面量;status/should-run 的 parity fixture 不变 | 回退为字面量;注册表保留集合 | | M2 | route 到 disposition 的投影、`decide_loop_disposition` 决策表与跨运行时集合通过共享契约发布,生成 Python 与 TypeScript 绑定,效仿协调契约生成器 | M1 合入;Q2 与 Q7 已决 | 生成器 `--check` 与 smoke 绿;`settlement.ts` 与 `transaction.py` 读取生成集合 | 从上一版契约重新生成 | -| M3 | 逐字段退休旧 should-run 字段,每个 PR 一个字段,预算降到零并删除字段 | 逐模块清空该字段的迁移面,并评审残留的 unresolved 与计算式键证据;计数归零本身不构成这道门 | 按 `AGENTS.md` 的 schema 缩减记录;附录 B 条目 | 从最后一个写方恢复字段 | +| M3 | 有条件逐字段退役:删除必须消除已证实的重复权威或不必要的消费者维护;派生兼容投影可以保留 | 说明净收益、目标版本、消费者、历史格式/签名和回滚窗口;停写前评审 unresolved 与计算式键证据 | 获准迁移、新输出及历史读取/拒绝测试、被替代代码实际删除、批准范围对应预算更新;保留有用投影不属于迁移失败 | 在声明的兼容窗口内恢复获准 writer | | M4 | 随迁移 RFC 的每次 replacement-first 切换调低孪生预算 | 每个切换 PR | 同 diff 中的预算修改 | 无需;预算跟随代码 | -没有目标的棘轮只是方向,不是计划。下表是本 RFC 完成时的状态;每一行都是一个 +**#4447 阶段验收提案。** 本 RFC 的长期里程碑不全部构成单个交付 tracker +的关闭条件。[#4447](https://github.com/loopx-project/loopx/issues/4447) 结合 +[讨论 #4738](https://github.com/loopx-project/loopx/discussions/4738) 的阶段方案, +分别验收守卫的真实采用、有限生产路径的重复维护消除和来源证据闭合。 +关闭 tracker 前必须由维护者接受该范围;本提案不认证交付完成,也不改变运行时检查。 + +下表记录长期目标,不是无条件删除配额,也不是 #4447 的验收清单;每一行都是一个 注册表预算或 smoke 可检查的词表属性。标为*未决*的行等待第 12 节的决策,这也 是计划在那些决策记录之前只是骨架的原因。 @@ -807,7 +813,7 @@ TypeScript effective-action 绑定与[术语表](../../reference/glossary.md)通 | 冲突值(语义) | 2 个名字 | `semantic-vocabulary-drift-smoke.py`:`conflicting_values_semantic` | 0 | 基线窄 PR | | 多值分叉 | 4(1 个误分类) | `semantic-vocabulary-drift-smoke.py`:`multi_value_forks` 与 `multi_value_forks_semantic`。今天只打印计数;#4614 增加 `divergent_value_sets` 以按名字列出存活的分叉 | `scope` 声明有界上下文名字后为 0 | M0.5 + 基线窄 PR | | 多值孪生 | 19 | `semantic-vocabulary-drift-smoke.py`:`multi_value_twins` | 0 | 基线窄 PR | -| 旧 should-run 字段 | 6 个字段,124 py / 10 ts 模块提及 | token 计数:`semantic-vocabulary-drift-smoke.py` 每个字段一对 `<字段>.py` / `<字段>.ts`;迁移面与五种角色:`--report` 下每字段每运行时一行 `retirement_role:` | 0 个字段 | M3,以清空 B3 迁移面为门;token 计数在 Q11 决策前继续计入预算 | +| 旧 should-run 字段 | 6 个字段,124 py / 10 ts 模块提及 | token 计数:`semantic-vocabulary-drift-smoke.py` 每个字段一对 `<字段>.py` / `<字段>.ts`;迁移面与五种角色:`--report` 下每字段每运行时一行 `retirement_role:` | 获准迁移面不再有不必要的独立权威;保留的派生/兼容字段仍可见 | M3 仅在收益与兼容性支持退役时启动;预算在经评审修改前继续执行 | | 合并候选组 | 32 组未评审 | `loopx/semantics/inventory.py` 的 `merge_candidate_groups()`;今天没有任何命令打印它,#4630 增加该 CLI 行。读可评审数而非原始数——注册的跨运行时词表本就同时拥有 Python 与 TypeScript 两个符号,这类配对是 I3 的要求而不是债务 | 每组已分类;只合并 `same_semantics` 的组 | 分类表 PR,随后逐组 PR | | 控制面 py/ts 孪生 | 43 | `semantic-vocabulary-drift-smoke.py`:`independently_maintained` | 跟随 TypeScript 迁移 RFC;本 RFC 不设目标 | M4 |