Chapter 7 — Deployment and operations¶
How the system runs in production, how releases move, and what the operator actually does. The deliberate headline: this is a small estate run with big-estate discipline — one VM, Compose, Caddy — governed by migration gates, provenance ledgers, and runbooks rather than by fleet machinery it does not need yet.
7.1 The production estate¶
The deployment target is recorded as an ADR, not folklore (ADR-GO-015): Docker Compose on a single cloud VM behind Caddy, with Cloudflare in front. The public surfaces:
| Surface | What it serves |
|---|---|
rosetta-design.com |
The console (enablement agent): registration, keys, engagements, governance views, admin; the KMS-gated install/download routes |
api.rosetta-design.com |
RGAS — the versioned REST API (canonical API hostname since the DT-RX-026 domain consolidation) |
mcp.rosetta-design.com |
The hosted MCP connector (streamable HTTP + OAuth) |
docs.rosetta-design.com |
The public docs build; /internal/ is the insiders build behind an auth gate |
The graph (Neo4j) and MySQL run on the same estate; Caddy terminates TLS and
health-checks RGAS's /health, which reports healthy only when both stores answer.
Infrastructure is Terraform in the producer repo (VPC, VPN, firewall, disks,
snapshots) — the estate is declared, not hand-built, and infrastructure ownership
itself has a governance trail (an early misalignment over which repo owned the VM was
resolved by a ratified divestment DT).
7.2 The migration lane¶
Production data changes ride governed lanes only — an explicit operating rule, not
a habit. The composed producer lane (make prod-migrate) chains: schema apply → seed
load → engagement-stack load → the serial invariant gates (all 39 INV-D checks; a
red gate stops the train) → API registration → a ProvenanceEvent ledger entry
recording the migration itself. MySQL migrations are idempotent and numerically
ordered, re-runnable on a fully-applied database by construction, and CI re-runs them
to prove it. The design consequence an assessor should note: a production migration
cannot silently skip its own verification, and every one leaves a graph-visible
record.
7.3 Release trains and the re-vendor chain¶
A constellation of pinned contracts means releases are trains, not events. The
canonical sequence when the producer cuts a release: platform tags and publishes two
sibling artifacts (the consumer intake tarball and the KMS-gated install bundle);
the app server re-pins its build-time intake and tags; the MCP server re-vendors the
OpenAPI contract, regenerates wrappers (the tool-policy completeness guard forcing a
conscious decision on any new tag), tags, cross-compiles, and byte-verifies the
published binaries; the console re-vendors the download channels. The umbrella's
compat matrix records what shipped together, and make versions flags pin drift.
The discipline is real and the record shows it working — and also shows its cost: at snapshot the MCP re-vendor train is mid-flight (main vendors the new contract; tag and binary publish pending), and three matrix rows lag observed reality. The release machinery is strong; the bookkeeping around it is manual and behind (Chapter 10, finding cluster B).
7.4 Observability¶
Three layers, each owned in the right place:
- Runtime logs ship to the estate log aggregator (documented and dashboarded from the sysops member, which owns the cross-estate view).
- LLM/trace observability is Arize Phoenix, deployed by the producer repo's compose (deployment authority stays with the platform; sysops documents the operator path), with OTLP collectors declared by ADR and dashboards checked into the repo.
- API-key audit is asynchronous and structural in RGAS (every authenticated request audited to a MySQL table), separate from logs.
7.5 CI and the runner estate¶
Both core repos run path-filtered CI behind a single required all-green check, with
the mutual-exclusion trick (a paths-ignore twin workflow) keeping the required check
present even on PRs that touch nothing CI-relevant. The jobs worth an assessor's
attention are the ones that load real databases: schema smoke, seed smoke,
migration-idempotency re-runs, the invariant gates, corpus replay against a live
stack, and an installer smoke that exercises the published distribution route with
a real scoped key — CI that tests the delivery mechanism, not just the code.
7.6 Operational surface discipline¶
The rule that makes the whole chapter auditable: make is the operational surface
(ADR-PL-004). Every operation — migrations, backups, seed loads, invariant runs,
bundle publishes, deploys — has a make target delegating to a category-organized,
shellcheck-gated script; raw docker exec / mysql / cypher-shell invocations are
banned from docs and runbooks. For an incoming operator this means the platform
Makefile (98 targets, make help indexed) is the operations manual, and the
runbooks under docs/runbooks/ cover the lanes that cross machines (release cut,
remote graph ops, content-author checklist).
Security and tenancy next: Chapter 8.