claude-spotter 0.13.0 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.13.1
4
+
5
+ **Haiku timeout 30s → 45s 緩和 + hook 側 IPC timeout を整合**。v0.13.0 以前の実セッション ([daemon-80b5c0af.log](../../.spotter/logs/daemon-80b5c0af-700f-47af-a3ac-796144823a7d.log) line 15) で `E_HAIKU_TIMEOUT: haiku did not respond within 30000ms` を観測。同ログ line 20 でも `mode=first, duration_ms=20948` と 30s の 70% 域まで達しており、timeout が実測レイテンシに対して狭すぎた。合わせて [src/hooks/stop.mjs](src/hooks/stop.mjs) の IPC timeout が元々 15s で Haiku 側 30s と整合していなかった既存バグ (turn_end で Haiku が 16s 超かかると hook 側が先に諦めていた) も同時解消。
6
+
7
+ ### 調査で判明した Haiku 4.5 の高速化ダイヤル不在
8
+
9
+ 公式 docs 確認 (2026-04-20):
10
+
11
+ - `--effort` フラグは Opus 4.7 / Opus 4.6 / Sonnet 4.6 のみ対応、**Haiku 4.5 は effort 非対応** ([model-config docs](https://code.claude.com/docs/en/model-config#adjust-effort-level))
12
+ - Haiku 4.5 は **extended thinking 対応だが adaptive thinking 非対応** ([models/overview](https://platform.claude.com/docs/en/docs/about-claude/models/overview) 比較表)
13
+ - `claude -p` CLI に thinking 直接フラグ無し、API デフォルトで thinking は OFF
14
+ - つまり Haiku 側で「速くする手段」は存在せず、timeout 緩和しか打ち手が無い (Sonnet 4.6 切替は遅くなる + 3 倍コストで逆効果)
15
+
16
+ ### 変更点
17
+
18
+ - **編集 [src/daemon/daemon.mjs](src/daemon/daemon.mjs)**: `DEFAULT_HAIKU_TIMEOUT_MS` を 30_000 → 45_000。first-call cold-start + 観測されたレイテンシスパイク (20.9s) + margin を包含
19
+ - **編集 [src/hooks/user-prompt.mjs](src/hooks/user-prompt.mjs)**: `TIMEOUT_MS` を 30_000 → 50_000 (Haiku 45s + IPC margin 5s)
20
+ - **編集 [src/hooks/stop.mjs](src/hooks/stop.mjs)**: `TIMEOUT_MS` を 15_000 → 50_000 (既存の整合性バグも解消)
21
+
22
+ ### 残課題
23
+
24
+ Haiku 突然死 (shutdown ログなしで daemon 再起動する事象、v0.12.0 auto-resurrect で救われているが見えない欠落ターンが発生する) は未対処。[docs/open-issues.md](docs/open-issues.md) P0 に残置。
25
+
3
26
  ## 0.13.0
4
27
 
5
28
  **Stop 判定軸を「要請充足チェック」から「ツール適用機会の監査」に転換**。v0.12.x 以前の `stage=turn_end` は `<user_input>` + `<used_tools>` + `<final_response>` を Haiku に渡し、「ユーザー要請されたツールが使われたか」を判定していた。この軸では Bell が Stop 到達後にすべき動作 — 事実断定の裏付け / 新知見の記録 / 既知情報の照会 — を拾えない。実セッションで Haiku が応答「判明: A モジュールは B に依存」に対し `caveat_record` を推奨する、といった本来期待される指摘が構造的に出ない状態だった (ユーザーが [この議論](https://github.com/kitepon-rgb/Spotter) で指摘)。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-spotter",
3
- "version": "0.13.0",
3
+ "version": "0.13.1",
4
4
  "description": "Audit agent running alongside Claude Code that catches missed tool calls — 気づく役と実行する役の分離",
5
5
  "type": "module",
6
6
  "bin": {
@@ -47,10 +47,11 @@ import { join } from 'node:path';
47
47
  import { writeFile, unlink } from 'node:fs/promises';
48
48
  const DEFAULT_HAIKU_CALL_WINDOW_MS = 10_000;
49
49
  // v0.5.0: lowered 60s → 30s. Session-scoped (--resume) means the first call still pays
50
- // cold-start but subsequent calls skip it. 30s covers the first-call cold path without
51
- // being excessive, and a role-collapse recovery cycle (reset → next call is effectively
52
- // a cold start again) stays within budget.
53
- const DEFAULT_HAIKU_TIMEOUT_MS = 30_000;
50
+ // cold-start but subsequent calls skip it. 45s covers first-call cold path plus the
51
+ // observed Haiku CLI latency spikes (2026-04-20 log shows 20.9s resumed calls and 30s
52
+ // timeouts in the wild). Role-collapse recovery (reset → next call is effectively a
53
+ // cold start again) stays within budget.
54
+ const DEFAULT_HAIKU_TIMEOUT_MS = 45_000;
54
55
  // v0.12.0: heartbeat-based orphan cleanup. Every envelope resets a setTimeout; if no
55
56
  // hook event arrives within this window, the daemon self-shuts. 30 min is the longest
56
57
  // silence we expect from a live Claude Code session. UserPromptSubmit auto-resurrects
@@ -15,7 +15,7 @@ import {
15
15
  import { getLastAssistantText } from './transcript-reader.mjs';
16
16
  import { sendRequest } from '../daemon/transport.mjs';
17
17
 
18
- const TIMEOUT_MS = 15_000;
18
+ const TIMEOUT_MS = 50_000;
19
19
 
20
20
  export async function runStop() {
21
21
  if (isChildCall()) return;
@@ -21,7 +21,7 @@ import {
21
21
  import { sendRequest, TransportError } from '../daemon/transport.mjs';
22
22
  import { spawnDaemonAndWaitReady } from './spawn-daemon.mjs';
23
23
 
24
- const TIMEOUT_MS = 30_000;
24
+ const TIMEOUT_MS = 50_000;
25
25
  const SHORT_PROMPT_MAX_CHARS = 10;
26
26
 
27
27
  export async function runUserPrompt() {