# Plan: demarkus as a service Status: exploratory draft, recorded 2026-07-17 (Fritz + Claude). Question explored: if demarkus were offered as a hosted service (signup, everyone gets their own library), how would it work? Conclusion: it is Phase 6 plus a self-service control plane; no new core, no new protocol. Not scheduled; recorded so the shape and the two hard problems are not lost. ## One-line A hosted demarkus: signup provisions a personal world behind the shared broker, readable and editable through the library, joinable from Claude Code, with the broker holding every token so users never touch one. ## Architecture: world-per-tenant behind one broker The tenant unit is a world (one demarkus-server process + PVC), fronted by the existing broker and library. Signup decomposes into three steps that all reuse Phase 6 machinery: 1. **Identity**: account in the IdP the broker fronts (OIDC; email or social login). Phase 6.3. 2. **Provision**: append the tenant to the `worlds:` list; the ApplicationSet stamps out a StatefulSet + PVC; the bootstrap Job mints the world's tokens into a Secret. Phase 6.1/6.2, unchanged. 3. **Grant**: broker AllowConfig row mapping the identity to the world (read + write). The broker mints and holds all capability tokens; users never see one. This dissolves the remote-token-issuance problem for hosted tenants: the broker is the sidecar of [/plans/remote-token-issuance.md](/plans/remote-token-issuance.md) with a Secret writer instead of a file writer, already built. Hand over three things at signup completion: the library URL (reading room via broker SSO, ADR 0004 in demarkus-library), the Phase 6.4 `GET /me/install` one-shot script (wires Claude Code MCP), and, once the cataloging desk ships, in-browser editing. The hosted case is fully brokered, so the brokerless-editing gap (library direct-QUIC adapter is read-only; desk design assumes broker auth) never arises. **Collaboration**: inviting someone to your world is an AllowConfig grant plus an IdP invite. Broker-side only; no new machinery. The join-URL work (step 1 of remote-token-issuance) stays relevant for self-hosted users, not hosted tenants. **Portability**: OKF export gives tenants "leave with your whole world as a conformant bundle", a differentiator most hosted note tools cannot match. Import likewise eases migration in. ## The two hard problems ### Idle-tenant economics World-per-tenant means one running pod + PVC per signup, including dormant users. A thousand tenants is a thousand mostly idle QUIC servers. Levers to design: - **Scale-to-zero with wake-on-request.** The broker's world pool already dials worlds lazily, so the broker is the natural wake trigger; waking a UDP/QUIC backend is fiddlier than HTTP scale-to-zero (no standard KEDA HTTP-add-on path), so this needs a real design: broker detects dial failure, requests scale-up, retries with backoff, cold-start budget measured. - **Postgres store backend** so dormant state is cheap rows, not attached PVCs; compute can sleep harder when storage is external. Subject to the backend-parity principle in /roadmap.md. - Server remains one-world-per-process by design; do not bend that for density without a deliberate decision. This is the difference between a service and a demo. Nothing in the current stack addresses it. ### Quotas and abuse - Per-document 1 MiB cap and per-IP rate limits exist; there is no per-world storage quota and version history grows unbounded (retention is per-doc, opt-in). - Needed before opening signup: world-level storage quota (enforced where? store-level fits backend parity; a sidecar sweeper is the zero-core-change shape), version-history budget defaults for hosted worlds, and per-tenant rate limits at the broker. ## The control plane (Phase 7 pulled forward) Phase 6 assumes an operator edits the worlds list. A SaaS needs an API that performs identity + provision + grant atomically, plus lifecycle: - **Signup service**: creates the IdP user, provisions the world (initially: commit to the worlds list and let Argo converge; later: the deferred Phase 7 operator with a `World` CRD), writes the AllowConfig grant, returns the three URLs. - **Deletion**: delete world = PVC + Secrets + grants + IdP unlink. Clean at world granularity; ARCHIVE's no-hard-delete semantics stop mattering when the deletion unit is the whole world. This is also the honest GDPR story. - **Domains**: per-tenant subdomain mapping to broker world names, wildcard cert. - **Billing**: out of demarkus scope entirely; the signup service owns it. Keep it there. The explicitly deferred Phase 7 items (World CRD operator, web UI on the broker) are exactly this control plane; a hosted offering is the business case that pulls them forward. ## Dependencies on other plans - Phase 6.1-6.4 (universe deployment): the substrate; 6.3/6.4 must be past prototype. - demarkus-library cataloging desk (its /demarkus-library/plans/phase-3-cataloging-desk.md): in-browser editing for tenants; hosted case is the broker-authenticated path it already assumes. - demarkus-library Phase 5 public face (anonymous read): whether tenant libraries can have public/shareable pages. - Graph completeness Tier 1 ([/plans/graph-completeness.md](/plans/graph-completeness.md)): the 1 MiB /graph.md export wall and tombstone growth become per-tenant liabilities at scale. - Remote token issuance ([/plans/remote-token-issuance.md](/plans/remote-token-issuance.md)): unaffected for hosted tenants (broker covers them); stays the self-hosted story. ## Sequencing sketch (when this becomes real) 1. Harden Phase 6.3/6.4 (broker + install flow) on the existing knowledge.demarkus.io deployment. 2. World-level quotas + hosted retention defaults. 3. Signup service v1: waitlist-gated, provision via worlds-list commit, manual approval. 4. Scale-to-zero design + measurement (the go/no-go gate for open signup). 5. Phase 7 operator when world count makes GitOps-converge provisioning too slow. ## Open questions - Free tier at all? Idle economics says a free tier is only viable after scale-to-zero works. - One shared library deployment for all tenants vs per-tenant library pods (shared is the ADR 0004 shape and the obvious answer; confirm nothing in the desk design assumes otherwise). - Postgres-per-world vs shared Postgres with per-world databases for the pgstore backend at tenant scale. - Does the hosted broker stay the same binary as the OSS broker (it should; divergence here recreates the fork demarkus exists to avoid)?