From d9fc61a5473b19865adb67d6c62d3a8fc5f785e1 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Tue, 22 Sep 2026 00:11:52 +0100 Subject: [PATCH 1/2] fix(test): repoint the frontend pin-coupling test at the setup-julia step Removing the 1x1 matrix broke a second consumer of `ci.yml` that I had not looked for: `frontend/tests/unit/coupling-toolchain-pins.test.ts` matched `julia-version: ["..."]` to check the CI copy of the Julia pin against mise.toml and tool_versions.yml. With the matrix gone the match returned undefined and CI failed with `Expected: "1.12.5" / Received: undefined`. The guard was right and the fix was incomplete: two files read the Julia pin out of `ci.yml`, and only the Julia-side one was updated. `grep -rln ci.yml` finds both; the six `bench/*.jl` hits are comments. The pattern is now anchored on `julia-actions/setup-julia@` rather than on a bare `version:` key, so it cannot latch onto some other step's version and pass for the wrong reason. A missing anchor yields undefined and fails loudly rather than vacuously. Verified: bumping the literal in ci.yml fails this test (3 pass / 1 fail); frontend suite 599 pass / 0 fail; test_install_pins.jl 102 / 102. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01X3hgXxWm6umMgZkjYyHnnm --- .../tests/unit/coupling-toolchain-pins.test.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/frontend/tests/unit/coupling-toolchain-pins.test.ts b/frontend/tests/unit/coupling-toolchain-pins.test.ts index e8996ea..29aa096 100644 --- a/frontend/tests/unit/coupling-toolchain-pins.test.ts +++ b/frontend/tests/unit/coupling-toolchain-pins.test.ts @@ -10,7 +10,11 @@ // consumed by CI via bun-version-file // config/defaults/tool_versions.yml — upstream pipeline-pin SOT holding // overlapping julia/bun copies -// .github/workflows/ci.yml — hardcoded julia matrix entry +// .github/workflows/ci.yml — hardcoded julia version on the setup-julia +// step. It was a 1x1 `strategy.matrix` until 2026-09-21; +// the matrix was removed because GitHub appends the +// matrix combination to the posted check name, which +// renamed the required status check on every bump. // A bump in any one copy without the others is silent CI/local divergence; // this test makes it a build-time failure instead. import { describe, test, expect } from 'bun:test' @@ -40,10 +44,14 @@ describe('coupling/drift: toolchain pins agree across all copies', () => { expect(toolVersionsPin('bun')).toBe(pin) }) - test('julia: mise.toml == tool_versions.yml == CI matrix', () => { + test('julia: mise.toml == tool_versions.yml == CI setup-julia step', () => { const pin = misePin('julia') expect(toolVersionsPin('julia')).toBe(pin) - const ci = read('.github/workflows/ci.yml').match(/julia-version:\s*\["([^"]+)"\]/) + // Anchored on the action rather than on a bare `version:` key, so this + // cannot silently latch onto some other step's version and pass for the + // wrong reason. A missing anchor yields undefined, which fails loudly. + const ci = read('.github/workflows/ci.yml') + .match(/julia-actions\/setup-julia@[0-9a-f]{40}[\s\S]*?version:\s*"([^"]+)"/) expect(ci?.[1]).toBe(pin) }) From 0af84a5e718fd76d85bdd3f49a41f8ce77817f93 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Tue, 22 Sep 2026 00:19:59 +0100 Subject: [PATCH 2/2] docs: repoint the pin-web docs at the setup-julia step The third and last class of `ci.yml` reader. Removing the 1x1 matrix in #40 fixed the workflow and #41 fixed the TypeScript coupling test, but five live documents still describe the julia pin as living in "the CI matrix", which no longer exists. A pin table that names a source of truth that is not there is worse than no table: the next person to bump julia goes looking for a matrix, does not find one, and has no way to tell whether the doc or the workflow is wrong. docs/reproducibility.md:26,60 the pin table and the pin web docs/compliance/standards-alignment.md:40 the single-sourcing claim docs/audit/type-system-reconnaissance.md:210 what test_install_pins.jl gates README.md:546 the CI gate summary Left alone deliberately: the nine occurrences under `docs/milestones/` and `docs/milestones/02c-cicd.md`. Those are dated records of what the workflow was at that milestone, and rewriting history to match today's shape would destroy the only evidence that the matrix ever existed -- which is exactly the evidence issue #38 turned on. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01X3hgXxWm6umMgZkjYyHnnm --- README.md | 2 +- docs/audit/type-system-reconnaissance.md | 2 +- docs/compliance/standards-alignment.md | 2 +- docs/reproducibility.md | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 544f68e..f76644d 100644 --- a/README.md +++ b/README.md @@ -543,7 +543,7 @@ clean checkout (`frontend/`): | Lint (tsc semantics + shell) | `scripts/check-lint.sh` | gated | CI runs the same gates (see `.github/workflows/ci.yml`: repo-hygiene job, -then the pinned Julia/frontend matrix). Contributor setup, commit and +then the pinned Julia and frontend jobs). Contributor setup, commit and branch conventions: `CONTRIBUTING.md`. Frontend reproducibility: `docs/reproducibility.md`. Type estate map: `docs/types/architecture.md`. Test inventory and metrics: `docs/testing/coverage.md`. diff --git a/docs/audit/type-system-reconnaissance.md b/docs/audit/type-system-reconnaissance.md index fb40a59..4e7112e 100644 --- a/docs/audit/type-system-reconnaissance.md +++ b/docs/audit/type-system-reconnaissance.md @@ -207,7 +207,7 @@ Observations on settings (facts, with contrast against actual code): (`apt_version: 4.5.0-3.2404.0`), Bioconductor 3.22, cutadapt 5.2, MultiQC 1.33, FastQC 0.12.1, vsearch/swarm/cd-hit with SHA-256-verified archives. `test/unit/test_install_pins.jl` exists to fail CI if the pin - file, `Manifest.toml`, and the CI matrix disagree. + file, `Manifest.toml`, and the `ci.yml` setup-julia step disagree. --- diff --git a/docs/compliance/standards-alignment.md b/docs/compliance/standards-alignment.md index ecbb3d0..447699f 100644 --- a/docs/compliance/standards-alignment.md +++ b/docs/compliance/standards-alignment.md @@ -37,7 +37,7 @@ Reference: `hyperpolymath/standards@main` (in particular | `mise.toml` toolchain manifest, pinned to CI versions, every name verified against the registry (estate doctrine from rsr-template) | `mise.toml` — julia 1.12.5 / bun 1.3.10 / node 20.20.2 / just 1.43.1, all confirmed resolvable 2026-09-18; R absent from registry → documented system exception | ✅ | | Guix development environment (`guix.scm`, per estate REQUIRED-FILES) | `guix.scm` (dev-shell inputs: julia, r, node-lts, just, git + pipeline-tool equivalents cutadapt/multiqc/fastqc/vsearch/cd-hit; swarm documented as download-lane-only) + `channels.scm` time-machine pin (guix master 2026-09-18; `just` input sighted live at the pinned commit) | ✅ recreation on hosts/CI | | Pipeline tools byte-exact | `config/defaults/tool_versions.yml` (version + URL + sha256-of-archive per tool) fetched by `install.sh`; preflight asserts against it | ✅ upstream-designed, fork-verified | -| Pin single-sourcing (codegen, minimal duplication) | `.bun-version` is generated from `mise.toml` by `just sync-pins`; overlap copies (`tool_versions.yml`, `ci.yml` matrix) are drift-checked, not generated | ✅ `coupling-toolchain-pins` test gates it | +| Pin single-sourcing (codegen, minimal duplication) | `.bun-version` is generated from `mise.toml` by `just sync-pins`; overlap copies (`tool_versions.yml`, the `ci.yml` setup-julia step) are drift-checked, not generated | ✅ `coupling-toolchain-pins` test gates it | | direnv auto-activation (`.envrc`) | `.envrc` — mise lane first, Guix fallback, `METAMANIFOLD_REPO_DIR` export | ✅ | | Single command to stand up a bare machine | `curl https://mise.run \| sh && just bootstrap` (or the time-machine one-liner) → `just ci` green from a naked env (evidence logged in `docs/reproducibility.md`) | ✅ verified 2026-09-18 | diff --git a/docs/reproducibility.md b/docs/reproducibility.md index be68fb1..fee9c74 100644 --- a/docs/reproducibility.md +++ b/docs/reproducibility.md @@ -23,7 +23,7 @@ either lane automatically via direnv. | Component | Pin | Pinned where | Verified | |---|---|---|---| -| Julia | **1.12.5** (exact) | `mise.toml` + CI matrix | `mise install` → `julia version 1.12.5` | +| Julia | **1.12.5** (exact) | `mise.toml` + the `ci.yml` setup-julia step | `mise install` → `julia version 1.12.5` | | Bun | **1.3.10** (exact) | `.bun-version` (CI reads the same file) + `mise.toml` | `mise x -- bun --version` → `1.3.10` | | Node | **20.20.2** (LTS) | `mise.toml` | `mise x -- node --version` → `v20.20.2` | | just | **1.43.1** | `mise.toml` | `mise x -- just --version` → `just 1.43.1` | @@ -57,7 +57,7 @@ The guix inputs' versions follow the channels pin, **not** | Value | Source of truth | Generated copies | Checked copies | |---|---|---|---| | bun version | `mise.toml` | `.bun-version` — generated by **`just sync-pins`** (codegen; CI consumes it via `bun-version-file`) | `tool_versions.yml` (fork-owned overlap) | -| julia version | `mise.toml` | — | `tool_versions.yml`, `ci.yml` matrix | +| julia version | `mise.toml` | — | `tool_versions.yml`, the `ci.yml` setup-julia step | | node / just versions | `mise.toml` | — | — (single-sourced by design) | | tool set versions | `tool_versions.yml` (upstream-declared SOT, checksum-bearing) | — | — |