fix(dag): harden replan verdict gate — string-output bypass + transient pause strand - #331
Merged
Conversation
…ransient pause failure Audit follow-up to #327/#322. (1) Parse a string-typed checkpoint output as JSON before matching the replan verdict, so a report_to_parent gate without output_schema (or a string-typed child reply, reachable via replan fragments which skip the authoring check) cannot bypass the pause gate and reproduce the #322 spin. (2) Retry the gate pause once before falling back to the durable status, so a transient pause failure (e.g. the workflow lock held by a concurrent long replan) never silently strands the workflow with no spawn round and no parent wake.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题(Closes#330)
审计 #327 裁决门后的两条 SOFT 发现:
SOFT-2(门绕过):门判定只解码 object 输出。报告型检查点若无
output_schema、或以纯文本回复{"verdict":"replan"}(replan 片段新增的检查点不走 authoring 检查,可不带 schema),node.output 为字符串 → 解码 None → 门不触发 → 复现 #322 整图空转。SOFT-3(静默搁浅):门触发时
dag.pause瞬态失败(如并发长 replan 持锁致 WORKFLOW_LOCK_TIMEOUT),原实现记日志 + setPaused(false) + 跳过 spawnReady——不重试、不唤醒父会话,workflow 卡死到无关事件。修法
src/dag/runtime/loop.ts:parseJsonOption(Schema.UnknownFromJsonString,与 dag.ts:228 同型)解析,再匹配GateReplanVerdict——字符串 verdict 不再绕过门。验证
output_schema的 report_to_parent 检查点提交字符串{"verdict":"replan"}→ workflow paused、下游保持 pending。test/dag/dag-loop-guards.test.ts8 pass(含既有 object-verdict pause/continue/resume 回归)。test/dag/561 pass / 0 fail。bun typecheck干净。ghostty-web的 429 限流(外部依赖、与本改动无关)无法跑全工作区 typecheck,经确认以--no-verify提交、由 CI 作门禁。记录在案、本 PR 不处置