Use cases — what each core / plugin / feature is for

Who this is for: you (or your agent) described a product need and want to know which pieces of the template carry it — before running advise, and in business language rather than registry ids. Each entry names canonical cases it enables and one line it is not for. Switch-off mechanics (env flag vs deletion) are in scope-taxonomy; this page is about fit, not removal.

Conventions: core is load-bearing (customize, never remove); plugin serves other capabilities (nothing user-facing disappears, but something stops working); feature is a terminal user surface (a page or journey disappears when trimmed).

Core

queue — background jobs, retry, SSE fan-out (core)

What: goqite-backed persistent jobs + worker pool with retry classification, plus the SSE hub that pushes updates to browsers.

Not for: multi-step processes with state between steps (that is dagnats); timers bound to one specific entity (no owner here).

database — app data in Turso/SQLite (core)

What: sqlc queries, migrations, and seeds. No admin UI, no separate service.

Not for: realtime fan-out (that is nats + SSE Hub record-sync); offline-first conflict resolution (that is offline-sync + collab).

What: login flow, session cookies, route gating. The middleware stays; the login page itself is removable UI.

Not for: API-token auth for machines (not included); BYOK accounting (that is credits).

Plumbing (core, not a decision)

server (shared boot), secrets (age env loader), app (deps bundle). You never keep-or-drop these; skip this section when deciding.

Plugins

nats — cross-process messaging (plugin, env-blessed)

What: embedded NATS JetStream — broadcast, KV, streams, leaf nodes. Runtime off: NATS_ENABLED=false (in-memory hub fallback).

Not for: single-process deployments (the hub covers fan-out; see "Topology profiles" below). Deletion is manual (15+ importers carry NATS types) — toggle, don't trim.

dagnats — durable multi-step workflows (plugin, offered)

What: DAG engine over JetStream: retries, timeouts, signals (suspend/resume), cron/webhook/NATS/HTTP triggers, DLQ with replay, operator console at /dagnats/. Runtime off: DAGNATS_ENABLED=false.

Not for: single fire-and-forget jobs (that is queue); per-step undo on failure — DagNats retries and replays, it does not compensate (see saga note below); timers owned by one entity (no owner here).

goakt — entity actors with supervision (plugin, offered)

What: one addressable grain per room (heartbeat roster plus an exactly-one presenter lock), supervised with restart budget, idle passivation. Standalone: no network, no discovery, no cluster. Runtime off: GOAKT_ENABLED=false.

Not for: converging data across replicas (that is collab/Loro); fire-and-forget jobs (that is queue); multi-step DAGs with replay (that is dagnats); cross-process placement (standalone only — cluster mode is out of scope for this unit).

llm — model calls (plugin, env-blessed)

What: GoAI client behind an injectable interface (any OpenAI-compatible provider), streaming, function-field injection for tests. Runtime off: unset GOAI_API_KEY (suggest button hides).

Not for: orchestration, memory, tool loops, supervision — single calls only. Multi-step agent behavior is dagnats (pipelines), not this.

collab — realtime convergence (plugin, bundled with whiteboard)

What: Loro CRDT DocStore, sync workers, presence transport. Never standalone (needs a producing feature: canvas, notes).

Not for: ownership or turn-taking (CRDTs converge data; they don't elect owners — no locks, no presenter token).

credits — AI metering + BYOK ledger (plugin, offered)

What: per-key usage accounting for metered LLM features. Runtime off: CREDITS_ENABLED=false (default; unmetered but working).

Not for: the model call itself (that is llm); subscriptions and invoicing (not included).

entity-store — where entities live (core)

What: Turso rows (server authority) vs Loro CRDT docs (converge without a round-trip). One store per entity — picked at design time, not a runtime switch.

Not for: both at once per entity — one strategy per store.

offline-sync — offline edits that arrive later (plugin, manual removal)

What: service-worker outbox + NATS CRUD proxy + idempotency. Runtime off: OFFLINE_SYNC_ENABLED=false.

Not for: conflict resolution on merge (that is collab); pure read-only offline pages (a cached shell needs none of this).

sounds, skins, datastar, components (plugins)

Small surface: UI sound cues (sounds, offered), non-default skins (skins-extra, offered), rendering helpers and shared UI plumbing (datastar, components — manual removal). Audible feedback and theming only; no business logic depends on them.

Features (user surfaces)

todo — reference CRUD (feature, manual removal)

What: the MVC demo every pattern in this repo points at. Keep it as the implementation reference; delete it manually when done reading.

Decision pairs (same need, different unit — pick once)

No unit for these (yet) — advise answers the full map

Real needs with no registry entry, verified against advise (no preset matched — decide from the table or build custom; do not force-fit):

whiteboard — shared canvas (feature, offered)

What: Loro canvas + Rough.js + presence (pulls in collab).

Stack pick: server-owned Loro Map (shape ops POSTed, resolved shapes broadcast) over Yjs-in-browser (a JS CRDT + bundler for a canvas that merges fine server-side) and over OT (shape conflicts resolve by versioned overwrite, not character transforms — OT buys nothing here). Pro: zero client deps beyond Rough.js, offline replay converges, and peers watch a stroke grow live (the in-progress shape rides the ephemeral presence channel and is committed on release). Con: every committed stroke round-trips; no live draft while offline.

Not for: owner arbitration (no presenter lock); canvas and notes share collab today.

room — presence demo page (feature, offered, bundled with goakt)

What: the /room/ page exercising the goakt engine (roster, presenter lock, crash hook). A reference implementation like todo, for entity actors.

Stack pick: GoAkt grains (addressable owners with supervision and restart budgets) over NATS request-reply with manual locking (no single owner, races on failover) and over record polling (polling, no supervision). Pro: exactly-one presenter survives crashes by design. Con: an actor runtime to learn and boot for what starts as a counter.

Not for: production rooms (no persistence, single process) — copy the grain pattern into your own feature instead.

notes — shared plain text (feature, manual removal, rides the whiteboard unit for trim)

What: the /notes/ pages exercising server-owned Loro Text (character ops merge, resolved text streams to peers, typing presence). A reference implementation like todo, for collaborative editing without a JS CRDT library.

Stack pick: server-owned Loro Text over Yjs-in-browser (second CRDT system + bundler + a sync protocol that fits websockets better than this SSE + NATS transport) and over OT à la the Datastar collab demo (server-serialized, plain-text-only, no offline merge — honest, but less than the CRDT already in the box gives). Pro: 3KB of vanilla JS, every keystroke converges, offline batches replay. Con: no client-local editing (round-trip per batch), no rich text, and peer presence is line/offset carets (no selection highlights).

Not for: rich text (no marks); offline-first editing (ops need the server — a dropped connection holds text in the tab only).

landing — public marketing page (feature, offered)

What: unauthenticated GET /, brand home. Dropping it 404s / (brand retargets to /todo).

config-view — ops visibility (feature, offered)

What: auth-gated read-only /config (env view for operators).

Topology profiles (when the stack shape changes)

One process (web binary only, no desktop, no second instance) never needs cross-process transport. That profile runs today via runtime switches, no rebuild: NATS_ENABLED=false (hub fallback), DAGNATS_ENABLED=false (workflows no-op), don't ship desktop. Degradations to know: onboarding pauses (DagNats no-op — rewrite as queue job chains for full parity), whiteboard sync and presence KV expect NATS (verify before relying on them switched off).

Multi-process (desktop edges, second instance, external workers) is the connected profile: NATS on, leaf nodes, crud proxy — the default you scaffolded. The cut is exactly this: does any second process need shared state? No → single profile. Yes → connected profile. A hard installer variant (clean single-process tree, no dead code) does not exist yet; the switches above are the blessed path until one is demanded.