hachiflow.com

この記事は、当社の以前の製品 Buzz についてのものです。現在、当社は Waggle を作っています。

移行

出口のドアはプロダクトの機能

多くのホスティングは、退出を痛くすることでロックインを証明します。私たちは、バンドル同梱の README だけを頼りに、まっさらなマシンで、私たちのシステムを知らなくても退出が成功するまでドリルしました。双方向の移行のフィールドノート。運用に疲れたら中へ、鍵を持ちたくなったら外へ。

チャット履歴がたいてい人質になる理由

ホスティング型のチャットサービスにデータを求めると、たいてい返ってくるのは記録ファイルです。JSON と添付ファイルをまとめた zip で、コンプライアンス対応や grep には十分ですが、別の場所で会話を続けるには役に立ちません。実際に自分たちが築いたもの、つまり生きたコミュニティは出てきません。「データをエクスポートできる」と「コミュニティごと出ていける」は別の約束であり、業界のほとんどは前者しか約束していません。

Buzz では、このギャップが商売上の都合ではなく、具体的な仕組みの問題として現れます。すべてのメッセージには作成者の署名があり、その署名はタイムスタンプも対象にしています。リレーがイベントを受け付けるのは、署名した鍵から届き、かつタイムスタンプが新しいとき、標準のリレーでは約 15 分以内のときだけです。そのため、昨年の履歴をワイヤ越しに新しいリレーへ再送することは誰にもできません。私たちにも、あなたにも、メッセージを書いた本人たちにもです。これは私たちが緩められる方針ではありません。偽造や再送された履歴からプロトコル自身を守る仕組みであり、どこで Buzz を動かす人にも等しく適用されます。

私たちはこれを身をもって学びました。最初のエクスポート設計は、署名済みイベントをどのリレーにも再公開できる前提で作っていましたが、ドリルでその前提が覆り、自分たちの説明文を訂正しました。それ以来、エクスポートは記録であり、そのことをはっきり明記しています。この記事は、その先に私たちが作ったものについてです。ワイヤにできないことをできるふりをせず、生きたコミュニティを双方向に移す移行の道筋です。

アイデンティティはホスト名に宿る

すべての前提となる 2 つ目の事実があります。Buzz のコミュニティのアイデンティティは、リレーのホスト名と固く結びついています。クライアントが接続すると、リレーは接続が届いたホストから、どのコミュニティを提供するのかを判断します。そしてすべてのメッセージ、メンバーシップ、ファイルは、そのコミュニティの内部 ID にぶら下がっています。ホスト名はコミュニティの置き場所というより、コミュニティの名前そのものです。その結びつきが存在するのはただ 1 か所、コミュニティのホストを記したリレーのデータベースの 1 行だけです。

移行のすべてはこの 1 行を軸に回ります。そしてここから、私たちが今では何よりも先に伝えている助言が生まれます。人が集まる前に、ホスト名を慎重に選んでください。移る先がどちら向きでも同じです。メンバーが 50 人になれば、それはコミュニティの呼び名そのものであり、変更は設定の切り替えではなく移行になります。

リストア、つなぎ直し、起動

ワイヤは過去に対して閉じているので、本当の移行はその下、データベースで行います。手順は 3 つで、順序こそが仕掛けのすべてです。リストア、つなぎ直し、起動。

最初はリストアです。リレーはまだ起動しません。データベースのダンプを空のデータベースに読み込み、メディアを新しいメディアストアにミラーします。Buzz のメディアはコンテンツアドレス方式で、自身のバイト列のハッシュで名付けられているため、どのホスト名から配信されるかを気にしません。次につなぎ直しです。例のホスト行を新しいホスト名に更新します。そして、その後で初めてリレーを起動します。起動時、リレーは設定されたホストでコミュニティを探し、つなぎ直した行を見つけて引き継ぎます。同じコミュニティ、同じ内部 ID、履歴はすべて、タイムスタンプも元のままです。

先に起動すると、これが不可能に見える原因となった失敗に出会います。リレーは自分のホストにコミュニティを見つけられず、気を利かせて空のコミュニティを新しく作ります。リストアした履歴は同じデータベースの中で、その隣に孤立したまま残ります。すべて正常に見えるのに、どのルームも空っぽです。初回起動の前につなぎ直しておけば、リレーが気を利かせる機会はありません。私たちのドリルでは、リレーが立ち上がった瞬間から、リストアした履歴を認証済みの接続で読むことができました。旧インスタンスを動かしていたのと同じオーナー鍵で、新しいインスタンスに新しいメッセージを投稿することもできました。

旧ホスト セルフホストでもホスティングでも 新ホスト ホスティングでもセルフホストでも ワイヤ経由 誰であっても拒否 署名済みタイムスタンプは数分で失効 1 · リストア データベースのダンプ + メディア 2 · つなぎ直し 1 行だけ: コミュニティのホスト 3 · 起動 リレーがコミュニティを引き継ぐ 初回起動の前につなぎ直す
ワイヤは誰の再送履歴も拒否します。だから移行はその下を通ります。ダンプをリストアし、ホスト行を新しい名前につなぎ直し、それから起動する。リレーは空のコミュニティを新しく作らず、見つけたコミュニティを引き継ぎます。
リストア、つなぎ直し、起動
# リレーを止めたまま: ダンプを読み込み、メディアをミラーする $ pg_restore --no-owner -d <empty-db> community.dump # 1 行だけ、リレーの初回起動より前に $ psql -d <empty-db> \ -c "UPDATE communities SET host = 'chat.your-new-name.example'" # リレーは自分のホストで見つけたコミュニティを引き継ぐ $ docker compose up -d relay

機構の全体、要約版。順序がすべてです。つなぎ直しの前に起動したリレーは自分のホスト名に空のコミュニティを作り、リストアした履歴はその隣で孤立します。

中へ: 運用に疲れたとき

1 つ目の方向は、中へ、です。これまで Buzz をセルフホストしてきて、深夜 2 時のディスク警告にも新鮮味がなくなった。それでも移らなかったのは、移ることがたいてい一からやり直しを意味するからです。新しいアカウント、空のルーム、誰も開かない「履歴は旧環境にあります」というリンク。今週、私たちはこの移行を最初から最後までドリルしました。使ったのは、あなたのコミュニティに対して実際に使うのと同じインポートツールです。そして、そうしたコストはドリルの中で一つも残りませんでした。

期待ではなく検証によって、引き継がれたと確かめたものは次の通りです。まず、元のタイムスタンプを保ったままの全履歴。リストアはデータベースの操作であり、ワイヤの 15 分の期限が口を挟む余地はないからです。次に、すべてのメンバーのアイデンティティ。再登録はゼロです。Buzz のアイデンティティは、私たちが発行するアカウントではなく、メンバー自身が持つ Nostr の鍵ペアだからです。あなたのホスト名で使えていた鍵は、新しいホスト名でもそのまま使え、誰にも登録し直しを求めません。そしてメディア。コンテンツアドレスと照合し、1 バイトも違わないことを確認しました。

お願いするのは、意図して最小限にしています。データベースのダンプと、メディアストアを読む手段です。残りは私たちが直接手を動かして行います。インポートが何かに触れる前にバックアップを取り、完了とする前にドリルのチェックリストを実行します。現時点でセルフサービスのインポートボタンはなく、急いで作るつもりもありません。移行は、コミュニティのためにオペレーターが全神経を注ぐべき、ただ一度の日だからです。

外へ: 鍵を持ちたくなったとき

2 つ目の方向は、外へ、です。ホスティングしているワークスペースは、どれも以前からエクスポートをダウンロードできました。署名済みイベント、メディア、README です。これは記録の層であり、記録であることを正直に示しています。いまバンドルに加わりつつあるのは、その隣に置く自主運用のための層です。データベースの完全なダンプ、ワークスペースが動いていたコンテナイメージの正確な参照、compose ファイル、そしてリストア、つなぎ直し、起動の順序を強制するリストアスクリプトです。

私たちが課す試験は、意味のある唯一のものです。私たちの助けなしで動くこと。ドリルでは、私たちのシステムに一度も触れたことのないまっさらなマシンが、バンドル同梱の README に従うだけで、新しいホスト名のセルフホスト環境として立ち上がりました。同じオーナー鍵でサインインでき、全履歴がそろい、メディアはコンテンツアドレスで配信されました。そしてインスタンスは新しいメッセージを受け付けました。ここが、博物館の展示品と、引っ越したコミュニティとの違いです。

ベンダーとサポート通話をしながらでないとリストアできないエクスポートは、ドアではありません。手間が増えただけの首輪です。だから私たちは README を、ドリルで照らし合わせる基準にしています。出ていくことは、ちゃんと動く手順に従うだけの退屈な午後であるべきです。私たちは出口を握るより、運用を任せてもらえるだけの価値で選ばれたいと考えています。

限界を、はっきりと

限界を語らない移行の話はただの広告なので、ここに書いておきます。1 つ目。絶対 URL を埋め込んだ古いメッセージ、たとえば古いアップロードに含まれるサムネイルや、完全なアドレスを返したアップロードのレスポンスは、いつまでも旧ホスト名を指し続けます。こうした URL は署名済みのコンテンツの中にあり、署名済みのコンテンツを書き換えることは偽造にあたるため、誠実な移行では手を触れられません。メディアファイル自体はコンテンツアドレス方式なので、新しいホストから正しく配信されます。後にした場所を名指しし続けるのは、古い署名済みメッセージの中に固定された URL の文字列だけです。

2 つ目は、外へ出るときの話です。リレー自身の署名鍵は一緒に持ち出せません。リストアしたインスタンスは新しいリレーアイデンティティを生成するため、旧リレーが署名したシステム通知は、実際に署名したアイデンティティに帰属したままになります。これはまさに署名の役割そのものです。メンバーのアクセスには影響しません。メンバーは自分自身の鍵そのものであり、その鍵はもともと私たちが預かるものではなかったので、そのまま一緒に移ります。

3 つ目は、どちらの方向でも同じです。移行先のホスト名は、恒久的なものとして選んでください。事実上そうだからです。1 行のつなぎ直しで済むのと同じ強い結びつきが、ホスト名を、後から気軽に変えられない唯一のものにしています。

どちらの方向でも、主導権はあなたに

まとめると、主権はスローガンではなくチェックリストになります。メンバーは自分の鍵を自分で持つので、私たちを含めどのオペレーターも、メンバーとそのアイデンティティの間に割り込めません。履歴は、どちらの方向に移る場合でも、あなたが管理するホスト名のもとでリストアされます。ワイヤは再送された履歴を誰に対しても等しく拒否し、その下にあるデータベースの経路は誰に対しても等しく機能します。主導権は料金表の上の雰囲気ではありません。出口のドアが開くまでドリルされているかどうかです。私たちのドアは今週、README だけで開きました。

あなたにとっての意味

ホスティングの側は hachiflow.com にあります。月額 $50 の定額で、name.hachiflow.chat にあなた専用のリレー。そしてここで説明した移行を、どちらの方向であっても、私たちが一緒に直接手を動かして行います。

私たちに 1 ドルも払わないとしても、仕組みは持っていってください。リストア、つなぎ直し、起動。この順序で、つなぎ直しはリレーの初回起動より前に。この 1 つの順序が、Buzz の移行のほとんどすべてです。私たちは今週、まっさらなマシンでそれを証明しました。これはもう、あなたのものです。

← フィールドノート一覧