Skip to content

feat(dag): node timeout escalation — signal, adjudication, cap backstop - #178

Merged
LeXwDeX merged 3 commits into
devfrom
feat/dag-timeout-escalation
Aug 7, 2026
Merged

feat(dag): node timeout escalation — signal, adjudication, cap backstop#178
LeXwDeX merged 3 commits into
devfrom
feat/dag-timeout-escalation

Conversation

@LeXwDeX

@LeXwDeX LeXwDeX commented Aug 6, 2026

Copy link
Copy Markdown
Owner

批次内容

DAG 节点超时升级引擎(经 5 轮双轴深度 review,阻断项全部闭合)。

超时信号

  • 节点超时不杀子会话,子会话继续执行、上报升级
  • 持久化 NodeTimeoutEscalated 事件与 timeout_extensions 计数,wake 主 agent 裁决
  • report_to_parent=false 的升级节点同样送达(F11:升级 wake 是 cap 的唯一力量)

延长路径

  • replan 携带新 worker_config.timeout_ms → 重算绝对 deadline(自裁决时刻)
  • §3.7 变更门控 + F2:fragment 省略 timeout_ms 不隐式缩短既有延长
  • A1 cap gate:仅当 deadline 已过期或存在待裁决 escalation 才允许 re-time,防循环改值绕过上限

上限兜底

  • timeout_extensions 达上限 → 强制 cancel + nodeFailed("timeout")
  • 计数 per-attempt 累计(NodeStarted/NodeRestarted 清零),配合 maxNodeReplanAttempts 构成全生命周期上界;上界为 COUNT-based(默认 10min 下单次尝试 ≈3.5h,全生命周期 ≈21h)

失败安全(review 验证过的不变量)

  • N1:extend 写入前置——写失败/dead/block 时旧 watcher 继续监督,节点不会失去 watcher
  • D1:per-node catchCause——单节点 extend 失败不中断 sweep/spawnReady/checkCompletion,restarted 节点不再被晾在 pending
  • written 行数可观测:guard 拒绝 = 0 行 → 不装 watcher 并记 warning

崩溃恢复:orphaned pending/adoption 恢复(Effect.ensuring 保证槽位释放);deadline watcher 自续轮询(S1/F5/F8)

Schema/透出escalation_pending 列 + 两个独立 migration(按 id 至多执行一次);summary/TUI/httpapi 透出 escalatedNodes(F10 指示);SDK types.gen.ts 已再生成

测试

  • packages/opencode: bun test test/dag/ 359 pass(含 N1/D1/A1/F1B 失败路径与 cap 回归;N1/D1 回归测试均经过「临时撤掉修复 → 测试失败」的可信验证)
  • packages/core: 1163 测,仅 2 个既有环境失败(Watcher/.git、ProjectCopy worktree),与本批无关
  • pre-commit 全量 turbo typecheck clean

chore 说明

oxlint warning ratchet 4734 → 4831:其中 4826 为本批 DAG 提交态实测(新增测试沿用既有 as never 惯例产生的 no-unsafe-type-assertion 警告,既有 committed DAG 测试同样大量存在),另 5 为工作树内同批未入本 PR 的非 DAG 改动贡献。

不在本 PR(留在工作树,后续 PR)

  • goal/loop.ts 暂停/恢复流程(已决定拆出)
  • session/llm/config/event 批次(publishMany、agent timeout、fork-batch、wellknown-offline 等)

已知遗留(不阻断,review 记录在案)

  • D2/D3 + escalation_pending 终态不清理:同一状态机问题,建议后续 change 整体处理
  • S5(workflow 锁无超时)/ S7(recovery INVENTED 推断)/ O1(remote config 降级缓存)/ P8(spawnReady 复杂度)

LeXwDeX and others added 3 commits August 4, 2026 12:30
…fig-repo templates (#173)

dev → main 正式版。全部 PR checks pass(第二次 run);第一次 dev-push run 的 HttpAPI effect 模式 CI 超时(偶发,非代码问题)。
fix: dev → main — 快速双击 ESC 可靠中断 + DAG extend 跨 condition-skipped 依赖 reopen
- 超时信号:节点超时不杀子会话;持久化 NodeTimeoutEscalated 与 timeout_extensions,wake 主 agent 裁决(report_to_parent=false 的升级节点同样送达,F11)
- 延长路径:replan 携带新 worker_config.timeout_ms → 重算绝对 deadline;§3.7 变更门控 + A1 cap gate(deadline 已过期或 escalation_pending 才放行,防循环改值绕过上限);F2 省略 timeout_ms 不隐式缩短既有延长
- 上限兜底:timeout_extensions 达上限 → 强制 cancel + nodeFailed(timeout);计数 per-attempt 累计(NodeStarted/Restarted 清零),配合 maxNodeReplanAttempts 构成全生命周期上界(§6:COUNT-based,默认 10min 下单次尝试 ≈3.5h)
- 失败安全:N1 extend 写入前置(写失败/dead/block 保留旧 watcher,监督不缺席);D1 per-node catchCause(单点 extend 失败不中断 sweep/spawnReady/checkCompletion);written 行数可观测(guard 拒绝 = 0 行)
- 崩溃恢复:orphaned pending/adoption 恢复(Effect.ensuring 释放槽位);deadline watcher 自续轮询(S1/F5/F8)
- escalation_pending 列 + 两个独立 migration(按 id 至多执行一次);summary/TUI/httpapi 透出 escalatedNodes(F10 指示)
- 测试:test/dag 359 pass(含 N1/D1/A1/F1B 失败路径与 cap 回归)
- chore: oxlint warning ratchet 4734 → 4831;其中 4826 为本批 DAG 提交态实测(新增测试沿用既有 as-never 惯例的 no-unsafe-type-assertion),另 5 为工作树内同批未入本 PR 的非 DAG 改动贡献
@LeXwDeX
LeXwDeX merged commit 0226006 into dev Aug 7, 2026
5 checks passed
@LeXwDeX
LeXwDeX deleted the feat/dag-timeout-escalation branch August 7, 2026 02:37
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.

1 participant