Skip to content

fix(control-plane): isolate host completion by Goal instance - #5967

Merged
huangruiteng merged 14 commits into
loopx-project:mainfrom
Duang777:codex/fix-host-completion-goal-instance
Oct 9, 2026
Merged

huangruiteng merged 14 commits into
loopx-project:mainfrom
Duang777:codex/fix-host-completion-goal-instance

Conversation

@Duang777

@Duang777 Duang777 commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator

Goal And Delivered Outcome

  • Outcome basis / optional anchor: Reproduced control-plane settlement identity collision.
  • Goal/source and gap: host_todo_completion.ts preserved an exact GoalRef in commands but derived turn_instance_id from only goal_id, agent_id, and todo_id.
  • Observable before → after, with the validation row that proves it: Two Goal instances with one alias produced the same settlement identity, so the successor could be blocked by the predecessor quota receipt. Exact Goal references now use a domain-separated digest that includes goal_instance_id; alias-only requests retain their existing bytes.
  • Issue/task and intended base: Self-contained bug fix against loopx-project/loopx:main.

Author Declaration

  • Written by: OpenAI model agent, directed by a human operator.

Implemented against

  • Specification and revision: No written specification; the request in this PR is the basis.
  • Criteria:
Criterion (spec clause) Disposition Symbol / path Test or command
Exact retries keep one settlement identity implemented turnInstanceId host_todo_completion.test.ts
Different Goal instances cannot share a settlement identity implemented turnInstanceId host_todo_completion.test.ts
Alias-only callers keep the legacy identity encoding implemented turnInstanceId Existing host completion and Python adapter tests
  • Self-check before submission: Reviewed the host completion, effect ID, and quota receipt call chain. Ran the focused TypeScript and Python suites, TypeScript typecheck, and diff-driven premerge. This PR does not change quota settlement schemas or Goal acceptance state.

Scope And Continuation

  • Completed scope and remaining work: Complete within host Todo completion identity derivation. Goal acceptance lifetime fencing is a separate change.
  • Slice boundary / successor: N/A for this defect; the fix is independently testable and preserves the alias-only contract.

Validation

  • Tested revision: d06fe964a07c6e04c915c4a914888765677cacf2
  • Run state: finished
  • Input classes: synthetic
Check kind Result Public-safe evidence / limitation
unit passed node --no-warnings --experimental-sqlite --experimental-strip-types --test tests/control_plane_ts/host_todo_completion.test.ts: 15 passed.
integration passed python -m pytest -q tests/test_goal_mode_mcp_settlement.py: 8 passed.
static passed npm run -s typecheck:control-plane.
real_entrypoint passed loopx canary premerge --from-git-diff --git-diff-base upstream/main: 13 selected checks passed with no manual hold.
real_backend not_applicable The changed identity reducer is deterministic and does not access a provider.
  • Coverage and gaps: Tests cover retry stability, cross-instance separation, downstream effect separation, and mismatched finalization. Existing adapter tests cover the alias-only path. No backend-specific path changed.

Frontend / Visual Evidence

  • UI impact: none
  • Before: N/A
  • After: N/A
  • States and viewports shown: N/A
  • Source data: none
  • Attention review: N/A

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Refactoring (no functional changes)
  • Documentation update
  • Test update

LoopX Area

  • Control plane (goals, todos, quota, scheduler, registry, runtime)
  • Benchmark boundary (adapters, runners, verifiers, scoring, evidence)
  • Capability or extension (providers, adapters, skills)
  • Public docs or presentation surface (README, protocols, dashboard)
  • Build, packaging, installer, or CI
  • Host or runtime integration

Technical Direction

  • Direction / acceptance reference, when applicable: Core control-plane hardening.

Shared-authority RFC fixture impact

N/A. This PR changes local identity derivation, not provider routing or shared-authority schemas.

Boundary Checklist

  • Neither the diff nor this PR body/comments/attachments disclose private state, credentials, raw traces or verifier output, internal links, or local machine paths (including .loopx/, .codex/goals/, and live ACTIVE_GOAL_STATE.md).
  • I did not duplicate maintainer-owned benchmark work unless a maintainer split out a public issue for it.
  • I kept the change scoped to the linked issue/task.
  • I completed the visual evidence section for UI changes, or marked UI impact none.
  • Every commit includes a DCO Signed-off-by trailer (git commit -s).

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

Reviewer: model_agent | gpt-6.1-sol | OpenAI | runtime_reported | reasoning_effort=xhigh

动机

使用显式 GoalRef 的宿主完成适配器,需要区分被删除后以同名重建的 Goal。 同名 Goal 的前后两个实例使用相同 Agent 和 Todo 时,旧代码生成同一完成身份,无法区分前一实例的回执;新代码生成不同身份并拒绝跨实例回执。 独立 RPC 对照确认了身份隔离和错误回执拒绝;这只修复已携带精确实例引用的完成请求。 本 PR 不开放 source-session profile,不迁移历史回执,也不授予新的执行、租约或扣额度权限。 普通 MCP 上下文尚未提供精确实例绑定;source-session profile 的完整宿主和产品验收仍在 #5206。

改动思路

修复复用现有 TypeScript 身份 owner;实例引用是既有事实,哈希是派生值,不新增状态或权限。 当前可交付边界是显式 GoalRef 的完成身份隔离;普通宿主接线和 source-profile 激活仍由 #5206 的 M3 验收负责。 请求仍从 complete_task 经 Python 适配器进入已注册的 TS RPC,expectedIdentity 给 prepare、finalize、vision context/recovery 提供同一身份。显式精确请求把实例加入本地哈希;不改通用 effect schema。普通 Claude、Kiro、Kunlun 的上下文没有 goal_ref,source-profile 普通入口在两版都不可执行;因此本次只认可 RFC 允许在激活前进行的 M1 owner 修复,不能把 RPC 输入可接受当成宿主接线或执行授权。

具体改动

精确 head:7f507438daa4c1ae31874bbfb36a3e721b79cc51;独立基线:ebda6db7b54843bfa339fa71252d1dc5b8af4204。全 diff 只有两个文件、35 additions / 4 deletions,生产部分10/4,其余是一个聚焦回归。作者说没有书面规范,但仓库已有 accepted RFC:docs/architecture/rfcs/goal-instance-identity-and-orphan-recovery-v0.md,spec_revision=ebda6db7b54843bfa339fa71252d1dc5b8af4204,同版规范。

criterion_id 本次判断
M1 implemented:在现有 typed owner 内修复并对照;不 mint 或激活实例。
History stays historical implemented(完成身份组件):A/B key 不同,A 回执不能通过 B 的 finalize;不改写历史存储。
Default-off parity implemented:省略引用的完整 prepare 输出逐字段一致;旧 CLI 结算和恢复保持一笔扣账。
M3 deferred:#5206 仍负责真实实例绑定、commit fence、迟到结果及升级恢复验收。
Product recovery is complete out_of_scope:RFC M5 的 App/Lark/CLI 全程恢复不在本修复内。

关键代码讲解

  • turnInstanceId(host_todo_completion.ts:208):没有精确引用时保留原三字段编码;有引用时加入内部域分隔和已校验实例。相同请求重试稳定、不同实例分离,不生成新 authority。
  • expectedIdentity(同文件:224):继续调用通用 settlementIdentity,因此现有 effect ID 自动携带新的 Turn key;prepare、vision context、vision refresh 与 finalize 都复用它,无平行 Python 决策。
  • finalize(同文件:739):现有 guard/阶段回执相等检查不变。独立实际 RPC 在 base 会把 A 的五阶段回执当成 B 完成,在 head 于 guard 阶段报 identity mismatch;正确实例的链仍完成。这里回执 provider 使用合成数据,未冒称真实 source-profile 结算。

对主干的风险

最强反例是“同 alias、同 Agent/Todo,迟到的 A 回执进入 B”。相同独立 harness 在 base 的隔离断言失败(exit1),在 head 通过(exit0);不是从新测试公式反推预期。v0/v1 legacy 完整 prepare 输出相同,5种 null/空/缺失实例/非法实例/alias不匹配输入的完整错误相同,恢复命令与 prepare 身份一致。实际 source registry codec + 普通 MCP context 的不可执行提示也在两版相同,零 provider 调用。

独立检查:head TS15 / base14通过;真实 Python CLI 结算、终止、三个丢响应阶段恢复、已有 successor 复用及完成校验两版各12通过;head typecheck、development advisory、全树语义检查及 premerge 的13个选中检查和3个 diff 检查通过,无 manual hold。没有查询或等待 CI。不能从这些结果推导 live source-profile ABA、原生 PG provider 或跨版本已持久化 exact key 的恢复已验收;改变旧 exact key 后的升级资格仍应在 M3 激活前核验,不能静默重标历史回执。

语义与 CI 对齐

复用现有 GoalRef / settlement 类型所有者;内部哈希盐是 local helper,不是公共协议扩展。未改变默认 legacy 行为、权限、额度、任务接受状态或 agent 消费的义务文字;强制 identity 拒绝仍是机器规则。semantic advisory 未发现支持语法的新词汇仅是提示,完整调用链和对照才支持本结论。

我的整体评价

没有本组件范围内的阻塞发现。delivery judgment 为 justified_increment:long_horizon 的完成身份隔离改进已复现,普通 user_experience 保持;完整宿主采用仍保留 #5206 的边界。代码规模与故障相称,沿现有 TS owner 修改即可。future-facing pass 已检查统一身份入口,现有 expectedIdentity 足够,不需要新抽象。可以合入这个 M1 修复;不表示 source-profile 可以激活或父 RFC 完成。运行时变更仍交维护者合并。

English verdict: APPROVE — 7f50743; exact completion identities and foreign-receipt rejection are independently verified against ebda6db; legacy real CLI retry/settlement and focused native checks pass. M3 host activation and exact historical-key upgrade remain unqualified under #5206; CI was not consulted.

Signed-off-by: Duang777 <duangjl007@gmail.com>
Signed-off-by: Duang777 <duangjl007@gmail.com>
@huangruiteng
huangruiteng merged commit 5388e6c into loopx-project:main Oct 9, 2026
7 checks passed
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