feat(room): keep the room log and read it back as history (room_log, room.rs, index.html, styles.css, main.ts, docs) - #113
Conversation
部屋の発言はウィンドウの DOM にしか無く、閉じれば消えていた。引用できない ことは症状のひとつに過ぎない——「実際に何が起きたか」を根拠にする設計判断 が、参加者の記憶と Master の記憶だけを頼りにしていた。 言われたことを追記のみの jsonl に残し、過去のやり取りは会話面の左の列で読 む。部屋の本文には復元しない——閉じれば部屋の中身は消えるという現在の振る 舞いは変えない。変えたのは、消えた先に読みに行ける場所があるかどうかだけで ある。 - ログの新規モジュール(`src-tauri/src/room_log.rs`): `logs/main.jsonl` への追記と読み出し。`config.rs` の `SavedChatMessage` / `SessionData` / `TabSessions` は流用しない。前者は `role` と `content_type` を持つチャッ トアシスタントの語彙であり部屋には当たる軸が無く(#39)、後者の鍵はタブ であって会話の器ではない。どちらを配線しても #39 が外した非対称が保存層 から戻る。載せるのは五欄(`message_id` / `speaker` / `content` / `to` / `ts`)で、`own` は見る側の属性であるため、`hue` は読み戻す頃に宣言した席 が無いため、どちらも持ち込まない。 - 部屋(`src-tauri/src/room.rs`): `deliver` が床を判定した一回の取得の内 側で追記する。ロックを離してから書くと、床が既に順序を付けた二人が逆順で ディスクへ届きうるため、一つの会話に二つの順序が生まれる。受理されたもの だけを書く——拒否された発言は部屋に無く、記録すべき出来事も無い。 - 追記の失敗で発言は失われない。発言はディスクに触れる前に部屋へ入っており、 書き込みの失敗が取り消せるものではない。失われうるのは記録の側だけである から、配送も戻り値も追記の成否に依存させず、`room-log-error` で画面の状況 行に出す。黙って記録を止めたログは依然としてログに見え、後から見に行った 者はその空白を「何も言われなかった」と読む。 - 履歴(`index.html` / `src/styles.css` / `src/main.ts`): 会話面の左の `<aside>`。参加者パネルと対にし、幅と地色を揃え、枠は会話面に向く側に置 く。二つの面を分けるのは起動であり、左は開く前、右は開いた後である——だ から発言が届くたびに伸びない。伸びる帯は隣の会話面をもう一度描いたものに なる。色はログが宣言色を持たないため名前から導く。 読み出しは画面のためのものであり、再配信ではない(#48 の制約)。あとから参 加したセッションの channel へ過去の発言を流し込まない——流し込めば部屋が 「誰が何を聞いたか」を持ち始める(#31 / #39 が退けた形)。ローテーションと 上限は持たない(Vision の `main.jsonl` が単数形で日付を持たないことに従う)。 複数部屋は実装せず、部屋名はパスの位置として `main` に固定する。 Closes #48 Co-authored-by: Claude Lin & Lay <eightborder@gmail.com>
一番古い行を正面に出すのは、上限を持たないログでは距離が伸び続ける側を毎回 見せることになる。この列の最後の行は隣の部屋の最初の行の直前に言われたもの であり、二つが一続きに読めるのは下端である。並びは部屋と同じ向き(古い方が 上)のまま、開く位置だけを末尾にする。 スクロールするのはリストではなくパネルである。見出しはその中に在り、他のす べてと一緒に流れることでその位置に居る——参加者パネルと同じ形である。 あわせて `renderHistory` のコメントの誤りを直す。部屋は履歴の「下」ではな く「隣」である。 Refs #48 Co-authored-by: Claude Lin & Lay <eightborder@gmail.com>
README の実装状況は docs/0-requirements.md の同じ節を写したものであり、片方 だけを直せば二つは食い違う。「会話ログの永続化と観測 UI」は未実装のままそこ に残っていた。 実装済みへログと履歴を足し、未実装には残っているもの——実機確認と複数の部屋 ——を置く。 Refs #48 Co-authored-by: Claude Lin & Lay <eightborder@gmail.com>
smileygames
left a comment
There was a problem hiding this comment.
自己レビュー(親 / auto モード)
実行モードは auto。人間ゲートは無く、この自己レビューが merge 前の唯一の判定面である。
brake 1(skills/evolution-parallel-agent-eval)は適用しない。rules/evolution/initiator-autonomy.md の self-evolution PR 定義は「① initiator path 発 かつ ② LI_PLUS_REPO のガバナンス面を変える」の両立を要求する。本リポジトリは USER_REPO5 であり条件②で外れる。同節が「ユーザーリポジトリの PR は別のゲート面」と明記している。
受け入れ基準の照合(#48 の制約、全8項)
| 制約 | 実装箇所 | 結果 |
|---|---|---|
| ログは部屋のもの、タブ単位にしない | room_log.rs 新規。TabSessions / SessionData / SavedChatMessage 不使用 |
pass |
| 5欄のみ、参加者クラスを値域に取る欄を作らない | LoggedPost = message_id / speaker / content / to / ts |
pass |
own を保存しない |
LoggedPost::of の明示的写像。Serialize derive を避けた理由も同所に記載 |
pass |
| 起動時の部屋は新規 | #room は空のまま起動。過去ログは本文へ復元しない |
pass |
| 履歴は左サイドバー | #history(index.html)。#participants と同幅 16.5rem、border-right 対 border-left |
pass |
| 参加者への再配信をしない | room_log は画面向けコマンド。room.rs:503 の later joiner 扱いは無改変 |
pass |
| ローカルに留める / 監視機構を作らない | 追加されたのは追記・読み出しコマンドのみ | pass |
| 追記失敗で発言が失われない、または失敗が観測できる | 発言はディスクに触れる前に部屋へ入る。失敗はロック外へ持ち出し room-log-error で状況行へ |
pass |
規約面
- PR タイトル純 ASCII(非 ASCII バイト 0、
od -c検証)、影響範囲を含む - PR 本文
Closes #48あり、日本語 - コミット 3本すべて本文に日本語の記述と
#48参照あり - docs 同 PR(
README.md/docs/0-requirements.md)。分割なし - CI 3コミットすべて緑、
mergeStateStatus=CLEAN
スコープ逸脱
無し。実装側は対象ファイル表を超える変更(テスト用クレートの新設)を、scope-exceed の対話確認面を持たないことを理由に自制し、テストの配置 節に記録して報告した。判断として正しい。
src-tauri/ にテストが無いのは既存の状態であり(#[cfg(test)] ブロック 0 件)、本 PR による後退ではない。
持ち越し(merge 前に起票済み)
保持を「無制限追記・ローテーションなし」とした決定は AI 側の既定であり、その決定時に読み出し側の形は検討されていない。実装は read_to_string で全体を読み、投稿 1件につき <li> を 1つ作るため、起動時コストが発言総数に比例して際限なく伸びる。#48 の記述には反しないが、決定の噛み合わせとして未検討である。
→ #114 として起票。
受け入れた形(記録)
追記が部屋のロック内で走る。ブロッキング IO を部屋を止めた状態で行う代わりに、ファイルの並びが床の並びであることを保証する。ロック外に出すと、床が既に順序づけた2つの発言がスケジューラ任せの順でディスクへ届き、会話の並びが2つ存在することになる。部屋が唯一の権威である軸を守る側を取った判断として妥当。
次段
self-review pass。auto モードにつき人間ゲート無し、squash で merge する。実機確認は merge 後に main 上で行うものであり、merge のゲートではない。
Closes #48
部屋の発言を
logs/main.jsonlへ追記し、過去のやり取りを会話面の左の列で読めるようにした。追記は床を判定した一回のロック取得の内側で行うため、ファイルの並びは床の並びである。保存するのは五欄(message_id/speaker/content/to/ts)で、config.rsのTabSessions系は流用していない。起動時の部屋は新規のままで、過去ログは本文へ復元しない。読み出しは画面のためのものであり、参加者への再配信はしない。追記に失敗しても発言は失われず(発言はディスクに触れる前に部屋へ入っている)、失敗は
room-log-errorで画面の状況行に出す。