From f899b3c01befc6662d9fb6bd7a6bb0e7b05dd034 Mon Sep 17 00:00:00 2001 From: Amirhossein Khalili Date: Thu, 20 Aug 2026 18:11:24 +0330 Subject: [PATCH] docs: record platform release decisions --- ...002-immutable-cross-repository-releases.md | 49 +++++++++++++++++++ ...003-consume-licensed-font-from-frontend.md | 47 ++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 docs/decisions/0002-immutable-cross-repository-releases.md create mode 100644 docs/decisions/0003-consume-licensed-font-from-frontend.md diff --git a/docs/decisions/0002-immutable-cross-repository-releases.md b/docs/decisions/0002-immutable-cross-repository-releases.md new file mode 100644 index 0000000..3ee41b8 --- /dev/null +++ b/docs/decisions/0002-immutable-cross-repository-releases.md @@ -0,0 +1,49 @@ +# ADR 0002: Immutable cross-repository releases + +- Status: Proposed +- Date: 2026-08-20 + +## Context + +The deployment repository composes independently owned backend and frontend repositories. A production release must identify one compatible revision of each repository, survive unavailable source forges, and roll back without rebuilding. The Qlockify reference updates nested server checkouts to mutable branches and builds in place. That is useful for a small deployment but makes the deployed inputs dependent on branch movement, server toolchains, and build timing. + +Service repositories also need focused CI without gaining independent authority to mutate the shared production server. Backend, frontend, and deployment changes can arrive close together, so direct per-repository SSH deploys would race and could assemble an unreviewed combination. + +## Decision + +Build each application image once in its owning repository after protected-revision quality gates, publish it to a private OCI registry, and address it in production by immutable digest. + +An authenticated backend or frontend event creates a deployment candidate containing its source SHA, image digest, interface/migration compatibility metadata, and provenance references. The event never directly deploys production. The deployment repository is the only release coordinator and serializes production changes under one deployment lock. + +Every approved release has a manifest containing the deployment, backend, and frontend SHAs; all image digests; expected migration version; non-secret configuration checksum; provenance/SBOM references; previous release; approval; and health outcome. Production pulls and runs only the digests in that manifest. Server-side source builds, `git reset --hard` synchronization, branch-name deployment, and floating image tags are not permitted. + +Migrations run as a one-off candidate-backend command before API/worker replacement. They use an expand/contract compatibility policy. Application rollback selects the previous manifest and never automatically runs a database down migration. + +## Alternatives considered + +### Qlockify-style server checkout and in-place build + +- Pros: simple; already proven on the reference server; no registry required. +- Cons: mutable inputs, larger server trust/toolchain surface, slow rollback, weak build provenance, and race risk across three repositories. +- Rejected for production: it cannot prove that a rebuilt server artifact is identical to the CI-tested artifact. + +### Let each service repository deploy its own services + +- Pros: fast and locally owned. +- Cons: backend/frontend/deployment workflows can race; no atomic compatibility manifest; migrations and Nginx/config changes cannot be coordinated safely. +- Rejected: the deployment repository is the approved operational control plane. + +### Git submodules + +- Pros: a deployment commit can pin service SHAs. +- Cons: conflicts with ADR 0001 and the approved ignored-checkout topology; still does not guarantee build-once artifacts. +- Rejected: release manifests provide provenance without merging repository mechanics. + +## Consequences + +- A private registry and trusted CI runner are release dependencies. +- Service CI owns testing/building its artifact; deployment CI owns compatibility, production approval, migration orchestration, health gates, and rollback. +- The server can roll back application images even if the source forge is temporarily unavailable, provided required digests remain in the registry/cache. +- Production rollout events must coalesce/serialize instead of racing. +- Registry retention must protect every digest referenced by the active and rollback manifests. +- Exact Gitea cross-repository event support and runner version remain implementation decisions in the Platform Operations spec. diff --git a/docs/decisions/0003-consume-licensed-font-from-frontend.md b/docs/decisions/0003-consume-licensed-font-from-frontend.md new file mode 100644 index 0000000..db68a20 --- /dev/null +++ b/docs/decisions/0003-consume-licensed-font-from-frontend.md @@ -0,0 +1,47 @@ +# ADR 0003: Consume licensed font from the frontend repository + +- Status: Accepted +- Date: 2026-08-20 + +## Context + +The frontend requires the licensed Iran Yekan X Professional Persian-number variable webfont. The approved ownership decision is implemented by frontend commit `64f5ac2`, which tracks these required files in its ordinary source tree: + +- `static/fonts/IRANYekanXVFaNumVF.woff2` +- `static/fonts/FontLicense.txt` + +The deployment repository must not duplicate application assets or introduce a second delivery path. + +## Decision + +Treat both files as ordinary frontend-owned build inputs. Frontend CI builds them through the normal frontend context and the immutable frontend image contains the emitted font resource. Deployment consumes only that normal frontend image/build context. + +Platform Operations does not create a separate asset-injection path, copy either file into deployment Git, or maintain font-specific credentials. Release provenance is the frontend Git SHA and immutable frontend image digest. + +Frontend CI and deployment smoke checks must fail if the required source inputs are absent, the built resource is absent, or the resource is not served with the expected font MIME type. The deployment repository records no second binary or license copy. + +## Alternatives considered + +### Separate CI asset injection + +- Rejected: it conflicts with the approved direct-tracking decision and creates a second source of build inputs. + +### Copy assets into the deployment repository + +- Pros: centralizes production build inputs. +- Cons: duplicates proprietary files, violates repository ownership, and can diverge from frontend source. +- Rejected: frontend owns static application assets. + +### Runtime host mount + +- Pros: keeps the binary outside the image. +- Cons: runtime drift, missing-asset failure after a deploy, harder rollback/provenance, and special server bootstrap. +- Rejected: the normal immutable frontend artifact must be self-contained. + +## Consequences + +- Frontend commit `64f5ac2` is the first approved provenance point for the tracked assets. +- Frontend repository policy and license compliance govern changes to the files. +- Deployment rollback automatically rolls font output back with the selected frontend image digest. +- No separate font injection workflow, font-specific deployment secret, or deployment-repository font copy is allowed. +- Platform smoke tests verify the emitted resource without reading or reproducing the license text.