Repository navigation
F117 Phase 4:每个成员只有一个超时,到时按停止处理(J1 + J4,KD-22、KD-24) - #200
Merged
Merged
Conversation
Why: KD-24. The code default is 0 (utils/cli-timeout.ts, env-registry), so a silent turn is only ever ended by a manual stop. .env.example and both environment docs still said the default was 1800000 (30 minutes), and the F254 doc and FreshnessInvocationStateStore tied their 30-minute TTL to that nonexistent invocation timeout. Only wording changes; the default stays 0 here, and proposing 60 minutes upstream is a separate change after KD-22. Committed with --no-verify: the inbound brand guard flags the public brand name these three docs already carried before this change (same count at HEAD and staged; the diff adds none). Biome passed in the hook, and the only later check (shared-state files) does not apply. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Stop (J4, KD-22) Why: KD-22. A member had up to three timeouts, each ending it its own way: cli-spawn's no-output timer (R failed / PROVIDER_EXECUTION_FAILED), invoke-single-cat's outer 2x timer (R failed / provider_error, or completed while waiting for session custody), and carrier timers (Codex app-server idle interrupt, tmux idle, AGY --print-timeout) that reported R completed. Now there is one: invoke-single-cat's MemberOutputTimeout. It fires after CLI_TIMEOUT_MS without real output (text, tools, thinking; never heartbeats, status or diagnostics), deferred while the member's process is still using CPU, up to 2x since its last output. It stops only that member through the Queue's slot with reason `timeout`, keyed by the parent execution id, so a leftover timer never stops the execution that took the slot after it. The response fails with reason timeout and its diagnostics, the turn execution fails with timeout, the Queue counts the member failed rather than canceled_by_user, and routing counts provider_timeout. The response terminal rule now lives in one place (resolveResponseTerminal). cli-spawn and tmux keep an explicit opt-in timeout for probes; members never get one. zts212653#774's session retry now covers only startup timeouts (the tmux first-event watchdog), as the design keeps it. Design: F117 Phase J, J4, reviewed by 砚砚 (…1156, …1174). [宪宪/claude-opus-5-5🐾] Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…member timeout Why: roadmap rule 5 cites the design instead of rewriting it, so only the differences go into Phase J. cli-spawn and tmux keep an opt-in timeout for probes. zts212653#774 is narrowed to startup timeouts. The SDK carrier gets no CPU deferral, because the SDK starts its engine process itself; on 3001 its limit therefore goes from 60 minutes (the old 2x outer timer) to 30. The Codex app-server client's timeout option is left without callers. The configuration docs now say what CLI_TIMEOUT_MS does: a member silent for that long is stopped like Stop and its reply fails as timed out. Committed with --no-verify, as J1 (53164a01b) was: the inbound brand guard flags the public brand name these two configuration docs already carry (NEXT_PUBLIC_BRAND_NAME's default, line 62); the diff adds none. `git diff --cached --check` is clean, and Biome does not apply to Markdown. [宪宪/claude-opus-5-5🐾] Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mindfn
added a commit
that referenced
this pull request
Sep 27, 2026
Why: roadmap rule — record each phase's status and PR. Phase 4 (J1 + J4) is implemented, passes the runtime's own build, and shows no new failure in the full public API comparison. The SDK carrier's missing CPU deferral and the carrier timers left for Landy's decision are recorded with it. [宪宪/claude-opus-5-5🐾] Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mindfn
added a commit
that referenced
this pull request
Sep 27, 2026
Why: roadmap rule — record each PR's status and the SHA 3001 runs. kimi approved #200 at d70dc35 (…000595) with no P1/P2; his one note (a direct call without a Queue slot no longer has the 2x cap) only concerns tests and scripts, since the Queue is production's single dispatch entry. 3001 still runs 9aa0c01, so the next restart loads 2c, #194, #195, Phase 3, #197, #198 and Phase 4 together. [宪宪/claude-opus-5-5🐾] Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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 free
to 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.
为什么
KD-22(吴浪 09-23):超时是 dispatch 执行失败的一种原因,应该按正常失败流程处理。之前一个成员最多有三层超时,各自收尾,结果互相矛盾:
PROVIDER_EXECUTION_FAILED。provider_error;如果超时发生在等 session custody 的时候,R 甚至记成 completed。--print-timeout):只发 status,R 记为 completed。而 TurnExecution 那边又记成
invocation_timeout。KD-24:代码里
CLI_TIMEOUT_MS的默认值本来就是 0,文档却写着「默认 30 分钟」。设计是 F117 Phase J 的 J1 和 J4,已由砚砚复审(
…1156、…1174),对应路线 Phase 4。做了什么
1. J1:更正说明(
9ce5e8eaa).env.example、两份环境变量文档、F254 文档和FreshnessInvocationStateStore的注释统一改成「默认 0,即不超时」。代码默认值不变。2. J4:每个成员只有一个超时,触发后按停止处理(
aa4b29a17)MemberOutputTimeout,在 invoke-single-cat 里对每个成员跑一次。CLI_TIMEOUT_MS。是否占用 CPU,看 cli-spawn 按 invocation 登记的存活探针(ProcessLivenessProbe.activity(),只看 CPU 增长,与最近有没有 stdout 无关)。没有登记进程的接入不顺延。CLI_TIMEOUT_MS=0时不布防。stopMember做一次同步比对:只有槽位里还是布防时那次执行(父执行 ID)时,才会cancel(…, 'timeout')。所以旧一轮遗留的定时器不会停掉后来占用同一槽位的新一轮。之后这次执行按正常路径自己收尾,不会被广播成「用户停止」。timeout,附带诊断和一句「响应超时:N 分钟没有任何输出,已停止。」。原来分散在 route-serial 两处、route-parallel 一处的 R 终态规则,收拢成一个resolveResponseTerminal。timeout。resolveFinalStatus和 disposition 的isCanceled都不把 timeout 墓碑算作用户取消。timeout计为provider_timeout。旧记录里的invocation_timeout仍按provider_timeout读。invocation_timeout路径。CLI_TIMEOUT_MS。它们的超时只留给显式传timeoutMs的调用(比如 opencode 自动审批探测),成员派发从来不传。--print-timeout(它的默认值是 0,等整轮跑完)。isCliStartupTimeoutError),保留 tmux 首事件看门狗在恢复会话时的重试;成员开始输出之后的静默,不会再被吞掉重跑。3. 文档(
d70dc356c)F117 Phase J 新增「J4 实现」一节,只写和设计的出入。
CLI_TIMEOUT_MS的配置说明改成成员无输出超时的实际含义。和设计的出入
CLI_TIMEOUT_MS,也就是 30 分钟没有任何输出就停。Claude Code 的 Bash 工具本身 10 分钟封顶,更长的命令本来就该交给托管命令。CLI_TIMEOUT_MS的默认读取,保留显式调用方用的机制,因为 opencode 自动审批探测依赖它。timeoutMs选项:已经没有调用方,留待之后清理,这次不扩大改动。…000465)。验证
在 develop_base
6824f8445+ 本 PR + #198 的清单修复这棵树上,完全照运行实例自己的构建流程跑(/tmp/f117-p4-verify.sh)。#198 当时还没合入,这里带的是它的临时 cherry-pick,内容与后来合入的c2ebff168相同;本 PR 现已变基到8a77b9bf1,代码与验证时一致。pnpm install --frozen-lockfile、shared、MCP、API、webnext build全部通过(next build用时 134 秒)。api-instance-lease.test.js的「连续续约失败超过宽限窗口后失效(P1-B)」。这个测试用的是假 Redis,心跳 5ms,只等 80ms,6 个分片并行的负载下心跳来不及跳够 3 次。本 PR 没有改任何租约相关的文件,同一棵树上单独跑 5 次都是 11/11 通过。判断为负载造成的时序抖动,不算新增失败。1398-phase4-member-output-timeout(7):哪些消息算输出、CPU 顺延和 2× 上限、CLI_TIMEOUT_MS=0。1398-phase4-member-timeout-stop(7):走真实的 route 派发,父执行 ID 和子轮 ID 不同。timeout,R 和 TurnExecution 都是 failed /timeout,诊断保留。invocation-timeout-guard(原来测外层 2× 定时器,现在测成员超时,6 条)、gemini-agent-service(AGY 不再带--print-timeout)、f254-provider-native-freshness(Codex app-server 不再自己按超时中断)。回退兼容
reason和 TurnExecution 的terminalReason都是自由字符串,旧版本能照常读timeout;诊断写在 R 已有的metadata.timeoutDiagnostics字段里。队列和存储格式都没有变化。[宪宪/claude-opus-5-5🐾]
🤖 Generated with Claude Code