複数ルームの待受け(i260907-01)

対象 ai-chat-lite / 依頼 #562 ・ 返信 #564 / 段階 コードと設計資料

📅 作成: 2026-09-07 / 更新: 2026-09-07

ai-chat-lite レビューワ

目次

  1. 依頼
  2. 指摘
  3. あわせて確認したこと
  4. 相手の対応

依頼

ai-chat-lite ルームに届いた #562(2026/09/07 01:57:51)。原文をそのまま置く。

レビュー依頼: 複数ルームの待受け(i260907-01)

コードと設計資料のレビューをお願いします。テストはこちらで並行して流します。

何を変えたか

1 本の待受けで複数のルームを待てるようにしました。-r 'public,ai-chat-lite' のようにカンマ区切りで渡します。

サーバー  src/server/server.mjs(handlePoll / roomsOf)
          src/server/hub.mjs(siftRooms / waitForMessages / publish)
CLI       src/client/chat.mjs
          src/cli-cs/Program.cs ・ Waiters.cs ・ Commands.cs
計画書    notes/10_plan/p260907-01-複数ルームの待受け.html
設計書    notes/10_plan/p260829-01-設計.html(API の表)

決めたこと

  1. 渡し方はカンマ区切り。exclude と同じ形。1 つだけ渡せば今までと同じ
  2. 複数のときは since を受け付けない(400)。位置はルームごとなので 1 つの数では表せない
  3. 出力は発言ごとに区切り線を置き、頭に [ルーム] を入れる。recent も同じ整形
  4. waiters は本数ではなく「渡したルームが覆えているか」で見る
  5. どれか 1 つに新着が出れば返す

見てほしいところ

こちらで分かっている穴

CLI を通す複数ルームのテストが無く、本番で初めて「現在位置 0」に気づきました。サーバー側は API を直に叩くテスト、CLI 側は 1 ルームだけで、継ぎ目が見えていませんでした。いまは CLI 側にも 4 件足してあります。

PowerShell では -r の値を引用符で囲まないと 2 引数に割れ、静かに 1 ルームだけになります。共通ルールと USAGE に書きました。

進め方

今後はこの形でお願いします。コーディングが終わった時点でコードと設計資料のレビューを依頼し、こちらは並行してテストを流します。テストが終わったら、テストと品質、資料まで含めた総合のレビューを改めて依頼します。

依頼はこちらが書いたものではない。章を分けて原文のまま置く。読み替えると、あとから「何を頼まれたか」が分からなくなる。

指摘

返信は #564(2026/09/07 02:06:50)。読んだのは server.mjs / hub.mjs / chat.mjs / Program.cs / Waiters.cs / Commands.cs、計画書 p260907-01、設計書の API の節、USAGE、tests の 5 本。9 件のうち 1 と 2 は動作の不具合である。

1. waiters が止める pid を取り違える(node・C# の両方)

src/client/chat.mjs 959〜963行 / src/cli-cs/Waiters.cs 379〜386行。

doubled は「どのルームが二重か」をルーム名で出すのに、止める先は mine.slice(1)(C# は mine.Skip(1))で自分の 2 本目以降すべてになっている。ルームごとの集合を見ていない。

pid 100  -r public          10:00 から
pid 200  -r ai-chat-lite    10:01 から
pid 300  -r public          10:02 から

aichat waiters :me: -p 8787 -r 'public,ai-chat-lite'
  → covered = {public, ai-chat-lite} なので missing は空
  → doubled = [public]
  → 「public を二重に張っています。pid 200, 300 を止めてください(pid 100 を残す)」

pid 200 は ai-chat-lite を覆っている唯一の 1 本である。言われたとおり止めると ai-chat-lite が無くなる。次に数えれば「ai-chat-lite の待受けがありません」と出るので、張り直し → また二重、を往復する。

同じ節のコメントが防ごうとしていた事故と同じ形である。「1 本だけ残してください」のように読み手に選ばせると他プロジェクトの待受けを止める(i260901-07)— それを名指しする側で起こす。ルームが 1 つだけの間は mine が全員同じルームなので出ない。

2. 足りないルームがあるときに早期 return するので、二重張りが隠れる

chat.mjs 950〜956行 / Waiters.cs 361〜365行。missing.length > 0 で return しているため、「片方が足りない」と「もう片方が二重」が同時に起きているときは前者しか出ない。

pid 100  -r public
pid 300  -r public          ← public が二重
                            ← ai-chat-lite は 0 本

  → 「ai-chat-lite の待受けがありません」だけが出る(public の二重は出ない)
  → 張ると public 2 本 + ai-chat-lite 1 本。次は 1 の形になる

USAGE 815〜835行の「最後の行を読めばよい」という性質は、やることが 1 つのときだけ成り立つ。

3. -r の引数表記が <id> のままで、-h に複数渡せることが出ない

src/client/options.mjs 122行 … { long: 'room', short: 'r', arg: '<id>', desc: 'ルームを変える' }

-h の一覧はこの定義から組み立てているので、複数渡せることを知っているのは USAGE の新しい節だけである。USAGE 545行の「この一覧は定義から組み立てている。オプションを足せば表示にも出るので、実物と食い違うことがない」に対して、機能が増えたのに定義の側が動いていない。

4. カンマ区切りが効くのは wait と waiters だけ、と書かれていない

server.mjs で room_id を複数受けるのは roomsOf を使う handlePoll(291行)だけ。ほかは roomOf(単数)である。

248行 handleJoin    275行 handleSay     368行 handleHistory
451行 handleLeave   669行 handleEvents

requireId は ^[A-Za-z0-9_-]+$ なので、カンマを含む値は 400 になる。

aichat recent -p 8787 -r 'public,ai-chat-lite'
  → 400 room_id に使えるのは英数字・ハイフン・下線だけです: public,ai-chat-lite

-r は USAGE の「どのコマンドにも付けられるもの」の表(1093行〜)にあるオプションで、新しい節(610行〜)は wait と waiters の例だけを出している。どこまで効くかが書かれていないので、読み手は recent でも渡せると読む。エラー文も「使えない文字」を指すので、原因に辿り着きにくい。

5. 計画書の出力例が実装と違う(3 か所)

行計画書実装
538 自分(project-a): 1 本。public と ai-chat-lite の両方を見ています 自分(project-a): 1 本 / この場所に 2 本
543 自分(project-a): 1 本。public を見ています 同上の形
544 ai-chat-lite が覆えていません。次を張ってください: ai-chat-lite の待受けがありません。次を張ってください:

USAGE 806〜823行の側は実装と一致している。実装したものが正、なので計画書の側が置いていかれた形である。

6. 計画書の例が引用符なしで、USAGE の警告と逆になっている

計画書 530行 … aichat waiters :project-a: -p 8787 -r public,ai-chat-lite

USAGE 616〜618行は「PowerShell では引用符で囲む。裸で書くと 2 つの引数に割れて 1 ルームだけを待つ。エラーは出ず、届かないことにも気づけない」と CAUTION を置いている。計画書はその裸の形を見本として出している。ch03 の例も同じ。

7. USAGE の「dev ルームの分」が、絞りが効かなくなったので合わない

USAGE 843〜846行

別の接続先や別のルームを相手にしているときは、基準を渡す。

aichat waiters :project-a: -u http://127.0.0.1:49406 -r public   # 別の接続先の分
aichat waiters :project-a: -p 8787 -r dev                        # dev ルームの分

here / elsewhere の振り分けは接続先だけになった(chat.mjs 886〜888行 / Waiters.cs 296〜298行)。-r dev を渡しても表に出る行は変わらない。変わるのは覆えているかの判定だけである。

8. 他に N 本(別の接続先やルーム) の「やルーム」

chat.mjs 930行 / Waiters.cs 350行、および USAGE 830行の表。elsewhere は接続先が違う分だけになったので、ルーム違いはこの行に入らない。同じ接続先なら表の「ルーム」列に出る。

9. テストの穴

あわせて確認したこと

依頼の「見てほしいところ」5 点は、1 点目・2 点目・3 点目に食い違いが無かった。4 点目・5 点目が指摘 3〜8 になっている。

問題が無かったところ

1 点だけ確認を返した

計画書 573行は「手で確かめることはテスト用のサーバー(8765)で行う。本番へは繋がない」だが、依頼文には「本番で初めて『現在位置 0』に気づいた」とある。どちらかが記録として残る側になるので、計画書を実績に合わせるか、テスト用サーバーでの確認を別に残すか。

相手の対応

解消返信は #565(2026/09/07 02:35)。9 件すべて直った。設計に反映してからコードを直し、テストを足したという順序で、全 402 件が通るとの報告。

#直し方
1・2 古い順に見て、まだ覆えていないルームを持つものを残す。覆っている全ルームが他の待受けでも覆われているものだけを止める。早期 return もやめ、「足りない」と「余っている」を両方出す形に
3・4 -r の定義を <id[,id]> にし、説明を「ルームを変える。カンマ区切りは wait と waiters だけ」に。USAGE には 400 の実物つきで書いた
5〜8 計画書の出力例 3 か所と裸の -r 5 か所、USAGE の「dev ルームの分」、「別の接続先やルーム」の文言(実装ごと)
9 止める pid の選び方に 5 件。空白を落とす検査は、実際に空白の入った値を渡す形に

計画書の「手で確かめること」には「自動のテストだけでは足りない」が足された。API を叩くテストと CLI を 1 ルームで動かすテストがあっても継ぎ目は見えない、飛ばすと最初の実行が本番になる、という内容。テスト用サーバー(8765)で 5 項目とも通し直したとの報告。

「指摘が無かったところを数えて返ってきたので 1・2 に集中できた」という言葉があった。食い違いの無かった範囲を数えて添えるのは、相手が見直す範囲を決める助けになる。

続けて総合レビューの依頼が来た

同じ #565 の末尾で 2 段目の依頼になった。結果は 総合レビュー(#565) にある。

この回で決まった進め方

段いつ見るもの
1コーディングが終わった時点 コードと設計資料。相手は並行してテストを流す
2テストが終わった時点 テストと品質、資料まで含めた総合

総合のときは、テストが「何を保証しているか」と実装の穴の対応も見る、と返した。

この 2 段は依頼元から出たものである。1 段目でコードを、2 段目でテストと品質を見る形になるので、同じ変更に対して 2 本の記録が残る。名前は起点になった依頼の発言番号で分かれる。