セグメントのセッション永続化チケット

This commit is contained in:
Keisuke Hirata 2026-04-27 13:25:16 +09:00
parent fd89c754f1
commit 0a676524ae
3 changed files with 77 additions and 0 deletions

View File

@ -8,8 +8,10 @@
- [ ] TUI 拡充
- [ ] フルスクリーン化によるオーバーホール → [tickets/tui-fullscreen-overhaul.md](tickets/tui-fullscreen-overhaul.md)
- [ ] 新しい Pod を spawn する UI の設計 → [tickets/tui-pod-spawn-ui.md](tickets/tui-pod-spawn-ui.md)
- [ ] Run 中の入力キューイング → [tickets/tui-input-queue.md](tickets/tui-input-queue.md)
- [ ] サブミット入力
- [ ] TUI 補完 + 型付き atom 化 → [tickets/submit-tui-completion.md](tickets/submit-tui-completion.md)
- [ ] セッションログの Segment 保持 → [tickets/session-log-segments.md](tickets/session-log-segments.md)
- [ ] メモリ機構
- [ ] ファイル形式 + Linter 土台 → [tickets/memory-file-format.md](tickets/memory-file-format.md)
- [ ] memory / Knowledge 検索ツール → [tickets/memory-search-tools.md](tickets/memory-search-tools.md)

View File

@ -0,0 +1,37 @@
# セッションログの Segment 保持
## 背景
`submit-segment-protocol``Method::Run` / `Event::UserMessage``Vec<Segment>` を運ぶようになり、TUI では paste を `[Clipboard #N | X chars, Y lines]` のラベルチップとして再描画できる。一方でセッション復元経路は worker の history`Item::user_message(text)`)からしか情報を拾えず、`crates/tui/src/app.rs` の `restore_history` は user message を `vec![Segment::text(text)]` 1 個に潰して復元している。
つまり「ライブで届いた `Event::UserMessage` では paste チップが見える / 同じセッションを開き直すと潰れたテキストになる」という非対称が残っている。今後 paste 部分を context から prune する話(後続チケット)にも segment 単位の永続化が前提になるため、ここで土台を入れたい。
LLM 側の入力は flatten 済み文字列のままで良いworker / llm-client 層は変更しない)。永続化と client 復元経路にだけ segment を残す。
## 要件
- セッションログに user message の元 `Vec<Segment>` を残す。worker の `Item` 表現や LLM 送信 payload は変更しない(`flatten_segments` の結果を引き続き食わせる)。
- 復元経路で client が segments を取り戻せるようにする。最低限、TUI の `restore_history` が paste segment を典型の magenta `[Clipboard #N | ...]` チップとして再構築できること。
- forward compat: 旧フォーマットsegments を持たないログ行)を読んでも panic / parse error にならず、従来通り text 1 個の segment として復元できること。
- 現行の compaction / fork / restore のフローを壊さない。
## 範囲外
- paste prunesegment メタデータを使って context から落とす話)。別チケットで扱う。
- FileRef / KnowledgeRef / WorkflowInvoke の resolve 結果の永続化。これらは resolver 実装チケット側の責務。
- worker / llm-client 層の API 変更。
## 完了条件
- セッションログに segment 情報が persist される(新規セッションから書かれる行は segments を含む)。
- TUI で paste を含むメッセージを送信 → セッションを開き直す → magenta チップが復元される。
- segments を持たない旧ログ行も正常に restore でき、テキスト 1 segment として表示される。
- 既存ビルド・テストを壊さない。新フォーマットに対する round-trip テスト 1 本は追加する。
## 参照
- `tickets/submit-segment-protocol.md`(前提)
- `crates/session-store/src/session_log.rs``LogEntry::UserInput`
- `crates/session-store/src/session.rs``restore`, `RestoredState`
- `crates/tui/src/app.rs``restore_history` — 現状 segment を捨てている地点)
- `crates/protocol/src/lib.rs``Segment`

View File

@ -0,0 +1,38 @@
# TUI: Run 中の入力キューイング
## 背景
Pod は `Method::Run` を Run 中に受け取ると `AlreadyRunning` で即座に拒否する設計1 turn = 1 message。これはプログラマティックなクライアントpod_cli、Pod 間通信の `sendToPod`にとっては自然な契約だが、TUI で人間が操作している場合、「現ターンが終わるのを待って次を投げる」ためにユーザーが目視で完了を待つ必要があり、テンポが悪い。
「次のターンが終わり次第すぐに投げる」を可能にしたい。
## 方針
**プロトコルには載せず、TUI クライアント側でキューを持つ。**
理由:
- キューイングは人間が連続入力する TUI 固有の都合。pod_cli や Pod 間通信は 1 turn = 1 message が自然で、不要な抽象を背負わせない。
- キュー上のメッセージは「まだ送信していないユーザー入力」であり、送信前のキャンセル・編集が自然にできるべき。これは TUI ローカル状態で扱うのが素直。
- Pod controller / protocol への変更が不要。他クライアントへの影響ゼロ。
## 要件
- Run 中に Enter で送信した入力は TUI 内のキューに積まれる(即座に Pod に送信されない)。
- 現在の Run が `RunEnd` で終了したら、キュー先頭を `Method::Run` として送信する。
- キューに積まれた状態がユーザーから見える(積まれていることが分かる UI 表現)。
- キュー内のメッセージは送信前にキャンセル・編集できる。
- Pause 中の Resume 入力との関係を整理するResume はキューイングではなく即座に発火、で良いはず)。
- キャンセル(`Method::Cancel`)が走った場合、キューをどう扱うかを決める(破棄が妥当と思われるが要検討)。
## 完了条件
- TUI で Run 中に入力を送信すると、現ターン終了直後に自動で次が投げられる。
- 積まれた状態と、送信前のキャンセル・編集ができる。
- pod プロトコルや pod crate に変更が入っていない。
## 範囲外
- 複数 Pod 間でのキュー共有・転送
- キューの永続化TUI 再起動をまたぐ保存)
- キュー内メッセージの優先度・並び替えFIFO で十分)