fix(session): let a participant declare who they are in the room - #45
Conversation
…d at join 参加者の同一性を名前から接続へ移し、名前と色を参加の時点の宣言にする。 - 名簿を `BTreeMap<origin, Seat>` に変更。同名の 2 参加者が 1 エントリに畳まれ、 片方の切断で両方が消える経路を塞ぐ。 - `hello` に `hue` を追加し protocol を 3 へ。名前と色は同じ宣言であり、 同じフレームで届く。宣言が無いときはキーごと省く(導出と区別するため)。 - `room_join` も同じ `seat` を通る。人間とセッションで着席の経路を分けない。 - `RoomMessage` に `hue` を載せる。画面が名前で色を引くと、名前が一意でない 瞬間に別人の色を引くため。 - `start_session` が名前と色を受け取る。タブ属性ではなく起動ごとの値であり、 `TabConfig.name` は起動するCLIのラベルに戻る。 - `.mcp.json` の登録鍵を参加者ごとに分ける(`server_name_for`)。同一作業 ディレクトリの 2 セッションが互いの識別を上書きする経路を塞ぐ。前回起動の エントリ(部屋アドレスが異なるもの)は登録時に掃除する。 #40 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
起動ごとに名前と色を選べるようにし、宣言色を導出色より優先する。 - ランチャに名前欄と色の選択を追加。人間側の `#display-name` と同じ形で、 タブ属性ではなく起動ごとの値。`localStorage` に残る。 - タイトルバーに人間側の色の選択を追加。名前と色は同じ宣言なので、 変更は同じハンドラで同じ着席を通る。 - 色の解決順は 宣言 > 自分の accent > 名前からの導出。宣言が accent より 上なのは、宣言した本人にだけ出ない色は宣言した色ではないため。自分を 自分と判じる手段は名簿の「(あなた)」と行の名前に残る。 - 名簿と宛先を `Participant` 記録から描く。自分の判定は接続で、名前では 行わない。宛先は表示名なので重複を畳む。 - 色相のみ宣言可能。明度と彩度は accent のままで、ライト / ダークの両方で 読める条件を維持する(#43)。 #40 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
実装に合わせて要求仕様と README を更新する。 - 投稿モデルに 2 項追加。参加者の同一性は接続にあること、名乗りは参加の 時点で行うこと。 - 部屋プロトコル: `hello` の `hue`、protocol 3、名簿の同一性が接続である こと。 - 参加者ごとの色を 3 段の梯子として書き直す。宣言 > 自分の accent > 名前からの導出。導出だけでは足りない実測(3 名が 75 度の帯)と、宣言が accent より上にある理由、自分を判じる手段の行き先を含む。 - 新節「参加の時点の名乗り」と「`.mcp.json` の登録単位」。 - 切り分けの 3 / 5 / 6 を参加者ごとの登録鍵に合わせる。 - README: 起動オプションと登録の説明、色の説明を実装に合わせる。 README は issue の対象ファイル一覧に無いが、変更で偽になる文言(固定鍵 `liplus-chat-room`、自分の色は accent 固定)を 3 箇所含むため同一 PR で 直す。事実の追随のみで、新しい記述は加えていない。 #40 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
smileygames
left a comment
There was a problem hiding this comment.
セルフレビュー(auto モード / 人間チェックなし)
完了条件の照合
| #40 の完了条件 | 結果 |
|---|---|
| 起動ごとに名前を選べる | 満たす。ランチャに名前欄。空名は黙ってタブ名へ落とさず拒否する |
| 並列 2 セッションが別々の名前で名乗る | 満たす |
| 同一作業ディレクトリでも名前が潰れない | 満たす。.mcp.json の鍵が liplus-chat-room-<slug>-<hash> で参加者ごと |
| 宛先の選択肢に両方が並び、片方を指定できる | 満たす。名前で重複排除 |
| 片方が切断してももう片方が名簿に残る | 満たす。名簿が BTreeMap<origin, Seat> へ。同一性が名前から接続へ移った |
| 参加者ごとに色を決められ、発言と名簿の両方に出る | 満たす |
| 色を決めていない参加者も参加でき、導出色が付く | 満たす |
制約の照合
- 名前も色も参加の時点で決める — 満たす。
localStorage保持で、人間側の既存形と同じ。config.jsonに焼いていない。 - 宣言が導出に優先する — 満たす。
speakerColorが 宣言 → 自分の accent → 名前由来 の順に落ちる。 - 宣言できるのは色相のみ — 満たす。
--speaker-l/--speaker-cは無変更。#43 の両テーマ可読条件を維持。 - 名簿の同一性はセッションに置く — 満たす。上記のとおり接続キーへ。
.mcp.jsonの既存内容を保持する — 満たす。詳細は下記。
.mcp.json の刈り込みを確認した
削除を伴う変更のため、親側で条件を読んだ。servers.retain は三重に絞られている。
SERVER_PREFIX(liplus-chat-room)で始まらない鍵は無条件で残す。他のサーバ登録は触れない。env.LIPLUS_ROOM_URLが文字列として存在し、かつ現在の部屋のアドレスと異なるものだけを落とす。LIPLUS_ROOM_URLを持たない前置き一致の鍵は残す。
制約「この repo の他のサーバ登録を壊さない」を満たす。旧来の固定鍵 liplus-chat-room も前置きに一致し、古いポートを持つため自動的に掃除される。移行経路として妥当。
残る狭い縁: 同一の作業ディレクトリに対して 2 つのアプリ実例を同時に走らせた場合、後発が先発の登録を落とす。既に起動済みのサイドカーは env を読み終えているため動き続け、影響は先発側での新規セッション起動に限られる。刈り込みを入れない場合の「使った名前の数だけ鍵が増え続ける」ほうが悪く、コード内にもその判断が書かれている。是認する。
issue が実装に委ねた判断(是認する)
「自分は accent 固定」と「色を宣言できる」の関係について、実装は宣言を accent より上に置いた。宣言した本人にだけ見えない色は宣言した色ではない、という理由づけは妥当。自分を自分と判じる手段は名簿の (あなた) と行頭の名前へ移り、どちらも既存である。宣言しない参加者にとっては従来どおり accent が自分の色として残るため、既定の挙動も変わらない。
スコープ
README.md は対象ファイル一覧の外だが、この変更で偽になる記述を 3 箇所持っていた(固定鍵での登録手順、起動オプションの server:liplus-chat-room、「自分の色は accent(青)」)。rules/operations/operations.md の「Docs update must be in same PR as implementation」が対象ファイル一覧に優先する。事実整合のみで、判断や仕様を足していない。是認する。
design/ に手を入れなかった判断も正しい。design/README.md が定める権威の向きは design が実装を写す側であり、実装側の PR で canvas を書き換えるのは逆走になる。ドリフトは下記に起票した。
検証
CI(CI / check)いずれも adb5764 で pass。crates/mcp-config に 5 件、往復ハーネスに 1 件のテスト追加。同一ディレクトリ 2 参加者、前回分の刈り込みと他者エントリの温存、非 ASCII を含む名前→鍵の全域性、未宣言時の hue 欠落が固定されている。親側で刈り込み条件・speakerColor の優先順・宛先の重複排除・Seat の接続キー化を読んで確認した。
実機未確認(明示)
2 セッション往復は未計測。docs の未実装節に記録済み。auto モードにおいて実機検証は継続観測であり、単発のマージゲートではない。阻却事由としない。
繰越(マージ前に起票済み)
#46 — design/ の 2 枚が実装から遅れた。ランチャの名前欄と色の選択が canvas に無く、起動コマンドのプレビューが旧鍵のまま。canvas.json の accent 値も #43 の実測とずれている。canvas の再生成は別作業。
リリース種別
minor と判定する。protocol が 2 → 3、.mcp.json の鍵の形が変わり、ランチャに欄が増える。いずれも user/system observable な構造変更。
自己レビュー通過。auto モードのため人間チェックはなく、このままマージへ進む。
Closes #40
参加者が参加の時点で自分の名前と色を決められるようにする。宛先がひとつの参加者を名指せ、発言の色でも追えるようになる。
変えたこと
名乗りを参加の時点へ。 セッションの名前と色をランチャで選ぶ。タブ属性ではなく起動ごとの値で、
localStorageに残る。人間側の#display-nameと同じ形に揃えた。既定のタブ 1 つに固定されたClaude Codeを全員が名乗っていた経路を塞ぐ。名簿の同一性を接続へ。
BTreeSet<String>をBTreeMap<origin, Seat>に変更。同名の 2 参加者が 1 エントリに畳まれ、片方の切断で両方が消えていた。名前は表示と宛先のための属性であって識別子ではない。色を宣言に。
helloにhueを足し(protocol 3)、room_joinにも同じ引数を足した。解決は 宣言 > 自分の accent > 名前からの導出 の 3 段。宣言できるのは色相のみで、明度と彩度は accent のまま——ライト / ダーク両方で読める条件(#43)を保つため。.mcp.jsonの登録鍵を参加者ごとへ。liplus-chat-room-<slug>-<hash>、宣言された名前だけの関数。同一作業ディレクトリの 2 セッションが互いの識別を上書きする経路を塞ぐ。起動ごとの id にしないのはファイルが際限なく伸びるため。登録時に前回起動のエントリ(部屋アドレスが異なるもの)を掃除する。決めたこと
issue の制約が判断を求めていた「自分の色が accent 固定であることと、色を宣言できることの関係」は、宣言が accent より上とした。宣言した本人にだけ出ない色は、宣言した色ではないため。accent は自分の既定として残るので、色を宣言しない参加者の見え方は変わらない。宣言した場合に自分を自分と判じる手段は、名簿の「(あなた)」と行に出ている自分の名前であり、どちらも既にある。色は 3 つのうち最も速い経路であって、唯一の経路ではなかった。
検証
CI の 5 コマンドをローカルで実行し、すべて通っている(
npm run build/sidecar:check/sidecar:test/cargo check --target x86_64-pc-windows-gnu/cargo test)。crates/mcp-configに 5 件、サイドカーのハーネスに 1 件テストを追加した。実機での 2 セッション往復は未確認。docs の「未実装」に記載済み。
範囲について
README.mdは issue の対象ファイル一覧に無いが、この変更で偽になる文言を 3 箇所含むため同一 PR で直した(固定鍵liplus-chat-room、server:liplus-chat-room、自分の色は accent 固定)。事実の追随のみ。design/は触っていない。design/Main.dc.htmlはランチャに名前欄と色の選択が無い状態を描いており、起動行のプレビューもserver:liplus-chat-roomのままで、実装より古い。design/README.mdの方針どおり実装側を正とし、キャンバスの更新は別軸として残す。docs の「UI の方向」にその旨を記載した。