From a78419b27226f3a434472abc0dee56c43b8cedd3 Mon Sep 17 00:00:00 2001 From: Alec Wenzowski Date: Sat, 26 Sep 2026 02:40:10 +0000 Subject: [PATCH] fix(land): a speculative lap is judged against the base it borrowed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `verify:gated` arms two gates with a base ref, and both named `origin/main` unconditionally on a premise the body states in its own comment: `verify` has already refused this branch unless it is rebased on current `origin/main`, so the task is a function of (commit, current trunk). That premise is false on a speculative lap. `land` replays the branch onto the lease holder's UNLANDED commits — "the main that is about to exist" — so the tree is a function of (commit, the holder's base), and judging it against trunk charges the holder's diff to the BORROWER. It refuses rather than merely misreporting, which is what made it expensive. `lint::groom` keys the claim receipt on the branch name, and a borrower carries one of its own, minted for its own row and naming no weakening: `Groom::Read({})` is "the groom looked and admitted nothing", a refusal by design (CLOUD-841, evidence of absence rather than absence of evidence). The holder's `Weakens:` trailer cannot admit it, because the borrower's groom already answered. MEASURED 2026-09-25/26, five laps over four different borrowed tips (`5fa3732a`, `2e6b457e`, `c3315ac6`, `3617f103`), every one refusing `recorder[board-issue-created] recorder-changed` and its sibling — while `mise run test:cargo` over the identical integrated commit was 6057/6057 green. Directly: `BATTEN_CONFIG_FROM=origin/main` gives 2 smells on that tree and `BATTEN_CONFIG_FROM=3617f103`, the borrowed base, gives 0. `commit-lint` had the same hole and its instance is already in this repository's cost record: CLOUD-1775's body tabulates a lap lost to "28 commits claim no CLOUD- issue". Those 28 were the holder's. `BATTEN_SPEC_BASE` is what `land` already publishes for exactly this question (`speculation::PUBLISHED_AS`, CLOUD-748), with `land.rs`'s own `a_body_gate_is_told_which_base_the_lap_borrowed` asserting it arrives. Reading it here is the bound CLOUD-1711 put on `race::authored_log`, applied to the two gates that still lacked it. NOTHING ESCAPES JUDGEMENT, which is what makes this a fix rather than a relaxation: every commit is still judged once, on its own branch, against the base it actually sits on. The holder's weakenings are adjudicated on the holder's own lap, against trunk, under the holder's groom. The pair of cases is the pair for a reason. Without the mirror, "read `BATTEN_SPEC_BASE`" is satisfied by dropping the base entirely — the dead-gate class — and a bare `$BATTEN_SPEC_BASE` would arm `config lint` with an empty ref off a bet and judge nothing at all, which is the silence house style §8 arms this gate against. Both were shown to fail: restoring either literal reddens both. Refs: CLOUD-1702 --- .../batten/tests/it/verify_unprovisioned.rs | 78 +++++++++++++++++++ mise.toml | 45 +++++++++-- 2 files changed, 117 insertions(+), 6 deletions(-) diff --git a/crates/batten/tests/it/verify_unprovisioned.rs b/crates/batten/tests/it/verify_unprovisioned.rs index 7d98c2ec6..366ddfc5d 100644 --- a/crates/batten/tests/it/verify_unprovisioned.rs +++ b/crates/batten/tests/it/verify_unprovisioned.rs @@ -318,6 +318,84 @@ fn the_extracted_verify_body_is_the_task_and_not_the_whole_file() { ); } +/// CLOUD-1702. THE BASE A SPECULATIVE LAP IS JUDGED AGAINST. +/// +/// `verify:gated` arms two gates with a base ref, and both used to name +/// `origin/main` unconditionally on a premise the body itself states: that +/// `verify` has already refused any branch not rebased on current trunk, so the +/// task is a function of (commit, current trunk). A speculative lap breaks that +/// premise — `land` replays the branch onto the lease holder's UNLANDED commits — +/// and judging that tree against trunk charges the holder's weakenings and the +/// holder's commits to the BORROWER. +/// +/// It refuses rather than merely misreports, because `lint::groom` keys the claim +/// receipt on the branch name: the borrower carries one of its own, minted for +/// its own row and naming no weakening, which is `Groom::Read({})` — a refusal by +/// design (CLOUD-841). The holder's `Weakens:` trailer cannot admit it. +/// +/// Both halves are asserted, because arming only one leaves the other charging +/// the same borrowed commits: `commit-lint`'s instance is already in this +/// repository's cost record as CLOUD-1775's lost lap, *28 commits claim no +/// CLOUD-N issue*. +/// +/// Fails by: restoring either literal, which is the state five laps over four +/// borrowed tips were measured in on 2026-09-25/26. +#[test] +fn both_base_armed_gates_read_the_base_the_lap_actually_borrowed() { + let body = task_body("verify:gated"); + assert!( + body.contains("mise run config-lint"), + "the extraction found the gate set, not a neighbouring table" + ); + for (armed, gate) in [ + ("CONFIG_LINT_BASE", "mise run config-lint"), + ("BASE_SHA", "mise run commit-lint"), + ] { + let line = arming(&body, armed, gate); + assert!( + line.contains("BATTEN_SPEC_BASE"), + "{armed} must read the base the lap borrowed, or a speculative lap \ + charges the holder's diff to this branch: {line}" + ); + } +} + +/// The line that ARMS `gate` with `armed`, never the prose that discusses it. +/// +/// Both halves of the pair are required, for the reason [`task_body`]'s own +/// comment records one layer up: this body explains each arming in a comment +/// above it, so a bare `find` for the variable name returns *"absent +/// `CONFIG_LINT_BASE` the task runs exactly ..."* — a sentence that will never +/// contain the expansion, so every assertion over it fails for the wrong reason. +/// Requiring the invocation on the same line is what picks the executable one. +fn arming<'a>(body: &'a str, armed: &str, gate: &str) -> &'a str { + body.lines() + .find(|line| line.contains(armed) && line.contains(gate)) + .unwrap_or_else(|| panic!("{armed} arms {gate} in this body")) +} + +/// CLOUD-1702's MIRROR, and without it the case above is satisfied by dropping +/// the base entirely — which is the dead-gate class, not a fix. +/// +/// An unspeculated lap and CI both leave `BATTEN_SPEC_BASE` unset, so the +/// expansion has to fall back to trunk. A bare `$BATTEN_SPEC_BASE` would arm +/// `config lint` with an empty ref there and judge nothing at all, which is +/// exactly the silence house style §8 arms this gate against. +#[test] +fn an_unspeculated_lap_still_falls_back_to_trunk() { + let body = task_body("verify:gated"); + for (armed, gate) in [ + ("CONFIG_LINT_BASE", "mise run config-lint"), + ("BASE_SHA", "mise run commit-lint"), + ] { + let line = arming(&body, armed, gate); + assert!( + line.contains("${BATTEN_SPEC_BASE:-origin/main}"), + "the fallback is the whole reason this is a no-op off a bet: {line}" + ); + } +} + /// CLOUD-1683. The load-bearing ordering. An unprovisioned tree has to stop /// BEFORE the receipt question, because that question is asked through a compile /// entry point: on a tree with no toolchain it fails for the wrong reason and is diff --git a/mise.toml b/mise.toml index ca57ab1c6..bd4ef36e0 100644 --- a/mise.toml +++ b/mise.toml @@ -4411,7 +4411,12 @@ if ! mise run test:bats; then echo "::error:: verify: the shell suite failed. No receipt written." >&2 exit 1 fi -if ! BASE_SHA="$(git rev-parse origin/main)" HEAD_SHA="$(git rev-parse HEAD)" mise run commit-lint; then +# THE SAME BOUND, AND THIS HALF IS ALREADY IN THE COST RECORD (CLOUD-1702). +# CLOUD-1775's body tabulates a lap lost to `commit-lint` reporting "28 commits +# claim no CLOUD- issue" — those 28 were the lease holder's, charged here +# because `BASE_SHA` named trunk while the tree sat on the holder's base. See the +# `config-lint` paragraph below for why the borrowed base is the honest one. +if ! BASE_SHA="$(git rev-parse "${BATTEN_SPEC_BASE:-origin/main}")" HEAD_SHA="$(git rev-parse HEAD)" mise run commit-lint; then echo "::error:: verify: commit-lint failed. No receipt written." >&2 exit 1 fi @@ -4424,10 +4429,38 @@ fi # CI confirms what this proved. The first arming ran in CI alone and a # ref-namespace mistake was unreachable by any local run — it cost a matrix. # -# `origin/main` is the right base HERE and is not the property-of-the-world -# mistake the `hk` gate must avoid: `verify` has already refused this branch -# unless it is rebased on current `origin/main` (see the guard in `verify`), so -# this task is a function of (commit, current trunk) before this line runs. The +# `origin/main` IS THE RIGHT BASE ONLY WHEN THE LAP DID NOT SPECULATE, and the +# paragraph below used to say it unconditionally (CLOUD-1702). Its reasoning — +# `verify` has already refused this branch unless it is rebased on current +# `origin/main`, so this task is a function of (commit, current trunk) — holds +# for an ordinary run and is FALSE on a speculative lap: `land` replays the +# branch onto the lease holder's UNLANDED commits, "the main that is about to +# exist", so the tree is a function of (commit, the holder's base) instead. +# +# Judging that tree against trunk charges the holder's weakenings to the +# BORROWER. `lint::groom` keys the claim receipt on the branch name, and a +# borrower has one of its own, minted for its own row and naming no weakening — +# `Groom::Read({})`, which refuses by design (CLOUD-841: evidence of absence, not +# absence of evidence). The holder's `Weakens:` trailer cannot admit it, because +# the borrower's groom has already answered. Measured 2026-09-25/26: five laps +# over four different borrowed tips, every one refusing +# `recorder[board-issue-created] recorder-changed` and its sibling, while +# `mise run test:cargo` over the identical integrated commit was 6057/6057 green. +# +# `BATTEN_SPEC_BASE` is what `land` already publishes for exactly this question +# (`speculation::PUBLISHED_AS`, CLOUD-748), and `land.rs`'s own +# `a_body_gate_is_told_which_base_the_lap_borrowed` asserts it arrives. Using it +# is the same bound CLOUD-1711 put on `race::authored_log`, which read the whole +# branch history where the shell read only the commits the branch authored. +# +# NOTHING ESCAPES JUDGEMENT, which is the property that makes this a fix rather +# than a relaxation: every commit is still judged once, on its own branch, +# against the base it actually sits on. The holder's weakenings are adjudicated +# on the holder's own lap, against trunk, under the holder's groom. +# +# A no-op wherever no bet is live — an ordinary local lap and CI both leave the +# variable unset, so the expansion is `origin/main` and the class is unchanged. +# The # pre-commit step stays single-tree, where that reasoning does not hold. # # Unarmed callers are unaffected: absent `CONFIG_LINT_BASE` the task runs exactly @@ -4445,7 +4478,7 @@ if ! mise run record-verdicts; then echo "::error:: verify: the validator verdicts could not be recorded, so the rows that read them would decide over a record nothing wrote. No receipt written." >&2 exit 1 fi -if ! CONFIG_LINT_BASE=origin/main mise run config-lint; then +if ! CONFIG_LINT_BASE="${BATTEN_SPEC_BASE:-origin/main}" mise run config-lint; then echo "::error:: verify: config-lint refused this tree — either batten.toml carries a policy smell, or this branch weakens policy against origin/main. No receipt written." >&2 exit 1 fi