Skip to content

fix(runtime): align heartbeat admission, context and correction - #6483

Merged
huangruiteng merged 14 commits into
mainfrom
codex/pause-resume-heartbeat-boundaries-20261015
Oct 15, 2026
Merged

huangruiteng merged 14 commits into
mainfrom
codex/pause-resume-heartbeat-boundaries-20261015

Conversation

@songoow

@songoow songoow commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

Goal And Delivered Outcome

Long-running work must wake only under current admission, consume current requirements, and correct the affected work without inventing a new replan or pause policy. This change connects that chain to the existing pause/resume boundaries in Codex Goal Chat, Codex App heartbeat instructions, the external CLI scheduler and Pi/OpenCode/OpenCode 2. It adds no scheduler, summary store or parallel Goal state.

Production path Before After / evidence
External scheduler → Core decision → configured wake Python truthiness could interpret a string "false" as admission Consume stop first; reject failed/non-boolean admission before any wake. Existing monitor backoff/reset rules remain.
Fresh guard → current requirements → Host Current source delivery existed, but the working-brief obligation and next-wake changed-source evidence were implicit Existing typed context guides a bounded progress/change, blocker, next-work, acceptance and stop brief. File/SQLite/legacy CLI → envelope → Codex prompt checks cover same-identity changed requirements and source loss. No second summarizer is added.
Local correction → review → subsequent work Templates/skill invented two-stall replan/self-pause and fixed candidate-count audits Remove those rules; reuse typed replan guidance for evidence-scoped widening, a due review that may retain its path, and checking subsequent adoption/results. Core triggers and semantic acceptance are unchanged.
Codex Goal Chat Stop/recovery → native pause → readback A successful set ACK was treated as pause; a late start event could still deliver resume context Read the same thread after pause; unconfirmed/missing/unavailable state closes the owned transport and fails. Late starts are retained for interrupt only. Controller/store recovery refuses an unconfirmed host.
Codex App quota → generated instruction → host stop Compact/brief/thin instructions omitted the single-attempt, verification and end-of-turn obligations All modes share the same stop clause. An unavailable/unconfirmed stop cannot be reported as successful, retried or converted into an RRULE fallback. Host API execution still belongs to the consuming Agent.
Pi idle → quota → task injection A hard stop cancelled a timer without disarming later idle probes; pause→resume retained the generation of a pending probe Persisted pause; existing generation advances on pause/resume; old results and cancelled callbacks cannot dispatch. File-backed restart and race tests.
OpenCode chat → idle → native resume → quota Automatic native resume could precede Core admission; a denied permission marked input pending rather than disarming continuation Admission precedes automatic native resume; denied permission/error disarms the bridge; serialized local binding updates and lifecycle revision checks reject stale probes. Unconfirmed native resume does not forward continuation.
OpenCode 2 initial task → quota The initial task reached the model before the first quota check Initial and continuation dispatch require Core admission. An unstarted objective survives restart privately; force-resume cannot bypass Core stop.
Validated terminal no-follow-up OpenCode adapters continued five-minute standby polling Disarm recurring continuation. Ordinary dependency wait/backoff remains distinct from terminal closure.

Five managed-adapter counterexamples plus five Codex pause/recovery cases and four generated-prompt obligation checks failed before their respective repairs and passed after them. Core denial cannot be overridden by a runnable scheduling hint. Original in-flight effects and settlement remain the original operation's responsibility.

Author Declaration

Criterion Disposition Implementation / validation
A wake or mode tag does not grant execution/resume authority implemented Existing adapter dispatch gates; contradictory-hint, initial-admission and force-resume tests
Pause/resume retains identity and rejects obsolete continuation implemented within named adapters Pi persisted generation; OpenCode local revision/serialized writes; worker persisted pause; controlled race/restart tests
Distinguish stop, gate, bounded wait and terminal no-follow-up implemented Existing Core decisions consumed by adapters; unchanged waiting tests and Core pause/gated-lane tests
Codex native Stop, cold recovery and resume input implemented within the owned transport Pause readback, fail-closed transport, late event suppression; existing original-objective/cumulative-usage and explicit-resume tests retained
Codex App stop text across modes implemented; host execution remains externally owned Full/compact/brief/thin require one pause attempt and confirmation; prompt generation is not an installed automation update
Installed host input consumption and in-flight stop latency deferred Remain provider qualification in the existing RFC, not inferred from adapter tests

Scope And Continuation

Complete for the named dispatch, Codex pause-confirmation and current-context/correction instruction defects and corresponding RFC alignment. Existing ESM adapters and Python Codex transport/prompt renderers retain their provider responsibility; no parallel Python admission owner is introduced. They consume existing Core decisions; shared work-context and replan instructions remain in the existing TypeScript owners. No new shared policy owner or vocabulary is introduced. The semantic advisory does not analyze these JavaScript carriers, so its empty result is not semantic equivalence proof.

The bounded companion refactor centralizes the stop clause so prompt compaction cannot drop its obligations, serializes OpenCode binding updates so an old snapshot cannot overwrite pause/resume, and removes obsolete automatic standby behavior. Private worker state gains an optional initial task body; legacy unstarted bindings can supply the original task explicitly. The objective remains private and is not a new Core authority.

Behavior change: activated OpenCode 1/2 adapters stop on validated terminal no-follow-up instead of standby polling; OpenCode permission rejection and host errors require explicit re-arming. Initial OpenCode 2 task dispatch is now gated. Codex Stop/recovery now fails closed when pause cannot be read back, and generated heartbeat modes retain the complete stop contract. The external scheduler now rejects malformed or failed admission. Full/compact/thin templates and the managed project skill no longer invent wake-count replan/self-pause thresholds; brief guidance uses the same Core ownership rule. Configured Core review cadence remains intact. Inactive/unbound sessions retain their existing route. Existing host commands and Goal/quota settings remain the controls; no new frontend or Lark configuration is needed.

Working briefs are Agent instructions over current sources, not deterministic summary generation or evidence that a model adopted the correction. A due review can retain a path; only relevant goal/path/dependency/acceptance evidence warrants wider change. Receipt, subsequent work and independently verified outcome remain separate. The existing Stride provider-result wake and live-utility qualifications remain open.

App-owned heartbeats still require the host's existing stop action and confirmed readback. Without a host pre-dispatch hook, the first wake may already invoke a model. This PR does not promise zero App model wakes, live vendor adoption, arbitrary cross-process cancellation, or cancellation of submitted tools. OpenCode 2 inactivity hold is an observation of an outstanding turn, not evidence of an explicit user pause. Those limits are recorded in the existing RFC rather than another tracking framework.

Prompt Size And Semantic Review

Clause-by-clause review preserves the current heartbeat target, single attempt, verified stop, unresolved outcome, no new work/spend, no retry/RRULE fallback, and the existing notification/settlement boundaries. Stop handling precedes wait/safe-bypass instructions in full and brief bodies. No task prose is treated as a new machine-enforced lifecycle owner.

The same scoped Agent projection grows from 3,182 to 3,299 JSON characters; its 5,400 ceiling is unchanged. Bound envelope fixtures now measure the shipped projection, as the contract already requires, instead of generator diagnostics. Compact scoped body: 7,086 → 7,213 including fixed optional headroom, against the old 7,140 ceiling. Thin real CLI with the supported 320-character scope: 2,992 → 3,109, against 3,000. Only these presentation allowances rise: compact 6,500 → 6,700; thin 3,000 → 3,200. Execution/token quotas, other body limits and key-count caps remain unchanged. The broader full-scoped fixture was already oversized and remains an overflow diagnostic; it is not reclassified as passed.

The current refinement reuses instruction carriers instead of adding fields or model calls. Matched ordinary generated bodies change by full −215 / compact +88 / brief +46 / thin +37 characters, with no further body-ceiling increase. Across the same small/crowded/multi-Agent real CLI fixtures, main → pause-only → final thin outputs measure 3,070/4,998 → 3,187/5,115 → 3,224/5,152 characters (JSON/Markdown), all 65 Markdown lines. The old 5,100 Markdown diagnostic ceiling already failed on the pause-only head; only that human-output ceiling becomes 5,250. The 3,400 JSON ceiling and line/key/compute limits stay unchanged. Replan advice adds 363 text bytes for local scope and followthrough: its bounded advice allocation rises from 1,500 to 1,800 while the 8 KiB envelope warning and existing overflow evidence remain unchanged.

Validation

  • Reviewed and tested head: 8647d7ad866aa4d2345d834e515e5f10347fd200.
  • Follow-up repairs: compact Markdown ceiling qualified against the same base/head fixture; exact complete-clause transitions now qualify bounded continuation instruction growth; OpenCode disarms local continuation before awaiting native pause/block IO. Four delayed native-stop cases fail before the ordering fix and pass after it. Native stop errors remain visible and leave local continuation disarmed.
  • Scope: synthetic/public fixtures, production source adapters/controller/store, actual temporary filesystem state, and packaged frontend with controlled API seams. No active Goal, installed host, deployment or live paid model was modified. No PostgreSQL authority/schema/routing change.
Check Current result Evidence and boundary
Python affected paths passed 149 cases covering native Codex Goal/controller/store, scheduler admission, heartbeat context and replan. Tested source unchanged by subsequent ESM and validation-only fixes.
Managed host adapters passed 108 Pi/OpenCode/OpenCode2 tests on the final head; 7 selected cases fail against the immutable original base; 4 additional delayed native-stop cases fail before the final fix. Real file recovery, controlled host/quota seams.
Typed owner passed 37 TypeScript interaction/replan cases and control-plane typecheck.
Output semantics and cost passed 134 differential cases; full real CLI base/head growth matrix passes. Compact Markdown 11,315→11,530 characters,145 lines; presentation cap11,750. JSON cap13,500 remains unchanged. Full old→new clauses and bounded allowances reject wrong surfaces, partial clauses and subsequent unrelated growth.
Native premerge canary passed Final frozen source:19/19 selected checks, no failures/skips/timeouts/tracked side effects; direct diff, compile and maintainability checks pass. Supported Node22.22.3, compile cache explicitly disabled.
Semantic/public boundary passed Full semantic drift, development advisory and public-boundary scan. Advisory does not prove ESM/prose semantic equivalence. Generated lockfile and local evidence excluded.
Packaged user journey passed Dashboard/chat build and existing loopx-mode browser journey; API seam controlled, real controller/store/native-host boundary validated separately. Existing bundle-size warnings remain.
Broad packaged browser failed, baseline-attributed work-map selected-node timeout at goal-work-map.mjs:178 and workspace showcase-reconcile vs showcase-map-columns at goal-workspace-m2.mjs:82 both reproduce with the same identity/detail after an independent build of immutable base3e611660af8e27aa8a97a8364606dad92e91ae7b. Their causal UI/scenario/fixture paths are unchanged. These red checks remain separate merge holds.
Remote exact-head CI pending at review observation DCO and dependency review pass; builds/other jobs are still queued or running. Local evidence is not a claim of remote CI completion.
Live provider / installed App not run Vendor stop latency, installed App scheduler shutdown, first-wake cost and model adoption remain existing RFC qualification gaps.

Earlier evidence is not erased: the a9472bb full growth gate failed before bounded semantic qualification; earlier Node25 runtime errors are not claimed fixed by this PR; a canary run overlapped tracked edits and was invalidated, then superseded by the frozen-head19/19 run. An older broad run also hit a2-second wall-time assertion; its later isolated pass is not presented as a timeout fix. The current source checks above establish the affected invariants. Original Core settlement, in-flight tool cancellation and cross-process host cancellation are unchanged and not newly qualified.

Frontend / Visual Evidence

  • UI impact: no layout, Lark or configuration changes. Existing Goal Chat pause/resume controls and host commands acquire corrected behavior. The existing packaged LoopX-mode browser journey passes; native Codex success/failure/recovery are qualified through production controller/store and controlled host seams. No new first-screen design or switch. Installed App prompts must still be explicitly updated and read back through the host; this PR does not mutate them.

Type of Change

  • Bug fix
  • Documentation update
  • Test update

LoopX Area

  • Host or runtime integration
  • Public docs or presentation surface

Technical Direction

  • Existing roadmap S7; Session Execution Modes §5; Stride §7.5. No broader RFC milestone is marked complete.
  • Shared-authority RFC fixture impact: N/A; no authority-store, schema or routing promotion.

Boundary Checklist

  • Public diff and description exclude private state, credentials, raw logs and local paths.
  • No benchmark execution, merge, deployment or installed-host mutation.
  • Changes are scoped to pause/resume, admission, current instruction and correction continuity.
  • Existing native controls are reused; no first-screen visual changes.
  • Every branch commit includes DCO sign-off.

Signed-off-by: song <liusongstep@gmail.com>
…artbeat-boundaries-20261015

Signed-off-by: song <liusongstep@gmail.com>
…artbeat-boundaries-20261015

Signed-off-by: song <liusongstep@gmail.com>
…artbeat-boundaries-20261015

Signed-off-by: song <liusongstep@gmail.com>
@songoow songoow changed the title fix(hosts): enforce pause and resume boundaries before heartbeat dispatch fix(runtime): fence Codex and managed-host pause/resume boundaries Oct 15, 2026
…artbeat-boundaries-20261015

Signed-off-by: song <liusongstep@gmail.com>
Signed-off-by: song <liusongstep@gmail.com>
…artbeat-boundaries-20261015

Signed-off-by: song <liusongstep@gmail.com>
@songoow songoow changed the title fix(runtime): fence Codex and managed-host pause/resume boundaries fix(runtime): align heartbeat admission, context and correction Oct 15, 2026

@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; model=gpt-6.1-sol; provider=OpenAI; declaration_source=runtime_reported; reasoning_effort=xhigh

Reviewed exact head: 6483@84e00bac1717cd07f25eafffbf60053bd1b46e5a.

动机

在 Codex、Pi、OpenCode 与外部定时器上运行长期 Goal 的用户。 用户暂停或 Core 拒绝工作后,旧检查或普通聊天原先仍可能恢复宿主、发送初始任务;新路径先检查当前准入并隔离暂停前结果,停止未确认则保留失败。 本头的受控宿主、文件绑定、CLI 与真实 Chat controller/store 测试支持停止隔离、恢复再准入和未发送任务恢复。 真实宿主停止延迟与 App 下发前拦截仍未资格化;模型纠偏采用和收益仍归原 Stride 后续验收。 不证明已安装厂商宿主、模型实际采纳、在途取消延迟、App 模型唤醒归零或长期纠偏收益;已提交效果仍需原结算。

改动思路

复用 Core 的当前准入和 replan owner,各适配器只负责自有传输、binding、计时器及结果隔离。修复落在已有状态与效果边界,验证直接覆盖旧竞态;无需新增通用框架。当前交付范围是源码中的状态发布/宿主派发不变量;安装态和长期收益仍保留原验收。通用决定继续属于 TypeScript owner;既有 Python/JS 宿主桥接不构成第二份决策规则。

原触发路径 本头行为 仍不代表
旧 quota 结果在暂停→恢复后返回 代次失效,下一次需新准入 已提交工具被取消
普通聊天或 OpenCode2 首次任务 不能绕过当前 Core 检查 宿主可自行解除 Goal 停止
Codex 暂停只收到 ACK 再读状态,未确认则关闭自有传输并失败 App 的周期任务已停
心跳累计几次无进展 遵循 Core,不再另设两次阈值/自行暂停 决定回执证明模型采用或收益

具体改动

  1. loopx/chat_codex_goal.py:115 的 pause 先设置停止标志,再与激活互斥;active→paused 后重新读回,仍 active、消失或不可用则失败并关闭自有连接。第 261 行观察循环与迟到 start 事件路径不再投递排队输入/resume context;原 controller/store 接收失败事实。
  2. goal-bridge-runtime.mjs:343 复用每 session 串行写入与本地 revision;普通聊天不解除显式暂停,原生 resume 先经过 Core。pi-goal-loop-runtime.mjs:788 递增原 generation,旧 timer callback 不能消费替代 timer。opencode2-goal-worker.mjs:580 把首次正文也放到准入后,保留未下发目标,终态退出;exclusive worker 的私有写入不被当作通用暂停 API。
  3. external_scheduler_worker.py:99 仅接受布尔准入,local stop 优先。生成器各模式共享一次暂停/确认/未确认即结束条款;typed context 与 replan 明确 unknown、局部修正、到期复核可维持路线以及后续采用/结果核验。文档明确终态不再五分钟待机和去掉旧计数规则;这些是行为变更,不是默认关闭功能的隔离声明。

基于变更前 docs/architecture/rfcs/agent-session-execution-modes-v0.md; docs/architecture/rfcs/hierarchical-agent-stride-control-v0.md,不可变版本 3e611660af8e27aa8a97a8364606dad92e91ae7b,验收点 §5、§7.3、§7.5。模式与原权限绑定、Todo/replan owner 和长期观察的提案边界仍保留;本 PR 新写的 RFC 检查点只作为待验证主张,不能反过来自证。相邻未来重构检查:共享 stop 文案已收敛到一个 owner;跨 provider IO 的进一步统一并无当前收益证据,不增加框架。

149 项 Python、103 项宿主适配 Node、21 项 typed replan 均通过且无 skip,control-plane 类型检查、生成心跳和热路径预算 smoke 通过。包括真实本地 Chat controller/store 冷恢复;厂商宿主边界仍受控。另把同一组新测试指向不可变基线适配器,7 项全部产生旧错误,完整本头套件覆盖相应通过结果。风险 canary 5 个直接检查通过,19 个选中检查中 18 个通过、1 个失败;显式关闭 Node compile cache,不声称默认缓存问题已解决,也没有查询远程 CI。

对主干的风险

[P2] 补齐 compact Markdown 的现有回归预算资格化。 loopx/control_plane/testing/cli_output_budget.py:541 仍给 heartbeat_prompt_compact 的 Markdown 11,500 字符上限。当前必需 cli-output-budget-regression-smoke.py 因输出 11,530 失败。同一原生 mode fixture 的不可变基线为 11,315,本头增加 215 字符;行数均 145,JSON 为 12,658→12,873,仍在 13,500 内。这是此头生成文案增长暴露的现有约束遗漏,不能归为远程 CI、路径噪声或已知旧失败。

最小修复是保留停止对象、单次尝试、确认失败、Core 局部纠偏与原结算等有用语义,为同一 compact Markdown 工作负载补上消费者价值、真实冗余判断与合理余量,并使对应预算及文档一致;也可以删除确实可推导的冗余,不能为了过线删义务。本次扩大了 thin/正文预算,但没有解决这处独立 Markdown 上限。复验 uv run --extra test python examples/control_plane/cli-output-budget-regression-smoke.py,再执行同基线风险 canary;不要改变夹具或放松语义锚点。

真实宿主在途取消、已安装 App 停调度、模型实际消费与长期纠偏收益仍未验证,不能把受控恢复和 prompt 条款说成上述结果。作者此前的 budget/壁钟/ambient 路由及 work-map 失败未被本评审宣称修复;当前独立通过证据只覆盖所改不变量,当前 compact 检查失败则保留为明确阻塞。

我的整体评价

当前精确头 REQUEST_CHANGES,阻塞点是已复现的 compact Markdown 预算遗漏,不是否定暂停/恢复修复。生产机制对原问题基本合适,未发现需新增调度器或改写权限模型的理由。请以测量支持完整文本及合理上限后再提交新头;安装态、真实模型和长期验收仍由原 owner 继续,源码评审不替代合并授权。

English verdict: REQUEST_CHANGES. The stop/admission fixes pass focused counterexamples, but the required compact Markdown matrix regresses from 11,315 to 11,530 characters against an unchanged 11,500 ceiling. Reconcile that presentation budget with evidence while preserving the complete obligations, then rerun the native matrix.

Signed-off-by: song <liusongstep@gmail.com>
@songoow

songoow commented Oct 15, 2026

Copy link
Copy Markdown
Collaborator Author

Follow-up: compact absolute budget repaired; merge holds remain

已推送 a9472bb29,仅修改 compact Markdown 的回归上限与双语预算合同。未更改生成指令、夹具、语义锚点或执行额度。

  • 已复现并修正的评审项: 同一原生 mode 夹具在不可变基线 3e611660a 为 11,315 字符,在原评审头 84e00bac1 为 11,530,均为 145 行。旧 11,500 上限确实失败。保留当前心跳单次停止、确认失败处理、局部纠偏和原结算义务,将该展示上限调至 11,750,余量 220;JSON 12,658 → 12,873,原 13,500 上限不变。相邻重构检查:没有需要为这项预算修正增加的抽象。
  • 通过: test_explicit_compact_and_detail_modes_are_characterized、test_heartbeat_agent_input.py、test_heartbeat_prompt_support.py,共 65 passed;语义漂移检查在安装仓库 dev dependencies 后通过;public-boundary 与 diff 检查通过。
  • 仍失败,不能将本次修正视为完整评审关闭: 针对同一不可变基线运行完整 cli-output-budget-regression-smoke.py,通过绝对尺寸检查后,增长差异仍失败。例如 quota Markdown 增加 208 字符、crowded quota JSON 增加 571、brief/compact Markdown 增加 163/215。远程 kernel-static-checks 也报告这类增长失败。下一步应由现有 instruction/budget owner 对这些增量逐项完成语义与消费者价值资格化,不能仅统一放宽增长比例或删义务。
  • Canary: 3 个 direct checks 和 Python compile 通过;19 个 selected checks 初次有 4 个失败。准备依赖后 semantic drift 单独复验通过;完整增长门和两个 auto-research smoke 的 EffectRuntimeInternalError 仍失败,后者尚未归因,不宣称基线无关。未运行真实模型/已安装宿主验收。
  • 旧头的其他 CI 阻塞: chat browser 与 Release Artifacts 在 goal-work-map.mjs:178 等待选中节点超时;dashboard shard 3 在 goal-workspace-m2.mjs:82 得到 showcase-reconcile 而期望 showcase-map-columns。保留给现有 frontend owner 归因/修复,新头 CI 不继承旧头通过结论。

本次是可独立回退的绝对展示预算修正。较广的增长规则和浏览器行为分别属于不同验证边界,保持明确失败,避免将局部修正包装成整个 PR 就绪。既有 REQUEST_CHANGES 保留;未批准、未合并。新头需要完整复验与 exact-head review。

Signed-off-by: song <liusongstep@gmail.com>
Signed-off-by: song <liusongstep@gmail.com>

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

Reviewer: model_agent; gpt-6-astra; OpenAI; runtime_reported; reasoning_effort=xhigh

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

评审对象:#6483,完整 head 8647d7ad866aa4d2345d834e515e5f10347fd200。本次按 capability policy 21 重新检查整个 PR,包含原有改动和三次修复;源码判断通过,合并状态另行判断。

动机

使用 Goal Chat、Pi、OpenCode 或外部调度器持续工作的用户,会在暂停、权限拒绝和重新恢复时遇到自动续跑边界。例如,用户在一次配额查询尚未返回时点击暂停,旧结果仍可能再发出一轮模型请求;现在暂停先使本地续跑失效,显式恢复后必须重新取得当前准入。已验证的改善是阻止暂停后的新派发、保留恢复所需的原始任务,并让续跑指令先读取当前工作和纠偏来源。

旧路径的实际代价是用户已经要求停止,却又产生模型请求或重复空唤醒;首轮被拒绝后重启还可能丢失原任务。此次验收覆盖持续运行中的暂停、重复事件、重启和显式恢复,不能只看一次成功调用。本次不承诺取消已经提交的工具、跨进程强制终止、零 App 首次唤醒,也不证明真实模型已采用纠偏。剩余的真实供应商停止延迟、已安装 App 调度关闭及长期模型收益,继续由现有 Session Execution Modes 和 Stride 验收负责。

独立依据是基线 3e611660af8e27aa8a97a8364606dad92e91ae7b 的 docs/architecture/rfcs/agent-session-execution-modes-v0.md §5,并对照同一基线的 Stride §7.3/§7.5 与 roadmap S7。没有用本 PR 新写的检查点反过来证明旧验收已满足;现有供应商资格和长期收益检查点仍然开放。

改动思路

保留现有 Core 准入与 TypeScript 指令 owner;Python 和 ESM 仅承担各自宿主的停止、读回及持久绑定,不另建统一运行时或第二套调度策略。本 PR 交付暂停、恢复、首轮准入和当前上下文的完整适配器修复;真实供应商与 App 安装态验收仍留在原有 RFC 检查点。

触发与路径 旧行为 当前行为与边界
本地暂停与待返回准入相交 旧结果可能继续派发;OpenCode 等 native ACK 后才解除续跑 先取消 timer、推进 binding revision 并持久关闭 autoResume,再等待 native IO;旧结果无权发送
普通消息、run_now 或 forceResume 个别路径能绕过暂停或否定准入 不能代替当前 Core should_run;显式恢复仍重新查询
OpenCode2 首轮或重启 首轮可能先调用模型;拒绝后的原任务不稳定 先保存原任务、再准入;重启继续同一任务
继续工作与纠偏 上下文可能陈旧,文本自行追加 wake-count 阈值 从现有 typed owner 读取当前来源,保持 Core cadence,区分指令、执行和结果

表格是源码流程说明,执行证据见后文。权限范围仍是已绑定会话和已有 Goal;安装插件、发现命令、普通输入都不会授予其他会话新的控制权。统一 provider 框架会增加无用维护面,本次只把重复停止顺序集中到现有 pauseBinding,这是已应用的有界重构。

具体改动

  1. Codex / Goal Chat:CodexGoalDriver.pause 先设置本地停止,再串行读取和更新 native Goal,确认状态后中断;拒绝、离线或无法确认时关闭自己拥有的 transport 并抛出错误。生产 controller/store 的停止和冷恢复路径一起覆盖,现有前端操作不增加设置或重复确认。
  2. Pi / OpenCode / OpenCode2:复用 session revision、CAS、timer、lease 和现有文件状态;Pi 不再把 run_now 当作越过否定准入的依据。OpenCode 普通消息不能解除硬暂停,resume 必须有成功宿主响应。OpenCode2 对第一条任务也准入,保留 private taskBody,forceResume 不能越过 Core 暂停。外部 scheduler parse_tick 拒绝非 boolean 和明确失败的准入,producer stop directive 的优先级保留。
  3. 当前上下文与纠偏:interaction_contract.ts、replan_semantics.ts 和现有 heartbeat renderer 共用当前来源,去掉自行发明的 wake-count replan/self-pause 阈值。完整、简短、紧凑和薄模式保持一次停止尝试、核实结果、未解决不冒充成功、停止新工作/花费以及不借 retry/RRULE 复活等义务;full/brief 把停止置于 wait/safe-bypass 之前。文档与 managed skill 同步披露,机器准入与 Agent 指令分别表述。
  4. 本次修复的输出预算问题:原 compact Markdown 11,500 上限确实失败。相同基线/头工作负载为 11,315 → 11,530 字符、均145行;仅该展示上限改为11,750,JSON仍13,500。完整 growth gate 还暴露 context/replan/heartbeat 文本增长,因此在原有测试 owner 中按完整 old→new 子句分别限定 +224/+384/+224 的迁移额度,错误 surface、缺失子句、已升级状态和再次超额均不能借用。没有缩短停止义务、改变执行配额或缩小原矩阵。
  5. 本次新发现并修复的竞态:4个 native stop 延迟场景在修复前全部失败,旧准入能在宿主停止尚未完成时转发1个事件。8647d7ad8 将 canonical pause/block、legacy pause 和 command pause 的本地 fence 移到 native IO 之前,4个场景全部通过;宿主抛错时继续暴露错误,本地仍保持关闭。新增 native-error 例覆盖此边界。
  6. 整个 diff 的其他部分:既有 Python/Node/TS 测试、三个现有 smoke/probe、provider README、heartbeat/Goal Chat/replan/interface-budget 文档,以及英中文 Session Modes、Stride、roadmap 检查点和 managed skill 均已读过。共41个 tracked 文件,+1361/-342;无生成锁文件、原始日志、私有状态或无调用方的新模块。

对主干的风险

  • 核心正向与失败证据:149个 Python 用例通过;最终 head 的108个适配器用例、134个输出差异用例通过;37个 TypeScript 用例与 control-plane typecheck 通过。基线真实 adapter 模块运行相同选定测试时7个原缺陷全部失败,新增延迟停止场景在修复前4个全部失败。实际文件绑定、worker restart、不同 session、旧 activation 结果、拒绝准入、明确恢复和 host 错误都有覆盖;host/quota 外部响应采用可控 seam,不能当作真实模型试验。
  • 项目原生检查:最终冻结提交的标准 canary 19/19 通过,无失败、跳过、超时或 tracked side effect;另有 diff/编译/maintainability 直接检查,semantic drift 与 advisory 通过。advisory 没有发现受支持的新词汇载体,但不覆盖所有 ESM 构造或证明语义等价。完整真实 CLI base/head growth matrix 通过。使用支持的 Node22.22.3 与显式禁用 compile cache;早先 Node25 runtime 失败没有被宣称修复。执行中途编辑造成的一次 canary side-effect 失败已作废,保留记录,以冻结源码运行替代。
  • 产品入口:打包 dashboard/chat 构建与既有 loopx-mode 浏览器交互通过(控制 API seam),生产 controller/store/native RPC 错误与恢复另有测试。没有 layout、首屏、Lark 或新增配置变更。没有 PostgreSQL authority 路由/schema 修改,因此不把未改动存储架构迁移验收强加到此 PR。
  • 仍为红色的独立检查:打包 work-map 在 goal-work-map.mjs:178 关闭详情后 selected-node locator 超时;workspace 在 goal-workspace-m2.mjs:82 得到 showcase-reconcile 而期望 showcase-map-columns。在不可变基线独立安装、构建后执行同命令,两者的失败身份和细节与当前 head 一致;相关 UI、场景及 fixture 路径未改动。判为 pre_existing_unrelated,保留红色,不能声称 CI 全绿或以此跳过合并门禁。
  • 未验证与兼容边界:真实供应商模型、已安装 App 调度关闭、首个 wake 成本、跨进程/已提交工具取消未执行。原有 legacy OpenCode 命令及持久文件读取仍有真实调用方,保留且覆盖;没有借兼容新增平行决策 owner。所有新默认行为在上述文档披露,通用错误和义务保持领域中立。

我的整体评价

此次实现给已有用户带来了可观察的暂停、首轮准入与恢复改善,修复后未发现需要继续阻塞该源码批次的实质问题。更严的准入没有删掉合法恢复:显式 resume 后重新准入、重启保留任务、普通原生未绑定路径与会话隔离均已验证。预算增加有同工作负载数据和完整子句约束,属于展示回归预算调整,不是放宽执行成本或牺牲 Agent 义务。

因此对当前精确 head 给出批准结论。这个结论仅针对已验证的适配器/指令批次,不关闭整个 RFC、不证明长期模型收益,也不授权合并。发布时远端部分构建仍在运行或排队,旧 REQUEST_CHANGES 尚需按项目流程核对;独立 browser 红项和实际 GitHub merge readiness 必须单独报告。

English verdict: APPROVE - 8647d7a; full-PR review completed, bounded output-growth qualification and the pre-native-stop admission race repaired. 149 Python, 108 adapter, 37 TypeScript and 134 differential tests plus 19 canary checks pass. Two independently reproduced baseline browser failures, pending CI and live-provider qualification remain separate holds; no merge authorized.

@songoow
songoow dismissed loopx-agent’s stale review October 15, 2026 08:25

Verified resolution at 8647d7a, following the requested PR review and repair. The sole blocking finding was the compact Markdown presentation budget: the unchanged fixture measures base11,315 vs head11,530 characters at145 lines, now qualified under11,750 while JSON remains capped at13,500. Complete stop and correction obligations are retained. The full native output matrix,134 differential cases and final frozen19/19 premerge canary pass. Full exact-head review5530175890 is published and read back; unrelated baseline browser failures and live-provider gaps remain explicitly recorded. This dismisses only the resolved budget blocker, preserves the discussion and does not authorize merge.

@huangruiteng
huangruiteng merged commit 7ca37c7 into main Oct 15, 2026
35 of 54 checks passed
@huangruiteng
huangruiteng deleted the codex/pause-resume-heartbeat-boundaries-20261015 branch October 15, 2026 08:28
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