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,672 @@
1
+ # Throughline Codex Trim Rollback 修正計画
2
+
3
+ この文書は、2026-05-06 の Codex trim rollback インシデントを受けた修正 TODO です。
4
+
5
+ 対象インシデント:
6
+
7
+ - [throughline-codex-trim-rollback-incident-report.md](throughline-codex-trim-rollback-incident-report.md)
8
+ - Codex thread: `019dfd6f-640e-7dd3-b163-3f9add39fde7`
9
+ - 報告元プロジェクト: `/home/kite/projects/Spotter`
10
+
11
+ ## 状態
12
+
13
+ 2026-05-08 update: この計画で一時導入した Codex trim execute / auto-refresh の
14
+ 過剰 blocker は解除済みです。
15
+
16
+ 現在の証拠では、rollback 対象 user prompt が `compacted.replacement_history` や
17
+ quoted/tool-output field に残り得ることは確認済みですが、それが次 turn の
18
+ model-visible input に入ることは controlled smoke で再現していません。incident-shaped
19
+ run の retained text は risk evidence として残す一方、単独では mutation 前 blocker にしません。
20
+ Codex current-thread trim は、明示 `--execute`、Throughline DB injectable memory、
21
+ Codex thread identity、rollout/app-server turn-count guard を条件に実行します。Codex Stop hook
22
+ auto-refresh は verified usage 90% 以上で同じ guarded path を試行し、estimate usage では実行しません。
23
+
24
+ 最初のインシデント仮説に対する重要な訂正:
25
+
26
+ - 対象 rollout には、永続化された `event_msg: thread_rolled_back` marker が
27
+ **存在します**。line `1784`、timestamp `2026-05-06T14:39:44.844Z`、
28
+ `num_turns: 19`。
29
+ - したがって主原因は、単純な「rollback marker が書かれなかった」ではありません。
30
+ - より強い仮説は、Codex restore が `compacted.replacement_history`、
31
+ あるいは Throughline の現行 guarded execute check が見ていない
32
+ restart / pending input source を使っている、というものです。
33
+
34
+ ## 日本語要約
35
+
36
+ Throughline は Codex の会話を短くするために、古い会話を rollback して、
37
+ 必要な記憶だけを developer message として入れ直す。
38
+
39
+ 今回わかった問題は、表の会話履歴には `thread_rolled_back` が残っていても、
40
+ その直前の `compacted.replacement_history` に古い user 発言が残っていたこと。
41
+ さらに app-server response の一部にも同文が見えたが、後続分類では
42
+ `aggregatedOutput` など quoted/tool-output field に限定された。したがって
43
+ 「新しい user 入力として復活した」とはまだ言い切らず、restore safety risk として扱う。
44
+
45
+ つまり現状の Throughline は「live app-server では rollback できた」ことを確認しており、
46
+ controlled marker では VS Code restart 後の model-visible 復活も再現していない。
47
+ 一方で `compacted.replacement_history` retention は診断として残す。
48
+
49
+ ## 関係ファイル
50
+
51
+ 関係しそうな実装ファイル:
52
+
53
+ - `src/cli/trim.mjs`
54
+ - `src/codex-app-server.mjs`
55
+ - `src/codex-host-primitive-audit.mjs`
56
+ - `src/codex-rollout-memory.mjs`
57
+ - `src/codex-auto-refresh.mjs`
58
+ - `src/trim-model.mjs`
59
+ - `src/codex-handoff.mjs`
60
+
61
+ 関係しそうなテスト:
62
+
63
+ - `src/trim-cli.test.mjs`
64
+ - `src/codex-app-server.test.mjs`
65
+ - `src/codex-rollout-memory.test.mjs`
66
+ - `src/codex-auto-refresh.test.mjs`
67
+ - `src/codex-capture.test.mjs`
68
+
69
+ 実装修正後に追従更新が必要な docs:
70
+
71
+ - `CLAUDE.md`
72
+ - `docs/THROUGHLINE_CODEX_FIRST_ROADMAP.md`
73
+ - `docs/THROUGHLINE_CODEX_TRIM_IMPLEMENTATION_PLAN.md`
74
+ - `docs/throughline-rollback-context-trim-insight.md`
75
+ - `docs/PUBLIC_RELEASE_PLAN.md`
76
+ - `docs/throughline-codex-trim-rollback-incident-report.md`
77
+
78
+ ## フェーズ 0: 危険な変更処理を止める
79
+
80
+ 目的: durable restore semantics が未解決の間、古い user prompt が model-visible
81
+ input に戻る可能性を安全扱いしない。
82
+
83
+ 2026-05-08 注記: このフェーズは incident 直後の封じ込め履歴です。controlled smoke
84
+ で rollback marker の model-visible 復活が未再現だったため、ここで導入した
85
+ execute / auto-refresh blocker は後段の製品判断で解除済みです。
86
+
87
+ TODO:
88
+
89
+ - [x] bare `$throughline` skill の挙動を変更し、自動では
90
+ `throughline trim --execute --host codex --all` を実行しないようにする。
91
+ - [x] `doctor --codex`、`trim --dry-run --host codex --all --json`、
92
+ `trim --preflight --host codex --all --json` は引き続き使えるようにする。
93
+ - [x] historical containment: `trim --execute --host codex` は、明示的な experimental / force flag が
94
+ 無い限り既定で拒否していた。
95
+ - [x] historical containment: 拒否メッセージでは、Codex rollback の VS Code restart / reconnect 越しの
96
+ durability が未解決であることを明示する。
97
+ - [x] historical containment: `src/codex-auto-refresh.mjs` の Codex auto-refresh mutation を無効化する。
98
+ - [x] Codex thread を mutate しない capture / summarize / resume は維持する。
99
+
100
+ 受け入れ条件:
101
+
102
+ - [x] historical containment: bare `$throughline` では Codex thread を mutation できない。
103
+ - [x] historical containment: Codex Stop hook は rollback / inject による auto-refresh を実行できない状態にしていた。
104
+ - [x] 手動 dry-run と preflight は引き続き動く。
105
+ - [x] 既存 Claude `/tl` と Claude resume behavior は変わらない。
106
+
107
+ ## フェーズ 1: 注入した記憶の識別を直す
108
+
109
+ 目的: Throughline が自分で注入した記憶を、後から正しく認識できるようにする。
110
+
111
+ 現状のバグ:
112
+
113
+ - 2026-05-07 修正前、execute は `## Throughline Trim Memory Preview` という見出しの text を注入していた。
114
+ - `parseCodexRolloutFile()` は、本文が
115
+ `## Throughline: Active Work Context` で始まる場合だけ、
116
+ Throughline が注入した active-work 記憶と認識する。
117
+ - incident rollout では `injectedDeveloperMessages` が `0` だった。
118
+
119
+ TODO:
120
+
121
+ - [x] dry-run preview と execute injection の意味を分離する。
122
+ - 実行で注入できるのは Throughline DB 由来の canonical active-work context だけ。
123
+ - Codex rollout 由来の `## Throughline Trim Memory Preview` は plan / dry-run 用で、
124
+ DB memory が無い場合の execute は `injectable_memory_required` で拒否する。
125
+ - [x] 実際に注入する developer message では
126
+ `## Throughline: Active Work Context` を使う。
127
+ - [x] `## Throughline Trim Memory Preview` は Codex rollout preview 用に限定し、
128
+ execute injection には使わない。
129
+ - [x] execute が active-work header を注入することをテストで固定する。
130
+ - [x] parser が injected active-work message を数えることをテストで固定する。
131
+
132
+ 受け入れ条件:
133
+
134
+ - [x] `trim --dry-run` は引き続き preview を表示する。
135
+ - [x] `trim --execute` は preview-only rollout text ではなく canonical active-work context を注入する。
136
+ - [x] `parseCodexRolloutFile()` が injected Throughline 記憶を正しく報告する。
137
+
138
+ ## フェーズ 2: 圧縮履歴からの復元リスクをモデル化する
139
+
140
+ 目的: rollback 対象の user turn が `compacted.replacement_history` に残っている場合、
141
+ Throughline は rollback を安全扱いしてはいけない。
142
+
143
+ 証拠:
144
+
145
+ - incident line `1775` は `compacted` row。
146
+ - その `replacement_history` には、後で risk text match として観測された user
147
+ prompt が含まれている。
148
+ - incident line `1784` は `thread_rolled_back { num_turns: 19 }`。
149
+ - incident line `1864` / `1865` では、同じ prompt と一致する text が
150
+ restart / reconnect 後の diagnostics に現れている。ただし現時点では、
151
+ これを次 turn の model-visible user message として再投入された証明とは扱わない。
152
+
153
+ TODO:
154
+
155
+ - [x] 次を含む fixture data を追加する:
156
+ - 通常の user turns
157
+ - それらの user turns を含む `compacted.replacement_history`
158
+ - `thread_rolled_back`
159
+ - restart simulation 後の duplicate user message
160
+ - [x] rollout parsing diagnostics を拡張し、`compacted` rows と
161
+ replacement-history user messages の数を検出する。
162
+ - [x] rollback 後も rollback-targeted text が compacted replacement source に
163
+ 残っている場合に検出できる diagnostic を追加する。
164
+ - [x] この diagnostic を `parseCodexRolloutFile()` に置くか、
165
+ 新しい restore-safety module に置くか、trim preflight layer に置くかを決める。
166
+ - 判断: rollout parser に `restoreSafety` diagnostics を置き、trim source /
167
+ dry-run / preflight plan へ伝播する。
168
+
169
+ 受け入れ条件:
170
+
171
+ - [x] incident-shaped fixture が durable-safety check に失敗する。
172
+ - [x] check は plain output と JSON output の両方で risk を説明できる。
173
+ - [x] 既存 active-turn reconstruction は引き続き `thread_rolled_back` を正しく適用する。
174
+
175
+ ## フェーズ 3: 事前確認 / 実行の意味を強化する
176
+
177
+ 目的: success status は、実際に証明できたことだけを表すようにする。
178
+
179
+ 現状のバグ:
180
+
181
+ - 2026-05-07 修正前、durable restart behavior が未検証でも、`trim --execute` は
182
+ `status: executed` / `reason: rollback_and_inject_sent` を返し得る。
183
+ - 2026-05-07 修正前、`postInjectVisibilityCheck` が timeout しても、外側の command は executed と
184
+ 報告し得る。
185
+
186
+ TODO:
187
+
188
+ - [x] `sent` と durable success が混同されないように status を rename / split する。
189
+ - [x] たとえば次のような status を追加する:
190
+ - `execute-refused`
191
+ - `execute-sent-live-only`
192
+ - `execute-unverified`
193
+ - `execute-durable-verified`
194
+ - [x] post-inject visibility timeout は clean success ではなく unverified と扱う。
195
+ - [x] `thread/inject_items` が turn list を返さない developer memory item-level injection は、
196
+ rollback 後 turn count のまま `match` と扱う。injected item を常に turn 増加として
197
+ 数える古い前提は捨てる。
198
+ - [x] preflight JSON に restore-safety diagnostics を含める。
199
+ - [x] historical 2026-05-07: preflight / execute は、既知の `restoreSafety.status: risk` を
200
+ `ready` / success と扱わず、`restore_safety_risk` で拒否していた。
201
+ 2026-05-08 unblock 後は diagnostic として表示し、単独では拒否しない。
202
+ - [x] preflight / execute は、まだ rollback event が無い rollout でも、
203
+ planned rollback 対象の user text が既存 `compacted.replacement_history` に
204
+ 含まれている場合は `planned_restore_safety_risk` を報告する。
205
+ - 2026-05-07 追加修正: incident-shaped live run は実行前
206
+ `restoreSafety.status = ok` だったが、rollback 後に compacted retention が
207
+ risk と判定された。これは実行前にも「rollback 予定 tail user text」と
208
+ compacted replacement history を照合すれば予測可能だったため、
209
+ `inspectCodexPlannedRollbackRestoreSafety()` を追加した。
210
+ 2026-05-08 unblock 後は mutation 前 blocker ではなく、dry-run report に
211
+ `Planned rollback restore safety` として表示する。
212
+ - [x] execute 後の durable verification は rollout を poll し、遅れて永続化される
213
+ `thread_rolled_back` marker と active-work memory injection を待てるようにする。
214
+ - [x] `execute-sent-live-only` は durable success ではないため、CLI exit code は
215
+ 失敗扱いにする。
216
+ - [x] default execute path では restore-safety diagnostics を表示する。
217
+ - historical 2026-05-07: default execute path 自体を拒否し、明示 local experiment でも
218
+ host primitive audit の same-thread repair contract を要求していた。
219
+ - 2026-05-08 unblock 後: rollout に新しい `thread_rolled_back` marker と
220
+ active-work memory injection が観測される場合だけ
221
+ `execute-durable-verified` / `durableVerification.durableVerified: true` を返す。
222
+
223
+ 受け入れ条件:
224
+
225
+ - [x] live app-server mutation しか観測していない時、CLI は durable success と言わない。
226
+ - [x] live app-server mutation しか観測していない時、CLI は exit 0 で成功扱いしない。
227
+ - [x] JSON output 上で live-only と durable-verified を混同できない。
228
+ - [x] post-inject timeout と compacted restore risk を別々の test で固定する。
229
+ - [x] historical 2026-05-07: 既知の compacted restore risk がある場合、execute は app-server を起動する前に拒否していた。2026-05-08 unblock 後は diagnostic-only。
230
+ - [x] historical 2026-05-07: planned rollback が compacted replacement history retained text を対象にする場合、
231
+ preflight / execute は app-server を起動する前に拒否していた。2026-05-08 unblock 後は diagnostic-only。
232
+ - [x] durable marker / injected memory row が遅れて rollout に出る場合も、
233
+ poll window 内なら durable verified として確認できる。
234
+
235
+ ## フェーズ 4: 安全な製品仕様を決める
236
+
237
+ 目的: インシデント後のユーザー向け挙動を決める。
238
+
239
+ 製品判断の前提:
240
+
241
+ - historical 2026-05-07 premise: Codex rollback / inject は、Codex が verified durable restart-safe primitive を
242
+ 提供するまで preview-only にする。
243
+ - historical 2026-05-07 premise: manual execute は local experiment 用の明示 danger flag だけでは許可しない。
244
+ host primitive audit の same-thread repair contract が
245
+ `candidate-requires-live-validation` を返す場合だけ mutation path へ進める。
246
+ - current 2026-05-08 decision: controlled rollback model-visible smoke が app-server
247
+ restart と VS Code reload/reconnect の両方で clean だったため、manual execute と
248
+ automatic mutation は再有効化する。host primitive audit と restore-safety は diagnostic-only。
249
+ - 目標は当該 Codex thread の context trim を restart-safe に成立させることであり、
250
+ new-thread handoff は完成形ではない。2026-05-08 unblock 後は current-thread trim
251
+ を本線に戻し、new-thread handoff は明示的に新規 thread で続けたい場合の surface として残す。
252
+ - 現行 host では、別 thread の作業継続 surface を new-thread handoff として出す。
253
+ `throughline codex-resume --session codex:<thread-id> --format handoff` で
254
+ 新規 Codex thread 用 handoff prompt を描画し、新しい Codex thread へ渡す。
255
+ これは current thread を mutate しない。
256
+
257
+ TODO:
258
+
259
+ - [x] Codex app-server が、rollback 済み user text の durable non-resurrection
260
+ primitive を提供しているか調査する。
261
+ - 2026-05-07 調査: `codex app-server --help` と generated schema / TypeScript では
262
+ `thread/rollback`、`thread/inject_items`、`thread/read`、`thread/resume`、
263
+ `thread/compact/start` は確認できたが、rollback 済み user text を deletion /
264
+ isolation / projection で model-visible input から外す documented durable rollback
265
+ primitive は見つからなかった。
266
+ - 2026-05-07 追加実装: `throughline codex-host-primitive-audit` を追加した。
267
+ installed Codex CLI の `codex app-server generate-json-schema --experimental` を
268
+ read-only で実行し、rollback 済み user text を current-thread の model-visible
269
+ input に復活させない deletion / isolation / projection primitive の有無を
270
+ 機械判定する。
271
+ 実環境の `codex-cli 0.128.0-alpha.1` では method count `89`、
272
+ `thread/rollback` / `thread/inject_items` / `thread/compact/start` /
273
+ `thread/start` / `thread/fork` / `thread/resume` は存在したが、
274
+ current-thread history rewrite / compacted-history clear 系 method は `0`。
275
+ isolation / projection 系 method も `0`。
276
+ `thread/resume(history)` は schema 上存在するが
277
+ `[UNSTABLE] FOR CODEX CLOUD - DO NOT USE` で、さらに `history > path > thread_id`
278
+ の precedence により `thread_id` が無視されるため、Throughline の
279
+ current-thread repair primitive としては採用しない。
280
+ 監査結果は `status = host-primitive-audit-blocked` /
281
+ `reason = no_current_thread_restore_non_resurrection_primitive`。
282
+ - 2026-05-08 追加実装: 同 audit に host-agnostic same-thread repair contract を
283
+ 追加した。contract は VS Code に依存せず、deletion / isolation / projection の
284
+ いずれかによる rollback non-resurrection guarantee、memory reinjection、
285
+ post-repair host read verification、restart/reconnect non-resurrection smoke を
286
+ 要求する。現行 schema では
287
+ `repairContract.status = blocked-missing-current-thread-non-resurrection-guarantee`。
288
+ VS Code restore / log / extension audit はこの contract の evidence collector であり、
289
+ repair primitive そのものではない。
290
+ - historical 2026-05-07: `trim --execute --host codex` は
291
+ `THROUGHLINE_EXPERIMENTAL_CODEX_TRIM_EXECUTE=1` があっても、実行前に
292
+ `codex-host-primitive-audit` 相当の schema audit を走らせ、same-thread
293
+ repair contract が blocked の場合は拒否していた。
294
+ - 2026-05-08 unblock: host primitive audit は diagnostic-only に変更した。
295
+ 現行 Codex CLI に same-thread repair primitive が無い事実は表示するが、
296
+ DB memory と rollout/app-server turn-count guard がそろう execute を塞がない。
297
+ - `~/.codex/state_5.sqlite` の `threads` table は rollout path / metadata を持つが、
298
+ turn bodies は持たない。turn body の主根拠は rollout JSONL 側である可能性が
299
+ 高いが、VS Code extension restore source は別途未確定。
300
+ - [x] fresh-thread handoff continuation path を表示する。
301
+ - 2026-05-07 追加: `trim --dry-run --host codex` の plan と
302
+ `doctor --trim --host codex` に fresh-thread handoff path を追加した。
303
+ guided command は `throughline codex-handoff-start --session codex:<thread-id>`。
304
+ smoke command は `throughline codex-handoff-smoke --session codex:<thread-id>`。
305
+ model smoke dry-run は `throughline codex-handoff-model-smoke --session codex:<thread-id> --dry-run --json`。
306
+ memory command は `throughline codex-resume --session codex:<thread-id> --format handoff`。
307
+ - 2026-05-08 unblock 後も、これは current-thread trim の代替ではなく、明示的に
308
+ 新規 thread で続けたい場合の選択肢として維持する。
309
+ これは current thread を mutate せず、新しい Codex thread に fresh-thread
310
+ handoff context を渡すための暫定 surface である。完成形はあくまで
311
+ 当該 thread の restart-safe trim / repair であり、handoff view は L2 件数 /
312
+ 本文長 / detail refs を cap し、full active-work context は通常の
313
+ `codex-resume` text renderer に残す。
314
+ - 2026-05-08 追加: `codex-handoff-smoke` は new-thread handoff prompt の
315
+ fresh-thread header、current-task contract、source session、start instruction、
316
+ mutation boundary、prompt size、detail command dedupe を read-only に検査する。
317
+ - 2026-05-08 追加: `codex-handoff-model-smoke --dry-run` は env なしで
318
+ structural smoke 後の `codex exec --ephemeral --ignore-user-config
319
+ --ignore-rules --sandbox read-only` command boundary と結合 prompt size を
320
+ 監査し、Codex CLI / model turn を起動しない。
321
+ - 2026-05-08 追加: `codex-handoff-start` は上記の smoke / model dry-run /
322
+ handoff render / optional live smoke / `--print-prompt` を一つの
323
+ read-only guided start plan として表示する。`--memo-stdin` 時は replay 用の
324
+ 個別 command にも `--memo-stdin` を伝播し、same memo を pipe する注意を出す。
325
+ - `thread/fork` / `thread/start` は app-server schema 上存在するが、VS Code の
326
+ current-thread identity switch と compacted-history behavior が未証明なので、
327
+ fresh-thread handoff の内部 primitive には採用しない。
328
+ - [x] human-readable dry-run が巨大な memory preview で診断を埋めないようにする。
329
+ - 2026-05-07 追加: text report の `Curated Memory Preview` は
330
+ `previewMaxChars` で truncate する。plan / JSON の `memoryPreview.text` は full のまま。
331
+ Codex では fresh-thread continuation path に新規 thread handoff 用の guided command
332
+ `throughline codex-handoff-start --session codex:<thread-id>` と直接 render command
333
+ `throughline codex-resume --session codex:<thread-id> --format handoff` を表示する。
334
+ - [ ] VS Code restore が rollout JSONL、`compacted.replacement_history`、
335
+ 別の persisted thread store、pending input queue のどれを使うか調査する。
336
+ - 2026-05-07 partial: `throughline codex-restore-source-audit` を追加した。
337
+ これは Codex rollout、`session_index.jsonl`、`state_*.sqlite`、VS Code
338
+ globalStorage / workspaceStorage 候補、installed OpenAI/Codex VS Code
339
+ extension bundle を read-only で棚卸しする。
340
+ - 実 project thread `019dfddb-8288-7392-a461-bf3ebc5da409` では rollout と
341
+ session index と `state_5.sqlite` の `threads` metadata row が見つかった。
342
+ `agent_job_items` / `stage1_outputs` は content 系 table 候補だが、この
343
+ thread id に紐づく row は 0。VS Code globalStorage / workspaceStorage audit は
344
+ 45 files scanned / 0 matches だった。
345
+ - proof scope は `local_restore_source_inventory_only` で、VS Code extension
346
+ restart の実 restore path を直接実行するものではない。そのためこの TODO は
347
+ full VS Code smoke ができるまで未完了のまま残す。
348
+ - 2026-05-07 追加実装: `codex-restore-source-audit` が installed VS Code
349
+ extension bundle の static audit も返すようになった。実環境では
350
+ `openai.chatgpt-26.429.30905-linux-x64` から `thread/read`、`thread/resume`、
351
+ `thread/turns/list`、`thread/compact/start`、`thread/rollback`、
352
+ `markAllConversationsNeedResumeAfterReconnect`、`needs_resume`、
353
+ `codex:persisted-atom:` を検出し、`replacement_history` は未検出。
354
+ conclusion は `vscode_extension_reconnect_appears_to_resume_threads_via_app_server`。
355
+ reconnect 時は in-memory conversation を `needs_resume` に戻し、app-server
356
+ resume/read 系へ寄せる仮説が強い。
357
+ - 2026-05-07 追加実装: `chatgpt.followUpQueueMode`、`send-follow-up-message`、
358
+ `steeringUserMessage` も static signal として
359
+ audit に出すようにした。実環境では follow-up queue signals は yes だが、
360
+ VS Code globalStorage / workspaceStorage は 45 files scanned / 0 matches のまま。
361
+ つまり pending input queue のコード経路はあるが、current thread id または
362
+ retained rollback text を持つ local persisted restore source は未検出。
363
+ - 2026-05-07 追加実装: 同 audit が VS Code `settings.json` と logs も別枠で
364
+ read-only scan するようになった。実環境では VS Code settings は searched だが
365
+ `chatgpt.followUpQueueMode` は not-configured。installed extension package の
366
+ default は `queue`。logs は 1185 files scanned / 1 match で、match は thread id
367
+ のみ。retained rollback text は VS Code logs でも未検出だった。
368
+ - 2026-05-08 追加実装: VS Code logs audit を structured signal に分けた。
369
+ thread id / retained rollback text の raw needle match に加え、
370
+ `Failed to apply patches for conversationId=<thread-id>`、thread stream broadcast、
371
+ `replacement_history` signal を数える。実 current thread の再監査では logs は
372
+ 1185 files scanned、raw match files `2`、thread id matches `40`、
373
+ retained rollback text matches `0`、patch apply failures `39`、
374
+ patch failure window `2026-05-07 00:35:35.339 -> 2026-05-07 00:36:29.925`、
375
+ thread stream signals `164`、`replacement_history` signals `0`。
376
+ これは VS Code extension log に thread-specific patch failure が多数ある証拠だが、
377
+ retained rollback text が logs に永続化されている証拠ではない。
378
+ - 同 bundle には webview `localStorage` の `codex:persisted-atom:` prefix も
379
+ 見える。これは UI atom persistence であり、rollback 済み user turn の durable
380
+ restore source かは未確定。
381
+ - [ ] 当該 thread の restart-safe trim / repair path を実現する。
382
+ - 完成条件は「同じ Codex thread で、rollback 対象 text が model-visible restore
383
+ path から再投入されず、VS Code restart / reconnect 後も復活しない」こと。
384
+ - 実装 contract は host-agnostic に固定する。VS Code は事故境界と実測環境として
385
+ 扱い、VS Code 専用 storage / webview patch を product repair primitive として
386
+ 直接採用しない。
387
+ - 既存の fresh-thread handoff path はこの TODO の代替完了条件ではない。
388
+ - 候補は、host が current-thread deletion / isolation / projection primitive を
389
+ 提供する場合の guarded repair、または host が実際に読む durable source を
390
+ 特定した上での current-thread repair である。未特定 source を推測で書き換えない。
391
+ - acceptance は `codex-vscode-rollback-smoke --verify --after-vscode-restart` が
392
+ `restartSafe: true` を返し、`restoreSafety.status = ok`、retained rollback text
393
+ `0`、resurrected user messages `0` になること。
394
+ - [ ] live `thread/read` だけに依存しない restart / reconnect smoke を設計する。
395
+ - 2026-05-07 partial: `throughline codex-restore-smoke` を追加した。これは
396
+ fresh Codex app-server process を複数回起動し、`thread/read` / `thread/resume` /
397
+ paginated `thread/turns/list` turn count が rollout active turn count と
398
+ 一致し続けるかを read-only で確認する。
399
+ - 2026-05-07 historical count-only 実測: project thread
400
+ `019dfddb-8288-7392-a461-bf3ebc5da409` では 2 cycles とも rollout /
401
+ read / resume turns `14 / 14 / 14` で stable だった。
402
+ - 2026-05-07 追加: smoke の app-server 観測口に `thread/turns/list` を足し、
403
+ `thread/read` / `thread/resume` とは別の paginated turn source も不一致なら
404
+ `app-server-restart-mismatch` にするよう固定した。current incident thread は
405
+ restore-safety risk があるため、この smoke は app-server 起動前に refused する。
406
+ 2026-05-08 の risky response inspection では、turn count 安定だけでは成功扱いせず、
407
+ retained rollback text を blocking candidate と quoted/tool-output field に分類する。
408
+ - proof scope は `app_server_process_restart_only` で、VS Code restart /
409
+ reconnect 越しの rollback / inject durability 証明ではない。そのためこの TODO は
410
+ full VS Code smoke ができるまで未完了のまま残す。
411
+ - 2026-05-07 partial: `throughline codex-vscode-restore-smoke` を追加した。
412
+ `--prepare` は hidden active-work marker memory を app-server に注入し、
413
+ VS Code reload / reconnect 後に marker を含まない prompt を送るための
414
+ 二段階手順を出す。`--verify` は rollout を読み、prepare 後の assistant
415
+ marker-free smoke prompt、assistant の marker-only answer、user prompt への
416
+ marker leak 不在を検証する。
417
+ - prepare は mutation なので `THROUGHLINE_EXPERIMENTAL_CODEX_VSCODE_RESTORE_SMOKE=1`
418
+ 必須。verify は read-only。`restartSafe: true` は `--after-vscode-restart`
419
+ 明示と marker proof がそろう場合だけ返す。
420
+ - 2026-05-07 実測: project thread `019dfddb-8288-7392-a461-bf3ebc5da409` で
421
+ `--prepare` が marker `TL_CODEX_VSCODE_RESTORE_46888202` を注入した。
422
+ VS Code reload / reconnect 後に marker-free smoke prompt を送ると、assistant は
423
+ marker-only answer を返した。`--verify --after-vscode-restart` は
424
+ `status = vscode-restart-visible` / `restartSafe = true` を返し、
425
+ `userMarkerMatches = []` だった。
426
+ - 同 run 中に、assistant の通常進捗メッセージに marker が含まれただけで
427
+ false positive になり得る verifier バグも見つけた。修正後は
428
+ marker-free prompt と marker-only answer がそろう場合だけ成功扱いする。
429
+ - これは hidden developer memory の restart / reconnect 後 model visibility 証明であり、
430
+ rollback 済み user turn が復活しないことの証明ではない。そのため、当時は
431
+ automatic trim 再有効化の根拠には使わなかった。
432
+ - [x] rollback 非復活 proof を read-only で判定する verifier を追加する。
433
+ - 2026-05-07: `throughline codex-vscode-rollback-smoke --verify` を追加した。
434
+ これは rollout を読み、`thread_rolled_back`、rollback 済み user message、
435
+ rollback 後の user message、`restoreSafety.status = ok` を必須条件にする。
436
+ - `--after-vscode-restart` が無い場合は
437
+ `rollback-nonresurrection-visible-restart-unacknowledged` で止め、
438
+ restart-safe proof とは扱わない。
439
+ - `compacted.replacement_history` に rollback 済み user text が残る場合、
440
+ または rollback 後に同じ user text が再出現する場合は `risk` として拒否する。
441
+ - `parseCodexRolloutFile()` は `userMessagesAfterRollback`、`latestRollbackAt`、
442
+ `restoreSafety.rolledBackTexts` を返すようになった。これで smoke 結果を
443
+ pass/fail だけでなく監査証跡として読める。
444
+ - [ ] incident-shaped thread で、rollback 済み user turn が VS Code restart /
445
+ reconnect 後に復活しないことを確認する。
446
+ - 2026-05-07 live run: current VS Code-origin thread
447
+ `019dfddb-8288-7392-a461-bf3ebc5da409` で、ユーザー明示許可後に
448
+ `THROUGHLINE_EXPERIMENTAL_CODEX_TRIM_EXECUTE=1 throughline trim --execute
449
+ --host codex --all --json` を実行した。
450
+ - 実行前 preflight は `preflight-ready`。rollback candidate は 20 turns、
451
+ `restoreSafety.status = ok` だった。
452
+ - historical 2026-05-07 追加修正後、この shape は live mutation 前に
453
+ `planned_restore_safety_risk` として拒否された。これは rollback 後に
454
+ risk になることを、rollback 予定 tail user text と既存
455
+ `compacted.replacement_history` の照合で予測するためだった。
456
+ - historical host primitive audit 必須化後は、同じ command は現行 Codex CLI では
457
+ `codex_execute_blocked_no_current_thread_repair_contract` でも拒否された。
458
+ - execute は live app-server に rollback / inject を送ったが、
459
+ `status = execute-unverified` / `reason =
460
+ post_inject_turn_count_not_visible_after_reads` で成功扱いしなかった。
461
+ 2026-05-08 の turn-count expectation 修正後は、developer memory item-level
462
+ injection が即時 `thread/read` の turn count を増やさない場合を正しく扱い、
463
+ 同 current thread の追加 live run は `execute-durable-verified` になった。
464
+ rollback / inject の durable evidence は rollout 上の新 rollback event と
465
+ injected active-work memory で判定する。
466
+ - rollout 直読では `thread_rolled_back` が記録され、
467
+ `rollbackEvents = 1`、`rolledBackTurns = 20`、
468
+ `rolledBackUserMessages = 21`、`injectedDeveloperMessages = 2` だった。
469
+ - ただし rollback 対象 user text が `compacted.replacement_history` に残り、
470
+ `restoreSafety.status = risk`、`rollbackTextRetainedInCompacted = 20`。
471
+ 2026-05-07 の read-only `codex-vscode-rollback-smoke --verify
472
+ --after-vscode-restart` 再確認では `resurrectedUserMessages = 4` になり、
473
+ `自走して` と `go` が rollback 済み user text と一致した。
474
+ これは incident-shaped thread の restore safety risk であり、non-resurrection
475
+ proof にはならない。ただし、後続の risky restore inspection で app-server
476
+ response 上の retained text は `aggregatedOutput` に限定されたため、
477
+ model-visible user message として再投入された証明とは分けて扱う。
478
+ この count は current thread に同じ user text が追加されると増え得るため、
479
+ 固定値ではなく risk の継続指標として扱う。
480
+ - historical 2026-05-07: 実行後 preflight は `restore_safety_risk` で拒否した。
481
+ 2026-05-08 unblock 後は、この risky rollout は diagnostic evidence として扱い、
482
+ 単独では追加 mutation を止めない。
483
+ - `codex-restore-source-audit` では Codex state DB は metadata only、VS Code
484
+ storage は short needle false positive を除去後 `matches = 0`。VS Code
485
+ extension bundle は reconnect 時に app-server resume/read 系へ寄せる signal を
486
+ 持つが、これは static inventory であり restart-safe proof ではない。ただし
487
+ rollout 自体の compacted history に retained rollback text があるため、
488
+ restart-safe とは扱わない。
489
+ - 2026-05-08 read-only 再監査: 同 current thread
490
+ `019dfddb-8288-7392-a461-bf3ebc5da409` は `restoreSafety.status = risk` のまま。
491
+ `capturedTurns = 14`、`compactedReplacementUserMessages = 344`、
492
+ `rollbackTextRetainedInCompacted = 20`、`resurrectedUserMessages = 14`。
493
+ historical `trim --preflight --host codex --all` は
494
+ `restore_safety_risk` で拒否し、`plannedRollbackRestoreSafety` も
495
+ `planned_restore_safety_risk` を報告した。2026-05-08 unblock 後はどちらも
496
+ diagnostic-only。`codex-host-primitive-audit` は
497
+ method count `89` で current-thread rollback non-resurrection primitive なし、
498
+ `codex-restore-source-audit` は state DB を metadata only、VS Code storage
499
+ matches `0`、extension bundle を reconnect -> app-server resume/read 系 signal
500
+ ありと報告した。これは追加の read-only risk evidence であり、
501
+ restart-safe proof でも model-visible reproduction proof でもない。
502
+ - 2026-05-08 追加実装: `codex-restore-source-audit` の VS Code extension
503
+ JSON に bounded `sourceSnippets` と機械判定用 `sourceFacts` を追加した。
504
+ 実 bundle では `thread/resume` 近傍に `history:null` と
505
+ `path:c?.rolloutPath??null` があり、reconnect handler 近傍に
506
+ `markAllConversationsNeedResumeAfterReconnect()`、follow-up queue 設定近傍に
507
+ default `queue` が見える。実 audit は
508
+ `sourceFacts.reconnectResumeViaAppServerRolloutPath = true` /
509
+ `hypothesis = reconnect_marks_threads_needing_app_server_resume_from_rollout_path`
510
+ を返す。これで minified bundle の巨大 1 行をそのまま貼らずに、
511
+ restore-path signal の短い監査証跡と機械判定を残せる。ただしこれは static
512
+ source signal であり、rollback 済み user turn の非復活 proof ではない。
513
+ - 2026-05-08 追加実装: VS Code storage audit に SQLite-backed storage
514
+ inventory を追加した。`.vscdb` / `.sqlite` / `.sqlite3` / `.db` 候補を
515
+ read-only で開き、table / searchable column / needle match summary を返す。
516
+ 実 current thread の再確認では default VS Code storage roots は 45 files
517
+ scanned、direct matches `0`、SQLite DB candidates `0`、SQLite matches `0`。
518
+ このため current environment では VS Code storage 側に retained rollback
519
+ text を持つ local persisted restore source は見つかっていない。
520
+ - 2026-05-08 追加実装: 同 audit の VS Code logs summary は、thread id matches
521
+ `40`、retained rollback text matches `0`、patch apply failures `39`、
522
+ patch failure window `2026-05-07 00:35:35.339 -> 2026-05-07 00:36:29.925`、
523
+ thread stream signals `164`、`replacement_history` signals `0`。log 上の
524
+ `Failed to apply patches for conversationId=<thread-id>` は VS Code webview 側の
525
+ reconnect / patch apply 問題を示す追加 signal だが、retained rollback text の
526
+ 復元 source そのものではない。
527
+ - 2026-05-08 追加実装: installed VS Code extension source audit に
528
+ thread-stream patch path facts を追加した。実 bundle では owner が
529
+ `thread-stream-state-changed` patches を broadcast し、follower が
530
+ `handleThreadStreamStateChanged` 内で patches を conversation state に適用し、
531
+ 失敗時に `Failed to apply patches for` を log する経路が見える。実 current
532
+ thread では source fact `threadStreamPatchApplyPathPresent = true` かつ logs の
533
+ patch apply failure `39` により `vscodeThreadStreamPatchFailureSignal = true`。
534
+ これは同一 thread repair の調査対象を VS Code reconnect / follower patch apply
535
+ path に絞る evidence だが、まだ repair primitive そのものではない。
536
+ - 2026-05-08 追加実装: installed VS Code extension source audit に rollback
537
+ non-resurrection projection candidate facts を追加した。削除 primitive だけに
538
+ 固定せず、`replacement_history` filter / tombstone、`restoreMessage` suppress /
539
+ exclude / projection、`thread_rolled_back` tombstone のような近傍 signal も
540
+ separate candidate として報告する。実 current thread の再監査では
541
+ reconnect / rollout-path resume / thread-stream patch path は見えるが、
542
+ `VS Code rollback projection candidate: no`。つまり現 bundle では、rollback
543
+ 済み source を model-visible input から隔離・投影する明示経路は見つかっていない。
544
+ - 2026-05-08 追加実装: `codex-restore-smoke --inspect-risky-rollout` を追加した。
545
+ historical blocker 期間は `restore_safety_risk` で app-server 起動前に拒否しつつ、
546
+ 明示 flag 時だけ read-only に `thread/read` / `thread/resume` /
547
+ `thread/turns/list` response を監査する。実 current thread では
548
+ app-server count は `expectedTurns = 15` / read-resume-list `15 / 15 / 15`
549
+ で安定したが、`restoreTextMatchCheck.status = matches-found` のため
550
+ 初期実装では上位 status を `app-server-restore-text-retained` に昇格した。
551
+ `restoreSafetyRiskInspected = true` で CLI exit は失敗扱いのまま。
552
+ retained rollback text 7 件が `thread_read`、`thread_resume`、
553
+ `thread_turns_list` の全 response に出た。これは compacted retained text が
554
+ rollout parser 上だけでなく、fresh app-server の read / resume / list
555
+ response 側にも見えている追加 risk evidence である。
556
+ 2026-05-08 の再確認時点では active turn が増えて `expectedTurns = 16` /
557
+ read-resume-list `16 / 16 / 16` だが、retained text 7 件が全 response
558
+ source に残っていた。後続分類では、これらは `aggregatedOutput` に限定され、
559
+ `app-server-restore-text-quoted` / `blocking-candidates=no` へ分離された。
560
+ - 2026-05-08 追加実装: `codex-restore-smoke` の retained text match は JSON path
561
+ と location kind も返すようにした。実 current thread の再確認では
562
+ `expectedTurns = 20` / read-resume-list `20 / 20 / 20` で count は一致するが、
563
+ retained text 7 件は `thread_read` / `thread_resume` /
564
+ `thread_turns_list` の `turns[1].items[*].aggregatedOutput` に出ており、
565
+ location kind は `aggregated_output`。つまり app-server response 上の
566
+ retained text は user message field ではなく、過去 tool/output aggregate に
567
+ 引用された text として見えている。このため app-server response retention は
568
+ compacted replacement-history risk と同一視せず、repair source 特定では
569
+ `userMessage.text` / `replacement_history` / `aggregatedOutput` を分けて扱う。
570
+ - 2026-05-08 追加実装: `codex-restore-smoke --inspect-risky-rollout` は
571
+ retained text の location kind から blocking candidate を判定する。direct
572
+ turn text / `replacement_history` は `app-server-restore-text-retained` のまま、
573
+ `aggregatedOutput` だけの場合は `app-server-restore-text-quoted` とし、
574
+ `blocking-candidates=no` を出す。実 current thread の再監査では
575
+ `expectedTurns = 29` / read-resume-list `29 / 29 / 29` で count は一致し、
576
+ retained rollback text 7 件はすべて `aggregated_output` /
577
+ `quoted_or_tool_output_context`、`blocking-candidates=no`。したがって
578
+ app-server response 上の retained text は、現時点では直接の user message
579
+ 復活ではなく、過去 tool output aggregate 内の引用として分類される。
580
+ - [x] rollback 済み user marker が本当に model-visible かを測る controlled smoke を追加する。
581
+ - 2026-05-08 追加実装: `throughline codex-rollback-model-visible-smoke` を追加した。
582
+ `--prepare` は unique marker を含む user turn を `turn/start` し、完了通知後に
583
+ `thread/rollback numTurns: 1` を送る。これは実 current thread を mutate するため
584
+ `THROUGHLINE_EXPERIMENTAL_CODEX_ROLLBACK_MODEL_VISIBLE_SMOKE=1` 必須。
585
+ - `--verify` は full marker を prompt に含めず、prefix
586
+ `TL_ROLLBACK_MODEL_VISIBLE_` だけを含む model turn を開始する。model が hidden
587
+ full marker を返した場合だけ `status = reproduced`、明示 not-visible token を
588
+ 返した場合は `status = not-reproduced`。fake app-server tests では
589
+ `promptIncludesMarker = false` を固定済み。
590
+ - 2026-05-08 追加修正: live run では prepare JSON / assistant 発言 / tool output に
591
+ full marker が出ると同じ thread の後続 model turn がそれを読めるため、汚染になる。
592
+ `--marker-file` を追加し、full marker を local file にだけ保存して CLI output は
593
+ `[redacted]` にする。marker-file prepare では per-trial prefix も生成し、古い
594
+ leaked marker prefix に verify が反応する false positive / inconclusive を避ける。
595
+ - 2026-05-08 実測: current thread
596
+ `019dfddb-8288-7392-a461-bf3ebc5da409` で、汚染除去後の `--marker-file`
597
+ prepare -> immediate fresh app-server verify は `status = not-reproduced` /
598
+ `reason = model_reported_rolled_back_marker_not_visible` /
599
+ `promptIncludesMarker = false` / `observedMarkers = []`。これは VS Code
600
+ reload/reconnect 後 proof ではないが、app-server process restart 境界では
601
+ rollback 済み controlled user marker の model-visible reproduction は未再現。
602
+ - 2026-05-08 追加実測: VS Code reload/reconnect 後 verify 用に
603
+ `.throughline-smoke/rollback-model-visible-after-restart.json` を `0600` で作成し、
604
+ prepare と restart 前 baseline verify を実行済み。baseline は `status =
605
+ not-reproduced` / `promptIncludesMarker = false` / `observedMarkers = []`。
606
+ `.throughline-smoke/` は secret marker を含むため `.gitignore` に追加した。
607
+ - 2026-05-08 追加実測: Windows 側 VS Code window に reload command を送り、
608
+ 同じ marker-file run を `--after-vscode-restart` 付きで verify した。結果は
609
+ `status = not-reproduced` /
610
+ `reason = model_reported_rolled_back_marker_not_visible` /
611
+ `promptIncludesMarker = false` / `observedMarkers = []`。controlled user marker の
612
+ rollback 後 model-visible reproduction は、app-server process restart 境界でも
613
+ VS Code reload/reconnect 境界でも未再現。
614
+ - この smoke は「Throughline skill を使った」「VS Code restart した」「以前
615
+ developer memory を注入した」などの混線を避けるため、rollback marker 自体を
616
+ controlled user turn に閉じ込める。今回の clean result は「rollback 済み user
617
+ text が fresh user message / model-visible input として復活した」という仮説を
618
+ 弱めるが、`compacted.replacement_history` retention と current-thread repair
619
+ primitive 不在を解消するものではない。
620
+ - [x] automatic Codex trim を再有効化するべきか決める。
621
+ - 判断: 再有効化する。controlled rollback model-visible smoke は clean で、
622
+ rollback 済み user marker の VS Code reload/reconnect 後 model-visible reproduction
623
+ は未再現。`compacted.replacement_history` retention は診断として残すが、
624
+ mutation 前 blocker にはしない。
625
+ - [x] 明示 `trim --execute --host codex` の製品判断を固定する。
626
+ - 判断: 明示 `--execute` で実行する。env opt-in と host primitive audit gate は外す。
627
+ DB memory が無い場合、または rollout/app-server turn count guard が合わない場合は
628
+ mutation 前に拒否する。実行後は `execute-sent-live-only` /
629
+ `execute-unverified` / `execute-durable-verified` で結果を分ける。
630
+
631
+ 受け入れ条件:
632
+
633
+ - [x] 決定した behavior が `CLAUDE.md` と roadmap docs に記録されている。
634
+ - [x] README には実装済みかつ verified な behavior だけを書く。
635
+ - [x] restart-safe evidence がない automatic mutation を安全扱いしている docs が無い。
636
+
637
+ ## フェーズ 5: ドキュメントを訂正する
638
+
639
+ 目的: ドキュメントを訂正済みの証拠と一致させる。
640
+
641
+ TODO:
642
+
643
+ - [x] incident report の「durable `thread_rolled_back` event が見つからなかった」
644
+ という記述を訂正する。
645
+ - [x] hypothesis を compacted replacement-history restore に言及する形へ更新する。
646
+ - [x] Codex Rewind-equivalent trim が complete だという roadmap claim を格下げする。
647
+ - [x] Codex auto-refresh は verified usage 90% 以上で guarded rollback / inject を
648
+ 実行する。estimate usage では実行しない。
649
+ - [x] 新セッションが古い「Codex side complete」claim ではなく、この fix plan から
650
+ 再開できるように `CLAUDE.md` を更新する。
651
+
652
+ 受け入れ条件:
653
+
654
+ - [x] 新セッションが `CLAUDE.md` を読んでこの plan に到達できる。
655
+ - [x] Codex trim が証明前に restart-safe だと主張している docs が無い。
656
+
657
+ ## 実装順
658
+
659
+ 推奨順:
660
+
661
+ 1. フェーズ 0: 危険な mutation を止める。
662
+ 2. フェーズ 1: 注入 memory の identity を直す。
663
+ 3. フェーズ 2: compacted replacement-history regression fixture を追加する。
664
+ 4. フェーズ 3: status と preflight / execute semantics を直す。
665
+ 5. フェーズ 4: durable host behavior を調査し、製品仕様を決める。
666
+ 6. フェーズ 5: 挙動修正後に広範な docs を更新する。
667
+
668
+ 作業量や複雑さを理由に目標を下げない。2026-05-08 時点の製品仕様は、
669
+ 同一 Codex thread で guarded rollback + Throughline DB memory inject を実行し、
670
+ rollout 上の新 rollback event と injected active-work memory で durable evidence を確認すること。
671
+ restore-safety / host primitive audit は diagnostics として残すが、単独では execute / auto-refresh の blocker にしない。
672
+ mutation 前 refusal は thread identity、Throughline DB injectable memory、rollout/app-server turn-count mismatch に限定する。