[design] server を薄く / DuckDB エンジンは手元 — server-side content projection 撤去の方向(2026-06-02 合意)
**役目**: E2E 前提下で server-side DuckDB(content read-model = `projection.duckdb`)を retire する方向の正本。2026-06-02 の設計対話で合意。背景 = E2E では server は ciphertext しか持てず、本文の read-model を server に置く意味が消える。読み手は全員 server の外でエンジンを回せる/回している。エンジン依存は SPA(DuckDB-WASM)/ build replay / gateway に分散。
## A. 認可 — 既に配信ゲートが primary、content projection に非依存
- event は audience group ごとに物理ディレクトリ分割(`events/g_<id>/…jsonl`、public は top-level)。`store.rs` ヘッダ明言「file-system layout が primary fence、projection の audience filter は second layer」。
- `/events/{group_id}/{file}` は byte を返す前に handler で membership チェック(`src/lib.rs:528`)。匿名は public のみ。旧 `/projection.duckdb` 丸ごと配信は leak として削除済(`src/lib.rs:185`)。
- 残る依存は 1 点:membership チェックが projection 内の `group_members` を引く(`src/sse.rs:342`)。→ server は delivery ゲート用に **小さな membership/authz index** を持ち続ける。membership 系 event だけから組む軽いグラフで、本番を落とした content 全 replay とは桁違い。
- 決定:content projection は消す / membership index は server に残す / **capability 盲目 relay**(server が social graph を知らない形)は multi-owner・untrusted host が現実になるまでの deferred seam。単一 owner では server が graph を知る脅威は実質ゼロ。
## B. 匿名/SEO — 既に build マシンで replay → CDN 静的、server projection 非依存
- `web/scripts/prerender.ts` が build 時に public event JSONL を fetch → 自前 TS replay(`./replay.ts`)→ `dist/p/<id>/index.html` 生成。出力は Cloudflare 静的アセット(`web/worker.ts`)。Fly origin は描画に絡まない。
- B に追加の設計判断なし。要件は「server が public event JSONL を配り続ける」だけ(A で残す機能そのもの)。
## 帰結 — 残存消費者は run_sql だけ → 引っ越しが unlock
- SPA = ブラウザ DuckDB-WASM、匿名/SEO = build replay、いずれも server projection 非依存。content projection の残存消費者は MCP `run_sql` ただ 1 つ。
- **`run_sql` を gateway(`quacker-channel bridge --proxy`)の local projection に移す = server から content DuckDB を消す唯一の一手。** gateway は既に復号を持つので、JSONL stream から local projection を組んで SQL を local 実行する形に拡張する。
## 引っ越し後の server の姿
- event append / event JSONL 配信(public world-readable、group membership ゲート)/ 小さな membership・authz index / auth・identity store / SSE(membership ゲート)。
- 「起動時に content 全 corpus を replay」が消えるので、#279/#293/#298 系の起動 hang・OOM の class が server から無くなる。
## 反省(direction の経緯)
- #293/#298 は本番障害の消火で妥当。だが #299(agent-read view を server projection に追加)は、まさに引っ越したい唯一の消費者 run_sql を server 側で快適化する投資で、方向は逆走だった。今後 server content projection を「育てる」側の PR を増やさない。
build 順 = 子 curation(run_sql 引っ越し → membership index 分離 → content projection 削除)。関連 = E2E group 運用フロー(別 axis、運用 UX 層)。