Skip to content

feat(control-plane): register the host-adapter settlement step vocabulary - #7619

Merged
huangruiteng merged 1 commit into
loopx-project:mainfrom
xiaoan17:codex/host-adapter-settlement-step-vocabulary
Oct 29, 2026
Merged

huangruiteng merged 1 commit into
loopx-project:mainfrom
xiaoan17:codex/host-adapter-settlement-step-vocabulary

Conversation

@xiaoan17

@xiaoan17 xiaoan17 commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Scope

One vocabulary gets a typed owner.

The TypeScript host owner authors an ordered provider plan and the Python
transport validates the plan it receives against the same sequence, but the two
sequences were private hand-kept copies:

  • loopx/control_plane/turn_driver/host_todo_completion.ts — a module-local const STEP_KINDS
  • loopx/control_plane/host_adapter_settlement.py — a module-local _STEP_KINDS

Neither was exported, so the semantic inventory could not see either carrier, and
neither loopx/semantics/vocabulary_v0.json nor the drift smoke could tie them
together. A divergence between them would have surfaced at runtime as
TypeScript host provider step order mismatch, after the plan had already been
accepted and partly executed. The C4.3 settlement vocabulary confirmation
recorded exactly this gap.

What changes

  • Both sequences become exported owners of a new cross-runtime vocabulary,
    host_adapter_settlement_step_kind, so the drift smoke checks each of them
    against the registry on every run.
  • The vocabulary is deliberately distinct from settlement_step_kind: that
    one names the turn settlement phases, whose validation phase is never
    executed, while every kind here is a command the host adapter runs. The
    registry meaning records that difference, so the two are no longer
    confusable.
  • The two owners keep different names per runtime, so no new multi-value twin
    appears: multi_value_twins stays 8/8 and every inventory budget is
    unchanged. Only the coverage floor grows, 28 → 29 vocabularies and 54 → 56
    owner symbols, in the registry and its anchor in the same diff.
  • New tests pin the two runtimes against each other directly, and prove the
    transport still refuses a plan whose step order drifts (that tripwire had no
    test).

Evidence

  • examples/semantic-vocabulary-drift-smoke.py → ok, coverage=vocabularies:29/29, owner_symbols:56/56, multi_value_twins=8/8, conflicting_values=16/16 — no
    budget moved.
  • The diff-scoped advisory now sees both carriers, which it did not before, and
    points each at the new vocabulary:
    reuse hint: host_adapter_settlement_step_kind (exact_values) plus
    settlement_step_kind (overlapping_values) — the C4.3 overlap is now a
    machine-visible hint instead of prose.
  • Semantic inventory, production and drift test suites pass; the MCP
    settlement, host vision and machine guard suites pass; the TypeScript host
    todo completion test passes (15) and the control plane typechecks.
  • loopx canary premerge --from-git-diff --git-diff-base 2a2323756 green
    (19 checks, 0 failures), surfaces control_plane, docs_project_content, public_boundary, python.

Coordination

#5677 extends this same vocabulary: it adds delivery_context and
direction_context to both carriers and rewrites the surrounding plan schema.
Whichever of the two PRs merges second must add those two values to the
registry entry (and its glossary row), because the registry values are what the
drift smoke checks the carriers against. This PR does not add them, because
they do not exist on this branch.

Unrelated observation

tests/architecture/test_semantic_production.py::test_real_return_producer_rejects_an_unregistered_result[turn_route-…driver.py-return LoopXTurnRoute.CONTRACT_ERROR]
already fails on main (2a2323756) — the registry still names a turn_route
return producer whose literal driver.py no longer carries. PR #7621 carries
that fix; this PR does not touch it.

Signed-off-by: xiaoan17 anbc1224@gmail.com

Rebase and re-validation (2026-10-29)

  • Base: main at b201da8bab305d053866aa0d4516b97ba4a4499e
  • Head: 1e3401591eda91ed67589cdbbfd45a78582a7082
  • The change itself is unchanged; only the parent moved.

This entry is independent of the merge order between #7617 and #7645: it adds no ledger file and does not touch the derived STATUS.md index.

All nine pull requests in this set were rebased onto the then-current main (this one onto b201da8bab305d053866aa0d4516b97ba4a4499e) and merged together in a local worktree. The merged state passes tests/architecture/, tests/canary/, tests/test_manager_context_roundtrip.py, tests/test_lark_native_reply_context.py, tests/control_plane/test_host_adapter_settlement_step_vocabulary.py and tests/control_plane/test_host_adapter_settlement_partial_steps.py — 1805 passed, 0 failed. python scripts/generate_rfc_status_index.py --check is clean.

Merge sequence (2026-10-29)

  1. docs(rfc): confirm the C4.3 settlement vocabulary question #7617 — CI is green end to end; merge it first. It must precede test(settlement): characterize the host adapter's partial-step boundary #7645.
  2. test(settlement): characterize the host adapter's partial-step boundary #7645 — chained on docs(rfc): confirm the C4.3 settlement vocabulary question #7617's head; merge it after docs(rfc): confirm the C4.3 settlement vocabulary question #7617.
  3. feat(control-plane): register the host-adapter settlement step vocabulary #7619 — independent of the two above.
  4. test(chat): assert the preserved operator material in the native input #7632, test(semantics): derive the output-evidence guard from the registry #7640, docs(rfc): record the Codex provider-routing activation seam #7642, fix(canary): lower the stale collaboration_mcp module ceiling #7646, fix(chat): keep the provider reply projection in the composition root #7631 — the five that restore main to green. Each one fixes only its own share of the six places where main is currently red, so until all five land every one of them still shows the others' red tests in its pytest / test-shard lanes. test(semantics): point the stale turn_route fixtures at their current owners #7621 was merged the same way, with a known base-red. Merge them in any order; each merge removes one share.

@xiaoan17
xiaoan17 force-pushed the codex/host-adapter-settlement-step-vocabulary branch 5 times, most recently from 1861555 to 3781b77 Compare October 29, 2026 09:26
…lary

The TypeScript host owner authors an ordered provider plan and the Python
transport validates the plan it receives against the same sequence, but
the two sequences were private hand-kept copies: a module-local const in
host_todo_completion.ts and a module-local _STEP_KINDS in
host_adapter_settlement.py. Neither was exported, so the semantic
inventory could not see either carrier, neither the vocabulary registry
nor the drift smoke could tie them together, and a divergence would have
surfaced at runtime as "TypeScript host provider step order mismatch"
after the plan had already been accepted and partly executed.

Both sequences are now registered owners of the new cross-runtime
vocabulary host_adapter_settlement_step_kind, so the drift smoke checks
each of them against the registry on every run. The vocabulary is
deliberately distinct from settlement_step_kind: that one names the turn
settlement phases, whose validation phase is never executed, while every
kind here is a command the host adapter runs. The registry meaning
records that difference.

The two owners keep different names per runtime, so no new multi-value
twin appears: multi_value_twins stays 8/8 and every inventory budget is
unchanged. Only the coverage floor grows, 28 to 29 vocabularies and 54
to 56 owner symbols, in the registry and its anchor together.

New tests pin the two runtimes against each other directly and prove the
transport still refuses a plan whose step order drifts.

Validation: semantic-vocabulary-drift-smoke ok; the diff-scoped semantic
advisory now sees both carriers and points them at the new vocabulary;
semantic inventory, production and drift test suites pass; the MCP
settlement, host vision and machine guard suites pass; the TypeScript
host todo completion test passes and the control plane typechecks; loopx
canary premerge --from-git-diff green.

Signed-off-by: xiaoan17 <anbc1224@gmail.com>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

动机 / Motivation

没有阻塞本次登记改动的 finding;有一条 P3 说明修正建议。 新测试第 11–12 行和 PR 说明声称顺序漂移在部分执行后才报错,实际入口先完整解码计划,再执行任何 provider 命令。建议改为“在运行时传输边界较晚发现,但在副作用前拒绝”。这不影响本次静态登记的价值。

受影响的是维护 Host 结算适配器的开发者:TypeScript 生成命令计划,Python 接收并执行,双方必须采用同一个有序步骤表。
此前两份私有常量缺少共同登记,改动一侧可能直到执行入口才被拒绝;本 PR 让现有语义检查识别两份 owner,并在仓库检查中比较取值和顺序。
两份 owner 已进入词汇检查,新四项测试通过;真实四种计划及原有效果前校验与基线一致,没有增加用户操作步骤。
本 PR 不删除结算解释器、不改变四步或五步计划、不统一不同阶段的标签,也不宣称完整 C4.3 迁移或长程收益已经完成。

评审版本:1e3401591eda91ed67589cdbbfd45a78582a7082。独立依据是改动前 docs/architecture/rfcs/ledger/controller-executor-unified-contract-v0/2026-10-27-refactor-handoff.md,spec_revision=b201da8bab305d053866aa0d4516b97ba4a4499e。C4.3 要求比较身份、校验、guard/vision、完成、写回、spend、closeout 与恢复后才能删除解释器。这里仅完成已有步骤表的登记;删除、调用方采用、跨事务恢复与完整成本比较仍未完成,不能由本条批准推出。

改动思路 / Approach

复用现有 TypeScript 计划 owner、Python 传输校验和语义登记器;只让已消费的常量可见,没有新策略、额外 RPC 或用户配置。
当前边界是既有 Host 步骤的登记与漂移检查,解释器删除、跨事务恢复与完整成本验收仍由原 C4.3 工作承担。

真正有区别的是 executable Host command 与已提交的结算阶段。现有 settlement_step_kind 含 validation,不能为了名字相似而塞进四步/五步 Host 命令序列。新 host_adapter_settlement_step_kind 表述的是两侧已经消费的同一命令表;不是新事务、执行权限或额外配置。没有增加用户声明、选择、确认、导航或复制步骤。

入口 此前 本次提交
普通/终止 Host 计划 4/5 步,原 effect identity 命令和完整 JSON 相同
最后一步顺序错误 整份计划拒绝,0 次命令 相同
静态词汇扫描 看不到两份私有常量 两份 owner 已登记,取值与顺序可检查

表格来自源码和下述执行观察;不代表安装或长期采用验收。

具体改动 / Changes

7 个路径、+142/-20:Python _STEP_KINDS 更名为 HOST_ADAPTER_SETTLEMENT_STEP_SEQUENCE;TS STEP_KINDS 导出为 HOST_ADAPTER_SETTLEMENT_STEP_KINDS;五个值和顺序未变。registry/glossary 声明两份 owner,覆盖下限 28→29、54→56 与既有锚点一同更新,库存上限未放宽。90 行新测试同时比较 registry、两侧顺序和错误计划拒绝。

providerSteps 仍构造原 CLI 计划;_decode_provider_steps 校验每一项后才返回完整 tuple;settle_host_todo_completion 随后执行既有 runner,再由 evaluateHostTodoCompletion finalize;check_owned_vocabularies 用原有 extractor 检查两份 carrier。没有新增状态存储、解释器或每步 RPC。对于两个实际消费者,保留两个 carrier 并增加直接一致性检查比另做生成框架更合适。

独立执行:四种真实 native prepare 输入(普通、终止、unchanged vision、exact Goal instance)与基线的完整 JSON 逐字节一致,没有归一化;最后一步变异在双方均为 step order mismatch、provider calls 为 0、无 finalize。基线运行使用另一个 checkout,先证明相关 production/smoke/test blob 与 b201da8bab305d053866aa0d4516b97ba4a4499e 完全一致,并未把那个 checkout 的 Git HEAD 冒称为基线。分别从真实 owner 解析值后删掉 terminal_closeout,原 Drift oracle 均捕获缺项。

对主干的风险 / Risks

新四项测试均通过;合并运行的语义测试为 130 passed、1 failed。失败是 test_explicit_output_evidence_cannot_be_removed_or_redirected[call_producers-loop_disposition] 的 DID NOT RAISE Drift。不可变基线对应源码与当前 head 用同一目标命令均复现相同签名;本次不改其 producer/anchor 因果路径。保留失败与独立修复责任,不要求这个登记 PR 顺带修复它,也不把它记成通过。

完整 semantic drift smoke 通过:29/29 vocabularies、56/56 owner symbols,库存预算不变。它仍报告 F1/F2=6/29、cross_runtime_unverified=23/24;静态值相同并不等于全部 producer 已形式化证明。diff advisory 同时给出 exact-values 与 overlapping-values 提示;这里按实际职责保留两套不同词汇,没有 substring/prose 分类、默认启用或权限扩大。

真实隔离夹具的 MCP settlement 8 passed、原生 TS 15 passed、control-plane typecheck 通过。标准 premerge 的 6 个直接和 14 个选中检查执行通过;完整门禁为 quality_invalid_receipt,因为 CQR 如实记录 required semantic suite 失败。审阅政策允许独立归因的基线失败与本次批准分开;合并门禁仍保留。未查询、轮询或等待远端 CI,也没有执行真实活动 Goal 的测试或合并动作。

我的整体评价 / Verdict

APPROVE,本次范围没有阻塞 finding。 这是一个完整、有用且可逆的仓库语义保护增量,既有 owner 被复用、运行行为保持一致;不是空登记等待另一个 PR 才有检查效果。P3 请修正失败时序叙述,原 C4.3 与 #3412/#5677 保留更大迁移的验收职责。若后续提案实际增加步骤,两份消费者、registry、glossary 和顺序检查需要一起更新。

本次检查的内部步骤常量、语义登记及 glossary 正文没有布局或首屏交互改动。未做界面视觉、安装升级、Windows 或真实 PostgreSQL 测试;本次没有更改这些 provider 或持久化 owner。尚未验证长期成本收益、模型采用或完整跨事务删除前提;这些限制没有被测试计数替代。批准不表示 CQR、完整 premerge、merge readiness 或 maintainer merge authority 已通过。

Reviewer: actor_kind=model_agent; model=gpt-6.1-sol; provider=OpenAI; reasoning_effort=max; declaration_source=runtime_reported.

English verdict: APPROVE

Comment on lines +11 to +12
`TypeScript host provider step order mismatch`, after the plan had already been
accepted and partially executed.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P3] 请把这里和 PR 说明中的失败时序改成“在副作用前拒绝”。settle_host_todo_completion 先调用 _decode_provider_steps 解码整份计划,成功后才调用 _run_provider_plan;即使只把真实 TypeScript 五步计划的最后一项改错,实际入口也会报 step order mismatch,provider 调用为 0,且不会 finalize。基线与当前 head 的对照观察一致。登记两份已有 carrier 仍然有用,但不是在修复“部分步骤已经执行后才拒绝”的风险。

@huangruiteng
huangruiteng merged commit 8caaf67 into loopx-project:main Oct 29, 2026
33 of 45 checks passed
xiaoan17 pushed a commit to xiaoan17/loopx that referenced this pull request Oct 29, 2026
The characterization described any durable commit as settled and the
before-completion case as having no settlement receipt, but the guard
has already committed the validation receipt and only the quota spend
settles the transaction. Spell the stage table out from the measured
readbacks, and drop the claim that a settlement receipt does not exist
before the lifecycle completion.

The next slices also asked for a caller that adopts both settlement
paths, which the parent confirmation entry already found and recorded
as a withdrawn candidate. Keep the deletion preconditions, point the
open slice at the host-adapter step registry in loopx-project#7619, and fix the
Chinese parent anchor to the id the strict build generates.

Signed-off-by: xiaoan17 <anbc1224@gmail.com>
xiaoan17 pushed a commit to xiaoan17/loopx that referenced this pull request Oct 29, 2026
The characterization described any durable commit as settled and the
before-completion case as having no settlement receipt, but the guard
has already committed the validation receipt and only the quota spend
settles the transaction. Spell the stage table out from the measured
readbacks, and drop the claim that a settlement receipt does not exist
before the lifecycle completion.

The next slices also asked for a caller that adopts both settlement
paths, which the parent confirmation entry already found and recorded
as a withdrawn candidate. Keep the deletion preconditions, point the
open slice at the host-adapter step registry in loopx-project#7619, and fix the
Chinese parent anchor to the id the strict build generates.

Signed-off-by: xiaoan17 <anbc1224@gmail.com>
xiaoan17 pushed a commit to xiaoan17/loopx that referenced this pull request Oct 29, 2026
PR loopx-project#7619 registered the ordered host-adapter step kinds and is merged, so
the parent confirmation entry and this entry must stop describing it as a
proposal. Update both mirrors and rebase this entry's baseline onto the
main that carries it.

Signed-off-by: xiaoan17 <anbc1224@gmail.com>
xiaoan17 pushed a commit to xiaoan17/loopx that referenced this pull request Oct 29, 2026
The characterization described any durable commit as settled and the
before-completion case as having no settlement receipt, but the guard
has already committed the validation receipt and only the quota spend
settles the transaction. Spell the stage table out from the measured
readbacks, and drop the claim that a settlement receipt does not exist
before the lifecycle completion.

The next slices also asked for a caller that adopts both settlement
paths, which the parent confirmation entry already found and recorded
as a withdrawn candidate. Keep the deletion preconditions, point the
open slice at the host-adapter step registry in loopx-project#7619, and fix the
Chinese parent anchor to the id the strict build generates.

Signed-off-by: xiaoan17 <anbc1224@gmail.com>
xiaoan17 pushed a commit to xiaoan17/loopx that referenced this pull request Oct 29, 2026
PR loopx-project#7619 registered the ordered host-adapter step kinds and is merged, so
the parent confirmation entry and this entry must stop describing it as a
proposal. Update both mirrors and rebase this entry's baseline onto the
main that carries it.

Signed-off-by: xiaoan17 <anbc1224@gmail.com>
xiaoan17 pushed a commit to xiaoan17/loopx that referenced this pull request Oct 29, 2026
The characterization described any durable commit as settled and the
before-completion case as having no settlement receipt, but the guard
has already committed the validation receipt and only the quota spend
settles the transaction. Spell the stage table out from the measured
readbacks, and drop the claim that a settlement receipt does not exist
before the lifecycle completion.

The next slices also asked for a caller that adopts both settlement
paths, which the parent confirmation entry already found and recorded
as a withdrawn candidate. Keep the deletion preconditions, point the
open slice at the host-adapter step registry in loopx-project#7619, and fix the
Chinese parent anchor to the id the strict build generates.

Signed-off-by: xiaoan17 <anbc1224@gmail.com>
xiaoan17 pushed a commit to xiaoan17/loopx that referenced this pull request Oct 29, 2026
PR loopx-project#7619 registered the ordered host-adapter step kinds and is merged, so
the parent confirmation entry and this entry must stop describing it as a
proposal. Update both mirrors and rebase this entry's baseline onto the
main that carries it.

Signed-off-by: xiaoan17 <anbc1224@gmail.com>
xiaoan17 pushed a commit to xiaoan17/loopx that referenced this pull request Oct 29, 2026
The characterization described any durable commit as settled and the
before-completion case as having no settlement receipt, but the guard
has already committed the validation receipt and only the quota spend
settles the transaction. Spell the stage table out from the measured
readbacks, and drop the claim that a settlement receipt does not exist
before the lifecycle completion.

The next slices also asked for a caller that adopts both settlement
paths, which the parent confirmation entry already found and recorded
as a withdrawn candidate. Keep the deletion preconditions, point the
open slice at the host-adapter step registry in loopx-project#7619, and fix the
Chinese parent anchor to the id the strict build generates.

Signed-off-by: xiaoan17 <anbc1224@gmail.com>
xiaoan17 pushed a commit to xiaoan17/loopx that referenced this pull request Oct 29, 2026
PR loopx-project#7619 registered the ordered host-adapter step kinds and is merged, so
the parent confirmation entry and this entry must stop describing it as a
proposal. Update both mirrors and rebase this entry's baseline onto the
main that carries it.

Signed-off-by: xiaoan17 <anbc1224@gmail.com>
xiaoan17 pushed a commit to xiaoan17/loopx that referenced this pull request Oct 29, 2026
The review noted that one sentence called the host-adapter step registry
slice both still open and already merged. It is completed in loopx-project#7619. Keep
the open work on the deletion and adoption preconditions the comparison
entry records.

Signed-off-by: xiaoan17 <anbc1224@gmail.com>
xiaoan17 pushed a commit to xiaoan17/loopx that referenced this pull request Oct 29, 2026
The characterization described any durable commit as settled and the
before-completion case as having no settlement receipt, but the guard
has already committed the validation receipt and only the quota spend
settles the transaction. Spell the stage table out from the measured
readbacks, and drop the claim that a settlement receipt does not exist
before the lifecycle completion.

The next slices also asked for a caller that adopts both settlement
paths, which the parent confirmation entry already found and recorded
as a withdrawn candidate. Keep the deletion preconditions, point the
open slice at the host-adapter step registry in loopx-project#7619, and fix the
Chinese parent anchor to the id the strict build generates.

Signed-off-by: xiaoan17 <anbc1224@gmail.com>
xiaoan17 pushed a commit to xiaoan17/loopx that referenced this pull request Oct 29, 2026
PR loopx-project#7619 registered the ordered host-adapter step kinds and is merged, so
the parent confirmation entry and this entry must stop describing it as a
proposal. Update both mirrors and rebase this entry's baseline onto the
main that carries it.

Signed-off-by: xiaoan17 <anbc1224@gmail.com>
xiaoan17 pushed a commit to xiaoan17/loopx that referenced this pull request Oct 29, 2026
The review noted that one sentence called the host-adapter step registry
slice both still open and already merged. It is completed in loopx-project#7619. Keep
the open work on the deletion and adoption preconditions the comparison
entry records.

Signed-off-by: xiaoan17 <anbc1224@gmail.com>
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.

3 participants