### 1) 目标问题(Why) 当前 runtime 主循环已经被 PR 365 推向“顺序 Todo + inline subagent + dispatch phase”的新模型,但现有计划仍停留在旧控制面语义上,导致问题定义与实现方向已经出现偏移。本issue只解决当前阶段必须收敛的控制面语义问题: 1. 完成判定问题:`assistant 本轮无 tool call` 仍容易被误判为完成,且在顺序 Todo + inline subagent 模型下,这个信号可靠性更弱。 2. 进展判定问题:当前 `repeat-cycle / no-progress` 仍偏向旧式“重复调用 + 弱证据”判断,容易误伤合理探索;同时 PR 365 已移除其硬停止语义,现有计划中的 stop 设计已过时。 3. 状态机问题:runtime 实际上已经引入 `dispatch` 阶段,但旧方案仍以 `Plan -> Execute -> Verify` 为主链,无法准确描述新的执行闭环。 4. 控制面分散问题:completion / progress / stop / dispatch / subagent 相关语义仍散落在 run loop、tool 执行和事件层,不利于后续 budget、ledger、resume 稳定接入。 本阶段目标不是引入更多能力,而是先让 runtime 的主循环语义与 PR 365 对齐,并形成可测试、可观测、可继续扩展的控制面契约。 ### 2) 设计(How) #### 2.1 控制面不变量 本阶段先固定以下运行时不变量,后续实现与测试均以此为准: 1. `assistant 本轮无 tool call != completed`。 2. 只要仍有 `pending agent todo`、`pending subagent todo`、`inline subagent in-flight`、`未验证写入`,就不能 completed。 3. `no-progress` 与 `repeat-cycle` 不是本阶段的硬 stop reason,只能作为 soft control / stalled 信号。 4. `Dispatch` 是正式 phase,不再是隐含流程。 5. 同一 turn 只能产出一个最终硬停止结果,本阶段仅允许: - `STOP_FATAL_ERROR` - `STOP_COMPLETED` - `STOP_USER_INTERRUPT` #### 2.2 运行状态机 本阶段固定 `RunState`: - `Plan` - `Execute` - `Dispatch` - `Verify` - `Compacting` - `WaitingPermission` - `Stopped` 主链迁移固定为: - `Plan -> Execute -> Dispatch -> Verify -> Plan` 补充迁移: - `* -> WaitingPermission -> previous_state` - `* -> Compacting -> Plan` - `* -> Stopped` 语义约束: - `Plan` - 负责本轮规划、顺序 Todo 更新、决定当前 todo 的 executor - `Execute` - 负责主 agent 的普通工具执行 - `Dispatch` - 负责 `executor=subagent` 的 todo、inline subagent 触发与结果回灌 - `Verify` - 负责验证与 closure - `Compacting / WaitingPermission / Stopped` - 保持治理/中断/终止语义,不承载业务推进 #### 2.3 CompletionGate 设计 `CompletionState` 固定包含: - `HasPendingAgentTodos` - `HasPendingSubagentTodos` - `HasInlineSubAgentRunning` - `HasUnverifiedWrites` - `LastTurnExecutedTools` - `LastTurnVerifyPassed` - `RequiresVerification` - `CompletionBlockedReason` 规则固定为: 1. 本轮 assistant 无 tool call,不直接视为完成。 2. 有 `pending agent todo` 时不能 completed。 3. 有 `pending subagent todo` 时不能 completed。 4. 有 inline subagent 尚未回灌完成时不能 completed。 5. 有未验证写入时不能 completed。 6. 只有 `RequiresVerification=false` 或 `LastTurnVerifyPassed=true` 时,才允许结束。 7. 纯读取、纯检索、纯解释型执行不自动要求 verify;写入类动作和显式 verify-required 工具会置 `RequiresVerification=true`。 #### 2.4 进展判定设计 `ProgressEvidence` 仅允许结构化证据: - `TASK_STATE_CHANGED` - `TODO_STATE_CHANGED` - `TODO_EXECUTOR_CHANGED` - `WRITE_APPLIED` - `VERIFY_PASSED` - `NEW_INFO_NON_DUP` - `PHASE_ADVANCED` - `DISPATCH_COMPLETED` - `SUBAGENT_RESULT_APPLIED` 证据分级固定为: - 强证据 - `TASK_STATE_CHANGED` - `TODO_STATE_CHANGED` - `VERIFY_PASSED` - `DISPATCH_COMPLETED` - `SUBAGENT_RESULT_APPLIED` - 中证据 - `TODO_EXECUTOR_CHANGED` - `WRITE_APPLIED` - `PHASE_ADVANCED` - 弱证据 - `NEW_INFO_NON_DUP` `ProgressScore` 至少包含: - `HasBusinessProgress` - `HasExplorationProgress` - `StrongEvidenceCount` - `MediumEvidenceCount` - `WeakEvidenceCount` - `NoProgressStreak` - `RepeatCycleStreak` - `SameToolSignature` - `SameResultFingerprint` - `SameSubgoal` - `StalledProgressState` - `ReminderKind` 规则固定为: 1. 出现任一强证据,或出现 `WRITE_APPLIED + VERIFY_PASSED` 闭环,才算 `HasBusinessProgress=true`。 2. 只有 `NEW_INFO_NON_DUP` 或仅有 `PHASE_ADVANCED` 时,不算业务进展。 3. `HasExplorationProgress` 仅在 `Plan / Execute / Dispatch` 阶段有效,用于给合理探索留缓冲,不直接视为业务推进。 4. `NoProgressStreak` 只在无业务进展且 exploration 缓冲已耗尽时递增。 5. `RepeatCycleStreak` 只在以下条件同时成立时递增: - `SameToolSignature=true` - `SameResultFingerprint=true` - `SameSubgoal=same` - `HasBusinessProgress=false` 6. `SameSubgoal` 使用三态:`same / different / unknown`;`unknown` 不推动 repeat。 7. `no-progress / repeat-cycle` 不直接 stop,只能推动 `stalled` 与 reminder。 #### 2.5 stalled 软纠偏设计 本阶段新增 `StalledProgressState`: - `healthy` - `stalled` 规则: 1. 当 `NoProgressStreak` 或 `RepeatCycleStreak` 首次达到阈值时,不直接终止 run。 2. 首次达到阈值后,进入 `stalled`,并注入一次固定的自修复提醒。 3. 提醒内容固定聚焦: - 总结 blocker - 更新当前 todo / 子目标 - 说明是否继续重复调用 - 若位于 `Dispatch`,说明为何仍需 subagent 或改回 agent 执行 4. stalled 期间允许继续运行;真正硬终止由后续 budget / turn / time 边界负责,不由 progress 直接负责。 #### 2.6 Dispatch / inline subagent 设计 本阶段将 `spawn_subagent(mode=inline)` 正式纳入控制面,不再视为普通附属工具: 1. `Dispatch` 阶段的职责是识别 `executor=subagent` 的 todo、触发 inline subagent、接收结构化结果并回灌。 2. inline subagent 结果一律按结构化 tool result 处理,不作为普通 assistant continuation。 3. `todo.executor` 只允许 `agent / subagent` 两种合法输入语义。 4. 本阶段的 dispatch 语义固定为“顺序 todo + inline child execution”,不承诺一般化 DAG 自动调度。 #### 2.7 事件与观测设计 本阶段固定最小事件集: - `phase_changed` - `progress_evaluated` - `stop_reason_decided` 其中 `progress_evaluated` 必须显式带出: - `HasBusinessProgress` - `HasExplorationProgress` - `NoProgressStreak` - `RepeatCycleStreak` - `SameToolSignature` - `SameResultFingerprint` - `SameSubgoal` - `StalledProgressState` - `CurrentTodoExecutor` - `HasPendingSubagentTodos` - `HasInlineSubAgentRunning` 本阶段不重做全部 subagent 事件,但 runtime 主事件必须能表达 dispatch/subagent 对 completion 和 progress 的影响。 ### 3) 一次性交付清单(What) 基于上述控制面设计,本阶段一次性交付以下内容: 1. 状态机与 gate 收敛 - 固化 `RunState` - 落地状态迁移表 - 固化 `PermissionGate -> CompletionGate -> ProgressGate -> StopReasonResolver` 2. Completion 语义收敛 - 实装 `CompletionState` - 将 completion 改成顺序 todo + inline subagent 感知 - 移除 “本轮无 tool call == completed” 的直接分支 3. Progress 语义收敛 - 扩展 `ProgressEvidence` - 落地证据分级 - 落地 `ProgressScore` - 引入 `stalled` 软纠偏 - 将 `STOP_NO_PROGRESS / STOP_REPEAT_CYCLE` 从本阶段最终 stop reason 中移除 4. Dispatch / subagent 接入控制面 - 将 `todo.executor` 纳入 completion / progress 判定 - 将 `spawn_subagent(mode=inline)` 正式写入 Dispatch 语义 - 将 dispatch/subagent 结果作为结构化证据进入 progress 计算 5. 事件与消费侧对齐 - 补齐 `phase_changed / progress_evaluated / stop_reason_decided` - TUI 改为消费新的 progress/stalled/dispatch 观测字段 ### 4) 验收模型(DoD) 统一按三类验收: 1. 正常路径 - assistant 无 tool call,但仍有 pending agent todo,不应 completed - assistant 无 tool call,但仍有 pending subagent todo,不应 completed - inline subagent 已 dispatch 但尚未回灌完成,不应 completed - 纯读取/检索型执行结束后,无 pending todo 且不需要 verify,可 completed - Dispatch 成功消费 inline subagent 结果后,允许继续进入 `Verify` 或返回 `Plan` 2. 异常路径 - 重复工具签名但结果不同,不应推动 repeat-cycle - 重复工具签名且结果相同,但 `SameSubgoal=unknown` 时,不应推动 repeat-cycle - 重复工具签名且结果相同、子目标相同、无业务进展时,首次达到阈值只进入 `stalled`,不 hard stop - exploration 只在 phase 宽容窗口内起缓冲作用,超过窗口后开始累计 `NoProgressStreak` - 同一 turn 最终只允许一个硬 stop result 3. 恢复/一致性路径 - 已有 session/todo 读取路径在接入新控制面后不应丢失 executor 语义 - `phase_changed / progress_evaluated / stop_reason_decided` 事件字段在恢复已有会话后仍保持结构一致 - 本阶段虽不引入 ledger/resume,但不得破坏后续 resume 对 phase/todo/progress 的接入前提 ### 5) 非目标(明确边界) 1. 不做动态 token 预算。 2. 不做 `RunLedger / ResumeCheckpoint`。 3. 不做 secret 延迟解析。 4. 不做 `internal/instructions` 与 `internal/repository` 分层。 5. 不做通用 DAG 调度产品语义。 6. 不把 `no-progress / repeat-cycle` 重新做回硬 stop。
1) 目标问题(Why)
当前 runtime 主循环已经被 PR 365 推向“顺序 Todo + inline subagent + dispatch phase”的新模型,但现有计划仍停留在旧控制面语义上,导致问题定义与实现方向已经出现偏移。本issue只解决当前阶段必须收敛的控制面语义问题:
assistant 本轮无 tool call仍容易被误判为完成,且在顺序 Todo + inline subagent 模型下,这个信号可靠性更弱。repeat-cycle / no-progress仍偏向旧式“重复调用 + 弱证据”判断,容易误伤合理探索;同时 PR 365 已移除其硬停止语义,现有计划中的 stop 设计已过时。dispatch阶段,但旧方案仍以Plan -> Execute -> Verify为主链,无法准确描述新的执行闭环。本阶段目标不是引入更多能力,而是先让 runtime 的主循环语义与 PR 365 对齐,并形成可测试、可观测、可继续扩展的控制面契约。
2) 设计(How)
2.1 控制面不变量
本阶段先固定以下运行时不变量,后续实现与测试均以此为准:
assistant 本轮无 tool call != completed。pending agent todo、pending subagent todo、inline subagent in-flight、未验证写入,就不能 completed。no-progress与repeat-cycle不是本阶段的硬 stop reason,只能作为 soft control / stalled 信号。Dispatch是正式 phase,不再是隐含流程。STOP_FATAL_ERRORSTOP_COMPLETEDSTOP_USER_INTERRUPT2.2 运行状态机
本阶段固定
RunState:PlanExecuteDispatchVerifyCompactingWaitingPermissionStopped主链迁移固定为:
Plan -> Execute -> Dispatch -> Verify -> Plan补充迁移:
* -> WaitingPermission -> previous_state* -> Compacting -> Plan* -> Stopped语义约束:
PlanExecuteDispatchexecutor=subagent的 todo、inline subagent 触发与结果回灌VerifyCompacting / WaitingPermission / Stopped2.3 CompletionGate 设计
CompletionState固定包含:HasPendingAgentTodosHasPendingSubagentTodosHasInlineSubAgentRunningHasUnverifiedWritesLastTurnExecutedToolsLastTurnVerifyPassedRequiresVerificationCompletionBlockedReason规则固定为:
pending agent todo时不能 completed。pending subagent todo时不能 completed。RequiresVerification=false或LastTurnVerifyPassed=true时,才允许结束。RequiresVerification=true。2.4 进展判定设计
ProgressEvidence仅允许结构化证据:TASK_STATE_CHANGEDTODO_STATE_CHANGEDTODO_EXECUTOR_CHANGEDWRITE_APPLIEDVERIFY_PASSEDNEW_INFO_NON_DUPPHASE_ADVANCEDDISPATCH_COMPLETEDSUBAGENT_RESULT_APPLIED证据分级固定为:
TASK_STATE_CHANGEDTODO_STATE_CHANGEDVERIFY_PASSEDDISPATCH_COMPLETEDSUBAGENT_RESULT_APPLIEDTODO_EXECUTOR_CHANGEDWRITE_APPLIEDPHASE_ADVANCEDNEW_INFO_NON_DUPProgressScore至少包含:HasBusinessProgressHasExplorationProgressStrongEvidenceCountMediumEvidenceCountWeakEvidenceCountNoProgressStreakRepeatCycleStreakSameToolSignatureSameResultFingerprintSameSubgoalStalledProgressStateReminderKind规则固定为:
WRITE_APPLIED + VERIFY_PASSED闭环,才算HasBusinessProgress=true。NEW_INFO_NON_DUP或仅有PHASE_ADVANCED时,不算业务进展。HasExplorationProgress仅在Plan / Execute / Dispatch阶段有效,用于给合理探索留缓冲,不直接视为业务推进。NoProgressStreak只在无业务进展且 exploration 缓冲已耗尽时递增。RepeatCycleStreak只在以下条件同时成立时递增:SameToolSignature=trueSameResultFingerprint=trueSameSubgoal=sameHasBusinessProgress=falseSameSubgoal使用三态:same / different / unknown;unknown不推动 repeat。no-progress / repeat-cycle不直接 stop,只能推动stalled与 reminder。2.5 stalled 软纠偏设计
本阶段新增
StalledProgressState:healthystalled规则:
NoProgressStreak或RepeatCycleStreak首次达到阈值时,不直接终止 run。stalled,并注入一次固定的自修复提醒。Dispatch,说明为何仍需 subagent 或改回 agent 执行2.6 Dispatch / inline subagent 设计
本阶段将
spawn_subagent(mode=inline)正式纳入控制面,不再视为普通附属工具:Dispatch阶段的职责是识别executor=subagent的 todo、触发 inline subagent、接收结构化结果并回灌。todo.executor只允许agent / subagent两种合法输入语义。2.7 事件与观测设计
本阶段固定最小事件集:
phase_changedprogress_evaluatedstop_reason_decided其中
progress_evaluated必须显式带出:HasBusinessProgressHasExplorationProgressNoProgressStreakRepeatCycleStreakSameToolSignatureSameResultFingerprintSameSubgoalStalledProgressStateCurrentTodoExecutorHasPendingSubagentTodosHasInlineSubAgentRunning本阶段不重做全部 subagent 事件,但 runtime 主事件必须能表达 dispatch/subagent 对 completion 和 progress 的影响。
3) 一次性交付清单(What)
基于上述控制面设计,本阶段一次性交付以下内容:
RunStatePermissionGate -> CompletionGate -> ProgressGate -> StopReasonResolverCompletionStateProgressEvidenceProgressScorestalled软纠偏STOP_NO_PROGRESS / STOP_REPEAT_CYCLE从本阶段最终 stop reason 中移除todo.executor纳入 completion / progress 判定spawn_subagent(mode=inline)正式写入 Dispatch 语义phase_changed / progress_evaluated / stop_reason_decided4) 验收模型(DoD)
统一按三类验收:
Verify或返回PlanSameSubgoal=unknown时,不应推动 repeat-cyclestalled,不 hard stopNoProgressStreakphase_changed / progress_evaluated / stop_reason_decided事件字段在恢复已有会话后仍保持结构一致5) 非目标(明确边界)
RunLedger / ResumeCheckpoint。internal/instructions与internal/repository分层。no-progress / repeat-cycle重新做回硬 stop。