Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down
2 changes: 1 addition & 1 deletion docs/audit/type-system-reconnaissance.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

---

Expand Down
2 changes: 1 addition & 1 deletion docs/compliance/standards-alignment.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |

Expand Down
4 changes: 2 additions & 2 deletions docs/reproducibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -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` |
Expand Down Expand Up @@ -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) | — | — |

Expand Down
14 changes: 11 additions & 3 deletions frontend/tests/unit/coupling-toolchain-pins.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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)
})

Expand Down
Loading