throughline 0.3.23 → 0.3.25

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 (111) hide show
  1. package/.claude/commands/tl-trim.md +42 -0
  2. package/.codex-sidecar.yml +62 -0
  3. package/CHANGELOG.md +583 -0
  4. package/README.ja.md +42 -5
  5. package/README.md +400 -23
  6. package/bin/throughline.mjs +168 -4
  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 +146 -0
  10. package/docs/L1_L2_L3_REDESIGN.md +415 -0
  11. package/docs/PUBLIC_RELEASE_PLAN.md +184 -0
  12. package/docs/THROUGHLINE_CODEX_DUAL_SUPPORT.md +249 -0
  13. package/docs/THROUGHLINE_CODEX_FIRST_ROADMAP.md +555 -0
  14. package/docs/THROUGHLINE_CODEX_MONITOR_IMPLEMENTATION_PLAN.md +220 -0
  15. package/docs/THROUGHLINE_CODEX_TRIM_IMPLEMENTATION_PLAN.md +528 -0
  16. package/docs/THROUGHLINE_CODEX_TRIM_ROLLBACK_FIX_PLAN.md +672 -0
  17. package/docs/archive/CONCEPT.md +476 -0
  18. package/docs/archive/EXPERIMENT.md +371 -0
  19. package/docs/archive/README.md +22 -0
  20. package/docs/archive/SESSION_LINKING_DESIGN.md +231 -0
  21. package/docs/archive/THROUGHLINE_NEXT_STEPS.md +134 -0
  22. package/docs/throughline-codex-trim-rollback-incident-report.md +306 -0
  23. package/docs/throughline-handoff-context.example.json +57 -0
  24. package/docs/throughline-rollback-context-trim-insight.md +455 -0
  25. package/package.json +6 -2
  26. package/src/cli/codex-capture.mjs +95 -0
  27. package/src/cli/codex-handoff-model-smoke.mjs +292 -0
  28. package/src/cli/codex-handoff-model-smoke.test.mjs +262 -0
  29. package/src/cli/codex-handoff-smoke.mjs +163 -0
  30. package/src/cli/codex-handoff-smoke.test.mjs +149 -0
  31. package/src/cli/codex-handoff-start.mjs +291 -0
  32. package/src/cli/codex-handoff-start.test.mjs +194 -0
  33. package/src/cli/codex-hook.mjs +276 -0
  34. package/src/cli/codex-hook.test.mjs +293 -0
  35. package/src/cli/codex-host-primitive-audit.mjs +110 -0
  36. package/src/cli/codex-host-primitive-audit.test.mjs +75 -0
  37. package/src/cli/codex-restore-smoke.mjs +357 -0
  38. package/src/cli/codex-restore-source-audit.mjs +304 -0
  39. package/src/cli/codex-resume.mjs +138 -0
  40. package/src/cli/codex-rollback-model-visible-smoke.mjs +373 -0
  41. package/src/cli/codex-rollback-model-visible-smoke.test.mjs +255 -0
  42. package/src/cli/codex-sidecar-diagnostics.mjs +48 -0
  43. package/src/cli/codex-sidecar-dry-run.mjs +85 -0
  44. package/src/cli/codex-summarize.mjs +224 -0
  45. package/src/cli/codex-threads.mjs +89 -0
  46. package/src/cli/codex-visibility-smoke.mjs +196 -0
  47. package/src/cli/codex-vscode-restore-smoke.mjs +226 -0
  48. package/src/cli/codex-vscode-rollback-smoke.mjs +114 -0
  49. package/src/cli/doctor.mjs +503 -1
  50. package/src/cli/doctor.test.mjs +542 -3
  51. package/src/cli/handoff-preview.mjs +78 -0
  52. package/src/cli/help.test.mjs +64 -0
  53. package/src/cli/install.mjs +227 -4
  54. package/src/cli/install.test.mjs +207 -4
  55. package/src/cli/trim.mjs +564 -0
  56. package/src/codex-app-server.mjs +1816 -0
  57. package/src/codex-app-server.test.mjs +512 -0
  58. package/src/codex-auto-refresh.mjs +194 -0
  59. package/src/codex-auto-refresh.test.mjs +182 -0
  60. package/src/codex-capture.mjs +235 -0
  61. package/src/codex-capture.test.mjs +393 -0
  62. package/src/codex-handoff-model-smoke.mjs +114 -0
  63. package/src/codex-handoff-model-smoke.test.mjs +89 -0
  64. package/src/codex-handoff-smoke.mjs +124 -0
  65. package/src/codex-handoff-smoke.test.mjs +103 -0
  66. package/src/codex-handoff.mjs +331 -0
  67. package/src/codex-handoff.test.mjs +220 -0
  68. package/src/codex-host-primitive-audit.mjs +374 -0
  69. package/src/codex-host-primitive-audit.test.mjs +208 -0
  70. package/src/codex-restore-smoke.test.mjs +639 -0
  71. package/src/codex-restore-source-audit.mjs +1348 -0
  72. package/src/codex-restore-source-audit.test.mjs +623 -0
  73. package/src/codex-resume.test.mjs +242 -0
  74. package/src/codex-rollout-memory.mjs +711 -0
  75. package/src/codex-rollout-memory.test.mjs +610 -0
  76. package/src/codex-sidecar-cli.test.mjs +75 -0
  77. package/src/codex-sidecar.mjs +246 -0
  78. package/src/codex-sidecar.test.mjs +172 -0
  79. package/src/codex-summarize.test.mjs +143 -0
  80. package/src/codex-thread-identity.mjs +23 -0
  81. package/src/codex-thread-index.mjs +173 -0
  82. package/src/codex-thread-index.test.mjs +164 -0
  83. package/src/codex-usage.mjs +110 -0
  84. package/src/codex-usage.test.mjs +140 -0
  85. package/src/codex-visibility-smoke.test.mjs +222 -0
  86. package/src/codex-vscode-restore-smoke.mjs +206 -0
  87. package/src/codex-vscode-restore-smoke.test.mjs +325 -0
  88. package/src/codex-vscode-rollback-smoke.mjs +90 -0
  89. package/src/codex-vscode-rollback-smoke.test.mjs +290 -0
  90. package/src/db-schema.test.mjs +97 -0
  91. package/src/haiku-summarizer.mjs +267 -26
  92. package/src/haiku-summarizer.test.mjs +282 -0
  93. package/src/handoff-preview.test.mjs +108 -0
  94. package/src/handoff-record.mjs +294 -0
  95. package/src/handoff-record.test.mjs +226 -0
  96. package/src/hook-entrypoints.test.mjs +326 -0
  97. package/src/package-files.test.mjs +19 -0
  98. package/src/prompt-submit.mjs +9 -6
  99. package/src/resume-context.mjs +44 -140
  100. package/src/resume-context.test.mjs +172 -0
  101. package/src/session-start.mjs +8 -5
  102. package/src/state-file.mjs +50 -6
  103. package/src/state-file.test.mjs +50 -0
  104. package/src/token-monitor.mjs +14 -10
  105. package/src/token-monitor.test.mjs +27 -0
  106. package/src/trim-cli.test.mjs +1584 -0
  107. package/src/trim-model.mjs +584 -0
  108. package/src/trim-model.test.mjs +568 -0
  109. package/src/turn-processor.mjs +17 -10
  110. package/src/vscode-task.mjs +94 -6
  111. package/src/vscode-task.test.mjs +186 -6
@@ -9,6 +9,25 @@
9
9
  * throughline process-turn # Stop hook (Claude Code から呼ばれる)
10
10
  * throughline session-start # SessionStart hook (Claude Code から呼ばれる)
11
11
  * throughline detail <時刻> # L2+L3 詳細取得 (Claude が Bash 経由で呼ぶ想定)
12
+ * throughline handoff-preview # Codex-facing throughline_handoff JSON preview
13
+ * throughline codex-capture # Capture active Codex rollout turns into Throughline DB
14
+ * throughline codex-hook stop # Codex native Stop hook (capture + L1 summarize)
15
+ * throughline codex-summarize # Summarize captured Codex L2 turns into L1 via Codex CLI
16
+ * throughline codex-resume # Render Codex active-work context from DB
17
+ * throughline codex-handoff-smoke # Validate fresh-thread Codex handoff prompt
18
+ * throughline codex-handoff-model-smoke # Experimental ephemeral Codex exec handoff smoke
19
+ * throughline codex-handoff-start # Guided fresh-thread Codex handoff start
20
+ * throughline codex-visibility-smoke # Experimental model-visible Codex memory smoke
21
+ * throughline codex-rollback-model-visible-smoke # Controlled rollback visibility smoke
22
+ * throughline codex-restore-smoke # Experimental read-only app-server restart restore smoke
23
+ * throughline codex-restore-source-audit # Read-only local restore source inventory
24
+ * throughline codex-host-primitive-audit # Read-only Codex app-server primitive audit
25
+ * throughline codex-vscode-restore-smoke # Manual VS Code reload/reconnect restore smoke
26
+ * throughline codex-vscode-rollback-smoke # Manual rollback non-resurrection smoke
27
+ * throughline codex-threads # List read-only Codex thread id candidates
28
+ * throughline codex-sidecar-diagnostics # Check codex-sidecar availability
29
+ * throughline codex-sidecar-dry-run # Print normalized sidecar request
30
+ * throughline trim --dry-run # Preview same-session context trim plan
12
31
  * throughline doctor # 環境チェック
13
32
  * throughline status # DB 統計表示
14
33
  * throughline --version # バージョン表示
@@ -27,13 +46,13 @@ switch (cmd) {
27
46
  await (await import('../src/cli/install.mjs')).run(['--uninstall', ...rest]);
28
47
  break;
29
48
  case 'process-turn':
30
- await import('../src/turn-processor.mjs');
49
+ await (await import('../src/turn-processor.mjs')).run();
31
50
  break;
32
51
  case 'session-start':
33
- await import('../src/session-start.mjs');
52
+ await (await import('../src/session-start.mjs')).run();
34
53
  break;
35
54
  case 'prompt-submit':
36
- await import('../src/prompt-submit.mjs');
55
+ await (await import('../src/prompt-submit.mjs')).run();
37
56
  break;
38
57
  case 'monitor':
39
58
  (await import('../src/token-monitor.mjs')).main();
@@ -44,6 +63,63 @@ switch (cmd) {
44
63
  case 'save-inflight':
45
64
  await (await import('../src/cli/save-inflight.mjs')).run();
46
65
  break;
66
+ case 'handoff-preview':
67
+ await (await import('../src/cli/handoff-preview.mjs')).run(rest);
68
+ break;
69
+ case 'codex-capture':
70
+ await (await import('../src/cli/codex-capture.mjs')).run(rest);
71
+ break;
72
+ case 'codex-hook':
73
+ await (await import('../src/cli/codex-hook.mjs')).run(rest);
74
+ break;
75
+ case 'codex-summarize':
76
+ await (await import('../src/cli/codex-summarize.mjs')).run(rest);
77
+ break;
78
+ case 'codex-resume':
79
+ await (await import('../src/cli/codex-resume.mjs')).run(rest);
80
+ break;
81
+ case 'codex-handoff-smoke':
82
+ await (await import('../src/cli/codex-handoff-smoke.mjs')).run(rest);
83
+ break;
84
+ case 'codex-handoff-model-smoke':
85
+ await (await import('../src/cli/codex-handoff-model-smoke.mjs')).run(rest);
86
+ break;
87
+ case 'codex-handoff-start':
88
+ await (await import('../src/cli/codex-handoff-start.mjs')).run(rest);
89
+ break;
90
+ case 'codex-visibility-smoke':
91
+ await (await import('../src/cli/codex-visibility-smoke.mjs')).run(rest);
92
+ break;
93
+ case 'codex-rollback-model-visible-smoke':
94
+ await (await import('../src/cli/codex-rollback-model-visible-smoke.mjs')).run(rest);
95
+ break;
96
+ case 'codex-restore-smoke':
97
+ await (await import('../src/cli/codex-restore-smoke.mjs')).run(rest);
98
+ break;
99
+ case 'codex-restore-source-audit':
100
+ await (await import('../src/cli/codex-restore-source-audit.mjs')).run(rest);
101
+ break;
102
+ case 'codex-host-primitive-audit':
103
+ await (await import('../src/cli/codex-host-primitive-audit.mjs')).run(rest);
104
+ break;
105
+ case 'codex-vscode-restore-smoke':
106
+ await (await import('../src/cli/codex-vscode-restore-smoke.mjs')).run(rest);
107
+ break;
108
+ case 'codex-vscode-rollback-smoke':
109
+ await (await import('../src/cli/codex-vscode-rollback-smoke.mjs')).run(rest);
110
+ break;
111
+ case 'codex-threads':
112
+ await (await import('../src/cli/codex-threads.mjs')).run(rest);
113
+ break;
114
+ case 'codex-sidecar-diagnostics':
115
+ await (await import('../src/cli/codex-sidecar-diagnostics.mjs')).run(rest);
116
+ break;
117
+ case 'codex-sidecar-dry-run':
118
+ await (await import('../src/cli/codex-sidecar-dry-run.mjs')).run(rest);
119
+ break;
120
+ case 'trim':
121
+ await (await import('../src/cli/trim.mjs')).run(rest);
122
+ break;
47
123
  case 'doctor':
48
124
  await (await import('../src/cli/doctor.mjs')).run(rest);
49
125
  break;
@@ -74,13 +150,101 @@ Usage:
74
150
  throughline monitor Multi-session token monitor (use --all, --session <id>)
75
151
  throughline detail <time> Retrieve L2+L3 detail for a turn (e.g. 14:23:05 or 14:23-14:30)
76
152
  throughline save-inflight Save in-flight memo (stdin) to the current /tl baton
153
+ throughline handoff-preview Print Codex-facing throughline_handoff JSON
154
+ throughline codex-capture Capture active Codex rollout turns into DB
155
+ (requires --codex-thread-id or env thread id)
156
+ throughline codex-hook stop Codex native Stop hook: capture rollout and
157
+ summarize old L2 turns into L1 via Codex CLI
158
+ throughline codex-summarize Summarize captured Codex L2 into L1 via Codex CLI
159
+ (requires a codex:<thread-id> session)
160
+ throughline codex-resume Render Codex active-work context from DB
161
+ (use --format handoff for a fresh-thread handoff)
162
+ (handoff accepts --max-recent-bodies,
163
+ --max-body-chars, and --max-detail-refs)
164
+ (use --format item-json for a developer message item)
165
+ (use --memo-stdin to prepend a current-work memo)
166
+ throughline codex-handoff-smoke
167
+ Read-only validation that --format handoff is
168
+ pasteable as a fresh Codex thread start prompt
169
+ (use --print-prompt to include the prompt)
170
+ throughline codex-handoff-model-smoke
171
+ Experimental: run the fresh-thread handoff prompt
172
+ through codex exec --ephemeral --sandbox read-only.
173
+ Use --dry-run to inspect readiness without model exec.
174
+ Use --print-prompt with --dry-run to include the prompt.
175
+ Use --memo-stdin to prepend current-work memo.
176
+ Live smoke requires THROUGHLINE_EXPERIMENTAL_CODEX_HANDOFF_MODEL_SMOKE=1
177
+ throughline codex-handoff-start
178
+ Guided read-only fresh-thread handoff start plan:
179
+ structural smoke, model-smoke dry-run boundary,
180
+ render command, optional --print-prompt, and
181
+ --memo-stdin replay guidance
182
+ throughline codex-visibility-smoke
183
+ Experimental: inject Codex active-work memory and
184
+ start a marker-check model turn. Requires
185
+ THROUGHLINE_EXPERIMENTAL_CODEX_MODEL_VISIBLE_SMOKE=1
186
+ (use --memo-stdin and --request-timeout-ms as needed)
187
+ (use --resume-after-inject to re-resume before turn/start)
188
+ throughline codex-rollback-model-visible-smoke
189
+ Experimental controlled two-phase smoke for whether
190
+ a rolled-back user marker is still model-visible.
191
+ --prepare starts a marker turn and rolls it back.
192
+ --verify asks for only the marker prefix after
193
+ reload/reconnect. Requires
194
+ THROUGHLINE_EXPERIMENTAL_CODEX_ROLLBACK_MODEL_VISIBLE_SMOKE=1
195
+ (use --marker-file to avoid leaking the full marker)
196
+ throughline codex-restore-smoke
197
+ Experimental read-only smoke: start fresh app-server
198
+ processes and compare thread/read + thread/resume
199
+ + thread/turns/list counts with the rollout source. Requires
200
+ THROUGHLINE_EXPERIMENTAL_CODEX_RESTORE_SMOKE=1
201
+ (use --inspect-risky-rollout only for read-only
202
+ risk-evidence inspection; it still exits nonzero)
203
+ throughline codex-restore-source-audit
204
+ Read-only local inventory of Codex rollout,
205
+ session index, state sqlite, VS Code storage,
206
+ settings, logs, and extension restore-path signals.
207
+ Does not prove restart safety
208
+ throughline codex-host-primitive-audit
209
+ Read-only Codex app-server schema audit for a
210
+ current-thread compacted-history remediation
211
+ primitive. Does not mutate threads
212
+ throughline codex-vscode-restore-smoke
213
+ Manual two-phase VS Code reload/reconnect smoke.
214
+ --prepare injects a hidden marker developer memory
215
+ and requires
216
+ THROUGHLINE_EXPERIMENTAL_CODEX_VSCODE_RESTORE_SMOKE=1.
217
+ --verify searches the rollout for the marker answer
218
+ throughline codex-vscode-rollback-smoke
219
+ Manual rollback non-resurrection smoke.
220
+ --verify requires a rollback event, rolled-back
221
+ user text, a later user turn, restore safety ok,
222
+ and --after-vscode-restart for restart-safe proof
223
+ throughline codex-threads List read-only Codex thread id candidates
224
+ for --codex-thread-id
225
+ throughline codex-sidecar-diagnostics
226
+ Check codex-sidecar diagnostics status
227
+ throughline codex-sidecar-dry-run
228
+ Print normalized read-only sidecar request
229
+ throughline trim --dry-run Preview same-session context trim plan
230
+ (Codex: accepts --codex-thread-id <id> or
231
+ THROUGHLINE_CODEX_THREAD_ID / CODEX_THREAD_ID)
232
+ (text preview accepts --preview-max-chars <n>)
233
+ throughline trim --preflight
234
+ Codex-only app-server read/resume guard; does not rollback
235
+ throughline trim --execute Codex rollback/inject guard; requires a Codex
236
+ thread id, injectable DB memory, and matching
237
+ rollout/app-server turns
77
238
  throughline doctor Check environment
239
+ throughline doctor --trim Show trim host boundary diagnostics
240
+ throughline doctor --codex Show Codex primary diagnostics
78
241
  throughline status Show DB statistics
79
242
  throughline --version Show version
80
243
 
81
- Hook subcommands (called by Claude Code):
244
+ Hook subcommands (called by Claude Code / Codex):
82
245
  throughline session-start SessionStart hook
83
246
  throughline process-turn Stop hook
84
247
  throughline prompt-submit UserPromptSubmit hook (/tl baton writer)
248
+ throughline codex-hook stop Codex Stop hook
85
249
  `);
86
250
  }
@@ -0,0 +1,157 @@
1
+ ---
2
+ name: throughline
3
+ description: Use when the user asks to use Throughline from Codex, continue or restore Throughline memory, run Codex trim/rewind/rollback, inject remembered context, summarize a captured Codex session, or check whether the Throughline Codex Stop hook captured the current session. Hide long Throughline command details behind this workflow.
4
+ ---
5
+
6
+ # Throughline
7
+
8
+ Use this skill to operate Throughline from Codex without making the user type long
9
+ commands.
10
+
11
+ If the user invokes `$throughline` by itself, treat that as a request to inspect
12
+ the current Codex context and prepare a refresh plan. Codex rollback / inject is
13
+ enabled again after controlled rollback model-visible smokes failed to reproduce
14
+ rollback marker resurrection.
15
+
16
+ ## Core Rule
17
+
18
+ Do not ask the user for a Codex thread id when the current environment can
19
+ provide it. Prefer the current `CODEX_THREAD_ID` / `THROUGHLINE_CODEX_THREAD_ID`
20
+ identity and verify it with `throughline doctor --codex`.
21
+
22
+ Do not manually capture payloads before checking natural Stop hook capture.
23
+ If natural capture looks wrong, inspect `doctor --codex`, the latest rollout,
24
+ and hook logs first.
25
+
26
+ ## Common Requests
27
+
28
+ ### Bare "$throughline" / "use Throughline"
29
+
30
+ Run:
31
+
32
+ ```bash
33
+ throughline doctor --codex
34
+ throughline trim --dry-run --host codex --all --json
35
+ throughline codex-handoff-start --session codex:<current-thread-id> --json
36
+ throughline trim --preflight --host codex --all --json
37
+ ```
38
+
39
+ This is the safe Codex context-refresh inspection flow. `--all` previews a
40
+ rollback-based reset of the model-visible thread. `codex-handoff-start` is an
41
+ optional fresh-thread continuation surface: it validates the handoff, shows the
42
+ model-smoke dry-run boundary, and can render the prompt with `--print-prompt`
43
+ without mutating the current thread. Report the preflight result, handoff-start
44
+ status, and context reduction estimate from the dry-run. Do not claim the
45
+ refresh happened unless `trim --execute` or auto-refresh actually ran.
46
+
47
+ The injected memory must preserve the original `/tl` memory contract:
48
+
49
+ - older turns: L1 summaries
50
+ - recent work: L2 full bodies for the latest 20 turns
51
+ - L3: detail references only; L3 bodies / tool payloads are not injected
52
+
53
+ If the dry-run reports no captured turns or no injectable memory, say that
54
+ clearly.
55
+
56
+ ### "Throughline status" / "doctor"
57
+
58
+ Run:
59
+
60
+ ```bash
61
+ throughline doctor --codex
62
+ ```
63
+
64
+ Report whether:
65
+
66
+ - Codex hooks feature is enabled
67
+ - Codex Stop hook is registered
68
+ - VSCode monitor task is registered, and whether `Developer: Reload Window` is
69
+ needed to make the folder-open monitor appear
70
+ - current Codex thread and latest DB session match
71
+
72
+ ### "resume" / "memory" / "continue from Throughline"
73
+
74
+ First run `throughline doctor --codex`.
75
+
76
+ If the current thread and latest DB session match, render memory with:
77
+
78
+ ```bash
79
+ throughline codex-resume --session codex:<current-thread-id>
80
+ ```
81
+
82
+ If the user gave a current-work memo, pipe it with `--memo-stdin`.
83
+
84
+ If the user wants to continue in a fresh Codex thread instead of mutating the
85
+ current thread, use:
86
+
87
+ ```bash
88
+ throughline codex-handoff-start --session codex:<current-thread-id> --print-prompt
89
+ ```
90
+
91
+ If the user gave a current-work memo, pipe it with `--memo-stdin`. This is
92
+ read-only and does not mutate the current thread.
93
+
94
+ ### "summarize"
95
+
96
+ Run:
97
+
98
+ ```bash
99
+ throughline codex-summarize --session codex:<current-thread-id> --json
100
+ ```
101
+
102
+ Codex-primary summarization uses the Codex CLI backend. Do not claim it fell
103
+ back to Claude Haiku.
104
+
105
+ ### "trim" / "rewind" / "rollback" / "context cleanup"
106
+
107
+ Default to the same inspection flow as bare `$throughline` when the user
108
+ asks to trim, rewind, rollback, clean up context, or use Throughline memory.
109
+
110
+ Preview:
111
+
112
+ ```bash
113
+ throughline trim --dry-run --host codex
114
+ ```
115
+
116
+ Safe new-thread continuation:
117
+
118
+ ```bash
119
+ throughline codex-handoff-start --session codex:<current-thread-id> --json
120
+ ```
121
+
122
+ Report the context reduction estimate from the dry-run when present:
123
+
124
+ - rollback candidate estimated tokens
125
+ - injected memory estimated tokens
126
+ - net estimated token reduction and percentage
127
+
128
+ The estimate is `chars / 4` from rollout text, not an exact host tokenizer
129
+ measurement. If rollback candidate turns are `0`, say that this session has no
130
+ current trim savings yet under the active keep-recent setting.
131
+
132
+ Guard check:
133
+
134
+ ```bash
135
+ throughline trim --preflight --host codex
136
+ ```
137
+
138
+ Execute path:
139
+
140
+ ```bash
141
+ throughline trim --execute --host codex --all
142
+ ```
143
+
144
+ Run this only when the user explicitly wants the current thread trimmed. It sends
145
+ rollback + Throughline DB memory injection after the app-server guard checks.
146
+
147
+ ## User-Facing Explanation
148
+
149
+ Explain the behavior simply:
150
+
151
+ - normal Codex turn end: Stop hook captures DB memory and writes monitor state
152
+ - `$throughline` / context refresh: doctor, dry-run, preflight, and optional
153
+ execute; execute mutates the current Codex thread
154
+ - Stop hook auto-refresh attempts rollback / inject when verified usage reaches
155
+ 90%; estimate usage does not trigger mutation
156
+ - dry-run reports estimated savings when there are rollback candidate turns, but
157
+ exact host-visible token reduction is not yet measured with the host tokenizer
@@ -0,0 +1,7 @@
1
+ interface:
2
+ display_name: "Throughline"
3
+ short_description: "Operate Throughline memory, Codex capture, resume, and trim"
4
+ default_prompt: "Use $throughline to check capture, resume memory, summarize, inspect guarded Codex trim, or prepare a safe fresh-thread handoff without typing long commands."
5
+
6
+ policy:
7
+ allow_implicit_invocation: true
@@ -0,0 +1,146 @@
1
+ # 引き継ぎ発火条件の絞り込み調査 & 実装計画
2
+
3
+ ## Status (2026-04-18 更新)
4
+
5
+ - **Phase 0 実機検証: 完了**
6
+ - **案 A 不成立**: VSCode 拡張 2.1.112 でも /clear 後の SessionStart は `source="startup"` で発火 (probe ログ 30 件中 startup 29 / resume 1)。公式 docs / MINGW64 環境と挙動が異なる既知差異
7
+ - **案 C 不成立**: SessionStart 発火時点で transcript ファイルは未作成
8
+ - **案 D(時間差ヒューリスティック): 撤回**。誤爆の可能性を排除できず、ユーザー明示指名の方が決定論的で意図が明確
9
+ - **採用: バトン方式(案 E)**: 旧セッションで `/tl` スラッシュコマンドを打つと UserPromptSubmit hook が `handoff_batons` テーブルに session_id を書き込み、次の新規セッションの SessionStart が TTL 1 時間以内のバトンを消費して merge する
10
+ - 実装: [src/baton.mjs](../src/baton.mjs), [src/prompt-submit.mjs](../src/prompt-submit.mjs), [src/session-start.mjs](../src/session-start.mjs), [src/session-merger.mjs](../src/session-merger.mjs) (`mergeSpecificPredecessor`), [.claude/commands/tl.md](../.claude/commands/tl.md)
11
+ - Bash tool サブプロセスには `$CLAUDE_SESSION_ID` 相当の env が無いため、session_id は UserPromptSubmit hook payload から取得する
12
+ - **GitHub issue**: [anthropics/claude-code#49937](https://github.com/anthropics/claude-code/issues/49937) 提出済み。修正されれば source ベースに戻す余地は残る
13
+
14
+ ## Context
15
+
16
+ Throughline の SessionStart フックは現在 **同一 project_path の未合流セッションがあれば無条件で記憶を引き継いでいる**。そのため以下が起きている:
17
+
18
+ - ユーザーが `/clear` していないのに手動で新規セッションを始めると、前任の記憶が引き継がれて「90 ターン引き継ぎました」と注入される(**最優先で解消したい挙動**)
19
+ - VSC を再起動して完全新規セッションを開いた場合も同様に引き継がれる
20
+
21
+ ユーザーの望む挙動: **`/clear` 直後の新規セッションのときだけ** 前任を引き継ぎ、手動新規・VSC 再起動後の新規では引き継がない。
22
+
23
+ ## Findings (2026-04-17 時点)
24
+
25
+ ### 現行実装 (根拠: [src/session-start.mjs](../src/session-start.mjs), [src/session-merger.mjs](../src/session-merger.mjs))
26
+
27
+ - [src/session-start.mjs:33](../src/session-start.mjs#L33) で payload の `source` を **読み捨てている**
28
+ - [src/session-start.mjs:48-51](../src/session-start.mjs#L48-L51) で無条件に `mergePredecessorInto` を呼ぶ
29
+ - [src/session-merger.mjs:68-78](../src/session-merger.mjs#L68-L78) の前任選定は「同 project_path・未合流・自分より created_at が古い・最新 updated_at」のみで、source や時間窓は見ていない
30
+
31
+ ### 過去ログは参考扱い
32
+
33
+ - `C:\Users\kite_\.throughline\spike\session-start.log` の 93 件は Opus 4.6 以前の採取で、モデル更新(現 4.7)と Claude Code バージョン更新を跨いでいる
34
+ - 「startup 76 / resume 16 / clear 1」の分布はあくまで参考値で、現行環境の挙動として採用しない
35
+ - コメント [src/session-start.mjs:7-10](../src/session-start.mjs#L7-L10) の「/clear 後も source='startup'」も当時の観察で、現行環境で再検証する
36
+
37
+ ### 確定したい前提
38
+
39
+ **「/clear 直後の SessionStart は `source === 'clear'` で識別できる」** を現行環境で実証できれば、案 A が成立する。できなければ別アプローチ(時間差 / transcript マーカー)に切り替える。
40
+
41
+ ## 想定アプローチ(合意用の選択肢)
42
+
43
+ ### 案 A: `source === "clear"` のみ引き継ぐ(シンプル案)
44
+
45
+ - [src/session-start.mjs](../src/session-start.mjs) で `source !== 'clear'` なら `mergePredecessorInto` を呼ばない
46
+ - 取りこぼし(startup で来る /clear)は許容
47
+ - ユーザー視点: 「手動新規・VSC 再起動・一部の /clear」で真に新規、それ以外は引き継ぐ
48
+
49
+ ### 案 B: `source === "clear"` + 時間差ヒューリスティック
50
+
51
+ - 案 A に加え、`source === "startup"` でも **前任の updated_at が N 秒以内**(候補: 60 秒)なら /clear 由来とみなし引き継ぐ
52
+ - 取りこぼしを減らせるが、「手動新規を早いタイミングで開いた」ケースを /clear と誤判定するリスクあり
53
+
54
+ ### 案 C: transcript マーカー判定
55
+
56
+ - 新 transcript の先頭に `<command-name>/clear</command-name>` が残っていれば /clear 由来と判定
57
+ - 未検証前提が多く、Claude Code 側の仕様変更で壊れやすい
58
+
59
+ ## 推奨アプローチ
60
+
61
+ **Phase 0 で `source` の実測 → 結果次第で案 A or B を確定 → 実装**。
62
+
63
+ - Phase 0 の結果、/clear で必ず `source='clear'` が来る & 手動新規・VSC 再起動では絶対に来ないことが確認できれば **案 A** で確定
64
+ - /clear で `source='startup'` が混じる場合は **案 B**(時間差ヒューリスティック併用)に切り替え
65
+ - いずれも案 C(transcript マーカー)は fallback として deferred
66
+
67
+ ## Phase 0: 実機検証(実装前に必ず実施)
68
+
69
+ **目的**: 現行環境(Opus 4.7 / 最新 Claude Code)で SessionStart payload の `source` が /clear / 手動新規 / VSC 再起動でそれぞれ何になるかを確定する。
70
+
71
+ ### 手順
72
+
73
+ 1. **debug ロガーを [src/session-start.mjs](../src/session-start.mjs) に一時挿入**
74
+ - payload を受け取った直後(L32 の JSON.parse 直後)に `{ ts, source, session_id, transcript_path, cwd }` を `C:\Users\kite_\.throughline\logs\sessionstart-probe.log` に追記
75
+ - 既存のマージ処理には触れない(挙動を変えずに観測だけする)
76
+ - 1 行 1 JSON (JSONL) 形式で append
77
+
78
+ 2. **ユーザー手動で 3 ケース × 複数回の実機採取**
79
+ - **ケース 1: /clear 後の新規セッション** — チャット中に `/clear` 実行 → SessionStart 発火 → 1 行ログ取得 × 3 回以上
80
+ - **ケース 2: 手動新規セッション** — VSC 内で新規チャット作成操作 → SessionStart 発火 → 1 行ログ取得 × 3 回以上
81
+ - **ケース 3: VSC 再起動直後** — VSC を終了 → 起動 → Throughline 有効なプロジェクトを開いた直後 → 1 行ログ取得 × 3 回以上
82
+
83
+ 3. **集計と判定**
84
+ - ケース 1 が **全回 `source='clear'`** → 案 A 確定
85
+ - ケース 1 に `startup` が混じる / ケース 2 または 3 に `clear` が混じる → 案 B に切り替えて時間差閾値を設計
86
+
87
+ 4. **debug ロガー撤去**
88
+ - 判定後は [src/session-start.mjs](../src/session-start.mjs) から削除(commit 分離)
89
+
90
+ ## 実装ステップ(案 A 前提・Phase 0 通過後に実施)
91
+
92
+ 1. **[src/session-start.mjs](../src/session-start.mjs) 修正**
93
+ - L33: `const { session_id, source, cwd } = payload` に変更して `source` を取得
94
+ - L7-10 のコメントを実機ログに合わせて更新(「source='clear' のときだけ引き継ぐ。startup で来る /clear は取りこぼす」仕様を明記)
95
+ - L48 付近: `if (source === 'clear') { mergePredecessorInto(...) }` でガード
96
+ - 引き継がない場合も [src/session-start.mjs:41-45](../src/session-start.mjs#L41-L45) の sessions INSERT は従来通り実行(DB には残す)
97
+
98
+ 2. **[src/session-merger.test.mjs](../src/session-merger.test.mjs) にテスト追加**
99
+ - `resolveMergeTarget` / `mergePredecessorInto` は現状維持(判定は session-start 側に持たせる)
100
+ - 代わりに session-start.mjs の条件分岐をユニット化する。テストは薄めの統合で:
101
+ - source='clear' → `mergePredecessorInto` が呼ばれ合流する
102
+ - source='startup' → 呼ばれず前任 sessions の merged_into が NULL のまま
103
+ - source='resume' → 同上
104
+ - 既存 [src/session-merger.test.mjs:121-151](../src/session-merger.test.mjs#L121-L151) の時系列単調性テストは引き続きパスする前提
105
+
106
+ 3. **[src/resume-context.mjs](../src/resume-context.mjs) と注入ヘッダ**
107
+ - 注入は session-start.mjs 側の `mergeResult.merged` 分岐で既に制御されているので修正不要
108
+ - ただし「同一 session 継続(source='resume')での注入」が必要か要検討。現状の resume フックは本計画のスコープ外として deferred(別タスクで検討)
109
+
110
+ 4. **[docs/L1_L2_L3_REDESIGN.md](L1_L2_L3_REDESIGN.md) / [CLAUDE.md](../CLAUDE.md) / [README.md](../README.md) の更新**
111
+ - 「記憶張り替えの発火条件は SessionStart source='clear' のみ」を明記
112
+ - CLAUDE.md 冒頭「設計の核」の「`/clear` 後も SQLite はそのまま残る。`SessionStart` フックで前任セッションの全レコードを新 session_id に張り替える」の直後に引き継ぎ条件を追記
113
+
114
+ ## 最終検証手順(Phase 0 通過 & 案 A 実装後)
115
+
116
+ 1. `node --test src/*.test.mjs` が全部グリーン(既存 + 追加ケース)
117
+ 2. 手動 E2E:
118
+ - Throughline 有効状態で VSC を終了
119
+ - VSC 再起動 → 新規セッション → 引き継ぎヘッダが **出ない** ことを確認
120
+ - そのセッション内で `/clear` → 新規セッション → 引き継ぎヘッダが **出る** ことを確認(source='clear' が来たケース)
121
+ - 同じ操作を 3 回繰り返し、source='startup' で /clear した回のスキップが許容範囲か観測
122
+ 3. `C:\Users\kite_\.throughline\throughline.db` を直接確認:
123
+ ```bash
124
+ node --input-type=module <<'EOF'
125
+ import { getDb } from './src/db.mjs';
126
+ const db = getDb();
127
+ console.log(db.prepare("SELECT session_id, merged_into, created_at FROM sessions ORDER BY created_at DESC LIMIT 10").all());
128
+ EOF
129
+ ```
130
+ - 手動新規 / VSC 再起動時の `merged_into` が NULL のまま残ること
131
+ - /clear 後のセッションでのみ前任の `merged_into` が新 session_id を指すこと
132
+
133
+ ## 重要ファイル一覧
134
+
135
+ - [src/session-start.mjs](../src/session-start.mjs) — 主変更箇所
136
+ - [src/session-merger.mjs](../src/session-merger.mjs) — 参照のみ(現状維持)
137
+ - [src/session-merger.test.mjs](../src/session-merger.test.mjs) — テスト追加
138
+ - [src/resume-context.mjs](../src/resume-context.mjs) — 参照のみ
139
+ - [CLAUDE.md](../CLAUDE.md) / [docs/L1_L2_L3_REDESIGN.md](L1_L2_L3_REDESIGN.md) / [README.md](../README.md) — ドキュメント更新
140
+
141
+ ## Non-Goals (本計画では扱わない)
142
+
143
+ - VSC 拡張側の source 送信挙動の調査・修正(Claude Code 本体のスコープ)
144
+ - 並行セッション X-1 問題の解決([docs/archive/SESSION_LINKING_DESIGN.md:194](archive/SESSION_LINKING_DESIGN.md#L194) で受容済み)
145
+ - source='startup' で来る /clear の取りこぼし対策(案 B/C は fallback として deferred)
146
+ - token-monitor / sc-detail 系 CLI への影響調査(本計画と独立)