Repository navigation
fix(session): Stop の直後に送信なしで届いた pre_tool_use で新しいターンを開かない - #3441
Merged
Merged
Conversation
## 原因(実測) - 本番 logs/server.log.1(worktree commandmate-issue-3420, instance claude): 23:40:24.052Z user_prompt_submit → 23:41:32.759Z agent-event-stop-applied → 23:41:35.219Z ask-user-question-recorded + agent-event-received pre_tool_use (detail AskUserQuestion)。user_prompt_submit は無い。23:41:35.954Z の detection-divergence は scraper=ready(input_prompt) / structured=running (hook_pre_tool_use)。23:42:32.785Z notification(idle_prompt)(Stop の 60 秒後 =その間 composer は空いたまま)。以後 Stop は来ない。 - transcript 07a5ddd9-....jsonl: 23:41:32.216Z の最終 assistant text → 23:41:32.760Z Stop hook_success → stop_hook_summary(preventedContinuation false) → turn_duration で終わり、その後の記録は last-prompt / cost-state のみ。 AskUserQuestion の tool_use はセッション全体に 1 件も無く、subagents も無い。 同時刻の他プロジェクトの transcript(CommandAgent-develop / issue-3429 / MyCodeBranchDesk)にも AskUserQuestion は無い。 - よって、この pre_tool_use は Stop が閉じた会話の続きではない(Stop hook は継続を 止めておらず、画面にピッカーも出ていない)。Claude プロセス内の本会話以外の 経路(会話記録に残らない内部の後処理エージェント等と推定。hook の payload は ログに残っておらず、送り主までは特定できない)から来た。サーバーはこれを 「開いていないので開く」と読んで Stop の来ないターンを開いた。 - 全 4 ログで「Stop の後、送信なしで最初に来た pre/post_tool_use」を数えると 31 件。 claude は本件の 1 件だけ(2.5 秒後)。残り 30 件はすべて command-code (user_prompt_submit を持たず pre_tool_use でターンが始まるソース)。 ## 扱い(候補 a を絞って採用) - 送信を報告するソース(supportedEvents に user_prompt_submit を宣言)からの pre_tool_use は、直近のターンがエージェント自身の stop で閉じていれば新しい ターンを開かない(ターン・表示とも不変)。宣言は intake が source の capabilities から読み、AgentEventRecord.promptOpensTurns で渡す(ツール id は 見ない)。該当するのは実質 claude のみ(codex/gemini/copilot/opencode-v2 は pre_tool_use を出さない)。 - (b)(c) を採らない理由: (b) 開いたうえで閉じる条件を足すと、wait が採用する openedAt が先に動いてしまう。(c) 直前のターンに属させると閉じたターンが running に戻り、Stop が来ないので同じ問題になる。 - 壊さないもの: 通常のターン(送信→活動→Stop)は開いたターンを続けるので不変。 post_tool_use は従来どおり開く(Stop hook が block して続いた場合も、claude は AskUserQuestion の post_tool_use でターンを開く)。stale / scraper_evidence / resync_idle / session_end / generation の後は開く(サーバー側の推定で閉じた ターンの続きを潰さない)。Command Code の pre_tool_use 始まり・antigravity の 自己再開 post_tool_use(#2614)は user_prompt_submit を宣言しないので不変。 時間窓は使わない(送信を報告するソースのターンは必ず送信で始まるため)。 ## 対になる場所 - TURN_ACTIVITY_EVENTS(src/lib/session/provisional-turn.ts)と CLI の写し TURN_OPENING_EVENT_TYPES(src/cli/commands/wait.ts): 集合は変えないので両方 不変。status-contract-1926 の一致はそのまま。 - src/lib/agent-health/hook-observation.ts の TURN_ACTIVITY_EVENTS の写し: 集合 不変のため変更不要(範囲外)。 - CLI wait(adoptTurnStart): turn record の openedAt を読むので、ターンが開かな ければ閉じたターンのまま turnSettled になる。変更不要。 - 古い動き(Stop の後の pre_tool_use で開く)を claude で固定したテスト: 探した (tests/unit/session/turn-model.test.ts, agent-event-turn-join-3330, lib/session/agent-event-turn-3375, api/hooks-agent-event)が無かった。 command-code の pre_tool_use で開くテストはそのまま通る。 - docs の ja/en: 該当記述なし。 ## 本文に無い指摘 - src/lib/hooks/agent-event-intake.ts:390 recordQuestionIfAsked は同じ pre_tool_use の質問を記録する(ask-user-question-recorded)。本件のような 会話外の AskUserQuestion でも質問レコードが残る。ターンとは別の状態なので 今回は変えていない。 - hook の payload(session_id / agent_id 等)を intake がログに残さないため、 本件の送り主を後から特定できない。 ## 検証 - npx vitest run tests/unit/lib/session/agent-event-turn-after-stop-3437.test.ts: 11 passed。判定行を外すと陽性 2 件が落ちることを確認(変異注入)。 - 関連(tests/unit/lib/session, tests/unit/session, tests/unit/hooks, tests/unit/lib/hooks, tests/unit/cli/commands, api/hooks-agent-event 等): 421 files / 6491 tests passed。 - npm run lint / npx tsc --noEmit: exit 0。 - ~/.commandmate / ~/.local/state の ls -la を前後で比較: エントリの増減なし ($HOME と ~/.local/state/commandagent の mtime のみ変化。別プロセス由来)。 ~/.commandmate/service.json は前後とも無い。tmux・サーバーは起動していない。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sional-turn-after-stop
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4 tasks
This was referenced Oct 8, 2026
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.
Summary
サーバーは
TURN_ACTIVITY_EVENTS(user_prompt_submit/pre_tool_use/post_tool_use)でターンを開く。2026-10-07T23:41Z、Claude の Stop の 2.5 秒後に送信の無いpre_tool_use(AskUserQuestion)が届き、サーバーが新しいターンを開いたまま Stop が来なかった。waitはこのターンを 3 時間待った(wait側は #3432 で上限を付けた)。この PR はサーバー側の根を直す。原因(実測):
logs/server.log.1: 23:41:32.759Z Stop → 23:41:35.219Zpre_tool_use(AskUserQuestion)。user_prompt_submitは無い。以後 Stop は来ないAskUserQuestionのtool_useが 1 件も無く、subagents も無い。Stop hook は継続を止めていない。このpre_tool_useは、Stop で閉じた会話の続きではなく、会話記録に残らない経路から来た(送り主は hook の payload がログに残っておらず特定できない)user_prompt_submitを持たずpre_tool_useでターンが始まるソース)変更: 送信を報告するソース(
supportedEventsにuser_prompt_submitを宣言。実質 Claude)からのpre_tool_useは、直近のターンがエージェント自身のstopで閉じていれば新しいターンを開かない。ツール id ではなく、intake が source の capabilities から読んだ宣言(AgentEventRecord.promptOpensTurns)で判定する。post_tool_useで開くターン、stale/scraper_evidenceなどサーバー側の推定で閉じた後の続き、Command Code のpre_tool_use始まり、Antigravity の自己再開(fix(cli): エージェントが自分を後で起こす形でターンを閉じる(agy の schedule 等)と、wait が作業途中で完了を返す #2614)。TURN_ACTIVITY_EVENTSと CLI の写しの集合は変えていない(status-contract-1926 の一致はそのまま)Refs #3437(develop 向けのため Closes は使わない)
範囲外(この PR では扱わない)
src/lib/hooks/agent-event-intake.ts:390のrecordQuestionIfAskedは、会話外のAskUserQuestionでも質問の記録を残すsession_id/agent_id等)を intake がログに残さないため、本件の送り主を後から特定できない(追跡 Issue にするかは run の完了報告で判断する)
Test plan
commandmatedev verify --task: work-evidence / scope / env-clean / lint / typecheck / unit(テスト全体)すべて PASS(exit 0)tests/unit/lib/session/agent-event-turn-after-stop-3437.test.ts(11 件。判定行を外すと陽性 2 件が落ちることを確認)npx tsc --noEmit、tests/unit/lib/session・tests/unit/session・guards・docs が合格。既存のit/describeの削除 0 件🤖 Generated with Claude Code