Consolidated Decision Record ★ Authoritative
31 architecture decisions, rejected alternatives, and 5 open items requiring sign-off.
Record date: 2026-07-16. Scope: final architecture decisions across research documents 00–13. This is the corpus's single changelog-style document. Architecture specifications state the current plan affirmatively; this record preserves dates, rejected alternatives and rationale.
Decisions
| # | Date | Founder decision | One-line rationale | Spec reference |
|---|---|---|---|---|
| 1 | 2026-07-16 | Use Boja as the assumed working product name pending founder confirmation. | One working name keeps the corpus coherent without treating the final brand decision as closed. | 00 title and §1; docs 01–13 titles/intros |
| 2 | 2026-07-16 | Use Rocicorp Zero for query-driven partial sync. Offline means cached readable state, instant resume, and a durable message-send outbox only. | Zero's query-shaped hydration fits unbounded chat history and jump-to-message once general offline domain mutations are removed from scope. | 00 §1, §7.7, §8, §13; 07 §2 and §6; 08 §2.9 and §3.30 |
| 3 | 2026-07-16 | Use PostgreSQL as the source of truth with shared-schema tenancy and explicit server_id. |
Relational membership, authorization, billing and course invariants need transactions, FKs and one manageable migration/publication model. | 00 §3 and §5; 07 §3.1 and decision 5; 08 §2–§3 |
| 4 | 2026-07-16 | Use Better Auth for identity and sessions only; Boja owns servers, memberships, invitations, owners, roles and authorization lifecycle. | One app-owned product-membership source prevents identity-plugin rows from drifting into a second authorization system. | 00 §9; 04 "Recommended boundary"; 07 decision 7; 08 §2.1 |
| 5 | 2026-07-16 | Use the TRW-derived layered permission algebra: rank-ordered roles, first-class cross-server attributes, allow/deny effects, timeout mask, bounded owner bypass and entitlement gating afterward. | It preserves the proven expressive policy while making order, bypass and moderation behavior explicit and testable. | 00 §6; 05 "Permission and entitlement architecture"; 07 §4.1–§4.2; 08 §1.6 and §3.4–§3.8 |
| 6 | 2026-07-16 | Store permission authority as human-readable capability_key + effect rows under a generated manifest; one pure-TypeScript calculator takes explicit inputs. Optional bitsets are derived caches only. |
Human-readable rows are auditable and evolvable without making numeric encoding the domain contract. | 00 §6; 05 layers 1–2 and permission architecture; 08 §1.6 and §3.31; 10 §0 and §2.8 |
| 7 | 2026-07-16 | Build separate Expo/React Native and React DOM renderers. Share DTCG tokens compiled by Terrazzo, DaisyUI semantic vocabulary, component semantics and domain logic; web uses shadcn-style owned components on Base UI, native uses Unistyles 3. | Separate rendering protects native/web quality while retaining one semantic design and business contract. | 00 §1 and §4; 05 "Native/web sharing target"; 06 Parts C–D |
| 8 | 2026-07-16 | Production runs on self-hosted infrastructure, with Cloudflare enterprise services—Stream, R2, Images, CDN and Workers—as first-class exceptions. Other SaaS is prototype-only except the tax calculation API. | This preserves infrastructure ownership while using the company's contracted edge/media plane and one justified regulatory specialization. | 00 §1, §3 and §17; 09 production policy and Parts B–C; 11 §17 and §22.2 |
| 9 | 2026-07-16 | Use pg-boss for jobs after one Bun runtime/load spike; use Graphile Worker if that spike fails. | PostgreSQL-native enqueue preserves the transaction boundary and avoids a new durable queue dependency. | 09 Part A, especially A1, A3 and "Part A spike"; 00 §17 |
| 10 | 2026-07-16 | V1 live is broadcast only through Cloudflare Stream. Self-hosted LiveKit self-hosted interactive rooms and Egress are fast-follow; Cloudflare Realtime/RealtimeKit remains a later parity candidate. | Launching one recorded broadcast path keeps the v1 media surface bounded while preserving the planned interactive architecture. | 09 Part B §§B1–B4, as superseded by this decision; 00 §12 and §17 |
| 11 | 2026-07-16 | Use private R2 + Cloudflare Images/Workers/CDN for files, a thin TypeScript control plane, and self-hosted infrastructure scan/processing workers. | Direct upload and edge delivery keep bytes out of the app path while PostgreSQL retains authorization and lifecycle authority. | 09 Part C §§C1–C9; 08 §3.11 and schema addendum |
| 12 | 2026-07-16 | Billing uses NMI + value.io under the custom TSYS deal through Boja's in-repo billing service and immutable double-entry ledger. | The contracted processing path is retained while payment, accounting, subscription and entitlement facts become explicit and transactional. | 11 Part 3 §§17–25; 00 §10; 08 §3.26–§3.27 |
| 13 | 2026-07-16 | The commercial model is paid membership per server; communities are the bridge, preserving the TRW lesson. Boja is the default merchant of record. Future Whop/Stripe connections are verified external subscription-source adapters into billing_events and the internal projection, never direct entitlement writers. |
One community-centered membership and entitlement projection preserves access authority even when a creator supplies an external subscription source. | 11 §17, §22.1 and §26; 00 §10 |
| 14 | 2026-07-16 | Seller-payable and payout ledger accounts are launch-critical. V1 billing also includes affiliate commissions and reserves and uses the 27-day card-updater cadence and hu2-baseline dunning as typed versioned policy. | Money owed to creators must be balanced, auditable and payable from launch. | 11 §18.2, §20 and §25.7 |
| 15 | 2026-07-16 | V1 excludes trials, coupons, proration, subscription pauses, escrow/wallet top-ups, Ethoca automation, crypto, gift balances and non-NMI payment processors. | A narrow v1 money surface keeps accounting, compliance and recovery state machines auditable. | 11 §17.2, §§19–20 and §30.5 |
| 16 | 2026-07-16 | Tax calculation is an adapter-isolated production SaaS exception; Anrok and Avalara are candidates. Tax posts to tax_payable:<jurisdiction> at authorization. |
Tax is a regulatory specialty, but its result still belongs in Boja's balanced ledger and reconciliation path. | 11 §17, §18.2, §22.2 and §29; 00 §10 |
| 17 | 2026-07-16 | Threads ship as channels; bots are first-class v1 service principals with capability-row grants and webhook-first events. | Existing chat primitives handle thread history, while non-human actors need explicit identity, scope, rate and audit boundaries. | 10 Parts 1–2; 08 schema addendum gaps 1–9 |
| 18 | 2026-07-16 | OpenAPI ships from day one on Elysia; MCP and CLI clients are generated from the same contracts. | One application layer and versioned HTTP contract prevent server/client/tooling drift. | 10 Part 3; 00 §3 and §17 |
| 19 | 2026-07-16 | bojastack is the admin-API-first ops CLI with redaction, audit, access-explain and controlled break-glass behavior. |
Operator tooling needs the same authorization and evidence standards as product APIs. | 10 Part 4; 08 schema addendum gaps 10–13 |
| 20 | 2026-07-16 | Boja is a greenfield new-company build. TRW is prior-art evidence only and there is no TRW data migration or runtime dependency. | The architecture should preserve proven ideas without importing legacy data, compatibility machinery or service coupling. | 00 §2 and §8; 08 Part 4; 09 scope; 10 §0; 11 §30.6 |
| 21 | 2026-07-16 | The history boundary is confirmed: a 90-day hot Zero publication plus an authorized archive API. | Bounded synced history protects Zero while preserving older-history access through an explicit source-tier seam. | 07 §2.1 and decision 1; 13 §3.11 |
| 22 | 2026-07-16 | The risk that already-readable offline data cannot be instantly revoked is accepted for all servers; v1 has no sensitive-server mode. | A single honest offline contract is preferable to an unproven special mode. | 07 §2.4 and decision 2 |
| 23 | 2026-07-16 | DMs are in v1, using the global dm_conversations model and conversation membership from 07 §3.1. |
Direct conversations are a launch surface and must not be modeled as server-owned channels. | 07 §3.1; 13 §§3.3–3.4 |
| 24 | 2026-07-16 | Access is invite-only in v1: no anonymous users, guest access or public discovery. | Launch communities are explicit membership spaces, reducing authorization ambiguity and public-surface scope. | 07 §4.4 |
| 25 | 2026-07-16 | Full TRW-style learning ships in v1: modules, prerequisites and server-authoritative completion-to-role rewards. | Courses are part of the paid-community core, not a later content add-on. | 07 §5.5 and decision 10; 08 §§3.20–3.24 |
| 26 | 2026-07-16 | Unreads use a dot plus exact mention counts. | The lightweight unread signal stays cheap while mentions retain exact user-visible accountability. | 07 §3.5 and decision 6; 10 §1.8 |
| 27 | 2026-07-16 | Push notifications contain minimal content and support per-server, per-channel and per-thread preferences. | Privacy-safe payloads and explicit attention controls are launch requirements. | 07 §5.4; 10 §1.9 |
| 28 | 2026-07-16 | Moderation v1 is timeout, ban, tombstones and audit only. | This is the smallest enforceable, reviewable moderation lifecycle for launch. | 07 §4.5; 08 §§2.7 and 3.29 |
| 29 | 2026-07-16 | All six platform-surface questions are decided: a valid reply auto-reopens an archived thread; v1 UI exposes server-owned/private bots; message content is a separate bot grant; CLI auth uses device/interactive auth plus expiring CI keys; production impersonation has no two-person approval at launch; webhooks retry seven times through 24 hours. | These answers close the remaining thread, bot, CLI, ops and webhook contract branches. | 10 §§1.5, 2.5, 2.7, 3.4, 4.3 and "Founder answers" |
| 30 | 2026-07-16 | Scale posture is growth from zero across many small servers, not day-one flagship load; capacity models and spike seeds must reflect that distribution while retaining explicit future stress tests. | Launch sizing should model the product Boja will actually operate without hiding future ceilings. | 07 §6; 13 Part 4 |
| 31 | 2026-07-16 | Synonym-friendly keyword search is a hard requirement. V1 has one platform-wide dictionary; per-server creator dictionaries are fast-follow, with exact timing pending founder confirmation. | Domain jargon, abbreviations and creator terminology must resolve to canonical concepts without changing the source content. | 13 "Addendum: synonym support (hard requirement)" and Part 4 |
Rejected Alternatives and Historical Rationale
Rejected after the offline requirement narrowed to reads, resume and message sends. Its React Native maturity, production history and dataset headroom remain evidence behind the mandatory Zero spikes; 03-sync-engine-landscape.md preserves the comparison.
Rejected to preserve server authority. The local durable command boundary contains message sends only.
Rejected for the relational greenfield model, cross-server users, shared Zero publication and migration complexity.
Rejected because identity, membership, billing and entitlements require distinct app-owned sources of truth.
Rejected in favor of capability/effect rows and the ordered TRW-derived calculator.
Rejected in favor of separate native/web components over shared tokens, semantics and logic.
Rejected outside the Cloudflare enterprise plane and narrow tax adapter exception.
Rejected in favor of the NMI/value.io deal and internal ledger/projection. Future Stripe support is an external subscription-source adapter only.
Deferred to fast-follow. V1 uses Cloudflare Stream broadcast only; LiveKit self-hosted remains the planned interactive-room and Egress path, with RealtimeKit a later parity candidate.
Open Items Requiring Sign-Off or Spike Evidence
Finance must select Anrok, Avalara or another compliant adapter and confirm launch jurisdictions, registration and remittance operations. See 11 §22.2.
Counsel must confirm Boja's default-MoR contract, seller and affiliate liability, payout/KYC obligations, refund/chargeback allocation, enabled NMI/value.io operations and the approved hosted-fields/QSA path. See 11 §18.2, §21, §28 and §31.
Record the supported zero-cache topology, publication size, failover, rebuild, migration, rolling-upgrade, disaster-recovery and RN lifecycle results. See 07 §2 and §6, especially Spikes 1–2 and 5.
"Boja" remains the assumed working name until the founder confirms the final product name.
Platform-wide synonyms are v1; confirm whether creator-managed per-server dictionaries remain fast-follow or must move into launch scope. See 13 "Addendum: synonym support (hard requirement)."
Next Actions
- Complete the finance and counsel reviews, confirm the product name and per-server synonym timing, and record the Zero spike evidence above.
- Run the merged spike plan:
07§6, the surface placements in10, and the infrastructure, media, billing and search spikes in09,11and13. - Scaffold the Boja monorepo from the accepted boundaries, generated contracts and canonical schema.