Skip to content

fix(semantics): keep retired migration vocabulary out of the repository map - #4486

Closed
huangruiteng wants to merge 1 commit into
mainfrom
codex/fix-public-smoke-fleet-3
Closed

huangruiteng wants to merge 1 commit into
mainfrom
codex/fix-public-smoke-fleet-3

Conversation

@huangruiteng

Copy link
Copy Markdown
Collaborator

Problem

examples/control_plane/peer-agent-hard-cut-boundary-smoke.py (and its wrapper peer-agent-runtime-v1-smoke.py) fail on current main:

AssertionError: legacy agent hierarchy escaped migration boundary:
loopx/semantics/inventory_v0.json:328: {"name": "LEGACY_HIERARCHY_ROLES", "module": "loopx/control_plane/agents/legacy_migration.py", "container": "set", "values": ["primary-agent", "side-agent"]},
loopx/semantics/inventory_v0.json:436: {"name": "TODO_REMOVED_REVIEW_CONTINUATION_POLICY_VALUES", "module": "loopx/control_plane/todos/contract.py", "container": "set", "values": ["primary_review", "review_handoff"]},

Root cause: build_inventory() copies every closed-set constant in loopx/.**, including constants that exist only to read or reject vocabulary retired by a one-way migration. The generated map therefore republishes retired hierarchy tokens into a derived artifact outside the migration boundary the guard protects, and it names a migration module as the current owner of a retired vocabulary.

Change

  • Declare the retired carriers explicitly as (module, constant) pairs in loopx/semantics/inventory.py instead of matching on name substrings, so a new carrier cannot be hidden by accident.
  • Exclude those carriers from every inventory section and keep the omission visible as retired_vocabulary_excluded in the rendered inventory.
  • Regenerate loopx/semantics/inventory_v0.json.
  • Pin the rule with a characterization test in tests/architecture/test_semantic_inventory.py (retired vocabulary is skipped, live vocabulary in the same module is still mapped).

No guard was relaxed: the peer-hierarchy boundary smoke keeps its rule and now passes because the derived artifact no longer leaks the tokens.

Validation

  • examples/control_plane/peer-agent-hard-cut-boundary-smoke.py — failed before, ok after.
  • examples/control_plane/peer-agent-runtime-v1-smoke.py — ok (runs continuation state machine, task orchestration, hard-cut boundary).
  • examples/semantic-vocabulary-drift-smoke.py — ok, all budgets reported x/x.
  • scripts/generate_semantic_inventory.py --check — up to date.
  • pytest tests/architecture/test_semantic_inventory.py — 13 passed.

Boundary

Public-safe only: no private artifacts, credentials, raw logs, or local paths.

…ry map

The generated semantic inventory copied migration-only constants into the
repository-wide vocabulary map. That misstated which module owns the vocabulary
today and republished retired hierarchy tokens into a derived artifact outside
the migration boundary, so examples/control_plane/peer-agent-hard-cut-boundary-smoke.py
failed on main with LEGACY_HIERARCHY_ROLES and
TODO_REMOVED_REVIEW_CONTINUATION_POLICY_VALUES.

Name the retired carriers explicitly instead of matching on substrings, keep the
omission visible in the rendered inventory, and pin the rule with a
characterization test.

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
@huangruiteng
huangruiteng force-pushed the codex/fix-public-smoke-fleet-3 branch from 62be8a2 to 370ece7 Compare September 16, 2026 01:58

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

Reviewed exact head: 370ece7709739006e8ffb7f611055bab98e4beef

动机

examples/control_plane/peer-agent-hard-cut-boundary-smoke.py(及其 wrapper)在当前 main 上是红的,报的是"legacy agent hierarchy escaped migration boundary",并直接指出 inventory_v0.json 里两行:LEGACY_HIERARCHY_ROLES(loopx/control_plane/agents/legacy_migration.py)与 TODO_REMOVED_REVIEW_CONTINUATION_POLICY_VALUES(loopx/control_plane/todos/contract.py)。根因不是迁移边界被破坏,而是派生产物越界:build_inventory() 会把 loopx/** 下所有闭集常量都抄进仓库语义地图,包括那些只为"读取或拒绝"已被单向迁移淘汰的词汇而存在的常量。结果一是把 retired 的层级 token 重新发布到边界之外的产物里,二是把迁移模块写成了这些词汇的"当前所有者"。对读者来说这会把历史词汇误读成现行契约,对 CI 来说则是每个基于 main 的分支都被这条守卫挡住。

改动思路

作者没有用"名字包含 legacy/removed"这类子串规则去过滤——那会把模块里仍然有效的常量一起藏掉——而是在生成器里把retired 载体声明成精确的 (module, name) 对:RETIRED_VOCABULARY_CARRIERS。过滤发生在 build_inventory 收集完 facts、进入派生计算之前,所以排除项不会经由 multi_value_carriers 再漏回来;同时渲染出的产物里多了一节 retired_vocabulary_excluded,把"被跳过的东西"留在产物里,而不是在代码里静默消失。这个组合正好对应仓库对"状态/词汇规则要显式声明、不要用 prose 或子串启发式"的要求,也保持了失败方向是 fail-closed:将来新增一个没声明的 retired 载体,守卫会照样变红,而不是悄悄放行。

具体改动

  • loopx/semantics/inventory.py:新增 RETIRED_VOCABULARY_CARRIERS 与 _is_retired_vocabulary;在 build_inventory 中对 enums、closed sets、literal aliases、const arrays、string constants 五类载体统一过滤;渲染结果新增 retired_vocabulary_excluded。
  • loopx/semantics/inventory_v0.json:重新生成——删除两行载体,新增排除说明,python_closed_sets 从 493 变为 491。
  • tests/architecture/test_semantic_inventory.py:新增 retirement_repo fixture 与 test_retired_migration_vocabulary_stays_out_of_the_map,同一模块里同时放一个 live 常量(TODO_DECISION_SCOPE_KIND_VALUES),断言只有被声明的那一个被排除。

关键代码讲解

  • loopx/semantics/inventory.py:26 RETIRED_VOCABULARY_CARRIERS:精确元组的 frozenset,注释明确写了"用显式配对而不是名字匹配,避免把新载体意外藏起来,并且被跳过的配对会保留在渲染产物里"——这句话和实现是一致的。
  • loopx/semantics/inventory.py:296 起的五处过滤:在派生计算之前完成,因此 multi_value_carriers 与后续渲染都不会重新引入被排除项;新增测试正是从这个角度断言 closed sets 的最终形状。
  • loopx/semantics/inventory.py:337 retired_vocabulary_excluded:把省略变成可见产物,评审者不必再看代码才知道地图少了什么。
  • tests/architecture/test_semantic_inventory.py 的 retirement_repo 用例:同一 contract.py 里既有 retired 又有 live 常量,断言列表里只剩 live 那个——这条负例正好排除了"按模块或按名字前缀过滤"的错误实现。

对主干的风险

我做的独立验证:python scripts/generate_semantic_inventory.py 输出 "semantic inventory up to date",且 git diff 对 inventory_v0.json 干净——也就是说提交进来的派生产物确实与生成器一致(这点很重要,因为最容易出的错是"代码改了、产物没重生成")。python examples/control_plane/peer-agent-hard-cut-boundary-smoke.py 现在 ok;pytest -q tests/architecture/test_semantic_inventory.py 13 项通过。产物只新增了一节、少了两个载体,没有运行时行为、协议字段、配额或授权面变化,回滚也只是删掉声明再重生成。仓库状态方面 GitHub 报这个分支对 main 是 DIRTY,合并前需要 rebase,这是流程事项不是代码问题。

一条非阻塞 P3:这个显式清单是每常量维护点。它的失败模式是 fail-closed(新载体被发布 → 守卫报错 → 维护者补一条并重生成),这是有意的;但目前"新增 retired 载体需要在这里加一条并重生成地图"只写在代码注释里。建议在 inventory 模块文档或语义 RFC 里补一句同样的维护规则,让下一位作者顺手就能遵守,而不是再被守卫教一次。

我的整体评价

结论是 APPROVE。这是一次范围很小但判断准确的修复:它没有去动迁移边界,也没有用子串/名字启发式去"让 CI 变绿",而是把"哪些常量是 retired 载体"变成显式、可评审、留在产物里的声明;过滤位置放在派生计算之前,避免了排除项从别的路径绕回来。最重要的一点我独立复现了——生成器重跑无 diff,说明产物与代码一致,而没有停在"测试通过"这一层。唯一值得跟进的是维护规则的可发现性(P3),以及合并前需要 rebase。没有阻塞项。

English verdict: APPROVE — exact head 370ece7709739006e8ffb7f611055bab98e4beef of #4486. The fix stops the derived semantic map from republishing retired migration vocabulary by declaring exact (module, name) carriers instead of using a name-based filter, and it keeps the omission reviewable by rendering a retired_vocabulary_excluded section. Independent validation at this head: python scripts/generate_semantic_inventory.py reports "semantic inventory up to date" with a clean git diff on inventory_v0.json (so the committed artifact really matches the generator), examples/control_plane/peer-agent-hard-cut-boundary-smoke.py prints ok, and pytest -q tests/architecture/test_semantic_inventory.py passes 13 tests including the new fixture where a live constant shares a module with a declared retired carrier. Filtering happens before the derived multi_value_carriers computation, so exclusions cannot leak back through another path, and the fail-closed direction is preserved: an undeclared retired carrier still breaks the guard instead of slipping silently into the map. One non-blocking P3: the explicit list is a per-constant maintenance point, and the rule "add one declared pair and regenerate" lives only in a code comment — mirror it in the inventory module docs or the semantic RFC. Note that GitHub reports the branch as DIRTY against main, so a rebase is required before merge. No runtime behaviour, protocol field, quota or authority surface changes.

@huangruiteng

Copy link
Copy Markdown
Collaborator Author

Closing as superseded: on current main the failure this PR was written for is gone, and the artifact it edits no longer exists.

Verified on origin/main (8c5524786) just now:

  • examples/control_plane/peer-agent-hard-cut-boundary-smoke.py — ok
  • examples/control_plane/peer-agent-runtime-v1-smoke.py — ok (continuation state machine, task orchestration, hard-cut boundary)
  • examples/semantic-vocabulary-drift-smoke.py — ok, budgets all x/x
  • pytest -q tests/architecture/test_semantic_inventory.py — 15 passed

Why the original symptom is gone: #4494 retired the committed loopx/semantics/inventory_v0.json (now .gitignore:42, generated on demand). The boundary smoke scans tracked surfaces, so it no longer sees the two retired carriers; the only remaining references to that path are tests asserting the snapshot is obsolete.

Why I am not re-fitting the change instead: the surviving part of this PR is a generator-level RETIRED_VOCABULARY_CARRIERS allowlist, and that conflicts with the converged model the repository adopted in the same window. The RFC makes loopx/semantics/vocabulary_v0.json the vocabulary authority and the generated inventory an automatic full-tree discovery map ("ordinary new carriers are discovered automatically and do not require a generated snapshot commit"), while legacy values have a model-defined home: vocabularies.<name>.compatibility_only with a retirement milestone. Re-adding a second, code-level exclusion list would give the generator its own retired-vocabulary authority instead of the registry's.

Residual, verified and left for the owner: the on-demand report still names the migration modules as carriers of the retired values (LEGACY_HIERARCHY_ROLES in loopx/control_plane/agents/legacy_migration.py, TODO_REMOVED_REVIEW_CONTINUATION_POLICY_VALUES in loopx/control_plane/todos/contract.py). Nothing in the repository consumes that report, and no check fails. If it should be tracked, the model-consistent place is the registry compatibility_only entry (M0.5 work), not the generator.

My earlier review on 370ece7709739006e8ffb7f611055bab98e4beef was an approval conditional on the pre-#4494 committed snapshot; with that artifact retired, the approval no longer applies.

@huangruiteng
huangruiteng deleted the codex/fix-public-smoke-fleet-3 branch September 16, 2026 13:10
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.

1 participant