Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ネットワークとユーザー発見

polkaのネットワークは、タグを中心とした階層構造と、Nostrによる発見メカニズムで構成されています。

タグによるグラフ構造

polkaでは、ユーザーごとに独自のタグ階層を持ちます。タグは、投稿やリンクを分類するためのカテゴリであり、同時にユーザー間のつながりを形成する単位でもあります。

タグ階層の例

タグはディレクトリのような階層構造を持ちます。

📁 alice.example.com/
  └─ japan/
      ├─ kokeshi/
      │   └─ [投稿1, 投稿2, ...]
      └─ shinobu/
          └─ [投稿3, 投稿4, ...]
  └─ photo/
      └─ landscape/
          └─ [投稿5, 投稿6, ...]

📁 shino.example.com/
  └─ kinpatsu/
      ├─ alice/
      │   └─ [投稿7, 投稿8, ...]
      └─ karen/
          └─ [投稿9, 投稿10, ...]

ユーザーのつながり図

polka.edgeレコードによる階層定義

タグの階層は、polka.edge レコードで定義されます。

たとえば、Aliceさんが japan の下に kokeshi タグを作る場合、以下のようなedgeレコードを作成します:

rpath: polka.edge/{rkey}
data: {
  from: "japan",
  to: "kokeshi",
  updatedAt: "2025-01-15T10:00:00Z"
}

from フィールドで親タグ、to フィールドで子タグを指定します。from を省略すると、ルート直下のタグとして扱われます。

グラフの再帰的構築

クライアントは、polka.edge レコードを走査することで、タグのグラフ構造を再帰的に構築します。

たとえば、japan タグから始めて、from: "japan" を持つすべてのedgeレコードを取得すれば、その子タグが得られます。

さらに、それらの子タグを from として持つedgeレコードを取得すれば、孫タグが得られます。このように再帰的に辿ることで、タグの階層全体が構築されます。

フォロー機構

polkaでは、特定のユーザーの特定のタグノードをフォローします。

タグノードのフォロー

たとえば、Aliceさんの japan/kokeshi タグに興味がある場合、以下のようなフォローレコードを作成します:

rpath: polka.follow/{rkey}
data: {
  did: "did:web:alice.com",
  tag: "japan/kokeshi",
  updatedAt: "2025-01-15T10:00:00Z"
}

クライアントは、このフォローレコードに基づいて、定期的に Alice さんのリポジトリから japan/kokeshi に属する投稿を取得します。

階層的な購読

タグの階層性により、柔軟な購読が可能です。

特定のカテゴリのみ alice.com/japan/kokeshi をフォローすれば、そのタグに属する投稿だけが取得されます。

広範囲な購読 alice.com/japan をフォローすれば、その配下の kokeshishinobu など、すべてのサブタグの投稿が取得されます。

この柔軟性により、細かい興味にフォーカスすることも、広いトピック全体を網羅することも可能になります。

投稿とタグの関係

投稿は、parents フィールドでタグを指定します。

Nostrによるディスカバリ

polkaは、ユーザー発見にNostrリレーを活用します。

ユーザー発見図

Nostrの役割: 一時的なブートストラップ

重要なのは、Nostrは「発見」のためだけに使われるということです。

ユーザーは自分の存在をNostrリレーに広告し、興味のあるタグを持つ他のユーザーを見つけます。一度つながりを見つけたら、その情報はローカルに保存され、以降はHTTPS経由で直接データを取得します。

Nostrリレーがダウンしても、既存のフォロー関係は影響を受けません。新しいユーザーの発見ができなくなるだけです。

タグ広告 (Kind 25565)

ユーザーは、Nostrリレーに Kind 25565 のイベントを送信します。このイベントには、自分のDIDと、使っているタグのBloom Filterが含まれます。

フィールド内容
kind25565
content.didユーザーの did:web
content.bloomタグ配列を格納した Bloom Filter(base64エンコード)

Bloom Filterを使うことで、タグのリストを圧縮表現できます。また、完全なタグリストを公開せずに済むため、プライバシーも保護されます。

発見からフォローまでの流れ

1. クライアントがNostrリレーをsubscribe Kind 25565のイベントを購読します。

2. イベントを受信 他のユーザーが送信したタグ広告イベントを受け取ります。

3. Bloom Filterでマッチングチェック 受信したBloom Filterに対して、自分が興味のあるタグが含まれているかをチェックします。マッチしたら次のステップに進みます。

4. did:web解決 イベントに含まれるDIDを解決し、公開鍵とサービスエンドポイントを取得します。

5. データ取得と確認 サービスエンドポイントからデータを取得し、実際にそのタグが存在するかを確認します。(Bloom Filterは偽陽性の可能性があるため)

6. フォローレコードを作成 確認が取れたら、polka.follow レコードを作成し、定期的にそのユーザーのデータを取得するようにします。

以降、Nostrリレーを経由せず、HTTPS経由で直接データを取得し続けます。

コミュニティの自然発生

polkaのタグは、中央管理者がいません。誰でも好きなタグを作り、使うことができます。

共通のタグによるつながり

たとえば、kokeshi というタグを使う人々が増えれば、自然とkokeshiコミュニティが形成されます。

Aliceさんが japan/kokeshi を使い、Bobさんが hobby/kokeshi を使い、Carolさんが collection/kokeshi を使えば、3人とも kokeshi に興味がある人として発見され、つながることができます。

タグの自由度

タグに厳密なルールはありません。階層の深さも、名前の付け方も、ユーザーの自由です。

この自由度により、フォークソノミー(集合知によるタグ付け)のような、自然で柔軟な分類が可能になります。

Nostr使用の一時性

繰り返しになりますが、polkaにおけるNostrの使用は一時的です。

初期発見のみ Nostrは新しいユーザーを発見するときだけ使われます。

継続的なデータ取得はHTTPS 一度フォローしたユーザーのデータは、HTTPS経由で直接取得します。Nostrリレーは経由しません。

リレーダウンの影響は限定的 Nostrリレーがダウンしても、既存のフォロー関係でデータを取得し続けることができます。新規のユーザー発見だけができなくなります。

この設計により、polkaは大規模なリレーインフラに依存せず、最小限の調整でネットワークが機能します。