throughline 0.3.24 → 0.4.0

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.
Files changed (116) hide show
  1. package/.claude/commands/tl.md +6 -21
  2. package/.codex-sidecar.yml +62 -0
  3. package/CHANGELOG.md +632 -0
  4. package/README.ja.md +71 -46
  5. package/README.md +420 -76
  6. package/bin/throughline.mjs +169 -7
  7. package/codex/skills/throughline/SKILL.md +157 -0
  8. package/codex/skills/throughline/agents/openai.yaml +7 -0
  9. package/docs/INHERITANCE_ON_CLEAR_ONLY.md +159 -0
  10. package/docs/L1_L2_L3_REDESIGN.md +415 -0
  11. package/docs/PUBLIC_RELEASE_PLAN.md +185 -0
  12. package/docs/THROUGHLINE_CLEAR_AUTO_HANDOFF_PLAN.md +286 -0
  13. package/docs/THROUGHLINE_CODEX_DUAL_SUPPORT.md +249 -0
  14. package/docs/THROUGHLINE_CODEX_FIRST_ROADMAP.md +555 -0
  15. package/docs/THROUGHLINE_CODEX_MONITOR_IMPLEMENTATION_PLAN.md +220 -0
  16. package/docs/THROUGHLINE_CODEX_TRIM_IMPLEMENTATION_PLAN.md +528 -0
  17. package/docs/THROUGHLINE_CODEX_TRIM_ROLLBACK_FIX_PLAN.md +672 -0
  18. package/docs/archive/CONCEPT.md +476 -0
  19. package/docs/archive/EXPERIMENT.md +371 -0
  20. package/docs/archive/README.md +22 -0
  21. package/docs/archive/SESSION_LINKING_DESIGN.md +231 -0
  22. package/docs/archive/THROUGHLINE_NEXT_STEPS.md +134 -0
  23. package/docs/throughline-codex-trim-rollback-incident-report.md +306 -0
  24. package/docs/throughline-handoff-context.example.json +57 -0
  25. package/docs/throughline-rollback-context-trim-insight.md +455 -0
  26. package/package.json +6 -2
  27. package/src/baton.mjs +17 -45
  28. package/src/baton.test.mjs +4 -41
  29. package/src/cli/codex-capture.mjs +95 -0
  30. package/src/cli/codex-handoff-model-smoke.mjs +292 -0
  31. package/src/cli/codex-handoff-model-smoke.test.mjs +262 -0
  32. package/src/cli/codex-handoff-smoke.mjs +163 -0
  33. package/src/cli/codex-handoff-smoke.test.mjs +149 -0
  34. package/src/cli/codex-handoff-start.mjs +291 -0
  35. package/src/cli/codex-handoff-start.test.mjs +194 -0
  36. package/src/cli/codex-hook.mjs +276 -0
  37. package/src/cli/codex-hook.test.mjs +293 -0
  38. package/src/cli/codex-host-primitive-audit.mjs +110 -0
  39. package/src/cli/codex-host-primitive-audit.test.mjs +75 -0
  40. package/src/cli/codex-restore-smoke.mjs +357 -0
  41. package/src/cli/codex-restore-source-audit.mjs +304 -0
  42. package/src/cli/codex-resume.mjs +138 -0
  43. package/src/cli/codex-rollback-model-visible-smoke.mjs +373 -0
  44. package/src/cli/codex-rollback-model-visible-smoke.test.mjs +255 -0
  45. package/src/cli/codex-sidecar-diagnostics.mjs +48 -0
  46. package/src/cli/codex-sidecar-dry-run.mjs +85 -0
  47. package/src/cli/codex-summarize.mjs +224 -0
  48. package/src/cli/codex-threads.mjs +89 -0
  49. package/src/cli/codex-visibility-smoke.mjs +196 -0
  50. package/src/cli/codex-vscode-restore-smoke.mjs +226 -0
  51. package/src/cli/codex-vscode-rollback-smoke.mjs +114 -0
  52. package/src/cli/doctor.mjs +503 -1
  53. package/src/cli/doctor.test.mjs +542 -3
  54. package/src/cli/handoff-preview.mjs +78 -0
  55. package/src/cli/help.test.mjs +64 -0
  56. package/src/cli/install.mjs +226 -3
  57. package/src/cli/install.test.mjs +205 -4
  58. package/src/cli/trim.mjs +564 -0
  59. package/src/codex-app-server.mjs +1816 -0
  60. package/src/codex-app-server.test.mjs +512 -0
  61. package/src/codex-auto-refresh.mjs +194 -0
  62. package/src/codex-auto-refresh.test.mjs +182 -0
  63. package/src/codex-capture.mjs +235 -0
  64. package/src/codex-capture.test.mjs +393 -0
  65. package/src/codex-handoff-model-smoke.mjs +114 -0
  66. package/src/codex-handoff-model-smoke.test.mjs +89 -0
  67. package/src/codex-handoff-smoke.mjs +124 -0
  68. package/src/codex-handoff-smoke.test.mjs +103 -0
  69. package/src/codex-handoff.mjs +331 -0
  70. package/src/codex-handoff.test.mjs +220 -0
  71. package/src/codex-host-primitive-audit.mjs +374 -0
  72. package/src/codex-host-primitive-audit.test.mjs +208 -0
  73. package/src/codex-restore-smoke.test.mjs +639 -0
  74. package/src/codex-restore-source-audit.mjs +1348 -0
  75. package/src/codex-restore-source-audit.test.mjs +623 -0
  76. package/src/codex-resume.test.mjs +242 -0
  77. package/src/codex-rollout-memory.mjs +711 -0
  78. package/src/codex-rollout-memory.test.mjs +610 -0
  79. package/src/codex-sidecar-cli.test.mjs +75 -0
  80. package/src/codex-sidecar.mjs +246 -0
  81. package/src/codex-sidecar.test.mjs +172 -0
  82. package/src/codex-summarize.test.mjs +143 -0
  83. package/src/codex-thread-identity.mjs +23 -0
  84. package/src/codex-thread-index.mjs +173 -0
  85. package/src/codex-thread-index.test.mjs +164 -0
  86. package/src/codex-usage.mjs +110 -0
  87. package/src/codex-usage.test.mjs +140 -0
  88. package/src/codex-visibility-smoke.test.mjs +222 -0
  89. package/src/codex-vscode-restore-smoke.mjs +206 -0
  90. package/src/codex-vscode-restore-smoke.test.mjs +325 -0
  91. package/src/codex-vscode-rollback-smoke.mjs +90 -0
  92. package/src/codex-vscode-rollback-smoke.test.mjs +290 -0
  93. package/src/db-schema.test.mjs +96 -0
  94. package/src/db.mjs +14 -1
  95. package/src/haiku-summarizer.mjs +267 -26
  96. package/src/haiku-summarizer.test.mjs +282 -0
  97. package/src/handoff-preview.test.mjs +108 -0
  98. package/src/handoff-record.mjs +294 -0
  99. package/src/handoff-record.test.mjs +226 -0
  100. package/src/hook-entrypoints.test.mjs +286 -0
  101. package/src/package-files.test.mjs +19 -0
  102. package/src/prompt-submit.mjs +9 -6
  103. package/src/resume-context.mjs +58 -171
  104. package/src/resume-context.test.mjs +177 -0
  105. package/src/session-start.mjs +85 -26
  106. package/src/state-file.mjs +50 -6
  107. package/src/state-file.test.mjs +50 -0
  108. package/src/token-monitor.mjs +14 -10
  109. package/src/token-monitor.test.mjs +27 -0
  110. package/src/trim-cli.test.mjs +1584 -0
  111. package/src/trim-model.mjs +584 -0
  112. package/src/trim-model.test.mjs +568 -0
  113. package/src/turn-processor.mjs +17 -10
  114. package/src/vscode-task.mjs +33 -10
  115. package/src/vscode-task.test.mjs +19 -9
  116. package/src/cli/save-inflight.mjs +0 -81
@@ -0,0 +1,286 @@
1
+ # Throughline `/clear` 自動引継ぎ計画 (TODO 兼)
2
+
3
+ `/clear` をトリガーにした **自動かつ軽量な引継ぎ** を実現する計画。
4
+ 2026-05-08 セッションの議論と実機検証、外部仕様調査に基づく。
5
+ A 案 (= /clear で自動引継ぎ + /tl は逃げ道として残す + /tl-trim 廃止) **採択確定**。
6
+
7
+ > 過去の経緯 (なぜ `/tl` バトンを採用したか) は [INHERITANCE_ON_CLEAR_ONLY.md](INHERITANCE_ON_CLEAR_ONLY.md) を参照。
8
+ > 本書は **2026-05-08 時点の現状検証 + 新理想設計** を扱う。
9
+
10
+ ---
11
+
12
+ ## 1. 確定した事実 (実機検証済み)
13
+
14
+ ### 1.1 `/clear` 後の SessionStart `source` は 2.1.128 で reliable
15
+
16
+ ```
17
+ inheritance-decision.log (2026-05-08 12:26 検証)
18
+ 12:26:08.481Z source="startup" session=05735717 ← 新 chat 開始
19
+ 12:26:52.257Z source="clear" session=b2addc4a ← /clear 後
20
+ ```
21
+
22
+ - Claude Code `2.1.128` (VSCode native extension, Linux/WSL2) で `/clear` 後の SessionStart は **確実に `source='clear'`** を payload に乗せる
23
+ - 過去の [GitHub issue #49937](https://github.com/anthropics/claude-code/issues/49937) (= VSCode 拡張で /clear 後も `source='startup'` になっていたバグ) は **解決済み**
24
+ - v2.1.105 (VSCode `/clear` not clearing conversation context fix) と v2.1.126 (Windows SessionStart hook env files apply) のリリースで段階的に修正された
25
+
26
+ ### 1.2 SessionStart `source` の 4 値 (公式 docs)
27
+
28
+ | 値 | 意味 |
29
+ |---|---|
30
+ | `startup` | 新 chat / VSCode 再起動 / 別 project / cold start |
31
+ | `resume` | `--resume` / `--continue` / `/resume` |
32
+ | `clear` | `/clear` 直後 |
33
+ | `compact` | 自動 / 手動 compaction 直後 |
34
+
35
+ source: [code.claude.com/docs/en/hooks](https://code.claude.com/docs/en/hooks)
36
+
37
+ ### 1.3 `/clear` 等価の user-defined slash command は **作れない**
38
+
39
+ 調査結果 (claude-code-guide Agent + bundled `claude-code` 検査):
40
+
41
+ - `.claude/commands/*.md` (skill markdown) は **prompt 拡張**であり、built-in `/clear` を programmatic に invoke できない
42
+ - "subcommand" や "exec built-in" 構文は無い
43
+ - `/clear` には built-in alias が存在しない
44
+ - CLI flag `claude clear` も無い
45
+ - cross-platform で「新ウィンドウ起動」する built-in も無い (`/branch` は full history copy で軽量化と矛盾、VSCode URL scheme は VSCode 専用)
46
+
47
+ → **「引継ぎたい /clear」と「reset したい /clear」を `source` 値で区別する手段は無い**
48
+
49
+ ### 1.4 `/rewind` は fork 動作 (caveat 記録済み)
50
+
51
+ - `/rewind` Continue 確認画面に "A new forked conversation will be created after rewinding" と明示
52
+ - 同 thread 内 rollback ではなく、新 fork session id を生成
53
+ - 詳細は caveat `claude-code/claude-code-rewind-fork-conversation-rollback-primitive` を参照
54
+ - 本計画では `/rewind` は **対象外**
55
+
56
+ ---
57
+
58
+ ## 2. 採用する理想設計
59
+
60
+ ### 2.1 引継ぎ発火条件 (2 経路)
61
+
62
+ | 経路 | 条件 | 起動 |
63
+ |---|---|---|
64
+ | **auto path** | `source='clear'` かつ env `THROUGHLINE_DISABLE_AUTO_HANDOFF` の値が `'1'` でない | 自動引継ぎ |
65
+ | **baton path** | `handoff_batons` テーブルに TTL (1 時間) 内 baton あり (= ユーザーが `/tl` を打った) | `source` 値関係なく引継ぎ |
66
+
67
+ 判定ロジック (擬似コード):
68
+
69
+ ```
70
+ on SessionStart(source, session_id, project_path):
71
+ baton = consumeBaton(project_path) // atomic SELECT + DELETE, TTL 超過は sessionId=null で返る
72
+ if baton.sessionId:
73
+ inject(curated_memory) // baton path
74
+ return
75
+ if source == 'clear' and env.THROUGHLINE_DISABLE_AUTO_HANDOFF != '1':
76
+ inject(curated_memory) // auto path
77
+ return
78
+ // 何もしない
79
+ ```
80
+
81
+ `consumeBaton` が先発なので「両方同時成立」は構造上発生しない (= baton ありなら baton 経路、無ければ source 判定)。
82
+
83
+ ### 2.2 注入内容: L1 + L2 + L3 refs のみ (baton/auto どちらの経路でも同一)
84
+
85
+ 含める:
86
+ - ヘッダ + Reading Contract framing (= Codex 側 `renderCodexRolloutMemoryPreview` の写像)
87
+ - **L1 summaries** (古い turn の一行要約)
88
+ - **L2 bodies** (直近 20 turn の verbatim)
89
+ - **L3 references** (= `throughline detail <時刻>` の取り出しコマンド一覧、Codex 風の `- ${kind}: ${detailCommand}` フォーマット)
90
+ - Continuation Instruction (= 「これは過去ログではなく現在進行中の作業」と明示)
91
+
92
+ 含めない (= 削除):
93
+ - 中断直前の in-flight memo (memo セクション)
94
+ - 中断直前の thinking (extended thinking セクション)
95
+ - 既存の Claude 向け footer の冗長な使い方説明
96
+
97
+ 理由: L2 全文があれば最後の assistant turn 自体に「次に何をしようとしていたか」が含まれている。memo / thinking は redundant。
98
+
99
+ ### 2.3 `/tl` の役割: **残すが簡素化**
100
+
101
+ - `/tl` slash command 自体は **維持** (= 明示意思マーカー = baton path のトリガー)
102
+ - 簡素化:
103
+ - memo 4 項目入力要求を **削除** ([.claude/commands/tl.md](../.claude/commands/tl.md) を「baton 立てるだけ」の最小実装に)
104
+ - `save-inflight` CLI を **削除** (memo を baton.memo_text に保存する役目だった)
105
+ - `handoff_batons.memo_text` 列を **drop** (schema v8 migration)
106
+ - `src/baton.mjs` の `updateBatonMemo` 関数を **削除** (memo_text 列が drop されるため)
107
+ - `prompt-submit.mjs` の baton 書き込み path は **維持** (`UserPromptSubmit` hook で `/tl` 検出 + writeBaton)
108
+
109
+ ユーザーから見た `/tl` の使い方:
110
+ - 自動引継ぎ ON (デフォルト): `/tl` を打たなくても `/clear` で自動引継ぎ。打っても挙動は同じ
111
+ - 自動引継ぎ OFF (env で disable): `/tl` を打ってから新セッションスタートすれば baton 経由で引継ぎ
112
+
113
+ ### 2.4 `/tl-trim` 廃止 (Codex 側を壊さない)
114
+
115
+ - 元機能: memo 入力 + dry-run preview 表示
116
+ - 新仕様で memo 廃止 + 軽量化方針 → 役割なし
117
+ - 削除対象:
118
+ - [.claude/commands/tl-trim.md](../.claude/commands/tl-trim.md) (slash command)
119
+ - [src/cli/trim.mjs](../src/cli/trim.mjs) の **Claude path 部分のみ** 削除 (`describeTrimHost('claude')` ブランチ、Claude 用 memory preview 経路など)
120
+ - 関連 test
121
+ - **維持** (Codex 側を壊さないため):
122
+ - [src/cli/trim.mjs](../src/cli/trim.mjs) の Codex path (`--host codex`, `--codex-thread-id`, `--preflight`, `--execute`, etc.) はすべて維持
123
+ - [src/trim-model.mjs](../src/trim-model.mjs) の `describeTrimHost('codex')` / `buildTrimPlan` の Codex 関連
124
+ - [src/codex-app-server.mjs](../src/codex-app-server.mjs), [src/codex-rollout-memory.mjs](../src/codex-rollout-memory.mjs), `codex-*` CLI 全般
125
+ - `bin/throughline.mjs` の `trim` dispatch (Codex 経路で必要)
126
+ - Codex skill ([codex/skills/throughline](../codex/skills/throughline)) の trim 機能 (= 機能自体は無変更、SKILL.md 内の `/tl-trim` 言及があれば 4 TODO で update)
127
+
128
+ ### 2.5 `THROUGHLINE_DISABLE_AUTO_HANDOFF` env var
129
+
130
+ - 値が `'1'` のとき auto path を skip
131
+ - それ以外の値、または未設定 → auto path 有効 (= デフォルト ON)
132
+ - 判定箇所: [src/session-start.mjs](../src/session-start.mjs)
133
+ - 設定方法: ユーザーが `.bashrc` / `.zshrc` / VSCode terminal env / `~/.claude/settings.json` の `env` セクションで設定
134
+
135
+ ### 2.6 トレードオフ (受容する)
136
+
137
+ - ⚠️ 「reset したい /clear」も auto path で引継ぎ発火する → 受容 (= 不要なら env で OFF)
138
+ - ⚠️ baton TTL は 1 時間 (= 既存仕様維持)
139
+
140
+ ---
141
+
142
+ ## 3. 確定した内部判断
143
+
144
+ ### 3.1 `/rewind` source 検証 — 不要
145
+
146
+ A 採択により本計画は `/rewind` を扱わない。`/rewind` 後の `source` 値は将来要件で再検討。
147
+
148
+ ### 3.2 `handoff_batons` テーブル — 残す + memo_text 列だけ drop
149
+
150
+ - table 自体は baton path で必要なので **維持**
151
+ - `memo_text TEXT` 列を schema v8 migration で drop
152
+ - 既存の memo データは廃棄 (受容)
153
+ - **SQLite DROP COLUMN 互換確認必須**: `ALTER TABLE ... DROP COLUMN` は SQLite 3.35.0+ で利用可。Node.js v22.5+ 同梱の SQLite バージョンで動作するか実装時に検証
154
+
155
+ ### 3.3 旧 `/tl` ユーザー移行 — `/tl` 自体は continue、memo 関連だけ breaking
156
+
157
+ - `/tl` slash command 自体は使い続けられる (簡素化されただけ)
158
+ - 廃止される機能: memo 4 項目入力、`save-inflight` CLI、`/tl-trim`
159
+ - breaking change として CHANGELOG に明示
160
+
161
+ ### 3.4 `source='compact'` 扱い — 引継ぎしない
162
+
163
+ auto-compaction は Claude Code 内部の context 圧縮で、conversation 連続性は host 側が担保している。Throughline 側で別途引継ぎを発火する必要なし。
164
+
165
+ ### 3.5 ログファイルの扱い
166
+
167
+ - `~/.throughline/logs/inflight-memo.log`: `save-inflight` CLI 削除で **新規書き込みなし**。既存ファイルは削除提案を README / CHANGELOG に書く (= 自動削除はしない、ユーザー手動)
168
+ - `~/.throughline/logs/inheritance-decision.log` 内の `baton_has_memo` フィールド: memo 廃止で意味を失うため、`logDecision()` から **削除**
169
+ - `~/.throughline/logs/baton-write.log`: 維持 (= `/tl` baton 書き込みログとして引き続き有用)
170
+
171
+ ---
172
+
173
+ ## 4. 実装 TODO (実装開始可)
174
+
175
+ 優先度順:
176
+
177
+ - [ ] **schema v8 migration** ([src/db.mjs](../src/db.mjs)): `ALTER TABLE handoff_batons DROP COLUMN memo_text`
178
+ - SQLite 3.35.0+ サポート確認 (Node.js v22.5+ 同梱版)
179
+ - 動かない場合は `CREATE TABLE` + `INSERT SELECT` + `DROP` の rebuild migration に切り替え
180
+ - [ ] **`src/baton.mjs`**:
181
+ - `consumeBaton` 戻り値から `memoText` プロパティを削除
182
+ - `updateBatonMemo` 関数を **削除**
183
+ - `BATON_TTL_MS`, `writeBaton`, `consumeBaton` は維持
184
+ - [x] **`src/handoff-record.mjs`**: **維持** (Codex 側 codex-handoff.mjs / codex-resume / codex-handoff-smoke 等が `memory.inflightMemo` / `memory.latestThinking` を参照しているため、削除すると Codex を壊す)。Claude 側で「使わない」のは resume-context.mjs 側で実現済み
185
+ - [ ] **`src/resume-context.mjs`**: 注入テキストを新仕様に書き換え:
186
+ - memo セクション削除
187
+ - thinking セクション削除
188
+ - L3 references 一覧追加 (Codex `renderCodexRolloutMemoryPreview` 形式)
189
+ - footer 簡素化 (Continuation Instruction だけ残す)
190
+ - [ ] **`src/session-start.mjs`** を 2.1 のロジックに改修:
191
+ - `consumeBaton` 先発 → `baton.sessionId` あれば inject
192
+ - 無ければ `source==='clear'` かつ env が `'1'` でない場合に inject
193
+ - それ以外は何もしない
194
+ - `logDecision()` から `baton_has_memo` フィールド削除
195
+ - [ ] **`src/cli/save-inflight.mjs`** 削除
196
+ - [ ] **`bin/throughline.mjs`** の `save-inflight` dispatch 削除 (`trim` dispatch は **維持**)
197
+ - [ ] **`src/prompt-submit.mjs`**: 維持 (baton 書き込み + ensureMonitorTaskFile)
198
+ - [ ] **[.claude/commands/tl.md](../.claude/commands/tl.md)**: memo 4 項目入力要求を削除、純粋に「baton 立てるだけ」の最小実装に書き換え
199
+ - [x] **`/tl-trim` 関連削除**:
200
+ - [.claude/commands/tl-trim.md](../.claude/commands/tl-trim.md) ファイル削除
201
+ - **`src/cli/trim.mjs` 自体は維持**: Codex 経路 (`--host codex`, `--preflight`, `--execute`, `--codex-app-server-bin` 等) と doctor `--trim --host claude` で使う `describeTrimHost('claude')` の dry-run 表示が依存しているため、コード削除はしない (= ユーザーが直接 `throughline trim --host claude --dry-run` を打つ余地は残す。実用は SessionStart 自動経路に置き換わる)
202
+ - [ ] **[src/cli/install.mjs](../src/cli/install.mjs)**: Throughline 管理 slash commands の copy 対象リストから `tl-trim.md` を除外。`tl.md` は維持。`src/cli/install.test.mjs` の関連 test も update
203
+ - [ ] **[bin/throughline.mjs](../bin/throughline.mjs) の `showHelp()` 文言 update**:
204
+ - `save-inflight` 関連 help 文言を削除
205
+ - `/tl-trim` / Claude trim 関連の help 文言を削除
206
+ - Codex trim 関連 (`trim --dry-run`, `--preflight`, `--execute --host codex` など) は **維持**
207
+ - `bin/throughline.mjs` の `save-inflight` dispatch case 削除 (上の TODO と重複するが help text だけ別作業)
208
+ - [ ] **[codex/skills/throughline/SKILL.md](../codex/skills/throughline/SKILL.md)**: `/tl-trim` への言及があれば削除し、`throughline trim --execute --host codex` 直接呼び出しに統一。Codex 側 trim 案内自体は維持
209
+ - [ ] **[.codex-sidecar.yml](../.codex-sidecar.yml)** 確認: `/tl-trim` / `save-inflight` 経路の参照があれば削除。無ければ no-op
210
+ - [ ] **テスト全部更新**:
211
+ - `src/baton.test.mjs` → memo 関連 test 削除、`updateBatonMemo` test 削除
212
+ - `src/session-merger.test.mjs` → source='clear' 自動経路の test 追加
213
+ - `src/resume-context.test.mjs` → memo/thinking 削除を反映
214
+ - `src/handoff-record.test.mjs` → projection 簡素化
215
+ - `src/hook-entrypoints.test.mjs` → save-inflight subprocess test ケース削除 (= 独立ファイルではなく本ファイル内の test)
216
+ - `src/turn-processor.test.mjs` → 既存維持
217
+ - `src/trim-cli.test.mjs` / `src/trim-model.test.mjs` → Claude path 関連テストのみ削除、Codex 経路テストは維持
218
+ - 新規: env var 判定 test、source='clear' auto path test
219
+ - [ ] **docs 更新**:
220
+ - [CLAUDE.md](../CLAUDE.md): 設計の核を書き換え (「`/tl` バトンのみ」→「`source='clear'` 自動 + `/tl` 逃げ道」)
221
+ - [README.md](../README.md): 以下範囲を update:
222
+ - Quick Start: 「`/clear` で自動引継ぎ」中心に書き直し
223
+ - 「Explicit handoff via `/tl`」セクション: `save-inflight` / memo 4 項目要求の記述を削除、`/tl` は逃げ道として簡素な記述に
224
+ - Troubleshoot / How it compares 等の他セクション: `/tl-trim`, `save-inflight`, `inflight-memo.log` への言及をすべて削除
225
+ - `THROUGHLINE_DISABLE_AUTO_HANDOFF` env var 紹介を新規追加
226
+ - 既存 `inflight-memo.log` ファイルは新版で書き込み停止することを README で告知 (= 手動削除提案)
227
+ - [CHANGELOG.md](../CHANGELOG.md): breaking change を明示 (memo 廃止、save-inflight 削除、/tl-trim 削除、`updateBatonMemo` 削除、baton_has_memo フィールド削除)
228
+ - [INHERITANCE_ON_CLEAR_ONLY.md](INHERITANCE_ON_CLEAR_ONLY.md): 「2026-04 段階の検証 → 2026-05 でバグ修正により案 A 成立、本書は履歴扱い」note 追加
229
+ - [PUBLIC_RELEASE_PLAN.md](PUBLIC_RELEASE_PLAN.md): version bump + breaking change 反映
230
+ - [ ] **package.json**: **0.4.0** に bump (semver minor、pre-1.0 の breaking)
231
+ - [ ] **caveat 記録**: 「`/clear` SessionStart `source` は 2.1.128 で reliable、過去 #49937 は fix 済み」を public で記録
232
+
233
+ ---
234
+
235
+ ## 5. 削減できるコード規模 (見積もり)
236
+
237
+ 廃止対象:
238
+ - `src/cli/save-inflight.mjs` (~80 行) → 削除
239
+ - `src/cli/trim.mjs` の Claude path 部分 (~30 行) → 削除 (Codex path は維持)
240
+ - [.claude/commands/tl-trim.md](../.claude/commands/tl-trim.md) (~40 行) → 削除
241
+ - `src/baton.mjs` の `updateBatonMemo` 関数 (~10 行) → 削除
242
+ - `handoff_batons.memo_text` 列 (schema migration、コードへの影響は consumeBaton 戻り値変更のみ)
243
+ - `src/hook-entrypoints.test.mjs` 内 save-inflight test ケース (~30 行) → 削除
244
+ - `resume-context.mjs` の memo/thinking セクション (~30 行) → 削除
245
+ - `handoff-record.mjs` の memo/thinking projection (~50 行) → 削除
246
+ - [.claude/commands/tl.md](../.claude/commands/tl.md) の memo 4 項目要求 (~20 行) → 削除
247
+
248
+ 代わりに追加:
249
+ - `session-start.mjs` の env / source 判定 (~15 行)
250
+ - `resume-context.mjs` の L3 refs framing (~30 行)
251
+
252
+ 純減 ~245 行。
253
+
254
+ ---
255
+
256
+ ## 6. Codex 側との整合 (壊さない)
257
+
258
+ Codex 側 v0.3.25 の以下は本計画で **完全に無変更**:
259
+
260
+ - `codex-capture` / `codex-summarize` / `codex-resume` (Codex primary L1/L2/L3 path)
261
+ - `codex-resume --format handoff` (新規 Codex thread 用 prompt)
262
+ - `trim --execute --host codex` / `--preflight --host codex` (app-server `thread/rollback` + `thread/inject_items`)
263
+ - Codex Stop hook 90% auto-refresh
264
+ - restore-safety / host primitive audit diagnostics
265
+ - Codex skill ([codex/skills/throughline](../codex/skills/throughline)) の trim 機能 (= 機能自体は無変更、SKILL.md 内の `/tl-trim` 言及があれば 4 TODO で update)
266
+ - [src/codex-app-server.mjs](../src/codex-app-server.mjs), [src/codex-rollout-memory.mjs](../src/codex-rollout-memory.mjs)
267
+ - [src/trim-model.mjs](../src/trim-model.mjs) の Codex 関連 (`describeTrimHost('codex')`, `buildTrimPlan` の Codex source path)
268
+
269
+ `codex-resume --memo-stdin` は引き続きユーザーが stdin で memo を流す経路。Throughline DB の baton.memo_text には依存していない (= 列削除の影響なし)。
270
+
271
+ `/tl-trim` 削除に伴って Codex 経由でも slash command としての `/tl-trim` は使えなくなる。Codex 用 trim は `throughline trim --execute --host codex` を **CLI 直接呼ぶ**運用に統一 (Codex skill SKILL.md がそれを案内する)。
272
+
273
+ ---
274
+
275
+ ## 7. 進め方
276
+
277
+ 1. **本計画 確定** (ユーザー A 採択済み、本書 update により方針固定)
278
+ 2. **実装** (上記 TODO 順)
279
+ 3. **テスト + 実機 smoke + commit**
280
+ 4. **publish** (npm 0.4.0 として release)
281
+
282
+ 実機 smoke 手順:
283
+ - 自動引継ぎ ON (デフォルト): /clear → 新セッションで curated memory 注入を確認
284
+ - 自動引継ぎ OFF: env を立てて /clear → 注入されないことを確認
285
+ - baton path: `/tl` を打って新 chat タブで開く → baton 経由で注入を確認
286
+ - Codex 側 regression: `npm test` で既存 Codex test がすべて pass することを確認、`throughline trim --execute --host codex` の CLI 動作も維持
@@ -0,0 +1,249 @@
1
+ # Throughline: Claude / Codex 両対応計画
2
+
3
+ この文書は Throughline repository に貼り付けるための実装ブリーフです。目的は、Throughline を Claude Code と Codex の両方から安全に使える形へ育てることです。
4
+
5
+ ## この文書の位置づけ
6
+
7
+ この文書は **Claude / Codex 両対応の architecture brief** です。
8
+
9
+ 関連文書:
10
+
11
+ | 文書 | 役割 |
12
+ |---|---|
13
+ | [THROUGHLINE_CODEX_FIRST_ROADMAP.md](THROUGHLINE_CODEX_FIRST_ROADMAP.md) | 2026-05-06 以降の次フェーズ計画。Codex primary 実用化を先行する |
14
+ | [THROUGHLINE_CODEX_TRIM_ROLLBACK_FIX_PLAN.md](THROUGHLINE_CODEX_TRIM_ROLLBACK_FIX_PLAN.md) | 2026-05-06 incident 後の修正計画。2026-05-08 の controlled smoke 後、過剰な Codex trim blocker は解除し、restore-safety / host primitive audit は diagnostics として扱う |
15
+ | [THROUGHLINE_CODEX_TRIM_IMPLEMENTATION_PLAN.md](THROUGHLINE_CODEX_TRIM_IMPLEMENTATION_PLAN.md) | この文書と rollback trim の気づきを統合した旧計画と実装履歴。完了済み根拠として参照する |
16
+ | [throughline-rollback-context-trim-insight.md](throughline-rollback-context-trim-insight.md) | conversation-only rollback を「model-visible context の delete primitive」と見る設計メモ |
17
+
18
+ この文書は Codex adapter / sidecar integration の方針を定義する。今後の実装順は [THROUGHLINE_CODEX_FIRST_ROADMAP.md](THROUGHLINE_CODEX_FIRST_ROADMAP.md) を優先する。
19
+
20
+ ## 目標
21
+
22
+ Throughline は agent-neutral な handoff / context compression infrastructure になるべきです。
23
+
24
+ Claude Code transcript と handoff behavior は守りつつ、Codex primary bridge と `codex-sidecar` 経由の compact context も生成できるようにします。現行の `HandoffRecord` は安定した中間表現だが、保存元はまだ Claude transcript 由来であり、Codex capture を実装して初めて source adapter が Codex 由来になる。
25
+
26
+ 目指す形:
27
+
28
+ - Throughline core は特定 agent に依存しない。
29
+ - Claude transcript support は first-class かつ stable のまま維持する。
30
+ - Codex support は `throughline_handoff` context block、Codex primary entrypoint、Codex CLI backend、`codex-sidecar` integration として追加する。
31
+ - 既存の Claude handoff behavior を壊さない。
32
+
33
+ ## 優先順位
34
+
35
+ 1. Throughline を Codex primary で使えるようにする。Codex primary の L2 -> L1 backend は Codex CLI を本線にする。
36
+ 2. Codex で Claude Rewind 相当の context trim を完成させる。2026-05-08 時点では Codex current-thread trim execute / auto-refresh は再有効化済みで、DB memory と turn-count guard を必須にする。
37
+ 3. そのあと Claude 側の `/rewind` UX / 自動化 surface を詰める。
38
+
39
+ Claude transcript handling の置き換えから始めないでください。Codex 対応は adapter / bridge / Codex primary entrypoint として追加します。
40
+
41
+ Claude primary で `codex-sidecar` が使えない場合は、現在の Claude subagent behavior をそのまま維持します。Codex 向け adapter / bridge が存在するからといって、既存の Claude path を削ったり劣化させたりしないでください。Codex primary の可用性は Codex CLI / app-server / rollout の実測で別に判定します。
42
+
43
+ ## Architecture 方針
44
+
45
+ 概念上、次の layer に分けます。
46
+
47
+ | Layer | Responsibility |
48
+ |---|---|
49
+ | Agent-neutral core | handoff record、compression output、reference、persistence、validation |
50
+ | Claude adapter | Claude Code transcript parsing、tool I/O assumption、Claude handoff command |
51
+ | Codex adapter | `throughline_handoff` context block、`codex-sidecar` request shaping、result capture |
52
+ | Shared fixtures | Claude / Codex adapter の両方で使う handoff example と expected output |
53
+
54
+ Codex path が Claude internals を parse するのは、それが明示的に adapter の責務である場合だけにしてください。core は stable handoff object を扱うべきです。
55
+
56
+ ## Codex Sidecar Integration
57
+
58
+ この節は `codex-sidecar` integration の設計です。Codex primary の capture / L2 -> L1 backend は [THROUGHLINE_CODEX_FIRST_ROADMAP.md](THROUGHLINE_CODEX_FIRST_ROADMAP.md) を優先します。
59
+
60
+ Sidecar 向けには、Throughline が `codex-sidecar` contract に合う plain JSON context block を生成します。
61
+
62
+ ```json
63
+ {
64
+ "kind": "throughline_handoff",
65
+ "source": "throughline",
66
+ "trust": "local",
67
+ "summary": "In-flight handoff: Next: continue",
68
+ "data": {
69
+ "throughlineHandoffSchemaVersion": 1,
70
+ "handoffRecordVersion": 1,
71
+ "sessionId": "session-id",
72
+ "projectPath": "/repo",
73
+ "sourceAgent": "claude",
74
+ "hostMode": "claude-primary",
75
+ "intent": "continue implementation",
76
+ "constraints": ["preserve Claude transcript contract"],
77
+ "originSessionIds": ["old-session"],
78
+ "stats": {},
79
+ "memory": {},
80
+ "detailReferences": [
81
+ {
82
+ "type": "throughline_detail",
83
+ "label": "tool_input:Bash",
84
+ "command": "throughline detail 12:00:01",
85
+ "sourceId": "toolu_1",
86
+ "detailKind": "tool_input",
87
+ "originSessionId": "old-session",
88
+ "turnNumber": 2
89
+ }
90
+ ]
91
+ }
92
+ }
93
+ ```
94
+
95
+ `codex-sidecar` の top-level `references` は `path` 必須です。Throughline の DB /
96
+ `throughline detail <時刻>` 参照は `data.detailReferences` に置きます。file path /
97
+ line reference は既知の場合だけ top-level `references` に足し、必須にはしません。
98
+ `SidecarContextBlock` は top-level `schemaVersion` を保持しないため、Throughline 側の
99
+ schema version は `data.throughlineHandoffSchemaVersion` に入れます。
100
+ `hostMode` は `claude-primary` / `codex-primary` / `unknown` を明示指定します。自動 host-agent detection は初期実装に入れません。
101
+
102
+ Codex-facing workflow では、この context block を次の用途に使います。
103
+
104
+ - `codex_explore`: previous handoff context を使って repo question に答える。
105
+ - `codex_review`: last handoff を intent として current changes を review する。
106
+ - `codex_opinion`: handoff に含まれる plan を challenge する。
107
+ - `codex_risk_check`: handoff が触れている risky area を確認する。
108
+ - `codex_work`: isolated worktree で小さな scoped task を続行する。
109
+
110
+ ## Claude Behavior を守る
111
+
112
+ コード変更の前に、現在の Claude contract を特定して文書化してください。
113
+
114
+ - transcript file shape
115
+ - tool input / output parsing assumption
116
+ - compaction format
117
+ - handoff markdown / JSON schema
118
+ - command name と argument
119
+ - resume behavior
120
+ - Claude session がまだ動くことを示す test / fixture
121
+
122
+ Codex のために既存の Claude-facing field を rename しないでください。必要なら Codex adapter projection を追加します。
123
+
124
+ ## Background Subagent Shift
125
+
126
+ 現行 Throughline で subagent 的に外部 model call しているのは、Stop hook の
127
+ L2 → L1 要約だけです。具体的には [src/haiku-summarizer.mjs](../src/haiku-summarizer.mjs)
128
+ が `claude -p --model claude-haiku-4-5-*` を呼びます。
129
+
130
+ 移行方針:
131
+
132
+ - Claude primary では、`codex-sidecar diagnostics --project <repo> --preset summarize-l1` が成功する環境では、L2 → L1 要約に `codex-sidecar` を使う。
133
+ - Claude primary では、`codex-sidecar` が disabled / unavailable / diagnostics failure / run failure の環境では、現行の Claude Haiku 要約を維持する。
134
+ - Codex primary では、次フェーズ計画 [THROUGHLINE_CODEX_FIRST_ROADMAP.md](THROUGHLINE_CODEX_FIRST_ROADMAP.md) に従い、L2 → L1 要約 backend は Codex CLI を本線にする。Codex CLI が使えない場合は silent fallback せず明示 error とする。
135
+ - `/tl` の in-flight memo は [.claude/commands/tl.md](../.claude/commands/tl.md) が現行メイン Claude に書かせる handoff memo であり、subagent ではない。これは Codex sidecar へ移さない。
136
+
137
+ handoff review、continuity check、risk analysis などは現行 `src/` 実装には存在しません。
138
+ 後続で追加する場合だけ、`throughline_handoff` context block と read-only sidecar workflow
139
+ として扱います。
140
+
141
+ ## 懸念: Codex が Codex を呼ぶ場合
142
+
143
+ ユーザーが Claude から Throughline を使っている場合、この形には価値があります。
144
+
145
+ ```text
146
+ Claude primary -> Throughline -> codex-sidecar -> Codex second opinion
147
+ ```
148
+
149
+ 一方、ユーザーが Codex から Throughline を使っている場合、次の形を無条件で行わないでください。
150
+
151
+ ```text
152
+ Codex primary -> Throughline -> codex-sidecar -> Codex again
153
+ ```
154
+
155
+ Codex-on-Codex が有効なのは、sidecar に別の境界がある場合だけです。
156
+
157
+ - isolated worktree から実行される。
158
+ - durable `SidecarResult` を生成する。
159
+ - diagnosis 用の raw App Server log を書く。
160
+ - critic / reviewer / risk-analyst など prompt role が明確に違う。
161
+ - independent second pass として明示的に要求されている。
162
+
163
+ 別の境界がないなら、Throughline は別の Codex に委譲せず、現在の Codex session に handoff を直接 consume させてください。
164
+ Throughline 自体を Codex primary から使う場合は、まず [THROUGHLINE_CODEX_FIRST_ROADMAP.md](THROUGHLINE_CODEX_FIRST_ROADMAP.md) の Codex primary capture / Codex active-work resume renderer / Codex CLI L2→L1 backend を本線にします。`throughline codex-capture` と `throughline codex-resume` が Codex primary の入口であり、`throughline codex-sidecar-diagnostics`、`throughline codex-sidecar-dry-run` などは sidecar を使う review / risk-check / second opinion の診断 surface です。
165
+
166
+ Recommended policy:
167
+
168
+ | Host agent | Sidecar choice |
169
+ |---|---|
170
+ | Claude | independent review、risk、exploration、scoped continuation には Codex sidecar を優先 |
171
+ | Codex | isolation、structured result capture、explicit second-pass review がある場合のみ Codex sidecar を使う |
172
+ | Unknown / automation | implicit recursion ではなく明示 config を要求 |
173
+
174
+ Sidecar availability policy:
175
+
176
+ この表は `codex-sidecar` の availability を表す。Codex primary の L2 → L1 backend availability ではない。
177
+
178
+ | Codex sidecar availability | Behavior |
179
+ |---|---|
180
+ | `unavailable` | `codex-sidecar` が存在しない、実行不能、この repo 向けに未設定、または diagnostics 失敗。既存の Claude subagent path を維持 |
181
+ | `configured` | `codex-sidecar diagnostics --project <repo>` が成功。request shaping、dry-run、docs、planned read-only integration は使ってよい |
182
+ | `operational` | `codex_explore` など read-only smoke が成功。approved review、explore、opinion、risk-check sidecar task に使ってよい |
183
+ | `work-capable` | `codex_work` smoke が成功し、allowed paths が設定済み。worktree-backed scoped edit に使ってよい |
184
+ | explicitly disabled | 既存の Claude subagent path を維持 |
185
+
186
+ これは hidden fallback ではありません。Claude primary の互換モードです。Codex sidecar が使えない環境では、現在の Claude-backed behavior を baseline とします。
187
+
188
+ 「Codex sidecar が使える」の最小実用定義は、単に `codex` binary があることではありません。`codex-sidecar` が存在し、対象 repository で diagnostics を成功させられることです。`codex-sidecar` がない場合、Throughline は sidecar unavailable と扱ってください。Codex primary 自体の可用性は、Codex CLI と app-server / rollout の実測で別に判定します。
189
+
190
+ Preferred health check:
191
+
192
+ ```bash
193
+ codex-sidecar diagnostics --project <repo> --preset review
194
+ ```
195
+
196
+ Development-path health check:
197
+
198
+ ```bash
199
+ node /home/kite/projects/codex-sidecar/packages/cli/dist/index.js diagnostics \
200
+ --project <repo> \
201
+ --preset review
202
+ ```
203
+
204
+ Dry-run checks:
205
+
206
+ ```bash
207
+ throughline codex-sidecar-dry-run \
208
+ --project <repo> \
209
+ --preset review \
210
+ --context-file docs/throughline-handoff-context.example.json \
211
+ "Review Throughline dual support request shape only."
212
+
213
+ throughline codex-sidecar-dry-run \
214
+ --project <repo> \
215
+ --preset risk-check \
216
+ --context-file docs/throughline-handoff-context.example.json \
217
+ "Risk-check Throughline dual support request shape only."
218
+ ```
219
+
220
+ Structured result policy:
221
+
222
+ - Dry-run output is diagnostic evidence only; it is not persisted in Throughline memory.
223
+ - Real read-only sidecar runs return structured JSON on stdout. If the result contains `rawEventLogRef`, treat that as the canonical durable link to the App Server event log.
224
+ - Do not mix sidecar result JSON into L1/L2/L3 memory tables. If Throughline later needs durable indexing, add a separate `sidecar_runs` style record keyed by project / workflow / preset / status / `rawEventLogRef`.
225
+
226
+ ## Implementation Checklist
227
+
228
+ - [x] 既存の Claude transcript / handoff contract を audit する。
229
+ - [x] adapter 変更前に、現在の Claude behavior を固定する test を追加する。
230
+ - [x] stable handoff object がまだない場合は追加する。
231
+ - [x] `throughline_handoff` 用の Throughline-to-`SidecarContextBlock` conversion path を追加する。
232
+ - [x] Codex context block の fixture snapshot を追加する。
233
+ - [x] Claude primary / Codex primary mode の docs を追加する。
234
+ - [x] Codex-on-Codex recursion を避ける explicit `hostMode` config を追加する。自動 detection は未実装。
235
+ - [x] background Claude subagent task を移す前に Codex sidecar availability check を入れる。sidecar absent または diagnostics failure は explicit `unavailable`。
236
+ - [x] sample handoff を使った read-only `codex-sidecar` smoke を追加する。2026-05-06 に `throughline_handoff` fixture + `codex-sidecar explore` で成功済み。
237
+ - [x] `review` / `risk-check` dry-run を追加する。2026-05-06 に `throughline_handoff` fixture + `throughline codex-sidecar-dry-run` で成功済み。
238
+ - [x] sidecar structured result は stdout JSON + `rawEventLogRef` link として扱い、Throughline memory tables には混ぜない方針を明文化する。
239
+
240
+ ## Done Definition
241
+
242
+ Throughline が dual-supported になったと言える条件:
243
+
244
+ - 既存の Claude transcript / handoff behavior が通る。
245
+ - Codex が `throughline_handoff` context block を受け取れる。
246
+ - Throughline が Codex の structured result を保存または link できる。
247
+ - Codex primary mode が実質的な境界なしに recursive delegation しない。
248
+ - Codex-unavailable environment では既存の Claude subagent behavior を維持する。
249
+ - Claude、current Codex、Codex sidecar の使い分けが docs に説明されている。