1Context
The forked learning core provides a per-course flat forum and announcements — and nothing else. The whole social platform — global boards/spaces, member directory, feeds/follows, member↔member DMs + group chat, events, notifications, presence — is greenfield. It must satisfy the locked foundation invariants: one identity, tier gates every object, AI permissioned at retrieval, one shell, on a small team.
The estate-scout confirmed: almost nothing in the estate is reusable turnkey for a human community. But the AI half (index + agent runtime) is real, existing estate.
2The four options considered
| A | Fully custom on our own service (own everything). |
| B | Fork + reskin a mature OSS community/forum engine (adopt frontend-and-all). |
| C | Headless engine behind our shell (adopt the backend/API, render from our shell). |
| D | Compose from estate blocks + our shell. |
3The panel — rankings diverged, architecture converged
Every lens ranked the four options differently. Read the core argument, not the rank. Full verdicts →
| Lens | Rank #1 | Core argument |
| Simplicity | B | "Self-run stateful services × ops-team size" is the ballgame. Fork a forum, map trust-levels → tiers, use async notifications, kill the AI home + realtime + fleet for v1. |
| Build-vs-adapt | C | You adopt-and-theme the learning core correctly, then contradict it by hand-building the most commodity piece. Put the seam at backend/presentation; own the shell; split boards from realtime; emit to the index via an outbox. |
| Data | A | You've implicitly chosen event sourcing and not noticed. Own an append-only, member-keyed, tier-stamped log as source of truth; boards/DMs/feed are derived views; feed = read-time query; presence = separate AP soft-state. |
| AI-native | D | The moat lives in the data layer. A foreign forum = two permission systems (→ tier leaks) + chunk drift. Own the object model + tier + index emission + agent read/write; borrow only the realtime transport. |
4The convergence
- Never make a foreign forum the system of record. Simplicity picks B only by also cutting the AI moat — a different objective. Every lens that keeps the moat says a vendor schema as source-of-truth is fatal (two permission systems, chunk drift, mutable history, merge tax).
- Own the data + permission + write-path-into-the-index; rent the rendering + realtime transport. Three lenses enter from three doors into the same room.
- Split durable boards from ephemeral realtime. Different stores, different consistency.
- Feed = read-time query, tier evaluated at read. A materialized per-user timeline leaks content after a tier downgrade.
- The estate's real contribution is the AI half (brain = index; governance plane = runtime) — not the human-community rendering.
5Decision — "Own the log · rent the rendering · defer the bells"
Own (the moat — cheap now, catastrophic to retrofit)
- The conversation event log is the single source of truth — append-only, immutable. Every post/message/RSVP/membership-change/AI-query is an event:
event_id · conversation_id · seq (per-conversation monotonic, store-assigned — NOT wall-clock)
· member_sub (FK) · tier_visibility (immutable on the object) · type · payload · created_at
- Boards, DM threads, directory, and the home feed are derived, rebuildable views over the log — never the record.
- Tier is a pure deterministic function at read time, against the reader's current tier, before any ranking. Never bake (reader-tier × object-tier) into a stored artifact.
- Every write emits into the permissioned index via an outbox (at-least-once, idempotent). The AI home reads the index, never a surface's store → engine swap = repoint, not moat rewrite.
- Governed agents read + write through the estate agent-governance plane; the estate knowledge brain is the index.
Rent (the commodity — don't hand-roll, don't let it become the record)
- Rendering / hard mechanics (threading UI, full-text search, moderation): adopt a mature engine as a derived view fed from our log — if a spike proves it can run as a pure projection with our tier as sole authority. Else build boards custom (threads over an event log isn't the hard part).
- Realtime transport: a borrowed AP best-effort pipe that resyncs from the log. Never the record.
Defer (the simplicity cut — scoped, not killed)
- v1 on one box. No dedicated fleet.
- No presence service / typing for v1 — async notifications cover ~95% of the value at ~5% of the ops cost.
- No ranking agent for v1 — home ships as "Latest / Top this week" over the index; upgrading to an agent is a repoint because the substrate exists from day one.
- But the append-only log + tier-at-read + index-emit are built from day one — cheap up front, catastrophic to retrofit.
6Tradeoff matrix
| Dimension | A custom | B fork | C headless | D estate | Decision |
| Own the append-only log | ✅ | ❌ | ⚠️ if disciplined | ✅ | ✅ by construction |
| One permission authority | ✅ | ❌ two systems | ⚠️ | ✅ | ✅ |
| Time-to-substance | ❌ slow | ✅ fast | ◑ | ❌ | ◑ rent rendering |
| Ops-service count / small team | ❌ | ✅ | ❌ | ◑ | ✅ defer bells |
| Reversibility of rendering | ✅ | ❌ | ✅ repoint | ◑ | ✅ |
| AI-indexable at write | ✅ | ❌ chunk drift | ⚠️ | ✅ | ✅ |
7Consequences
New locked invariants (promote into the foundation spec)
I9 The conversation log is append-only and is the source of truth; every board/DM/feed is a derived, rebuildable view; tier is evaluated at read time against the reader's current tier. (The single most important missing sentence.)
I10 The community store and the tier/permission authority are ours; any borrowed component is a transport/library/derived-view, never the system of record or the permission authority.
New required evals (the moat is only as trustworthy as these)
P0 Retrieval-permission tier-leak eval, fail-closed. Golden set (member fixtures T0–T3, query, must-return / must-not-return) run on every model bump, prompt change, schema migration. No eval = the invariant is a wish. Built before the first agent reads the first board — a cross-tier leak in a paid, vetted community is the most expensive failure this platform can have.
P1 Directional home-ranking regression eval + a production engagement proxy (so the feed can't rot silently). P1 Per-flow prompt eval for each governed agent; fixtures are source code under review.
First task is a spike, not a build
Evaluate 2–3 candidate rendering engines against the contract (pure derived view fed from our log · presentation owned by our shell · our tier as sole permission authority). Decide C-vs-custom on evidence.
8Preserved dissent (do not resolve away)
- Simplicity vs the moat: the ranking agent is deferred, but the cheap substrate is built from day one. If members never hit a firehose, the agent may never earn its place — an acceptable, reversible bet.
- "Don't build a database": renting the rendering only holds if we never let the engine's DB become the record. The day discipline slips, C silently becomes B and history rots.
- C vs custom rendering is not decided — handed to the E4 spike. The log/tier/index spine is decided; the rendering engine is a repoint either way.
← Roadmap · index · deeper: the 5-lens panel → · architecture diagram →