Skip to Content
Design DecisionsRelease Records, Not Bytes

Release records reference artifacts, never bytes

Status: Accepted · Date: not dated as a single decision in the memory record (the registry evolved with the release tooling; the Vercel target was retired 2026-07-02) · Area: Releases

Context

The platform builds several components from one repo (aurora-webapp, orbit-webapp, maxq-orbit-agent, maxq-orbit-agent-webapp, and the registry services), and needs an authoritative answer to “what exactly is release X of component Y?” The naive options both have problems: committing build output bloats history and duplicates what the container registry already retains, and a single platform-wide version number forces lockstep upgrades on components that ship at different cadences.

Decision

  • releases/ is a per-repo registry of release records. Each record is a small releases/<component>/v<semver>/release.yaml validated by releases/release.schema.json, pinning the immutable source (scoped git tag <component>/v<semver> + commit) and a reference to the built output — a container artifact (registry/repository/tag/digest in ACR). Never build bytes: git tags are immutable source snapshots and ACR retains every pushed image, so the record points at them instead of duplicating either.
  • Components version independently. The scoped tag form lets multiple components in one repo tag on their own cadence; there is no all build target (a future one should read a platform-version manifest such as releases/platform/v<X>.yaml).
  • Record + drive: the YAML files are the authoritative record, and infrastructure/azure/build-images.sh is the worker that builds from the tag and writes/reconciles the record as part of the build — the record is a build side effect, not a manually maintained log.
  • House conventions: no $schema key inside the data file (validation is external), and released_at is a quoted "YYYY-MM-DD" string — unquoted, PyYAML parses a bare date as datetime.date and schema validation fails.

Consequences

  • Any release can be reproduced or audited from its record: the tag gives the exact source, the digest gives the exact image; nothing in git history grows with build output.
  • The registry survives platform shifts as history: Vercel-era aurora-webapp records keep target: vercel and pre-consolidation records keep source.repo: aurora — the schema retains both values so old records stay valid, left as written.
  • Releasing is a fixed workflow: commit → git tag <component>/v<version>build-images.sh → bump images.*_tag in the Azure config → redeploy. Skipping the tag step is impossible by construction, since builds only read tags (ADR-002).
  • Accepted trade-off: no one-command whole-platform release exists; each component is cut on its own. The Aurora webapp may later render the registry as a portfolio view.

Evidence

  • releases/release.schema.json and releases/<component>/v<semver>/release.yaml records
  • infrastructure/azure/build-images.sh — the builder and record writer
  • memory/release-registry.md (the “Key decisions” section), memory/orbit-auto-deploy.md (the container target and tag-build workflow)