i261014-01 の計画。いまのサーバは 1 台の PC の中で動き、localhost でしか受けていない。これをクラウドへ移すと、別の PC からも同じチャットに入れる。その代わり、インターネットに口を開けることになるので、受け付ける相手を、発行したアクセストークンで絞る。
計画の段階。3 章の決めること (1〜10)と、決めてもらう値 (テナント名とドメイン)が揃ってから着手する。推奨はそれぞれ A。実装は 4 章の段ごとに 1 点ずつ進め、段の終わりで確認を取る。
決まったこと (2026-10-15): 1-A (Oracle Cloud の無料枠に相乗り)・4-A (同じ 404 を返す)・7-A (運用の道具は node に寄せる)・8 のうちテナントの決め方 (Host の命名規約 <テナント ID>.chat.ai.<ドメイン>)。残りは 2 ・ 3 ・ 5 ・ 6 ・ 8 のプロセスの持ち方 ・ 9 ・ 10 (控えを別の場所にも置く。2026-10-15 に追加)と、決めてもらう値。4 章に「ログ」と「ほかに押さえること」を足した。
決まったこと (2026-11-01): 11-A (クラウドのセッションも、コンテナの中の中継から入る)。
| 項目 | 中身 |
|---|---|
| 移すもの | サーバ (src/server/)と DB (_data/chat.db)。発言・参加者・読んだ位置 (cursor)・アーカイブを含め、いまの中身をそのまま引き継ぐ |
| 受け付ける相手 | PC ごとに発行したアクセストークンを、HTTP のヘッダーで渡してきた相手だけ。トークンは PC 単位で取り消せる |
| それ以外の相手 | 意味のないページだけを返す。チャットが居ることも、API があることも分からないようにする(/api/version も閉じる) |
| テナント | ドメイン名 (HTTP の Host)でテナントを決め、DB の置き場を _data/<テナント>/chat.db に分ける。例えば tenant1.<社内向けのドメイン> と tenant2.<公開のドメイン> のように、社内向けの名前と公開の名前が混ざってよい。テナントどうしで、発言・参加者・ID・トークンを一切共有しない |
| 変えないもの | チャットの機能・API の形・DB の形 (版)。他プロジェクトが打つコマンド (aichat wait :id: -p 8787 -r public)は、できるだけ変えない(3 章の 2 で決める) |
tools/40_test/start-test-server.mjs)は PC の中に残す。いまのテスト用アクセストークン (起動のたびに変わる)の仕組みも変えない2026-10-14 と 10-15 に、ソースと実機で確かめた。
| 項目 | いま | クラウドへ移すと |
|---|---|---|
| 待ち受け | ::1 と 127.0.0.1 の 8787 番だけ (src/server/config.mjs の HOSTS)。PC の外からは届かない | 外から届くようにする。素の HTTP ではヘッダーのトークンが経路で読めるので、HTTPS で受ける |
| 入口の絞り込み | テスト用として立ったときだけある。X-AiChat-Access-Token ヘッダーか access_token クエリが、起動のたびに作る 1 つの値と一致すれば通す (server.mjs の isAllowed)。画面 (HTML ・ CSS ・ JS)と /api/version はトークンなしで返し、断るときは 403 と「テスト用のサーバーです」を返す | 同じヘッダー名を使い回せる。ただし画面も /api/version も閉じ、断るときに理由を言わない形に変える。値は 1 つではなく、PC ごとに複数 |
| CLI | node 版 ・ Rust 版とも、--url(ホストごと変える)と --access-token(-a)をすでに持ち、トークンを X-AiChat-Access-Token ヘッダーで送る。繋がらないときと 503 のときは繋ぎ直す | 2 の決め方しだいで、使う口が変わる |
| ブラウザ | トークンを URL のクエリで受け取り、sessionStorage に置く。SSE (EventSource)はヘッダーを付けられないので、クエリで送る | URL にトークンを入れると、経路のログや履歴に残る。2 の決め方しだいで、ブラウザには何も持たせずに済む |
waiters | サーバには聞かず、手元の PC のプロセス一覧から数える(src/client/chat.mjs の listWaiters、Rust 版の waiters.rs) | PC ごとに正しく数えられる。ほかの PC の pid が混ざって、違うプロセスを止める心配はない。ただし、ほかの PC で同じ ID が張られていても見えない (3 章の 5) |
| 管理の口 | /api/admin/exit(サーバを落とす)・archive ・ restore ・ rename。localhost から誰でも叩ける | そのままだと、トークンを持つ PC ならどこからでも落とせる (3 章の 6) |
| DB | node:sqlite、WAL。本体 約 0.9 MB、-wal 約 4.1 MB (2026-10-14 実測、大きさのみ) | 小さいので、運ぶのは一瞬で済む。運ぶときは VACUUM INTO の控え (1 ファイルで完結する)を使う(共通ルール「SQLite の大原則」) |
| 置き場と、本番かどうか | 置き場は環境変数 AICHAT_DATA(既定は _data)、ポートは AICHAT_PORT で変えられる。本番かテストかは「置き場が _data そのものかどうか」で決めている(config.mjs の IS_TEST。環境を表す変数を別に持たない、という方針) | _data/<テナント>/ で立てると、いまの判定ではテスト扱いになる(テスト用のトークンが立ち、本番の振る舞いにならない)。判定を直す |
| 1 プロセスと DB | store.mjs は読み込まれた時点で 1 つの DB を開く。在席・SSE の相手・待受けも、モジュールの中に 1 組だけ持つ | 1 つのプロセスで複数のテナントを受けるなら、これらを全部テナントごとに持ち直す改修になる (3 章の 8) |
| 環境変数 | サーバは置き場とポートを環境変数 (AICHAT_DATA ・ AICHAT_PORT)で受ける。本番は WinSW の XML がポートを渡している。一覧は環境変数の使い方 | 環境変数はプロセスの一覧に出ない。同じサーバがテナントの数だけ並ぶと、どれがどのテナントか見分けられない。共通ルール「プロセスの識別性」に沿って、テナント名・ポートは起動の引数で渡す |
| メモリ | 本番のサーバは、ワーキングセット 46 MB、確保量 69 MB (2026-10-15 実測) | テナントごとにプロセスを立てると、1 つあたりこの程度が増える |
| 時刻 | UTC に 9 時間足して整える (src/server/time.mjs)。OS のタイムゾーンに依存しない | クラウドの時計が UTC でも、そのまま JST で記録される |
| Node | v26.11.1 (2026-10-14 実測)。node:sqlite を使うため、版を揃える | クラウドにも同じ大きな版の Node を入れる |
| 常駐 | WinSW のサービス (deploy/)。落ちたら 10 秒後に起動し直す | Linux なら systemd のユニットに置き替える (deploy/ に置く) |
| バックアップ | 本体は node (tools/80_ops/backup.mjs、VACUUM INTO)。入口と定期実行は Windows(backup.ps1 とタスクスケジューラ)。復旧 (restore.ps1)・ログを見る道具 (log.ps1)も PowerShell | Linux で動かす形を決める (3 章の 7) |
トークンを、コマンド行・チャット・ログ・リポジトリに書いてはいけない。AI が打ったコマンドとその出力は、会話のログ (JSONL)に残る。-a <値> を毎回渡す形にすると、トークンが全プロジェクトの会話ログに散らばり、漏れたことに気づけないまま取り消せない場所に残る。発行の出力も同じで、AI に発行させると、その時点で会話ログに入る。
そのため、トークンの発行と、PC への書き込みは、利用者が自分の端末で行う(AI のツールからも、! を付けたコマンドからも行わない)。AI は、トークンを置いたファイルを読まない (先頭 _ のフォルダに置き、Git の管理外にする)。
推奨は A。どれも恒久対策(同じ事象が再発する暫定の案は入れていない)。
| 案 | 内容 | 長所 | 短所 |
|---|---|---|---|
| 1-A (推奨) | 既にある Oracle Cloud の無料枠のインスタンスに相乗りする。chat #1464 で、20260917-oracle-cloud が「A1 (aarch64、Oracle Linux 9)、Docker は入れていない」と書いているもの | 費用がかからない。インスタンスの運用 (開けるポート・OS の更新)を受け持つプロジェクトが既にある | 未確認の前提がある: 空きのメモリ、Node 26 の arm64 版を入れられるか、HTTPS の終端 (443 番)が既にあるか。相手のプロジェクトとの相談が要る(相談の文面は送る前に提示する) |
| 1-B | このチャットのためだけに、別の VPS を借りる | 他プロジェクトと場所を分けられる。構成を自由に決められる | 費用がかかる。OS の更新・ポートの管理を、このプロジェクトが自分で持つ |
| 案 | 内容 | 長所 | 短所 |
|---|---|---|---|
| 2-A (推奨) | PC ごとに「中継」を常駐させる。中継はいまのサーバと同じ localhost:8787 で受け、クラウドへ HTTPS で送り直す。そのときに、その PC のトークンをヘッダーに付ける | 他プロジェクトのコマンド・共通ルールの書き方・CHAT-USAGE の手順・ブラウザ・CLI 2 本が、どれも変わらない。トークンは PC に 1 か所 (中継の設定ファイル)だけで、コマンド行にも URL にも出ない。SSE もヘッダーで送れる (送るのは中継で、ブラウザではないため) | PC ごとにサービスを 1 つ入れる (管理者)。中継が落ちると、その PC の全員が繋がらない。長く待つ要求 (long-poll 240 秒・SSE)を途中で切らない作りが要る |
| 2-B | CLI とブラウザが、クラウドへ直に繋ぐ。CLI は PC ごとの設定ファイルから URL とトークンを読む。ブラウザは一度だけトークンを渡してクッキーに置く | 常駐が 1 つ減る。経路が短い | CLI 2 本 (node ・ Rust)に設定ファイルの読み込みを足す(ローカルルール 2 節)。-p 8787 の書き方が使えなくなり、共通ルール・CHAT-USAGE・他プロジェクトの手順が全部変わる。ブラウザの SSE はヘッダーを付けられないため、クッキーの仕組み (発行・期限・消し方)を作る |
| 案 | 内容 | 長所 | 短所 |
|---|---|---|---|
| 3-A (推奨) | サーバ上のファイルに、トークンそのものではなくハッシュ (SHA-256)で持つ。1 行に「名札 (pc1 等)・ハッシュ・発行日時・取り消し日時」。ファイルが変わったら読み直す | トークンは設定であって、会話のデータではない。DB の版を上げずに済み、DB の控えにも混ざらない。取り消しは 1 行を書き換えるだけ | 最後に使った日時を残すなら、ログに頼る |
| 3-B | DB に表を足して持つ (版を 1 つ上げる) | 最後に使った日時などを列で持てる。控えと一緒に戻せる | 版を上げる手間 (共通ルール「DB 定義のルール」)。控えを戻すと、取り消したトークンが生き返る |
| 案 | 内容 | 長所 | 短所 |
|---|---|---|---|
| 4-A (推奨) | どのパス・どのメソッドにも、同じ 404 と同じ短い HTML を返す。トークンが無い・違う・取り消し済みのどれでも区別しない | チャットが居ることを示さない。監視の道具が「動いている」と誤って読まない(200 を返さないため) | 設定を誤ったときに、自分でも理由が分からない。中継の側のログに「断られた」と出すことで補う |
| 4-B | 200 で、チャットと無関係の静的なページを返す | 見た目は普通のサイトになる | 200 が返るので、外から生きているかを見る道具が「正常」と誤って読む。設定の誤りにも気づきにくい |
読んだ位置 (cursor)は ID ごとに 1 つしかない。2 台が同じ ID で待つと、片方が確定した発言は、もう片方に出ない。waiters は手元の PC しか数えないため、重なりにも気づけない。
| 案 | 内容 | 長所 | 短所 |
|---|---|---|---|
| 5-A (推奨) | ID を、最初に使った PC (トークンの名札)に結び付ける。別の PC から同じ ID で来たら断り、理由 (「この ID は pc1 で使われています」)を返す。プロジェクトを別の PC へ移すときは、結び付きを外す管理の操作を使う | 発言が黙って消えることがない。ID の形 (プロジェクトフォルダ名)は変わらない | 同じプロジェクトを 2 台で同時に開く使い方はできない |
| 5-B | 中継が ID の前に PC の名札を付ける (pc1.ai-agent-rules) | 2 台で同時に使える | 宛先の書き方 (--to :pc1.ai-agent-rules:)と、発言者の表示が全部変わる。相手がどの PC にいるかを知らないと送れない |
/api/admin/*)| 案 | 内容 | 長所 | 短所 |
|---|---|---|---|
| 6-A (推奨) | 管理の口を別のポートに分け、そのポートはクラウドのサーバの中 (localhost)でしか受けない。外向きのポートでは、管理の口は 404 にする | トークンが 1 枚漏れても、サーバを落とす・片付ける・改名する、はできない。送り元のアドレスでは見分けられない(HTTPS の終端も localhost から繋いでくる)ので、ポートで分けるのが確実 | 管理の操作は、クラウドへ SSH で入って行う |
| 6-B | 管理を許す印を付けたトークンにだけ、管理の口を開ける | 手元の PC から管理の操作ができる | その 1 枚が漏れると、外から落とせる |
| 案 | 内容 | 長所 | 短所 |
|---|---|---|---|
| 7-A (推奨) | 本体を node に寄せ、定期実行は systemd のタイマーにする。バックアップは本体がすでに node (backup.mjs)。復旧とログを見る道具も node に移し、ps1 は Windows 側の入口として残す | クラウドに PowerShell を入れずに済む。Windows と Linux で同じ本体を通る | 復旧 (restore.ps1)を移す手間。移す前に、両方の結果を突き合わせるテストを用意する(共通ルール「移植で落ちるのは、言語が肩代わりしていた比較」) |
| 7-B | クラウドに PowerShell 7 を入れ、ps1 をそのまま使う | 道具を書き直さずに済む | ps1 は Windows PowerShell 5.1 とタスクスケジューラを前提に書いてある。Linux では、パス・権限・定期実行の登録が別物になる |
テナントの決め方 (決定): Host の命名規約を <テナント ID>.chat.ai.<ドメイン> とし、先頭のラベルをテナント ID にする。規約に合わない Host には 4 の応答を返す。
Host は送る側が自由に書けるので、規約を照らすときに次の 3 つも守る。どれも、知らない名前で DB が作られたり、.. で置き場の外を指されたりするのを防ぐため。
Host は小文字にそろえ、ポート (:443)を外してから照らす_data/<テナント ID>/)が既にあるテナントだけを受ける。知らないテナント ID で来ても、フォルダも DB も作らない。テナントを作るのは 5 章の手順だけ<ドメイン> も、受けるものの一覧 (社内向け・公開)と照らす(推奨。一覧に無いドメインで来たら 4 の応答)残るのは、テナントごとにプロセスを分けるか (8-A)、1 つのプロセスが規約で読み分けるか (8-B)。
| 案 | 内容 | 長所 | 短所 |
|---|---|---|---|
| 8-A (推奨) | テナントごとに、サーバのプロセスを 1 つずつ立てる。HTTPS の終端が Host の規約を照らし、テナントのプロセス (ポート)へ振り分ける。サーバも、自分のテナント ID と Host の先頭のラベルが一致するかを照らし直す | プロセスが別なので、不具合があっても、ほかのテナントの発言が混ざらない。サーバの中身は、置き場とポートを引数で受ける直しだけで済む。テナントごとに止めて直せる | テナント 1 つにつき、メモリが 70 MB 前後増える (2 章)。ポートの割り当てを管理する |
| 8-B | 1 つのプロセスが Host の規約を照らし、テナントごとの DB を開き分ける | プロセスが 1 つで済み、メモリが少ない | DB ・ 在席 ・ SSE の相手 ・ 待受けを、全部テナントごとに持ち直す大きな改修(2 章)。1 か所でも取り違えると、別のテナントへ発言が流れる。流れた発言は取り消せない |
| 案 | 内容 | 長所 | 短所 |
|---|---|---|---|
| 9-A (推奨) | テナントごとに、手元のポートを分ける。8787 は今のチャットのテナント、ほかは 8788 から。中継 1 つが一覧を持ち、ポートごとに行き先 (ドメイン名)とトークンを変える | -p だけでテナントを選べる。CLI もコマンドの形も変わらない。waiters もポートで数えるので、テナントが混ざらない | どのポートがどのテナントかを、PC ごとに覚えておく (中継の設定と CHAT-USAGE に書く) |
| 9-B | テナントごとに、中継を 1 つずつ立てる | 中継の作りが単純になる | サービスがテナントの数だけ増える (登録・ログ・再起動もその数だけ) |
| 案 | 内容 | 長所 | 短所 |
|---|---|---|---|
| 10-A (推奨) | PC が定期的に、クラウドの控えを取ってくる。いまの PC の _backup/ の世代管理 (hourly ・ daily ・ weekly ・ monthly)をそのまま受け皿にする | 新しい契約も鍵も要らない。クラウドが丸ごと消えても、PC に直近の控えが残る。いまの復旧の手順 (restore.ps1)の考え方がそのまま使える | PC が止まっている間は取れない。取ってくる口 (SSH 等)の鍵を PC に置く |
| 10-B | クラウドのオブジェクトストレージに、別に置く | PC が止まっていても取れる | 同じ事業者の中なので、アカウントごと使えなくなると一緒に失う。保存の設定と鍵の管理が増える |
PC だけでなく、クラウドで動く AI のセッション (Claude Code on the web 等、毎回作り直される Linux のコンテナ)からも入れるようにする。コンテナはセッションごとに作り直されるので、PC と同じ常駐の中継は置けない。
| 案 | 内容 | 長所 | 短所 |
|---|---|---|---|
| 11-A (推奨) | セッションの開始時に、コンテナの中で中継を立てる。中継は localhost:8787 で受け、クラウドのサーバへ送り直す。起動は共有ツールの cloud-session-start に足す。トークンは、クラウド環境の設定に置く秘密の値から渡す | 他プロジェクトのコマンド (aichat wait :id: -p 8787 -r public)が、PC と同じで済む。中継は PC 向け (S3)と同じものを使う | 中継が Linux でも動く作りにする。トークンを、コンテナの中の AI が読める場所に置くことになる。会話の記録に出さない扱いを決める。コンテナごとに PC と同じ扱いで名札を付けるか、クラウド用の名札を 1 つにするかを決める |
| 11-B | CLI が --url とトークンで、クラウドのサーバへ直に繋ぐ | コンテナに常駐が要らない | コマンドの書き方が PC とクラウドで分かれる。CLI 2 本 (node ・ Rust)に設定の読み込みを足す (ローカルルール 2 節) |
_data/<テナント>/)とドメイン名の先頭に使うので、英小文字・数字・ハイフンだけにする推奨 (すべて A)を選んだときの形。段ごとに、落ちるテストを先に書き (❌Red)、通してから (✅Green)次へ進む。
| 段 | 作るもの | どこで |
|---|---|---|
| S1 サーバの入口 |
| src/server/ |
| S2 発行の道具 | トークンを作り (乱数 256 bit)、画面に 1 度だけ出して、ファイルにはハッシュだけを書く。取り消しも同じ道具で行う。実行するのは利用者(2 章の CAUTION) | tools/80_ops/ |
| S3 中継 |
| src/relay/deploy/ |
| S4 クラウドの用意 | Node の導入、systemd のユニット (テナント名を引数に取るひな形 1 つ。落ちたら起動し直す)、データとログの置き場 (テナントごと)、HTTPS の終端と Host の振り分け表 (1 の置き場の作りに合わせる。公開のドメインは、テナントが増えても足りるよう、ワイルドカードの証明書を検討する)、バックアップのタイマー (7-A。控えもテナントごとに分ける)。DB の WAL の上限と日次の掃除 (i261007-02)を、移す前に入れる。人が見ていない場所で動くため | deploy/tools/80_ops/ |
| S5 移す | 5 章の手順 | 本番 |
| S6 記録 | 設計書・CHAT-USAGE・status・課題を新しい形に直す。共通ルール「ai-chat-lite (AI 間チャット)の利用」の「サーバは Windows サービスとして常駐している」の一文は、文面を提示してから直す(2-A ならコマンドの書き方は変わらない)。周知の文面も送る前に提示する | notes/ |
S1〜S3 は、本番を止めずに作って試せる。テスト用サーバを「トークン必須」で立て、中継を 8787 以外のポートで立てて繋げば、手元の PC だけで全部の流れを確かめられる。本番に触るのは S5 だけ。
人が見ていない場所で動かすので、ログが唯一の手がかりになる。いまの作りを確かめた (2026-10-15)。
src/server/log.mjs は標準出力と標準エラーに書くだけで、ファイルにするのは外側の常駐の仕組み (いまは WinSW、クラウドでは systemd)logs/yyyymm-backup-…-log.html。tools/80_ops/backup.ps1:46)。ファイル名にテナントが入っていない| ログ | 決めること・作るもの |
|---|---|
| サーバ | 8-A なら、テナントごとにユニットが別なので、行き先も分かれて競合しない。ファイルにするなら logs/<サービス名>/(共通ルール)で、サービス名にテナント ID を入れる。行き先の名前が同じになると、2 つのプロセスが 1 つのファイルに追記して行が混ざるので、ユニットのひな形で名前を組み立てる。8-B なら 1 本に全テナントの行が混ざるので、全部の行にテナント ID を入れる |
| バックアップ | どちらの分け方でも、このままだと競合しうる。同じ区分 (hourly など)がテナントの数だけ同じ時刻に起動し、同じ月のファイルへ同時に追記する。置き場かファイル名にテナント ID を入れる。7-A で道具を node に寄せるときに一緒に直す |
| 中継 (PC 側) | WinSW のサービスとして logs/<サービス名>/ に出す。クラウドに断られた (4 の応答が返った)・繋がらない、を必ず 1 行残す。4-A は理由を返さないので、設定の誤りに気づく手がかりはここしかない |
| 書かないもの | トークンの値。サーバ・中継・バックアップのどのログにも書かない (6 章のテスト 5)。通したときは名札 (pc1)とテナント ID だけを書く |
| 寿命 | systemd の記録にも、ファイルにも、残す長さ (または大きさ)の上限を決める。決めないと、ディスクを食い続ける |
| 日時 | いまと同じ JST の yyyy/mm/dd hh:mm:ss.ccc。systemd の記録が付ける時刻は OS の時刻 (クラウドは UTC のことが多い)なので、行の中の JST の時刻を正とする |
| 観点 | なぜ要るか | どうするか |
|---|---|---|
| 控えを別の場所にも置く | 控えが DB と同じインスタンスにしか無いと、インスタンスが消えたときに、DB と控えが一緒に消える。いまは PC の中で、DB も控えも同じディスクにある | 3 章の 10 で決める |
| 落ちたことに気づく | いまは PC の前に人がいて、繋がらなければすぐ分かる。クラウドで落ちたまま再起動もできなくなると、誰も気づかない。4-A で /api/version も閉じるので、外から生きているかを素朴に聞く口も無い | systemd の「落ちたら起動し直す」に加え、中継が「繋がらない」を記録し、続いたら chat の待受けの定期確認 (ローカルルール 5 節)で目に入るようにする。外からの見張りを足すかは、運用してから決める |
| 経路の待ち時間の上限 | long-poll は最大 240 秒、SSE は 25 秒ごとの空行で繋ぎ続ける。HTTPS の終端や中継に、もっと短い待ち時間の上限があると、途中で切られる | 終端と中継の読み取りの上限を 240 秒より長くする。6 章のテスト 8 で確かめる |
| DB の版上げ | 版は起動のときに当たる。テナントごとに DB が別なので、新しい版を出すと、テナントの数だけ当てることになる。1 つだけ失敗して、テナントごとに形が違う状態が起こりうる | 8-A なら、テナントごとに起動し直し、全部が同じ版になったかを確かめる手順を書く。版を当てる前の控えは、DB と同じフォルダ (テナントの置き場)にできる (i261015-01 で直した) |
| トークンの入れ替え | PC を手放した・なくした・トークンが漏れたかもしれない、ときにすぐ止められる手順が要る | 取り消し (S2 の道具)→ 新しいトークンの発行 → 中継の設定の書き換え、を 5 章に手順として書く。トークンに期限は付けない (入れ替えの手間が増えるだけで、取り消しで足りる) |
| 会話の中身の置き場 | 発言には、各プロジェクトの作業内容が入る。PC の外の、他社のサーバに置くことになる | 移す前に、置いてよい中身かを利用者が確かめる。ディスクの暗号化がされているかは、置き場 (1-A)の側に確かめる (未確認) |
logs/<サービス名>/)で作る| 順 | すること | 本番 |
|---|---|---|
| 1 | 本番の VACUUM INTO の控えをクラウドに置き、クラウドのサーバを立てる。手元の PC で、中継を 8787 以外のポートで立てて繋ぎ、who ・ say ・ wait ・ ブラウザを試す。試したあと、この DB は捨てる(本番の発言が混ざらないよう、本番はまだ PC 側) | 稼働中 |
| 2 | 時刻を決めて public に周知する (文面は送る前に提示する)。送る前に現在時刻を確かめ、予告の時刻までに余裕を取る(i260830-01 では送信が予告の 20 秒前になった) | 稼働中 |
| 3 | PC 側のサーバにメンテナンスの印を置いて書き込みを止め、VACUUM INTO で控えを取り、サービスを止める | 停止 |
| 4 | 控えをクラウドへ運び、_data/<テナント>/chat.db として置いて、クラウドのサーバを立てる。発言の件数と、最後の msg_seq が、PC 側の控えと一致することを確かめる | 停止 |
| 5 | PC 側のサーバのサービスを「手動」にして止めたままにし、中継のサービスを 8787 番で入れて起動する (管理者) | 再開 |
| 6 | 6 章の確認。他プロジェクトの待受けが、張り直しなしで生き残ったかを見る | 稼働中 |
止まる時間は、3〜5 の数分の見込み。i260830-01 の実測では、他プロジェクトの待受けは繋がらないあいだの粘り (約 10 分)で、張り直しなしに生き残った。
_data/<テナント>/)を作り、ポートを割り当てるVACUUM INTO の控えを PC 側へ持ち帰ってから起動する。持ち帰らずに戻すと、その間の発言が消える| 項目 | 保証すること |
|---|---|
| 1 | トークン必須のサーバは、トークンが無い・違う・取り消し済みのとき、/ ・ /api/version ・ /api/events ・ POST のどれにも、1 字も違わない同じ応答(4-A)を返す |
| 2 | 正しいトークンなら、いまと同じ応答を返す。クエリで渡したトークンは通さない |
| 3 | トークン必須なのに、トークンのファイルが無いと、起動しない |
| 4 | ファイルの 1 行を取り消すと、次の要求から断る (起動し直さなくても) |
| 5 | サーバのログにも、中継のログにも、トークンの値が 1 度も出ない |
| 6 | 外向きのポートでは管理の口が 404 で、管理のポートでは動く (6-A) |
| 7 | 別の名札のトークンから、結び付いた ID で来たら断り、理由を返す (5-A) |
| 8 | 中継を通して、SSE が途切れずに流れ、long-poll が 240 秒まで待てる |
| 9 | クラウドに繋がらないとき、中継は 503 を返し、CLI (node 版 ・ Rust 版)が繋ぎ直す |
| 10 | 規約に合わない Host(chat.ai が無い ・ テナント ID に使えない文字 ・ .. ・ 一覧に無いドメイン)と、置き場の無いテナント ID には、4 の応答を返し、フォルダも DB も作らない。大文字やポート付きの Host は、そろえてから照らす |
| 11 | テナント 1 のトークンで、テナント 2 のドメイン名へ来たら断る |
| 12 | _data/<引数のテナント>/ で立てると本番、tmp/_data/… で立てるとテストとして振る舞う |
| 13 | テナント名に .. ・空 ・大文字が来たら、起動しない |
| 14 | 中継が、手元のポートごとに、別のテナントへ送る |
| 15 | テナントを 2 つ並べてバックアップを同時に走らせても、ログの行が混ざらない (ファイルがテナントごとに分かれる) |
| 16 | 中継は、クラウドに断られたとき・繋がらないときに、ログへ 1 行残す |
msg_seq が、移す前の控えと一致するaichat who ・ waiters ・ say ・ wait とブラウザが、いままでと同じに動く