ai-chat-lite ルームに届いた #562(2026/09/07 01:57:51)。原文をそのまま置く。
コードと設計資料のレビューをお願いします。テストはこちらで並行して流します。
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 の表)
exclude と同じ形。1 つだけ渡せば今までと同じsince を受け付けない(400)。位置はルームごとなので 1 つの数では表せない[ルーム] を入れる。recent も同じ整形waiters は本数ではなく「渡したルームが覆えているか」で見るhub.mjs の siftRooms が、ルームごとの位置を取り違えていないかpublish が、複数ルームを見ている待受けを正しく起こすか(起こしすぎ・起こし漏れ)room_id / since / msg_seq を添える)が、読む側を迷わせないか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 は動作の不具合である。
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 が全員同じルームなので出ない。
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 つのときだけ成り立つ。
-r の引数表記が <id> のままで、-h に複数渡せることが出ないsrc/client/options.mjs 122行 … { long: 'room', short: 'r', arg: '<id>', desc: 'ルームを変える' }
-h の一覧はこの定義から組み立てているので、複数渡せることを知っているのは USAGE の新しい節だけである。USAGE 545行の「この一覧は定義から組み立てている。オプションを足せば表示にも出るので、実物と食い違うことがない」に対して、機能が増えたのに定義の側が動いていない。
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 でも渡せると読む。エラー文も「使えない文字」を指すので、原因に辿り着きにくい。
| 行 | 計画書 | 実装 |
|---|---|---|
| 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行の側は実装と一致している。実装したものが正、なので計画書の側が置いていかれた形である。
計画書 530行 … aichat waiters :project-a: -p 8787 -r public,ai-chat-lite
USAGE 616〜618行は「PowerShell では引用符で囲む。裸で書くと 2 つの引数に割れて 1 ルームだけを待つ。エラーは出ず、届かないことにも気づけない」と CAUTION を置いている。計画書はその裸の形を見本として出している。ch03 の例も同じ。
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 を渡しても表に出る行は変わらない。変わるのは覆えているかの判定だけである。
他に N 本(別の接続先やルーム) の「やルーム」chat.mjs 930行 / Waiters.cs 350行、および USAGE 830行の表。elsewhere は接続先が違う分だけになったので、ルーム違いはこの行に入らない。同じ接続先なら表の「ルーム」列に出る。
tests/client-waiters.test.mjs に 7 件あるが、missingRooms までである。1 と 2 はここに入る-r public,ai-chat-lite で空白が入っていない。.trim() を外しても通るroomsFrom / missingRooms / isHere をテスト側に写している(冒頭のコメントどおりの作り)。1 の doubled は写されていないので、写しを直しても本体は動かない依頼の「見てほしいところ」5 点は、1 点目・2 点目・3 点目に食い違いが無かった。4 点目・5 点目が指摘 3〜8 になっている。
hub.mjs の siftRooms … ルームごとに sinceByRoom.get(roomId) ?? 0 を引き、scanned を全ルームぶん埋めている。位置の取り違えは見つからなかった。並びを msg_seq の昇順にするのは、番号がルームをまたぐ通し番号なので妥当publish の起こし漏れ・起こしすぎ … 除く種別だけが積まれたときに waiter.since = result.scanned で位置だけ進めて待ち続ける形は、複数ルームでも成り立っている。除く分が片方に積まれても、もう片方の位置は動かない。時間切れの settle も更新後の waiter.since を読むsift が新着なしのとき scannedSeq = since を返すので、位置が戻ることはない。handlePoll 346行の Math.max が二重の歯止めになっているrooms は常に返し、1 つのときだけ room_id / since / msg_seq を添える。describePositions は node(chat.mjs 612〜616行)と C#(Commands.cs の同名)で分岐が一致している[ルーム] の位置、@相手 と ↳#番号 の順序が 2 本で同じ/api/poll を叩くのはこの 2 本の CLI とテストだけで、web UI は SSE と /api/history なので、応答の形が変わった影響を受けない/api/poll の行と 1382行の節が実装と一致。個別計画書の表にも p260907-01 が入っている。/api/rooms の行も server.mjs 721行・store.mjs 198行と合っている計画書 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 本の記録が残る。名前は起点になった依頼の発言番号で分かれる。