Skip to content

feat(runtime): fence first-party Host state by GoalRef - #5141

Merged
huangruiteng merged 8 commits into
loopx-project:mainfrom
Duang777:codex/goal-instance-m3-host-runtime
Sep 27, 2026
Merged

huangruiteng merged 8 commits into
loopx-project:mainfrom
Duang777:codex/goal-instance-m3-host-runtime

Conversation

@Duang777

@Duang777 Duang777 commented Sep 26, 2026 •

Copy link
Copy Markdown
Collaborator

Goal And Delivered Outcome

  • Outcome basis / optional anchor: Accepted goal-instance-identity-and-orphan-recovery-v0 RFC, Section 11 M3, for the first_party_host_runtime inventory owner.
  • Goal/source and gap: advance the first_party_host_runtime owner in the Goal instance RFC. Source-session Host state previously used only goal_id, so a recreated Goal could resume state or accept a late result from the retired instance.
  • Observable before -> after, with the validation row that proves it: source-profile Turn, Codex, DSH, and Kunlun paths now bind Host state to the exact {goal_id, goal_instance_id}. Goal B rejects Goal A state and results before journal, validation, writeback, spend, scheduler, or Kunlun closeout work can continue.
  • Issue/task and intended base: Related to fix(app): preserve conversational intent and plan App-first continuity #5064. Intended base is main; this change is independent of feat(chat): bind attached sessions to GoalRef #5130.

Scope And Continuation

  • Completed scope and remaining work: TypeScript owns the exact GoalRef decision. Python owns registry I/O, lifecycle locking, and Host state commits. Non-source profiles keep their existing paths, schemas, and serialized bytes.
  • Slice boundary / successor: this is partial M3 enforcement. Accepted-before-retirement downstream drain, warm or unsupported binaries, and the remaining inventory owners still require qualification. execution_authority: false and the M3 activation hold remain unchanged.

Validation

  • Tested revision: deee231c8664f8d2cb96e4339eb06e52667cf11e
  • Run state: finished
  • Input classes: synthetic, public_fixture
Check kind Result Public-safe evidence / limitation
unit passed Exact-head TypeScript policy tests passed 7/7. The full npm run test:control-plane suite passed on pre-rebase revision 071da8317: 3163 tests, 3133 passed, 30 environment-gated skips, 0 failures. The rebase changed no runtime or TypeScript file in this diff.
integration passed 332 Python tests passed across Host admission, Turn execution and recovery, Codex sessions, DSH lineage, Kunlun runtime, source lifetime, and architecture checks.
static passed TypeScript typecheck, targeted Ruff, docs governance, git diff --check, the 246-site project-registry I/O manifest, and semantic vocabulary drift at 43/43 passed.
real_entrypoint passed Standard diff-selected premerge passed with no failed commands or manual holds.
regression_parity passed Non-source plans retain legacy paths, schemas, and bytes. Goal A/B tests prove stale state and late results fail closed for the source profile.
static failed examples/repository-hygiene-smoke.py reports release timeline is missing version entries: v1.2.0; the changed-file set contains neither release metadata nor the hygiene checker, and the same failure was reproduced on the preceding origin/main base.
  • Coverage and gaps: tests use the file-backed source registry and synthetic Host callbacks. No external provider process runs because source_session_v1 still has no execution authority. Open PR feat(usage): observe quota cycles and bound Codex turns across Hosts #5137 touches one telemetry line in turn_driver/executor.py; this PR keeps telemetry around the Host call and limits the GoalRef guard to short state commits.

See validation disclosure guidance.

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; no UI files or public response shapes changed.

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: Shared Goal Authority and cross-host coordination; partial M3 first_party_host_runtime enforcement in goal-instance-identity-and-orphan-recovery-v0.

Shared-authority RFC fixture impact

  • Production-scale fixture schema: no authority-store fixture schema changes. Source-profile Host records gain exact GoalRef bindings while existing paths and legacy bytes remain unchanged.
  • Semantic dimensions changed, or reviewed no-impact rationale: Host state selection, resume, and result admission now compare the planned GoalRef with fresh source authority under the alias lifecycle lock.
  • Provider conformance arms run: file-backed source registry across Turn, Codex, DSH, and Kunlun paths. Tests cover absent state, exact resume, alias-only state, malformed state, Goal recreation, cached recovery, late results, and concurrent commit/recreation.
  • Read-only legacy/file/PostgreSQL three-arm rehearsal (required for promotion, runtime-routing, or compatibility-projection changes): not applicable. This PR does not promote an authority provider or change runtime routing, and source_session_v1 remains disabled for execution.

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).

Maintainer repair at the merged head

The reviewed head 9f34365fd832fcd8c49a99ce9d54428370a30e6b was reached by merging origin/main into the branch to clear the conflict in loopx/cli_commands/turn.py (main's single-name import style from #5148 against this PR's added first_party_host_admission import) and to pick up main-side fixes. The PR's own delta is unchanged: 23 files, +1736/-63.

Verification at that head: npm run typecheck:control-plane; npm run test:control-plane (3262 tests, 3232 passed, 30 environment-gated skips, 0 failures); 305 Python tests across test_first_party_host_runtime.py, test_loopx_turn_driver.py, test_loopx_turn_codex_cli.py, test_loopx_turn_executor.py, test_dsh_goal_mode.py, test_kunluncode_goal_mode.py; the 7/7 TypeScript policy tests; 131 architecture tests; targeted Ruff; git diff --check; and the premerge public-boundary scan.

Two red checks on this head are main-side and were independently attributed rather than repaired here:

  • examples/control_plane/cli-output-budget-regression-smoke.py reports loopx_turn_plan/crowded/json emitted 14514 chars; baseline ceiling is 14500 identically on this head and on origin/main, while the PR base 39f2fd15e passes it. The fixture's plan carries no goal_ref, and both sides measure exactly 14514, so the 355-char growth came from main's own TurnEnvelope work (the range registers fix(replan): preserve goal fidelity and audit completion evidence #5132). The budget owner needs to choose compaction or an evidence-backed rebaseline; the 341-char regression margin is exhausted.
  • examples/repository-hygiene-smoke.py reports a public/private boundary hit at tests/control_plane/test_public_safety_credential_shape_owner.py:51/54 on both this head and origin/main.

Merge used admin bypass because the protect main ruleset requires require_last_push_approval and dismiss_stale_reviews_on_push, and the maintainer main-integration push made the maintainer the last pusher; the exact-head review is published at #5141 (review).

Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
huangruiteng
huangruiteng previously approved these changes Sep 26, 2026

@huangruiteng huangruiteng 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.

English verdict: APPROVE

Reviewed head: 1a1e543294de7113b8f04caa0f94bbd926183012;immutable base: 39f2fd15e45987a01769bd9bd5a4da42e89e12d9。无本 PR 引入的阻断项。批准的是 partial M3 first_party_host_runtime enforcement,不是 source-profile execution activation 或完整进程/下游效果 drain 的验收。

动机

同一个 goal_id 被退休并重建后,Host descriptor、Turn journal、DSH session lineage 或 Kunlun runtime 不能把旧实例的状态与迟到结果交给新实例。已有 GoalRef/RFC 身份 owner 解决身份表达,不能自动约束这些实际持久化/返回边界。本 PR 把现有 first-party Host 路径接到 exact GoalRef,而不是新增 Goal ledger、peer 权限模型或替换 runtime。

最强的反对理由是“给每个 Host 加一个检查,仍无法证明整个 M3 安全开放”。这个反对成立,所以我按已接受 RFC Section 11 的分阶段边界审查:当前交付阻止过期状态选取和迟到结果进入指定 Host 状态提交;accepted-before-retirement downstream drain、warm/unsupported binaries 和其他 inventory owner 仍明确未验收。源码及登记仍保留 execution_authority: false,没有把局部测试提升成完整上线许可。

改动思路

TypeScript 决定 planned/current/Host GoalRef 是否一致及 typed refusal;Python 只读取 registry、复用 alias lifecycle lock,并在短状态提交时执行决定。锁不跨模型或网络请求,避免把 Goal lifecycle 卡在长调用上。更小的“比较一下 goal_id”解决不了重建,单纯给 session filename 加实例后缀也挡不住已缓存的 journal 和晚到结果;复用既有 exact parser/guard、把各真实提交点接入同一边界是有需求的最小完整 slice。

legacy 分支不要求新字段或重写历史记录;source 分支拒绝 alias-only/malformed/foreign/stale Host state,不自动给旧 descriptor 补上新实例身份。正常恢复与明确的 orphan/import 处理保持分开。

具体改动

全量 23 个文件、+1736/-63:10 个生产文件接线/实现,2 个 inventory/registry I/O 清单,9 个测试文件,2 份 RFC qualification ledger。没有新 CLI 参数、执行权限或前端配置入口。

关键代码讲解

  • first_party_host_runtime.ts::decideFirstPartyHostRuntime:复用 parseExactGoalRef,以 operation/authority/Host state 的 typed 分支区分 start_new、resume、accept_result 和 refusal;non-source 先返回 legacy,不把 strict decoding 扩散到旧输入。
  • FirstPartyHostGoalAdmission::select_state/accept_result:在既有 alias lifecycle guard 内重新读当前 authority,并把检查与 Host 状态 commit 放在同一短锁内;状态不存在可创建 exact-bound 新记录,alias-only/旧实例状态只能拒绝,不能 silent relabel。
  • executor.py::run_loopx_turn_once:启动和 cached recovery 前验证 current;Host 结果/失败 journal checkpoint 通过 result admission 提交。迟到结果异常不会被普通 Host failure wrapper 吞掉后继续 validation/writeback/spend。
  • codex_cli.py::run_codex_cli_host 与 runtime.py::run_native_goal:Codex descriptor 和 Kunlun runtime 加 exact binding、读旧状态先检查、接受新状态/终态再检查。DSH 只在 exact instance 存在时使用 v2 lineage digest,legacy v1 与缺 lineage 的 fallback 继续原样。

对主干的风险

关键风险有三类:legacy 误被 strict gate 覆盖;A→B 后旧 state/cached result 被重用;“拒绝旧 A”后新 B 也无法继续。独立 reviewer probe 使用真实 file-backed registry、TS journal 和实际 run_loopx_turn_once:legacy 整体 plan digest 与基线相同,首轮 commit、重放及三类效果各一次;A 的迟到结果不进入 host_result journal、不验证/写回/扣额/调度,旧 A retry 不再启动 Host;用新 B 的 exact plan 可 commit,旧 A journal 原样保留。进程内绕过 result admission 会重新接受已退休 A,反例能检测这个边界缺失。

Python 定向套件原始结果为 308 passed / 2 failed:registry I/O census 在 immutable base 与 head 有相同 usage_goal.py::_bound_codex_session 漏登记及 quota.py::_dispatch_quota_turn_start_hooks 的 metadata 漂移,该代码不在本 PR;另一项 30 秒 Codex e2e smoke 超时,base 与 head 同命令单独运行通过,head 约 12 秒。八项旧 Codex/DSH/Kunlun 会话、终态和 crash recovery 原生对照在两边均通过。

完整 TS 套件 3145 passed、0 failed、30 个既有 PostgreSQL 环境门控 skip,typecheck 和 changed-source Ruff 通过。这里未改变 SQL authority store、provider routing 或 promotion,PostgreSQL skip 不被算成这条 file-registry Host admission 路径的验收。标准 premerge 原始记录含一个 120 秒 CLI budget timeout;同一 smoke、同一 120 秒 wrapper、同一工作负载重跑,base/head 分别约 90/92 秒通过,不改预算或测试预期。其余 16 项 premerge smoke、direct checks 和全 changed-file 公共边界扫描通过。原始失败保留,不宣称第一次 canary 全绿,也不因与本 PR 无关的红检查 request changes。未查询或等待远端 CI。

共享语义与剩余边界

GoalRef owner、source registry codec 与 lifecycle guard 复用现有契约,inventory 正确写为 source_exact_partial,而非“已完成 M3”。新 refusal 是机器强制,不是可忽略 guidance;语义与错误文案不绑定某种项目/benchmark。

#5130 的 attached Chat binding、#5139 的 App turn acceptance 和 #5144 的 Host process supervision 是相邻但不同边界:session/Host admission 不证明子进程已 drain,App acceptance 不替代 exact GoalRef。它们不能因本次 approval 被视为一并验收。无 frontend/Lark schema 或设置改动,这个未开放执行的 qualification slice 不需要另造 UI 开关;未来 activation 仍须原 RFC 的完整接线和真实运行验收。

我的整体评价

APPROVE,保留现有 integration/merge-readiness holds,由 maintainer 合并。长期可靠性的增量是切断跨 Goal lifetime 的 state/result 复用,同时保留旧 lane 的正常重复工作;不是测试数或新字段本身。代码量主要是四条真实 Host 路径和负例,边界内合并审查合理。未来改动的简化检查已落实到 shared parser、既有 guard 与一个 TS decision owner;没有理由再加第二份 Python 状态机或通用 Host framework。M3 的下游 drain、unsupported process 和 orphan 恢复仍是已有 RFC 的独立剩余工作,不能凭这条 review 开启 execution_authority。

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
@mergify

mergify Bot commented Sep 27, 2026

Copy link
Copy Markdown

Hi @Duang777, the DCO Sign-off check did not pass. Please inspect
its details first: checkout, fetch, timeout or infrastructure errors
need their own recovery, not a rewrite of otherwise signed commits.

If the log confirms a missing Signed-off-by trailer, amend the
affected commit with git commit --amend -s; for multiple commits,
use an interactive rebase against the current base from the correct
base-repository remote and sign off each affected commit. Push the
rewritten PR branch with git push --force-with-lease origin HEAD.

@huangruiteng huangruiteng 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.

PR #5141 复审 — exact head 9f34365fd832fcd8c49a99ce9d54428370a30e6b

动机

按 docs/architecture/rfcs/goal-instance-identity-and-orphan-recovery-v0.md 第 11 节 M3 的 first_party_host_runtime 归属,source-profile 的 Host 状态此前只按 goal_id 绑定。于是同一 alias 下的 Goal 被重建(新 goal_instance_id)之后,旧实例留下的 Turn journal、Codex session 描述符、DSH session 标识与 Kunlun 运行状态仍可能被恢复,迟到的 Host 结果也可能被新实例接受。本 PR 把 source profile 的状态选择与结果准入绑到精确的 {goal_id, goal_instance_id},让 Goal B 在 journal、validation、writeback、spend、scheduler 与 Kunlun closeout 之前就拒绝 Goal A 的状态与结果。

改动思路

决策所有权按仓库既定方向划分:TypeScript 拥有 GoalRef 决策,Python 只做 registry I/O、生命周期锁与 Host 状态提交。TS 侧新增 decideFirstPartyHostRuntime 并注册为 effect runtime handler,用 typed union 返回 legacy / start_new / resume / accept_result / reject(code),拒绝码是枚举而不是子串判断。Python 侧新增一个 admission 对象,在 alias 生命周期锁(guard_path)下把三种时机收敛成三个检查点:select_state(选状态,缺失则用精确 GoalRef 初始化)、require_current(Host 启动、closeout 每一步之前)、accept_result(任何状态提交写盘之前)。capture_first_party_host_goal_ref 在锁内读取 source authority 得到精确 GoalRef,registry 缺失或非 source profile 时返回 None,从而让非 source 计划完整保留既有路径、schema 与字节。

具体改动

新增 loopx/control_plane/goals/first_party_host_admission.py(212 行)与 loopx/control_plane/goals/first_party_host_runtime.ts(171 行),并在 effect_runtime_handlers.ts 注册 goal.first_party_host_runtime.decide。四个 Host 路径接入同一组检查点:turn.py 在 plan 阶段捕获 GoalRef 并传入 build_loopx_turn_plan,在 run-once 恢复分支重建 admission 并 require_current,把 admission 交给内置 Codex host 与 session binding resolver;executor.py 让 host request 携带 goal_ref,并把 _host_result_stage 的三处 journal 写入改为经 accept_result 提交;codex_cli.py 在 session 描述符里持久化 goal_ref,读取时用 select_state 比对,store/discard 都走 accept_result;dsh_goal_mode/turn_host_adapter.py 让 source session id 在 lineage 之外再纳入 goal_instance_id;kunluncode_goal_mode/runtime.py 把 goal_instance_id 写进 binding,并把所有 write_runtime_state 改为 _commit_runtime_state,在 closeout 的 delivery、todo complete、quota spend 各步之前 require_current。driver.py 与 transaction.py 让 goal_ref 进入 plan payload 与 turn identity;语义清单 goal_instance_binding_inventory_v1.json 更新了 producer/consumer/effect boundary/identity strength/disposition,RFC 增加 2026-09-27 的部分执行记录。测试侧补充了 TS 7 项 policy 测试与 Python 侧 Goal A/B、legacy state、cached recovery、并发提交/重建等负例。

对主干的风险

最大的风险是"默认关闭隔离"被破坏:非 source profile 必须逐字节保留旧行为。这一点在代码上有明确出口(enabled 为假时 select_state/require_current/accept_result 都直接走原回调,turn.py 用 strict_goal_admission is None 回退到旧调用),并由 legacy profile 测试与 non-source profiles preserve legacy behavior TS 测试固定;全量 npm run test:control-plane 3262 项 0 失败也在这一 head 上复验。第二个风险是新增持久化字段(Codex 描述符与 Kunlun binding 的 goal_ref、turn identity 里的 goal_ref):旧 source 记录没有 goal_instance_id,代码选择显式拒绝(legacy_host_state)而不是推断升级,方向正确,但意味着 source 档案一旦启用就要求先前的 Host 状态被清理或重建,这一点由 RFC 的剩余 hold 与 execution_authority: false 兜住。锁方面,所有检查都在 alias guard 内,测试覆盖了结果提交与重建串行化。需要单独记录、但不属于本 PR 的主干红灯:examples/control_plane/cli-output-budget-regression-smoke.py 在本 head 与当前 origin/main 上给出同一条 loopx_turn_plan/crowded/json emitted 14514 chars; baseline ceiling is 14500,而 PR base 39f2fd15e 上该 smoke 通过;对照 head 与 main 测得完全相同的 14514,说明本 PR 的 diff(该 fixture 的计划里并不存在 goal_ref)没有贡献增量,是主干自身的 envelope 增长越过了 341 字符的回归余量,应由预算所有者决定压缩还是重定基线。同类情形还有 examples/repository-hygiene-smoke.py 的 public/private boundary 断言,在 main 与 head 上以同一签名失败。

我的整体评价

这是一次边界清晰、所有权正确的部分执行:决策留在 TS,Python 只做 I/O 与锁,四个 Host 路径复用同一组检查点,而不是各自发明一套比较逻辑;三处 accept_result 的位置说明"提交前检查"覆盖了 journal、校验失败与正常结果三条写出路径。我复验了 TS 类型检查、全量 control-plane TS 套件(3262 项 0 失败)、PR 涉及的 Python 套件(305 项)与架构套件(131 项)、针对性 Ruff、git diff --check 与 premerge 的 public boundary 扫描,均通过;未通过的两条已独立归因到主干。剩余风险(warm/unsupported binaries、accepted-before-retirement drain、其余 inventory owners)已经在 RFC 与 PR 正文里显式保留为 hold,因此我不把它计为本 PR 的缺口。建议合入。

本次复审的 head 相对上一次复审只多了主干并入(#5131 的文档引用修正与 monorepo-distribution-split RFC 草稿),与 base 的差异仍是同一份 23 文件 +1736/-63;代码面未再变化,因此前述验证结论继续成立。

English verdict: APPROVE - 9f34365 binds source-profile Host state and result admission to the exact GoalRef behind a TypeScript-owned typed decision, keeps non-source plans byte-identical, and passes typecheck, the full 3262-test control-plane suite, 305 PR Python tests, 131 architecture tests and the premerge public-boundary scan; the two remaining red checks (CLI output budget and repository hygiene) fail with identical signatures on origin/main and the PR base passes the budget smoke.

@huangruiteng
huangruiteng merged commit af3e7f1 into loopx-project:main Sep 27, 2026
6 of 7 checks passed
@huangruiteng

Copy link
Copy Markdown
Collaborator

Merged as af3e7f1f00e2815e45f99258c0d8ec58774ec9bb (second parent = reviewed head 9f34365fd832fcd8c49a99ce9d54428370a30e6b).

  • Exact-head review: feat(runtime): fence first-party Host state by GoalRef #5141 (review) (APPROVED).
  • Conflict from main's style(turn): simplify single-name import declarations #5148 import style resolved by keeping this PR's first_party_host_admission import and adopting main's single-line form.
  • Validation at the merged head: typecheck; 3262-test control-plane suite (0 failures); 305 PR Python tests; 7/7 TS policy tests; 131 architecture tests; Ruff; git diff --check; premerge public-boundary scan.
  • Admin bypass was required by the protect main ruleset's require_last_push_approval after the maintainer main-integration push.
  • Two red checks are main-side and recorded as holds, not repaired here: the CLI output budget (turn plan crowded fixture 14514 > 14500 on main as well, base passes) and the repository hygiene public/private boundary hit.

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.

2 participants