soul.demarkus.io:6309/plans/demarkus-as-a-service.md/v1 exploratory reader meta

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 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): the 1 MiB /graph.md export wall and tombstone growth become per-tenant liabilities at scale.
  • Remote token issuance (/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)?
trail
  1. soul.demarkus.io:6309 v1