[design] account / group / token / 鍵 の関係モデル(simplify 確定 2026-06-03)

機能が固まってきたので、「似ているのに対応がややこしい」account / group / token / 鍵 の関係を 1 枚に確定する。E2E 残課題の調査中に、master_seed の性質(account 単位・all-or-nothing)から関係が自然に綺麗になると分かったのが起点。

## 要件(これを満たす最小モデルを探す)
- (1) 同一 account でもマシンが違えば見たい group が違う
- (2) エージェントは account が属する group の中から read/write する物を個別に選べる
- 制約:今の鍵システム(master_seed → per-group 鍵)のまま、シンプルに

## 確定 1:境界は α(選択 / フォーカス)であって暗号隔離ではない
マシン/エージェント間の group の境界は「この文脈は当面この group 群で作業する」という **選択** で、「特定 group を暗号レベルで読めなくする」隔離ではない(端末は信頼でき master_seed を持って良い)。
- 帰結:per-context のサブセット化は **鍵の層に置かない**。master_seed は account 単位で全 per-group 鍵を導出する all-or-nothing なので、マシンを区別できない。サブセット化は token / 配信の層に置く。
- (β) ハード暗号隔離(seed を渡さず per-group 鍵だけ個別 custody)は別モデル・複雑なので不採用。必要になったら別 axis で。

## 確定 2:3 役の分離(simplify の核)
以前は token・鍵・membership が「その group の一員」を 3 通りに言っていてややこしかった。α だと 3 つは別々の単一責務になる:
- **membership** = account が属する group の最大集合(server の事実 / account 単位)
- **master_seed** = 届いた物を復号できる能力 = 全 per-group 鍵(account 単位 / all-or-nothing)
- **token scope** = その文脈が活性化する group の選択(membership の部分集合)+ default 書き込み先(#300)。**マシン/エージェントごとに変わるのは唯一これだけ**

→ token と鍵はもう双子ではない:**鍵 = 能力、token = 選択、直交軸**。

## 確定 3:マシン = エージェント = 「scope 付き token を持つ文脈」
同一プリミティブ。違いは **seed custody が pairing(マシン)単位** な点だけ:
- **マシン**:pair 済み(account の master_seed 保持 = 復号能力)+ 自分の token(scope = そのマシンの group 群)
- **エージェント**:そのマシンの seed を継承 + 自分の token(scope ⊆ マシン/account)
- 入れ子:`account membership ⊇ machine token scope ⊇ agent token scope`。実効アクセス = `token scope ∩ membership`

## 実装の実態と seam(2026-06-03 実態調査で更新)
token scope は **読み経路の大半で既に enforce 済み**。当初「/events は membership ゲートのみ」と書いたが誤りで、正しくは経路ごとに差がある:
- `run_sql`(MCP)= token scope clamp 済み(`getvariable('current_token_scope')`、posts_current/curations_current view)✓
- SSE `/events/stream`(live push)= token scope clamp 済み(`sse.rs` の `subscriber_can_read` が `allowed_groups` で弾く、test 有)✓
- 静的 `/events/{group}/{file}`(SPA が projection を組む bootstrap 経路)= **membership ゲートのみ、token scope 非適用**(`serve_group_event_file`/`event_file_dir` は `is_member_of` だけ)✗ ← **(1) を効かせる残 lever はここ**
- さらに SPA の「active workspace」は **client 側の単一フィルタ**(`localStorage: quacker:active-workspace`、`workspace.tsx`)で token scope 駆動ではない。SPA session token も scoped とは限らない(OAuth callback は unscoped 発行)
→ (1)「マシンの可視集合 = token scope」を本当に効かせるには:静的 /events を token scope で絞る or client が token scope で filter、+ SPA の active-group を token scope と整合。実装は別 PR、本 note は関係モデルの確定が目的。

## 参考:group の 5 役(別論点)
group 1 実体が audience / workspace / 暗号化単位 / 鍵 namespace / membership を兼ねる。本 note では「account が属する group」facet が主役。5 役を分割するかはさらに別の確定論点。

## 関連
[[project_quacker_e2e_master_seed]](乱数 seed・recovery 無し)/ [[project_quacker_identity_account_direction]](owner/collaborator/guest)/ [[project_quacker_token_scope_direction]](#13 L2 scope)/ [[project_quacker_e2e_group_context_token_flow]](正本 curation c_01KSZV31PR…)/ token default audience #300。UX 実態調査の詳細は本 note 投下時のスレッド参照。