From 95baaaf90b5c302bcfad500047a296f77968881b Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Thu, 14 May 2026 21:29:04 +0100 Subject: [PATCH] =?UTF-8?q?docs(adr):=200009-build-path=20=E2=80=94=20carg?= =?UTF-8?q?o=20+=20Containerfile=20canonical;=20rest=20experimental?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #61. Four parallel build-environment definitions (`flake.nix`, `.guix-channel` / `guix.scm`, `Containerfile`, `.devcontainer/`) plus the implicit `cargo build` lived side-by-side. None was documented as canonical, so new contributors had to guess. ADR-0009 picks **two canonical paths**: - **`cargo build` for development.** Direct Rust toolchain, fastest iteration, MSRV-pinned via V-L3-K1 (#57). - **`Containerfile` for ops.** OCI image suitable for deployment, CI, reproducible release builds. Complementary to the V-L3-L1 (#58) release workflow that produces native binaries. Everything else (`flake.nix`, `guix.scm`, `.guix-channel`, `.devcontainer/`) is **experimental**: kept in the tree, not maintained, not CI-tested. Re-promotable via a future ADR if a maintainer emerges. Alternatives considered: - Pick exactly one path: rejected; dev vs ops have legitimately different cost-benefit profiles. - Delete the experimental files: rejected; no CI cost to keeping them, someone put work in. Follow-up: small README "Install" rewrite (separate PR). Co-Authored-By: Claude Opus 4.7 --- docs/decisions/0009-build-path.adoc | 119 ++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 docs/decisions/0009-build-path.adoc diff --git a/docs/decisions/0009-build-path.adoc b/docs/decisions/0009-build-path.adoc new file mode 100644 index 0000000..fdd42e5 --- /dev/null +++ b/docs/decisions/0009-build-path.adoc @@ -0,0 +1,119 @@ += Architecture Decision Record: 0009-build-path + + + +# 9. Canonical build paths: cargo for dev, Containerfile for ops + +Date: 2026-05-14 + +## Status + +Accepted + +## Context + +The repo carries four parallel build-environment definitions: + +* `flake.nix` + `.guix-channel` / `guix.scm` — reproducible + builds via Nix and Guix. +* `Containerfile` — OCI image build, used by ops. +* `.devcontainer/` — VS Code Dev Container definition. +* The implicit fifth path is **just cargo** — every Rust contributor + runs `cargo build` locally without invoking any of the above. + +Nothing is documented as canonical. Each path drifts at its own +cadence; nothing keeps them in sync. New contributors don't know +which one is the "right" way to build. + +## Decision + +Two paths are canonical, the rest are experimental: + +* **`cargo build` is canonical for development.** Direct Rust + toolchain. Fastest iteration loop. The MSRV is pinned + (`rust-version = "1.85"` per V-L3-K1) so a contributor with + `rustup` and the right toolchain is fully set up. The + Justfile wraps this. + +* **`Containerfile` is canonical for ops.** Produces a single + OCI image suitable for deployment, CI, and reproducible + release builds. The release workflow (V-L3-L1, #58 / PR #80) + builds binaries for four targets natively, but + `Containerfile` is the supported way to *run* verisimiser in + production. + +`flake.nix`, `guix.scm`, `.guix-channel`, and `.devcontainer/` +are **experimental**: + +* They remain in the tree because they were contributed by + someone who needed them. +* They are not maintained by the core team. CI does not exercise + them. If they drift, the next user fixes them. +* The README's "Install" section names cargo + Containerfile; + the experimental paths are listed in a "Other build + environments" subsection with the same caveat. + +### Alternative considered + +Pick exactly one canonical path. Rejected because dev and ops +have legitimately different cost/benefit: + +* For dev: cargo is universally faster than every container + alternative. Forcing developers through a Containerfile + build every time wastes hours per week. +* For ops: a pinned OCI image with reproducible layers is more + valuable than instructing operators to install rustup. + +### Alternative considered (also rejected) + +Delete the experimental paths. Rejected because there's no harm +in keeping them around — they take no CI time (CI doesn't invoke +them), and someone has put work into them. Marking them +experimental is the polite middle. + +## Consequences + +### Positive + +* README's "Install" section now has a single primary answer: + use cargo for dev, the Containerfile for ops. +* Contributors don't lose hours picking between four equally + unmaintained paths. +* The CI matrix (`rust-ci.yml` with `1.85` + `stable`) tests + the canonical dev path. The release workflow tests the + canonical ops path. No CI cycles spent on experimental + paths. +* Drift in `flake.nix` etc. is no longer a blocker — the + experimental tag says "this might be broken; PR welcome". + +### Negative + +* Nix and Guix users get a worse experience. They were + presumably attracted by the presence of those files. If they + want to keep those paths first-class, they'll need to + volunteer maintenance. +* `.devcontainer/` users (VS Code remote-container workflows) + are also demoted. + +### Neutral + +* No file is removed. The experimental files stay in the tree + and can be re-promoted in a future ADR if a maintainer + emerges. +* The Justfile already wraps cargo, so the dev experience is + unchanged for anyone using `just`. + +## Follow-ups (separate work) + +* README "Install" section rewrite — small follow-up PR, not + part of this ADR. + +## Cross-references + +* ADR-0001 — RSR template adoption. +* V-L3-K1 (#57) / Cargo.toml `rust-version = "1.85"` — pins the + cargo dev path. +* V-L3-L1 (#58) — release workflow that builds native binaries + for four targets. +* `Containerfile`, `flake.nix`, `guix.scm`, `.devcontainer/` — + the files this ADR classifies.