From 3d1b157fb10c9d98e2b1e248557409301b5a0924 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Thu, 27 Aug 2026 23:48:20 +0200 Subject: [PATCH] feature: pin the toolchain with varve, and add the drift check that would have caught meld#390 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit jess had NO varve pin. AFD-045 turned that from a backlog item into a demonstrated defect: jess filed meld#390 against meld 0.41.3 while 0.52.0 was latest, and nothing noticed. THE MEASURED DRIFT — three sources, all disagreeing, never compared: TOOL PATH VARVE-PIN CI-YML STATUS rivet 0.32.0 0.34.0 0.25.0 DRIFT <- three different versions spar - 0.40.0 0.24.0 DRIFT meld 0.41.3 0.52.0 0.41.3 DRIFT synth 0.49.0 0.58.0 - DRIFT loom 1.2.0 1.4.0 - DRIFT SHARPENS AFD-045's ACCOUNT: CI pins meld 0.41.3 TOO. So the local machine was not drifted from CI — BOTH were drifted from upstream, and CI would NOT have caught the bad report either. The problem is not a stale laptop; it is that nothing ever compared the pins to the world. WHAT LANDS: varve.toml realm=pulseengine, channel=rolling, layer=2026.08.4, WITH DIGEST varve-realms.toml fetched from the varve release, not pasted (rolling root is provisional) tools/varve/check-drift.sh compares PATH vs varve pin vs ci.yml env; exits 1 on disagreement THE DIGEST IS NOT OPTIONAL HERE: two entries for layer 2026.08.4 exist in this realm under different digests, and varve REFUSES to guess between them rather than silently picking one. That refusal is the feature. The pinned digest is the one `varve install` fetched and verified against the realm's trust root. VERIFIED THE NEWER TOOLCHAIN ACTUALLY WORKS before recommending it — "it installs" is not "it works": rivet 0.34.0 (vs CI's 0.25.0) `rivet validate` -> Result: PASS, rc=0 spar 0.40.0 (vs CI's 0.24.0) WIT-derivation gate -> OK, regenerates wit/ byte-identically A VACUOUS ROW IN MY OWN CHECKER, CAUGHT AND FIXED: sigil is installed nowhere, so the first version scored it "ok" — reporting agreement where NOTHING was compared. Now "absent (not checked)", and the footer says such rows are not evidence. Negative-controlled: a tool that IS present and agrees reports ok with rc=0, so a passing result is reachable and the checker is not stuck at DRIFT. HONEST CAVEAT — THE PIN IS NOT UNIFORMLY NEWER: the layer carries synth 0.58.0 while the campaign is on 0.60.0 (AFD-042). Adopting it wholesale would DOWNGRADE synth. That is why this commit adds the pin and the check but does NOT switch ci.yml over: reconciling CI's env pins with the layer is a separate, reviewable change, and it needs the synth gap resolved first. Co-Authored-By: Claude Opus 4.8 --- tools/varve/check-drift.sh | 57 ++++++++++++++++++++++++++++++++++++++ varve-realms.toml | 11 ++++++++ varve.toml | 21 ++++++++++++++ 3 files changed, 89 insertions(+) create mode 100755 tools/varve/check-drift.sh create mode 100644 varve-realms.toml create mode 100644 varve.toml diff --git a/tools/varve/check-drift.sh b/tools/varve/check-drift.sh new file mode 100755 index 0000000..6108845 --- /dev/null +++ b/tools/varve/check-drift.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +# Report toolchain DRIFT across the three places a jess tool version can come from, +# and fail if they disagree. +# +# WHY THIS EXISTS: on 2026-08-27 jess filed meld#390 against meld 0.41.3 while 0.52.0 +# was latest — eleven minor versions — and nothing noticed, because the three sources +# below were never compared to each other: +# +# (1) PATH what a developer (or an agent) actually runs locally +# (2) varve pin what varve.toml says this project is qualified against +# (3) ci.yml env what CI actually downloads and runs +# +# All three disagreed. A pin that nothing checks is decoration, so this is the check. +# See AFD-045. +set -uo pipefail +ROOT="$(cd "$(dirname "$0")/../.." && pwd -P)" +CI="$ROOT/.github/workflows/ci.yml" +drift=0 + +ci_pin() { # tool -> the version ci.yml downloads, or empty + local var; var="$(printf '%s' "$1" | tr '[:lower:]' '[:upper:]')_VERSION" + sed -n "s/^[[:space:]]*${var}:[[:space:]]*v\{0,1\}\([0-9][^[:space:]]*\).*/\1/p" "$CI" | head -1 +} +ver() { "$@" --version 2>/dev/null | head -1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1; } + +printf '%-8s %-12s %-12s %-12s %s\n' TOOL PATH VARVE-PIN CI-YML STATUS +for t in rivet spar meld synth loom sigil; do + p="$(ver "$t")" + v="$(varve run "$t" --version 2>/dev/null | head -1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)" + c="$(ci_pin "$t")" + # Compare only the sources that actually exist. A tool absent from a source is not + # drift — spar is legitimately not on this machine's PATH, and not every tool is + # pinned in ci.yml. Treating absence as disagreement would make this cry wolf. + seen=(); [ -n "$p" ] && seen+=("$p"); [ -n "$v" ] && seen+=("$v"); [ -n "$c" ] && seen+=("$c") + uniq_n=$(printf '%s\n' "${seen[@]:-}" | sort -u | grep -c . || true) + # A tool present in NO source is "absent", not "ok". Scoring it ok would be a vacuous + # pass — it reports agreement where nothing was compared, which is how a checker ends + # up green on a toolchain it never looked at. + if [ "${uniq_n:-0}" -eq 0 ]; then st="absent (not checked)" + elif [ "${uniq_n:-0}" -eq 1 ]; then st="ok" + else st="DRIFT"; drift=1; fi + printf '%-8s %-12s %-12s %-12s %s\n' "$t" "${p:--}" "${v:--}" "${c:--}" "$st" +done + +echo +if [ "$drift" -ne 0 ]; then + cat <<'MSG' +DRIFT: at least one tool resolves to different versions depending on where you look. +Reconcile before reporting any result upstream — a defect report cites a version, and +a wrong citation costs a supplier's attention (AFD-045, meld#390). + varve run ... runs the PINNED binary regardless of PATH + varve verify re-checks the pinned layer and reports PATH shadowing +MSG + exit 1 +fi +echo "no drift: every tool agrees across the sources that define it." +echo "(rows marked 'absent (not checked)' were compared against nothing — they are not evidence.)" diff --git a/varve-realms.toml b/varve-realms.toml new file mode 100644 index 0000000..51971f9 --- /dev/null +++ b/varve-realms.toml @@ -0,0 +1,11 @@ +# Canonical realm definitions for the PulseEngine toolchain. +# Commit this beside your varve.toml (or above it); `realm = "pulseengine"` +# in the pin then needs no environment variable — the realm supplies both +# the registry and the trust root, and the realm's root is authoritative. +# +# The rolling root is PROVISIONAL until the v1.0 ceremony (see SECURITY.md); +# the rolling channel makes no qualification promise. + +[realm.pulseengine] +registry = "oci://ghcr.io/pulseengine/varve/layers" +trust-root = "4e771dc62a08be89e3450f8cd807da58ff70af4a4e124ebf2d2b71684cfd9973" diff --git a/varve.toml b/varve.toml new file mode 100644 index 0000000..5f3683e --- /dev/null +++ b/varve.toml @@ -0,0 +1,21 @@ +# jess's toolchain pin. +# +# WHY THIS EXISTS, concretely: on 2026-08-27 jess filed an upstream defect report +# (meld#390) against meld 0.41.3 while 0.52.0 was latest — ELEVEN minor versions +# stale. Nothing detected the drift, because nothing was pinned: the local binary +# came from PATH and CI pinned its own separate versions in ci.yml. That cost a +# supplier's attention on a report whose version citation was wrong. See AFD-045. +# +# The realm supplies both the registry and the trust root, so no environment +# variable is needed; varve-realms.toml is committed beside this file. +manifest-version = 1 + +[toolchain] +realm = "pulseengine" +channel = "rolling" +layer = "2026.08.4" +# The layer NAME is not sufficient on its own: two entries for 2026.08.4 exist in this +# realm under different digests, and varve refuses to guess between them rather than +# silently picking one. That refusal is the feature. This digest is the one `varve +# install` fetched and verified against the realm's trust root on 2026-08-27. +digest = "sha256:c1e6a418f87dedfb97caca3d983cb7a17b3365492f66de920487a8470f064fe1"