Skip to content

Architecture Decision Records

Zozo's ADRs (docs/adr/) are binding constraints, not history (see CLAUDE.md). This index is generated from that directory on every build — adding or removing an ADR there changes this page with no hand edit.

ADRTitle
0001Orchestrate vendor agent runtimes, not raw model APIs
0002Core library with a thin server wrapper, in TypeScript
0003Harness-owned Thread state; Runtime sessions are a cache
0004Append-only Event journal as the durability and streaming primitive
0005Tool governance rides runtime hook surfaces, and fails closed
0006Multi-agent coordination is caller-scripted turn-taking, not agent-to-agent messaging
0007Workspace is bound to the Thread; the caller owns its lifecycle
0008Threads carry opaque metadata the engine never interprets
0009Bypass is the empty Permission Policy, gated by server opt-in
0010The Dispatcher is the front door; the Server binds localhost-only behind it
0011Runtime credentials are bring-your-own and stored outside the Event journal
0012Loop process invariants are dispatcher-owned; project prompt customization is layered on top
0013Usage-cap handling uses runtime reset signals; the proactive usage gauge is deferred
0014Interruption model: pause is a Thread flag, aborted means deliberate, the stopper owns cleanup
0015Dispatch admission: one global cap, human-triggered work queues and goes first, one fleet Drain
0016Managed worktree reaping keys on follow-up disposition, not Run terminality
0017Suspending a fleet Drain is a graceful selector stop, not an abort
0018Requeue is conditional; a resolved or unshipped attempt is never requeued
0019Intake Sessions are read-only; only the Dispatcher writes to the Project or the forge
0020Intake Session lifecycle: the worktree is a reconstructible read-cache, and grill Runs share the one admission cap
0021The Intake Session overlay is durable; a session stuck in Planning reconciles from the Event journal
0022Credentials are validated by a minimal Runtime turn, and their health is Run-affirmed not re-probed
0023Auto-drain is a scheduled fleet-Drain trigger; Suspend clears it
0024Remote mobile access is a Tailscale-fronted PWA over HTTPS
0025Event → Web Push is a poll-based, edge-triggered Dispatcher worker
0026Wayfinder Maps: GitHub owns the Map, the overlay owns orchestration
0027Per-Ticket policy tiers, human-approved at claim
0028Interactive admission reserve, and queued-for-admission is a first-class observable state
0029task Tickets answer empirical questions; Tickets never carry implementation work
0030task Tickets are pre-decision unblocking work; research owns empirical questions
0031The Endgame hands off through a Spec and a Ticketing session; ready-for-agent means frontier
0032Runs execute in Cells: an operator-selected Executor seam, rootless, fail-closed
0033Issue spec is injected into the Run prompt at dispatch; agent Cells hold no forge credentials
0034Engine schema changes move through a forward-only migration ledger, fail-closed on skew
0035Hosted credential onboarding is browser-to-stack; API-key credentials are first-class (amends ADR-0011)
0036Control-plane persistence is managed Postgres with its own migration ledger; convergence is an idempotent in-process sweep loop
0037Stack-side contract v1 is pull-only, bearer-token-scoped-by-construction, and additive within an N/N−1 window
0038Hosted tenancy is one Stack per tenant VM; the Dispatcher's supervisor pulls a versioned contract and never self-registers
0039The tenant stack image is a single idempotent Debian 13 provisioning script; the rootless membrane's safety is a pinned, explicitly-verified property, not an assumed default
0040The Hetzner provisioning sweep converges four independent, idempotent steps per stack; Primary IP and VAPID identity are tenant-owned, never stack-owned
0040Under-specified drains convert to a Clarification detour on the same Thread
0041Control-plane sign-in is GitHub OAuth into an opaque, revocable, server-side session; identities and tenant membership are both extensible without a migration
0042Hosted stacks are reached direct-to-VM on PSL-listed origins via a one-time-code handoff (supersedes ADR-0024 for hosted stacks only)
0043Stripe billing is Checkout/Portal-only with dumb webhook receivers; the five-state tenant lifecycle is decided exclusively by an idempotent reconciler sweep
0044The Dashboard's credential onboarding checklist reads real stack state; subscription credentials are consent-gated server-side; Status gains an additive per-credential health map
0045Credential re-auth is a tenant-self-service email, edge-triggered off a persisted per-credential alert state, never a per-poll notification
0046Metering rollup is a pure read of the journal, upserted per (stack, day, provider); visibility only, never a Run gate
0047Quiesce and suspend are one graceful wind-down primitive, actuated at the admission gate from two independent desired-state facts
0048Fleet alerting is a closed, code-reviewed condition set, edge-triggered against persisted state, to exactly one webhook
0049Tenant stack backup is a daily encrypted PUT to separate-provider object storage; restore is rebuild-and-refeed, never restore-in-place
0050Export archive is a Dashboard-only, on-demand download; the decommission sweep is gated on the same unshipped signal, overridable only by an audited tenant confirmation
0051The host-side updater is a dumb, faked-service-tested executor: quiesce-gated, backed up locally first, health-gated, self-reverting
0052Abuse detection is provider-signal-only and never auto-acts; the response ladder is a fully human-triggered state machine with one new substrate primitive
0053Break-glass shell access is structurally consent-or-loud-override, never an ops claim; one mutable row is both the window and its own audit entry
0054The two v1 quotas are shaped by where they're enforced: the Run cap flows to the stack's own admission gate, the watched-Projects cap never leaves the control plane
0055The control plane's first production deployment: one Hetzner VM, self-hosted Postgres until the first paying customer, Caddy for TLS, DNS-only

Docs for Zozo — a coding-agent harness.