creator-os-runtime — Architecture (behavioral spec)
One process. One command. One source of truth. Max capability inside the box, min authority outside.
What it is
The runtime is the credential proxy + policy gate + ledger that sits between agents (the COG, sub-agents, Claude sessions, MeshMarket agents) and real infrastructure (Railway, Cloudflare, GitHub, Stripe). Nothing outside the runtime ever holds a root credential. Agents hold grants — signed, scoped, budgeted, expiring capability tokens — and every real-world action is a controlled exit the runtime performs on their behalf after verifying the grant.
For "Creator-OS for everyone" this is the same box, multi-tenant: each creator is a tenant, their subscription tier is literally a grant budget, and the COG is the agent that turns "launch my tip bot" into grants + worker deploys without the creator seeing any of the plumbing.
Actors
| Actor | Holds | Can | Cannot |
| **Tenant** (a creator) | a root grant = their ceiling | everything their tier allows | exceed tier ceilings, touch other tenants |
| **COG** (agentic helper) | a grant with `cog.plan`, `cog.execute` | propose grant sets + deploy plans; ask gatehouse to execute | sign grants, hold infra creds, exceed the tenant ceiling |
| **Sub-agent** | an attenuated child grant | only what its grant lists, inside its scope/budget/TTL | widen anything; see root creds |
| **Gatehouse** (policy gate) | the signing key | evaluate proposals deterministically; sign or deny | be talked into anything — it is not an LLM |
| **Controlled Exit** | RAILWAY_API_TOKEN / tenant OAuth tokens (vault) | perform the infra call a valid grant authorizes | act without a grant; act while paused |
| **Ledger** | — | append-only record of reserve/settle/release + every exit | be edited |
Invariants (the fail-safe contract)
money.* / wallet.* / trade.* capability in the registry, so no grant can express it. Unknown caps are rejected. Break-glass never lifts this.worker.delete in a production environment requires a live, time-boxed (≤25 min) break-glass window armed by the admin.t-<tenant>- and deploy only into the tenant's allowed targets./docs, /routes, /.well-known/creator-os.json, /selftest are served by the running instance — the deployed instance is the spec.The COG loop
intent ("launch a tip-alert worker for tenant X")
→ COG.plan : deterministic template planner (+ optional LLM refinement, re-validated)
→ proposal : { grants: [...attenuated child specs], deploys: [...deploy intents], estimate }
→ gatehouse : ceilings + hard rules + tier → sign each grant or deny the whole proposal
→ exit : for each deploy intent → dry-run plan → (if confirmed & armed) Railway GraphQL
→ ledger : reserve → settle/release, every step referenced by ids
→ events : bus entries (cog.planned, grant.issued, deploy.requested, deploy.status, …)
requireDryRun (default on for a worker name's first deploy) returns the plan with executed:false; a second call with confirm:true executes. Without RAILWAY_API_TOKEN (or a tenant OAuth token) the exit is unarmed and always returns the plan — the loop is safe to run before any secret exists.
Brain + memory (every app ships with both)
Memory is the REMEMBER chamber, per tenant: records keyed by (partition, key) with content, tags, a monotonic version, and tombstones — the same LWW model as cognitive-mcp / the bridge. Partitions: tenant (shared), agent:<sub>, worker:<name>, fan:<id>. Search is Postgres full-text + substring. Surfaces: POST/GET/DELETE /api/memory (caps memory.read / memory.write, partition scope enforced) and MCP tools memory_search, memory_write, memory_forget.
The COG remembers. cog.plan pulls prior evidence (memory matching the intent + template) and prior failures on that template before proposing; the proposal carries evidence[] and warnings[]. cog.execute writes back what happened (agent:cog / deploy:<name>). A Railway Deployment.failed webhook writes worker:<name> memory — so the next plan for that worker already knows.
Brain is the event bus. Inbound: /webhooks/brain (signed). Outbound: every events row is fanned out to BRAIN_URL (signed with BRAIN_WEBHOOK_SECRET, header X-Brain-Signature) through the outbox table — retries with backoff, gives up after 10 attempts with the error kept, POST /api/admin/outbox/drain for a manual/scheduled push, /api/admin/outbox to look.
Sync peer. The runtime speaks the bridge's seam protocol both ways: it serves GET /sync/changes?since=<version> and POST /sync/apply (bearer COG_SYNC_TOKEN; records carry partition = "<tenant>/<partition>", LWW on version, tombstones honored), pushes each memory change to COG_BRIDGE_URL/sync/apply through the outbox, and pulls with POST /api/admin/memory/pull (cursor kept in settings). Point the cognitive-mcp bridge at the runtime and the runtime at the bridge: memory flows both directions, and the box keeps working when either side is away.
Subscription SaaS = grant budgets
| Tier | workers | deploys / period | compute allowance (¢) | max grant TTL | max depth |
| starter | 2 | 20 | 500 | 1h | 2 |
| pro | 10 | 200 | 5,000 | 24h | 3 |
| studio | 40 | 1,000 | 25,000 | 7d | 4 |
| house | 500 | 100,000 | 10,000,000 | 30d | 6 |
Prices are set in Stripe; the runtime maps price_id → tier via STRIPE_PRICE_MAP (JSON). Stripe webhooks drive tenant state: checkout.session.completed activates, customer.subscription.updated re-tiers, customer.subscription.deleted / invoice.payment_failed suspend. A suspended tenant's grants fail verification (fail closed) until resumed.
Surfaces
/): hub-and-spoke. One hub with an index of pages (#/tenants, #/grants, #/deploys, #/ledger, #/memory, #/events, #/webhooks, #/outbox); each page shows one clear thing and a Back link. The cockpit is content (cockpit.html, stored as doc _cockpit), not code./api/*, /mcp, /routes, /.well-known/creator-os.json): dense, complete, typed. This is where agents live.Integrations and arming
Every integration is optional and reported by /health.armed. Missing secret ⇒ the dependent route returns 503 {armed:false, needs:"NAME"}.
| Env var | Arms | Set where |
| `DATABASE_URL` | persistence (required) | Railway reference `${{Postgres.DATABASE_URL}}` |
| `RUNTIME_ADMIN_KEY` | admin routes + cockpit | Railway Variables (rotate the scaffold key) |
| `GRANT_SIGNING_KEY` | grant signatures (auto-generated + persisted if absent) | optional |
| `VAULT_KEY` (64 hex) | encrypted tenant tokens (Railway OAuth) | Railway Variables |
| `RAILWAY_API_TOKEN` | house controlled exit (deploy workers) | Railway Variables |
| `RAILWAY_OAUTH_CLIENT_ID` / `RAILWAY_OAUTH_CLIENT_SECRET` | per-tenant Railway login (redirect `/auth/railway/callback`) | Railway Variables |
| `STRIPE_WEBHOOK_SECRET`, `STRIPE_PRICE_MAP` | billing webhook | Railway Variables |
| `RAILWAY_WEBHOOK_TOKEN` | deployment-status webhook (`/webhooks/railway?token=`) | Railway Variables + project Webhooks tab |
| `GITHUB_WEBHOOK_SECRET` | repo push webhook | Railway Variables + repo webhook |
| `BRAIN_WEBHOOK_SECRET` | Brain event intake | Railway Variables |
| `MESH_RECEIPT_SECRET` | MESH receipt intake (402 receipt-as-grant experiment) | Railway Variables |
| `ANTHROPIC_API_KEY`, `COG_MODEL` | LLM refinement inside COG.plan | Railway Variables |
| `BRAIN_URL` | outbound event fan-out to the Brain (signed with `BRAIN_WEBHOOK_SECRET`) | Railway Variables |
| `COG_SYNC_TOKEN` | serves `/sync/changes` + `/sync/apply` to a memory peer | Railway Variables + bridge config |
| `COG_BRIDGE_URL`, `COG_BRIDGE_TOKEN` | push memory changes to the cognitive-mcp bridge; `POST /api/admin/memory/pull` pulls | Railway Variables |
Storage
Postgres via Bun.sql. Tables: settings, tenants, grants, ledger, deploys, webhook_events, events, vault, oauth_states, breakglass, docs, memories, outbox. Schema is created idempotently at boot (CREATE TABLE IF NOT EXISTS). Counters (reserved_*, settled_*) live on the grant row and are updated inside transactions; the ledger table is the audit trail.
Over-the-top layer (designed, not yet shipped)
Deployment.failed/crashed webhook (already written to memory) → COG proposes a bounded repair grant (restart, rollback, re-deploy) → self-healing workers the creator never notices.tz_capability_nodes/edges) so the Thinking Box can pull "how did this get deployed" toward the current problem./mcp already exposes the runtime as tools, so COG is a connector into Claude/ChatGPT/DevDesk today.