# entry / post modeling 再考: A / B / C 比較(embed UX 議論) # entry / post modeling 再考: option 比較 本 entry は `n_01KSN2F6FWQSQAWEE3N4PQVAWC` 由来の dispatch `entry-inline-embed` の **alignment phase 出力**。impl scope ではなく、modeling 議論の thinking partner として user judgment に必要な material を整理したもの。 --- ## 問題提起 「entry を post 内で inline embed したい」という UX 要件を起点に impl を始めたところ、user から方向転換: > 今の entry と post が別物という風に定義しているモデリングが妥当なのかを再考したくなっています。「埋め込み」をした時に、返信はどちらに行われるのか / URL は何をシェアする、などの話が発生するため。 つまり embed UX の細部(syntax / presentation / scope)より先に、**embed されたとき何に向かって reply するのか / 何の URL を共有するのか** を決めるための modeling 軸が問われている。 --- ## 現状 modeling (Phase 1 alignment, "level A" choice) | | post (`n_<ULID>`) | entry (`en_<ULID>`) | |---|---|---| | body cap | 300 graphemes | 100,000 graphemes (markdown) | | reply graph | あり (`parent_post_id`) | **なし** | | tag / refs | あり | **なし** | | publish path | `app.bsky.feed.post` | (未実装、WhiteWind 想定) | | feed 表示 | timeline 主軸 | 独立 `/entries` page | | 社交 graph | post 間で閉じている | disjoint | 根拠 (`docs/design.md` § Entry aggregate): 1. **Distinct identity** — entry は "long version of a post" ではなく異種 record 2. **300-grapheme invariant 保護** — `app.bsky.feed.post.text` の lexicon contract を維持 3. **Ecosystem alignment** — WhiteWind lexicon 互換で publish-ready この前提が、embed の自然な reply / URL semantics と衝突するという問題提起。 --- ## option 比較 ### A. 装飾扱い(現状維持 + additive embed) **modeling 変更**: 無し **仕組み**: - post body に何らかの syntax(`@entry/<id>` / `[[en_...]]` / form 下ボタンから modal editor 経由で attach)で entry id を埋め込む - SPA は post-card render 時に該当 entry を fetch して inline 展開 - 「reply」ボタンは常に post に向かう - 「share」ボタンは post URL を返す - entry detail page は独立して残る、share したいときはそちらで個別取得 **pros**: - 凍結事項 100% 守れる(本 child の brief 内で完結) - ATProto publish path(WhiteWind)無傷 - migration 不要 - 短期で動くものが出る **cons**: - 「embed されてる entry に直接 reply」できない(reply は常に post に集まる) - 「entry 中心の thread」が組めない、必ず post が hub - 同じ entry を複数 post で embed したとき、reply が post 単位で散らばる(entry に集約されない) - 例: agent 調査レポート(entry)を複数の議論 post から embed → 各 post に reply が散在、entry 単位で会話が見えない ### B. entry / post を 1 aggregate に統合 **modeling 変更**: 大きい(Phase 1 alignment を覆す) **仕組み**: - post の 300 grapheme cap を撤去、長文も post として扱う - entry aggregate 廃止 or post の variant に - reply / share URL / social graph 全部 post 軸に集約 **pros**: - semantics 1 つ、reply / URL に迷い無し - embed は「自分自身の本文の一部」、概念 minimal - triage / 検索 / feed が 1 axis に統合 **cons**: - **ATProto compat 大破壊**: `app.bsky.feed.post.text` は 300 grapheme cap が lexicon 契約、cap 撤去すると bridge 不可能になる - WhiteWind lexicon 互換も失う(entry → post 統合で WhiteWind shape を捨てる) - 既存 event log の rewrite migration が大規模(`entry_created` → `post_created` 変換) - **Phase 1 alignment で明示的に却下した方向**(`docs/design.md` § Entry aggregate で distinct identity を選んだ) - post の feed / mention / replies すべての index に長文混入、SPA / DB cost up - pre-alpha は "clean over compat" 方針(memory `feedback_kneume_pre_alpha_clean_over_compat.md`)だが、ATProto compat は外部 ecosystem 都合で kneume の判断だけでは捨てられない **scope**: 本 child の brief を完全に超える。複数 PR + 段階 rollout 必要。 ### C. entry に reply / share URL / tag を生やして post と peer に **modeling 変更**: 中(additive 拡張) **仕組み**: - entry はそのまま独立 aggregate、ただし reply / tag / share URL / publish path を持つ - post と entry はどちらも social surface を持つ peer - embed は post と entry の **関係**(typed link, 例: `post_refs` を拡張するか entry 側に新 table) - UI: 「embed されてる entry に reply」と「embed してる post に reply」を切替可能、reply destination は明示的に選ぶ - share URL は post / entry それぞれ独立に存在(embed されてても entry detail page は機能する) **pros**: - modeling 拡張は **additive**(既存 post の挙動 1px 触らない) - entry を中心とした thread(例:WhiteWind blog post への comment 集約)が表現可能 - ATProto WhiteWind 互換維持(WhiteWind は entry 単位の comment graph を持たない、kneume 拡張が乗る形) - entry が「単独で意味を持つ独立した記事」として扱える(現状の延長) - 同じ entry を複数 post から embed しても、reply は entry 自体に集約する option が選べる **cons**: - entry に reply graph を入れる migration(event log 拡張、SPA UI 拡張、reply destination 決定 UX)が必要 - 本 child の brief の凍結事項を一部超える(entry 挙動を additive に拡張する) - UI 設計判断が増える:reply destination 切替の UX をどう自然に出すか - entry に reply graph が乗ると「post の thread に entry reply が混じる」表示問題が新規発生(sort / display 設計) **scope**: 本 child の brief を一部超える(中程度)。modeling 拡張 + reply destination UI が新規。 --- ## 軸別比較表 | 軸 | A. 装飾 | B. 統合 | C. peer 化 | |---|---|---|---| | reply 先の自然さ | post 固定(entry に直接 reply 不可) | 単一 | 選択可(UI 必要) | | share URL の自然さ | post URL のみ | 単一 | post / entry 両方 | | 既存 modeling との衝突 | ゼロ | 大破壊 | additive 拡張 | | ATProto compat | 維持 | 喪失 | 維持 (kneume 拡張) | | Phase 1 alignment(distinct identity)との一貫性 | ◎ | ×(覆す) | ○(拡張) | | 本 child の scope | 内 | 大幅超 | 一部超 | | 「entry 中心の会話」表現力 | × | ○(post と一緒) | ○(明示的) | | 短期 UX 改善速度 | 高 | 低 | 中 | --- ## 私(child)の感想(judgment は user に委ねる) 短期で「entry が post 内で読める」体験だけ欲しいなら **A** で十分。実際の使われ方を観察してから B/C を判断する余地が残る。 ただし user が「entry 中心の thread」「entry に直接 reply して議論を集約」を未来要件として強く見ているなら、A で固めると後で migration cost(reply graph 後付け、URL semantics 変更、syntax 変換)が増えるので、最初から **C** で peer 化した方が cost trajectory が良い。 **B** は ATProto compat と Phase 1 alignment を覆すので、よほどの理由がない限り推奨しない。pre-alpha の clean-over-compat 方針(`feedback_kneume_pre_alpha_clean_over_compat.md`)は kneume 内部の判断にのみ適用、ATProto 互換は外部 ecosystem 制約で kneume の都合だけでは外せない。 --- ## 判断のために user に聞きたいこと 1. **使われ方の主従**: entry の使われ方として「post 内で embed して読む」と「entry 単独で thread / 議論を組む」のどちらが主か?(両方半々?) 2. **読み手は誰か**: entry を読みに来るのは(a) 自分の retrospective、(b) 他者の comment 受け取り、(c) agent への input、のどれが多そうか? 3. **「entry に reply」したい具体シナリオ**: 「post じゃなく entry に reply したい」と感じる場面、想像できる例があるか?(無ければ A で十分の signal) 4. **同じ entry の複数 post 埋め込み**: agent 調査レポート(entry)を 3 つの議論 post から embed したとき、それらへの reply は post 単位で散らばっていてほしい(A)か、entry に集約したい(C)か? --- ## 周辺 modeling option(本筋から外れるが参照) - **D. post_refs に `embeds` kind を新設**: A の sub-variant、syntax を本文に書かず post_refs(別 channel)で関係を持つ。reply / URL は post 固定なので A と同じカテゴリ。 - **E. entry を curation の特殊 case として吸収**: curation aggregate(`c_<ULID>`、order + narrative)に対する extension で長文 narrative + ordered post members とみなす。entry が単独で立たない設計、Phase 1 alignment と矛盾するので除外候補。 --- ## refs - 元 note: `n_01KSN2F6FWQSQAWEE3N4PQVAWC` - entry 用途 Q&A: `n_01KSN0G0Q96SM47CMPVEHGXYVX` ↔ `n_01KSN0K9XFSGCNZ22NNFGM8PWA`(user 記事 / agent 調査レポート / 300+ 返信) - alignment Q: `n_01KSN8MP20R0MY60MGHP0BG7CW`(本 entry の起点 thread) - modeling 軸 reply: `n_01KSN99RE4GVAVKPT74PRW7R6F`(A/B/C 短縮版) - 設計 doc: `docs/design.md` § "Entry aggregate (`entry`)"、§ "Post refs" - 関連 PR: #110 (entry v1)、#114 / #117 (mention)、#122 (post_refs)