Appearance
Releases
The single source of truth for release management. Every production change — schema, migrations, policies, functions, config, storage, scheduled jobs, secrets, app builds, store submissions — is planned, documented, reviewed, approved and tracked here before it is deployed.
| Page | What it is for |
|---|---|
| HLD | Architecture, governance, roles, gates, integrations |
| LLD | Data model, state machine, automation, audit, notifications |
| Process | How to actually run a release, day to day |
| Production state | What is live on each surface right now |
Release register
| Version | Type | Status | Target | Frozen | Deployed | Closed |
|---|---|---|---|---|---|---|
| 26.0.1 | train_monthly | 🔵 draft | 2026-08-15 | 2026-08-11 | — | — |
Status legend: 🔵 pre-approval · 🟡 in flight / partially deployed · 🟢 closed · 🔴 rolled back
Metrics
Derived from the release records themselves, so there is nothing separate to keep up to date. Populated at G5; a release in flight contributes nothing yet.
| Metric | Value | Notes |
|---|---|---|
| Deployment frequency | — | releases reaching deployed per month |
| Lead time | — | G0 → deployed |
| Change failure rate | — | rolled_back ÷ deployed |
| MTTR | — | rollback trigger → resolved |
| Scope stability | — | items at G1 ÷ items at G0 |
| Gate waiver rate | — | waived gates ÷ total gates |
| Store approval latency | — | submitted → live, per platform |
| Resubmissions | — | per release, per platform |
| Open surface divergences | 0 | and their age |
These are objective. They sit alongside the delivery log's self-reported narrative under that page's own rule: where the two disagree, the numbers win.
Rules that are not negotiable
- No production change without a Change Record.
deploy-prodrefuses to apply a migration or Edge Function that is not declared in the active release'srelease.json. release.jsonis the machine source of truth. Markdown carries narrative keyed by id, andnpm run check:releaseasserts the two agree in both directions.- Approvals bind to a commit SHA and a manifest hash. Change the manifest and the approval is void.
- A release is not atomic. Per-surface
targets[];deployedis derived, never asserted. - All three surfaces ship in sync — Android native, iOS native, Web PWA. There is no exception path.
- Irreversible changes carry a forward fix, not a fictional rollback plan.
Starting a release
bash
cp -r documentation/portal/releases/_template documentation/portal/releases/<version>
# fill release.json: version, type, cadence, base_ref
npm run check:release_template/ is the canonical skeleton — copy it, never improvise a folder. The leading underscore marks it as a non-content directory (same convention as backend/edge-functions/_template.md), and the gate skips it.