ADR 0081 — New-surface deploy/preview convention as Raxx standard
Status: Accepted Date: 2026-05-12 UTC Author: sre-agent Parent card: #649 Supersedes: nothing (consolidates ADR-0052, ADR-0053 into a single normative statement) Related ADRs: 0052, 0053
Context
ADR-0052 and ADR-0053 established the hosting-tier decision tree and the
required deploy workflow step sequence. Neither ADR stated explicitly that the
combination of conventions documented in docs/architecture/new-surface-convention.md
is the Raxx platform standard, nor did either call out the scaffold tooling as
the normative first step for a new surface.
As Raxx acquires more surfaces — Antlers, getraxx.com, support.raxx.app, raxx-mockups, console.raxx.app, docs.raxx.app — the risk of ad-hoc bootstrapping compounds. Each surface added without the scaffold accumulates operational debt: missing status tiles, no audit row on deploy, no CF Access gate, undocumented vault paths. This ADR codifies the scaffold-first requirement as a platform invariant and records the six existing surfaces as parity baseline.
Decision
1. The scaffold is the required starting point
scripts/scaffold/new-surface.sh is the authoritative starting point for any
new Raxx surface. A surface is not permitted to reach its first production deploy
without having run the scaffold (or having manually satisfied all of its output
requirements, with a PR comment explaining why the scaffold was bypassed).
The scaffold produces, at minimum:
- A deploy workflow stub (.github/workflows/deploy-<surface>.yml)
- A terraform stub for the CF Pages project (terraform/cf-pages-<surface>/main.tf)
or a note for Tier B/C surfaces explaining the absence
- A branch-protection note (docs/surfaces/<surface>/branch-protection.md)
- A surface README (docs/surfaces/<surface>/README.md)
2. The convention document is the normative reference
docs/architecture/new-surface-convention.md and the runbook at
docs/runbooks/new-surface-convention.md are the normative references for
all new surfaces going forward. ADR-0052 and ADR-0053 remain valid for
their specific decisions but are superseded by this ADR for questions of
scope and completeness.
3. All six existing surfaces are the parity baseline
The following surfaces are the baseline for convention compliance. Future surfaces must be at parity with the most-complete surface in their tier:
| Surface | Domain | Tier | Workflow | Status tile | ADR parity |
|---|---|---|---|---|---|
| Antlers | app.raxx.app | A (CF Pages) | deploy-antlers.yml | raxx-app | Partial (predates 0052) |
| getraxx | getraxx.com | A (CF Pages) | deploy-getraxx.yml | getraxx-com | Full |
| raxx-mockups | raxx-mockups.pages.dev | A (CF Pages) | deploy-mockups.yml | raxx-mockups | Full |
| console | console.raxx.app | B (Heroku) | deploy-console.yml | console-raxx-app | Full |
| support | tickets.raxx.app | C (Lightsail) | none (TF-only) | tickets-raxx-app | Tier C exemption |
| docs | docs.raxx.app | A (CF Pages) | deploy-customer-docs.yml | docs-raxx-app | Full |
Tier C surfaces (Lightsail) are exempt from the CI deploy step requirement per ADR-0052. They must still have a status tile and documented vault paths.
4. The six invariants from the convention document are binding
These six invariants apply to every new surface, no exceptions:
- No credentials in workflow YAML files.
- Audit row on every deploy (success and failure).
- Deploy-freeze gate before any environment is touched.
- Status tile registered before first production deploy.
- Internal surfaces behind CF Access — not "internal by convention."
- Slack DM to
D0AJ7K184TVon prod deploy health-check failure.
Consequences
- The scaffold is a required step, not an optional helper. Pull requests that introduce a new surface without scaffold output require a written bypass justification in the PR description.
- The branch-protection note (
docs/surfaces/<surface>/branch-protection.md) created by the scaffold must be reviewed by the operator before the first merge. It documents the expected branch protection rules for that surface's source directory. - The terraform stub created by the scaffold is a placeholder, not production Terraform. The actual TF stack is authored in a follow-on PR scoped to the surface. The stub prevents the surface from being bootstrapped without infrastructure intent documented.
- Existing surfaces (the six above) are not required to re-run the scaffold. Where they diverge from the template, the divergence is accepted as pre-convention technical debt, tracked per surface in the parity table above.
Alternatives Considered
Reusable workflow (workflow_call) as the enforcement mechanism:
A reusable workflow would mechanically enforce the step order. Rejected because
the build step is too surface-specific to parametrize cleanly today (see
ADR-0053). The scaffold template is the practical equivalent for now.
A pre-push lint that rejects workflows missing required steps: A CI job that parses workflow YAML and checks for freeze-check, audit emit, and health-check steps would detect drift. Deferred — the YAML AST approach is brittle; the composite-action approach (ADR-0053's deferred alternative) is cleaner and gates this ADR's successor.
Not documenting the parity table: Without an explicit parity baseline, "existing surfaces are exempt" is an unbounded escape hatch. The parity table bounds the exemption: existing surfaces are exempt from re-scaffolding, not from future operational requirements.