Skip to content

fix: make verify runnable on macOS, and gate the constructs that broke it (CLOUD-282) - #330

Merged
wenzowski merged 7 commits into
mainfrom
wenzowski/cloud-282-verify-cannot-run-on-macos
Aug 13, 2026
Merged

wenzowski merged 7 commits into
mainfrom
wenzowski/cloud-282-verify-cannot-run-on-macos

Conversation

@wenzowski

Copy link
Copy Markdown
Contributor

Closes CLOUD-282.

mise run verify is the authorization the whole workflow contract rests on —
"verify exhaustively before CI", "the gates ARE your authorization". On macOS it
could not pass, for reasons no branch caused, so an agent there either stopped
on a red verify it did not break or landed on CI's word alone. CI runs ubuntu
and is structurally blind to the whole class: the same "verdict is a property of
the machine" shape as CLOUD-227.

The gates themselves, not just their tests

  • sed's NUL-separated mode is GNU-only; BSD sed exits illegal option -- z.
    Three files used it to scrub quoted spans across newlines — run-shape-guard,
    stop-posture-check, and memory-guard-check, which CLOUD-282 does not
    name
    . All now use perl -0777 -pe. Byte-identity was differentially
    verified over every substitution against the real tests/*.bats bodies plus
    both edges the issue calls out (a leading \n, a blank line before >): 18
    cases, zero divergence. Only \1 becomes $1.
  • mapfile is bash 4 and macOS ships 3.2, so gh-guard-check and
    run-shape-guard (also unnamed in the issue) died before judging
    anything. Both now use the while IFS= read -r idiom issue-guard and
    ready-guard already carry. The load-bearing half is printf '%s\n': read
    returns false on an unterminated final segment, and a single-segment command
    like gh pr merge is all final segment, so the guard would have silently
    allowed everything it exists to deny. tests/gh-guard.bats confirms it still
    denies.
  • xargs -r in memories-check bought nothing — the /dev/null sentinel
    already makes a zero-file invocation a silent exit 1.
  • target-ensure's prose still called its lock a flock; it has been a mkdir
    mutex since CLOUD-286.

The test call sites

New tests/helpers.bash carries what the suites need and macOS does not ship,
and 22 call sites move onto it:

  • sed_i — -i.bak plus removal, the one in-place form GNU and BSD both
    accept. 11 sites, not the 3 the issue lists: ci-local-parity.bats (7) and
    release-assets-check.bats (1) carry it too.
  • run_timeout — a stand-in for coreutils timeout(1), which is absent
    from a stock macOS entirely, so those 9 sites failed on a missing binary
    rather than a flag. Its exit mapping is pinned in tests/helpers.bats because
    the suites assert the numbers directly.

Three fixture repos, and a correction to the issue

git branch -f main built the topology these suites need — a second branch
marking the trunk while HEAD stays on the feature branch — only by accident: it
works while git's default is master, and git refuses to force the branch that
is checked out, so any developer with init.defaultBranch=main (recommended by
git since 2.28) failed every case in all three suites at setup().

Not branch -M main, which the issue recommends. -M renames the current
branch, so no second branch is left to check out — rewriting them that way made
verified.bats's moved-main case fail. What landed is git init -b work plus a
plain git branch main. Measured under init.defaultBranch=main: -f exits
128, this does not. The suites also neutralise GIT_CONFIG_GLOBAL/SYSTEM,
closing the wider class the way crates/batten/tests/common/mod.rs already does.

The gate

Six forbid rows in batten.toml rather than a 50th mise task, per the
engine-first amendment: batten check already runs in the shared hk gate with
no glob, so the construct set is config a reviewer can read. Globs are
mise-tasks/* and tests/*.bats, both anchored at two segments so neither can
match the root batten.toml, and the single-segment test glob keeps the walk
out of the vendored tests/bats submodule. Pinned by
the_committed_portability_rules_fire_on_every_banned_shape in cli.rs: a
seeded tree is exit 2 with byte-exact sorted stdout, and the portable spellings
adopted here are silent.

One finding worth the reader's attention: every rationale comment explaining a
banned construct fires the row that bans it
, since forbid is a literal
substring with no exclude and the guarded files sit under the guarded globs.
The comments therefore name the flag without spelling the invocation — the same
dodge no-consumer-account-literal already documents. That is CLOUD-283's gap
one layer earlier than it predicted: not only fixture strings, but a rule's own
explanation.

Verified

All 166 cases across the ten touched suites pass under a GIT_CONFIG_GLOBAL
carrying init.defaultBranch=main and commit.gpgsign=true — the exact
configuration that previously failed three whole suites at setup(). Full
mise run verify green.

Split out rather than dropped

  • CLOUD-382 — hk.pkl's ShellCheck selector for tests/*.bats and the ten
    !-led assertions it exposes. hk.pkl was held by another session, and the
    fixes belong with the gate that keeps them.
  • CLOUD-383 — mise-tasks/land's wait -n, the last bash-4 construct.

Still gated by CLOUD-283: the tests/*.bats half of the sed -i and flock
rows, which cannot be written without firing on the suites that prove the guards
work.

Not proven by any of this: that it works on a Mac. Every check ran on Linux
— the same residual gap macos-link-check has against darwin-link. Recorded
on CLOUD-282.

Refs: CLOUD-282


Generated by Claude Code

@linear-code

linear-code Bot commented Aug 11, 2026 •

Copy link
Copy Markdown
CLOUD-282 `verify` cannot run on macOS: `doctor` needs `flock`, two gates are GNU-only `sed -zE`, and three test suites assume git's default branch is not `main`

Why

Local verify is the authorization gate the whole workflow contract rests on — "verify exhaustively before CI", "the gates ARE your authorization". On macOS it cannot pass, for reasons no branch causes. A macOS agent therefore either stops on a red verify it did not break, or lands on CI's word alone, which is the failure mode the contract exists to prevent. CI runs ubuntu, so CI is structurally blind to every class below — the same "verdict is a property of the machine" shape as CLOUD-227.

Surfaced on PR #205 (wenzowski, 2026-08-10), where mise run land stopped at verify; the author reproduced every failure identically on origin/main from a detached worktree. Confirmed by reading the source on main @ 5adcaef.

Two independent defect classes

1. GNU-only sed -zE. BSD sed has no -z; it exits sed: illegal option -- z. This is not only a test failure — the gates themselves cannot run on macOS:

  • mise-tasks/run-shape-guard:64 — sed -zE "s/'[^']*'/QUOTED/g; …"
  • mise-tasks/stop-posture-check:67-70 — four chained sed -zE, including s/(^|\n)…/ which depends on NUL-slurping to see \n in the pattern space at all

Both are whole-input transforms that need the buffer unsplit by newlines. -z is one way; perl -0777, or an awk with RS='\0', are portable ones. perl -0777 -pe is byte-identical to sed -zE for all five substitutions, differentially verified against the real bats fixtures and the \n-at-start and blank-line-before-> edges; only \1 becomes $1, at line 70. The one divergence, embedded NUL, is unreachable here. Not awk: it would have to inline its regex literally to satisfy awk-regex-check, and this repo's dev boxes are mawk while the runner is gawk — the exact divergence that made ready-lint silently vacuous.

Related but distinct, same file class: tests/ci-tools-check.bats:85,94,105 use sed -i with no backup suffix, which BSD sed rejects (it reads the next argument as the suffix).

2. git branch -f main under init.defaultBranch=main. Suites build a fixture repo with git init, commit, then force-create main. git refuses branch -f on the branch that is currently checked out. It works in CI only because the runner's git still defaults to master, so main is a different branch — an accident of the runner's configuration, not a property of the test. Any developer whose global gitconfig sets init.defaultBranch=main (the common modern setting, recommended by git since 2.28) fails these suites on any OS. It is a setup() failure, so every test in the suite errors, not just one.

Re-measured: three suites break, not four. tests/verified.bats:14-19, tests/landed-check.bats:16-21, tests/issue-guard.bats:19-24. tests/linear-check.bats:114 is a false positive — branch -M main renames the current branch, and renaming main to main takes git's lenient validation path and succeeds. Two in-repo models are already correct: tests/released.bats:16 (git init -q -b main .) and the Rust builders at crates/batten/tests/common/mod.rs:249-266, which use branch -M main. Because common/mod.rs:177 forces init.defaultBranch=main, the Rust suite already runs -M main on an already-main branch every invocation and passes — in-repo proof that -M is safe and -f is not.

The wider class survives that fix: no bats suite neutralizes the developer's global git config, while common/mod.rs:184-185 sets GIT_CONFIG_GLOBAL=/dev/null and GIT_CONFIG_SYSTEM=/dev/null. init.defaultBranch is one leak; commit.gpgsign is the same shape and is disabled in only one suite.

Note the PR comment also listed memories-check under this class; tests/memories-check.bats:10 only calls git init -q and carries no git branch -f, so that suite fails for some third reason. See the xargs -r bullet below for the candidate.

What ShellCheck can and cannot do here (measured 2026-08-10, ShellCheck 0.11.0)

It cannot see this class at all. Over 17 GNU-only constructs — sed -i, sed -E, date -d, grep -P, stat -c, readlink -f, base64 -w0, mktemp --suffix, head -n -1, sort -V, xargs -r, find -printf, timeout, sha256sum, tac, nproc, cut --complement — it reports 0 findings under --shell=bash and 0 under --shell=sh. It models the shell language, not the utilities a script calls; there is no GNU-vs-BSD flag database, and --list-optional carries no check in that family. -s sh adds only SC3xxx bashism warnings, so a sh shebang is not the lever: it would flag legitimate bash and break bats, which requires bash.

And it has never read the bats suite, which is why these classes accumulate unseen. hk.pkl overrides Builtins.shellcheck, whose selector is (glob **/*.sh, **/*.bash) OR (types: sh, bash). hk check --all --step shellcheck -v batches 45 files — every mise-tasks/*, .claude/hooks/session-start.sh, two fixture .in files — and none of the 42 tests/*.bats, because #!/usr/bin/env bats is neither type. .shellcheckrc has carried an SC2030/SC2031 suppression reasoning about bats run subshells the whole time; a suppression reads as evidence a file is being read, and it is not. One selector entry fixes it — ShellCheck derives the bats dialect from that shebang unaided, so no --shell flag and no per-file directives.

Selecting them costs 99 findings at this repo's --severity=style posture (SC2016×55, SC2314×43, SC1007×1), of which 10 are error severity and are real defects: an !-led assertion does not fail a bats test, so ten assertions currently assert nothing — tests/issue-guard.bats:136,260,266, tests/land.bats:451, tests/run-shape-guard.bats:99, tests/stop-guard.bats:56,65,73,80, tests/target-race.bats:140. bats is v1.14.0, so run ! is available. Expect some to fail once converted; an assertion that never asserted may have been masking a defect, and that is the real yield.

Three further classes, distinct from the two above

  • timeout — nine executed sites. tests/main-watch.bats:73,89,100,110,121,131, tests/ci-wait.bats:57,69, tests/land.bats:642 (including -k and -s KILL). It is GNU coreutils and absent from a stock macOS, so these fail on a missing binary rather than on a flag. Measured: it is the only coreutils-only utility this tree invokes, and there are zero GNU-only flags on stat/base64/readlink/date/sort/head/cut anywhere — so the answer is a portable helper in a shared test file, not a coreutils pin supplying one binary used only in tests. tests/gh-guard.bats:141 carries timeout inside a fixture string being parsed, not an invocation; leave it.
  • bash 3.2. macOS ships 3.2 as /bin/bash and mise registry carries no bash, so these are rewrites and not pins. mapfile at mise-tasks/gh-guard-check:26 — the rewrite exists twice already at mise-tasks/issue-guard:79 and mise-tasks/ready-guard:36, and the load-bearing detail is that printf '%s' must become printf '%s\n': without the trailing newline read returns false on the final segment, and for a single-segment command like gh pr merge the guard then silently allows everything. wait -n at mise-tasks/land:254 — its exit status is discarded, the winner is read from which rc file is non-empty, and a killed loser must leave its rc empty; both racers are unbounded so a naive downgrade to bare wait deadlocks, and a wall-clock cap is forbidden. A FIFO rendezvous (exec 3<>fifo, one blocking read) preserves every property. While there, fix the bare wait at land:256, which hangs if the group kill did not land — reap_watch at land:318-323 already has the correct shape.
  • xargs -r at mise-tasks/memories-check:65 — the candidate for the unexplained memories-check.bats failure. BSD xargs did not accept -r until recent macOS. Test it first; it is version-dependent and unverified on a Mac.

Refinement — Ready (verify passes on macOS, and a gate keeps it that way, expressed as rules rather than a 50th mise task)

  • Source of truth (§1). batten.toml's [[rule]] rows for the banned invocations, and hk.pkl for ShellCheck's file selection. The construct set is config, not prose, and not a second copy inside a shell script.
  • The mechanism is a computable predicate (§2). Engine-first, per the 2026-08-07 amendment: kind = "forbid", scope = "tree" rows in batten.toml — sed -zE, sed -i (trailing space, so sed -i.bak is not a hit), mapfile , wait -n, xargs -r, flock , branch -f main — evaluated by batten check, already in the shared hk gate at hk.pkl:281-289 with no glob, so it runs on every commit and in CI with no new wiring. This supersedes the earlier note proposing a sibling of awk-regex-check: that amendment exists precisely because the prior wording made a bash task the cheapest satisfying artifact, and CLOUD-202 is in flight porting the existing guards out of that layer. Anchor every glob at two or more segments so it cannot match the root batten.toml and self-fire — the file walk is fs::read_dir, not git ls-files, and skips only .git. The half a literal pattern cannot express — flag clusters judged by their letters, and excluding comments, case-pattern token lists and fixture strings — is CLOUD-283.
  • Output & exit contract (§5). Findings stay pointer-only (path:line plus rule id). Note the inversion when the gate moves into the engine: a batten check violation is exit 2, the opposite of the mise-tasks/*-check convention where 2 means unreadable input.
  • Commit / bump (§6). fix → patch until 0.1.0.
  • Test obligation (§7). The committed rows are pinned in crates/batten/tests/cli.rs, not in the fixture corpus — that corpus tests the engine, and cli.rs:1562-1570 records the standing obligation that "any rule landing later owes one of its own". Model on the_committed_repo_agnosticism_rules_fire_on_every_banned_shape (cli.rs:1600-1689): dirty tree → exit 2 with byte-exact stdout, clean tree → exit 0 with empty stdout. Those tests copy the committed batten.toml into the scratch repo, so a glob matching it would break byte equality. Plus the existing bats suites green under the portable forms.
  • Blockers (§8). blockedBy CLOUD-286 — doctor refuses to run without flock, so this cannot reach its own Done until that lands. relatedTo CLOUD-283, the engine gap the gate's harder half needs; the literal-expressible rows land without it.

Done

  • Both gates run under BSD sed; the three sed -i call sites carry a portable form.
  • The three fixture setups do not depend on git's default branch name, verified by re-running them under git -c init.defaultBranch=main.
  • gh-guard-check still denies a single-segment gh pr merge after the mapfile rewrite.
  • hk check --all --step shellcheck -v lists all 42 tests/*.bats, and the step passes at --severity=style.
  • The ten !-led assertions use run ! and fail when their subject succeeds — verified by inverting each subject once, not by a green run.
  • The nine timeout call sites use a portable test helper.
  • The banned invocations are batten.toml rows, not a new mise-tasks/*-check program, and each fires when its literal is seeded under its glob.
  • Landed on main by fast-forward, CI-confirmed green.

Not proven by any of the above: that it works on a Mac. Every check here runs on Linux — the same residual gap mise-tasks/macos-link-check has against mise-tasks/darwin-link. Someone with a Mac has to run mise run verify once.

Not blocking anything today — filed because it is real and reproduces on main, not because it is in flight. Discovered while adopting PR #205 (CLOUD-281); it is not that change's to fix.


Implementation notes (2026-08-11) — four places the issue's own analysis was wrong, and the scope split

Everything below was measured on main @ ec3639a while building this, not inferred.

1. branch -M main is the WRONG replacement, and the issue recommends it. -M renames the current branch; these three fixtures need a second branch marking the trunk while HEAD stays on the feature branch, which is the topology tests/verified.bats's moved-main case checks out (git checkout -q -). Rewriting them to -M first made that case fail — there was no other branch left to check out. The in-repo precedent the issue cites (common/mod.rs:249-266) is doing a genuinely different thing: making the current branch be called main.

What landed instead: git init -q -b work "$REPO" plus a plain git branch main. Naming the working branch makes the topology explicit rather than inherited, and main is then a fresh name needing no force at all. Measured under init.defaultBranch=main: git branch -f main exits 128 (cannot force update the branch 'main' used by worktree at …), git branch main off work succeeds.

2. Two call sites the issue does not name. sed -zE is in three files, not two — mise-tasks/memory-guard-check:95 carries the identical scrubber. mapfile is at two sites, not one — mise-tasks/run-shape-guard:237 as well as gh-guard-check:26. Both are now fixed; both would have been missed by working from the issue's list.

3. sed -i is at 11 sites, not three. tests/ci-local-parity.bats (7) and tests/release-assets-check.bats (1) carry it too, beyond the three in ci-tools-check.bats.

4. GNU timeout returns 137, not 124, when a -k escalation actually fires. Measured against real coreutils rather than assumed, because the portable helper had to agree with the tool it replaces in the one case the two could differ. The helper's mapping is: the command's own status when it finished in time; 137 when the child died of SIGKILL; 124 otherwise. tests/helpers.bats pins all three branches plus the case that distinguishes a self-raised SIGTERM (143) from a TERM-timeout — an implementation reading only the exit status would report a genuine crash as a timeout.

What landed

  • perl -0777 -pe in all three gates. Byte-identity differentially verified over every substitution against the real tests/*.bats bodies plus both edges the issue names (\n at start, blank line before >) — 18 cases, zero divergence.
  • mapfile → the read loop issue-guard/ready-guard already use, with printf '%s\n'. Confirmed against tests/gh-guard.bats: a single-segment gh pr merge is still denied, which is the case the missing newline would have silently allowed.
  • xargs -r → bare xargs; the /dev/null sentinel already bought what -r did.
  • New tests/helpers.bash (sed_i, run_timeout) + tests/helpers.bats; 22 call sites moved onto it.
  • The three fixture setups also neutralise GIT_CONFIG_GLOBAL/GIT_CONFIG_SYSTEM, closing the wider class rather than the one leak.
  • Six forbid rows in batten.toml (no-gnu-sed-z, no-gnu-sed-in-place, no-bash4-mapfile, no-gnu-xargs-r, no-util-linux-flock, no-branch-f-main), pinned by the_committed_portability_rules_fire_on_every_banned_shape in cli.rs.

Verified: all 166 cases across the ten touched suites pass under GIT_CONFIG_GLOBAL carrying init.defaultBranch=main and commit.gpgsign=true — the configuration that previously failed three whole suites at setup().

A finding about the rows themselves. Every rationale comment explaining a banned construct fires the row that bans it — forbid is a literal substring with no exclude, and the guarded files live under the guarded globs. The comments are therefore worded to name the flag without spelling the invocation, which is the same dodge no-consumer-account-literal already documents. This is CLOUD-283's gap showing up one layer earlier than expected: it is not only fixture strings and case token lists, it is a rule's own explanation.

Split out, not dropped

Two pieces sit in files another session held, and each shipped as its own issue rather than as a silent omission:

  • CLOUD-382 — hk.pkl's ShellCheck selector for tests/*.bats, and the ten !-led assertions it exposes. The fixes belong with the gate that keeps them (non-negotiable rule 2).
  • CLOUD-383 — mise-tasks/land's wait -n and the bare wait, the last bash-4 construct in the tree.

Still gated by CLOUD-283: the tests/*.bats half of the sed -i and flock rows. tests/memory-guard.bats:106,107,135,145,164 carry the in-place form as fixture strings — it is the suite proving memory-guard denies that shape — and tests/target-ensure.bats:162 names the util-linux lock in a test title. Neither row can be written today without firing on the tests that prove the guards work. The mise-tasks/* half, which is the layer that actually could not run, landed.

And still not proven: that it works on a Mac. Every check here ran on Linux. Someone with a Mac has to run mise run verify once — the same residual gap macos-link-check has against darwin-link.

Review in Linear

@wenzowski
wenzowski marked this pull request as ready for review August 11, 2026 20:27
@wenzowski
wenzowski force-pushed the wenzowski/cloud-282-verify-cannot-run-on-macos branch 4 times, most recently from 90f6480 to d8ad917 Compare August 11, 2026 21:13
@wenzowski

Copy link
Copy Markdown
Contributor Author

/fast-forward

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #330 (comment) by @​wenzowski.

Trying to fast forward main (87ed397) to wenzowski/cloud-282-verify-cannot-run-on-macos (d8ad917).

Target branch (main):

commit 87ed39733221612abd4f99ce64c5f93e773439d4 (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 18:56:29 2026 +0000

    fix(verify): refuse to receipt a HEAD whose bytes were not the ones validated
    
    `verify` runs every gate over the WORKING TREE and then writes a receipt keyed
    to HEAD. Nothing asserted the two agree, so a dirty tree could attest a commit
    nobody verified: the receipt is written, `verified` matches it, `ready-guard`
    accepts it, and CI runs a commit that was never the thing that passed.
    
    Measured 2026-08-09 landing CLOUD-269 — a backgrounded `land` compiled a
    mid-edit snapshot and reported `verify failed on c5bfe05`, a commit containing
    none of that code. That direction is loud and self-correcting; the mirror is
    silent, and it is the one this closes.
    
    `mise-tasks/tree-clean` is the predicate: `git --no-optional-locks status
    --porcelain --untracked-files=normal`, exit 1 with a count and the porcelain
    lines as pointers, exit 2 when it cannot look. Untracked-but-not-ignored counts
    as dirty — decided, not omitted — because `cargo test` auto-discovers
    `crates/batten/tests/*.rs` and the bats suite globs `tests/*.bats`, so a new
    untracked file is run by `verify` with zero tracked-file change. Ignored paths
    are excluded structurally.
    
    Wired into `[tasks.verify]` at both ends of the window: in `depends` so a dirty
    tree fails in seconds rather than after ~170s, and in the body — the
    load-bearing one, since `depends` completes before a tree can be dirtied
    mid-run. Not an hk step: `pre-commit` runs over a tree that is dirty by
    definition. `land` inherits it through `verify` and re-implements nothing.
    
    Refs: CLOUD-277

Pull request (wenzowski/cloud-282-verify-cannot-run-on-macos):

commit d8ad917aec45f26f1dfba7376c5a1023c0d336cf (pull_request/wenzowski/cloud-282-verify-cannot-run-on-macos)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 20:49:54 2026 +0000

    fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
    
    CLOUD-282's six portability rules are scoped to `mise-tasks/*`, a path
    `batten-check`'s glob did not carry. `batten-glob-check` (CLOUD-224, landed on
    main while this branch was in flight) catches exactly that and names the fix:
    without it the gate silently stops running for commits that touch only
    mise-tasks/, so the rows would be feedback-deleted while still passing CI.
    
    Both surfaces of that gate failed identically — the hk step and
    tests/batten-glob-check.bats' 'the committed pair covers itself today' — which
    is the pair working as designed.
    
    Refs: CLOUD-282

Can't fast forward main (87ed397) to wenzowski/cloud-282-verify-cannot-run-on-macos (d8ad917). main (87ed397) is not a direct ancestor of wenzowski/cloud-282-verify-cannot-run-on-macos (d8ad917). Branches appear to have diverged at 98aceb0:

* d8ad917aec45f26f1dfba7376c5a1023c0d336cf fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
* 828ca8f80edaf4d66dd2aaaa616d05fa36b39494 fix(tests): assign the helper's empty default explicitly
* 049e645e581bede71525ea7caa197951a9eafbd0 fix(tests): stop the suites depending on GNU tools and on git's default branch
* 84614cb26853e3be3810a6d66ac539707c44f6c2 fix(gates): run the shell gates under BSD sed and bash 3.2
| * 87ed39733221612abd4f99ce64c5f93e773439d4 fix(verify): refuse to receipt a HEAD whose bytes were not the ones validated
|/  
* 98aceb05393d0fdfc91d977603ae486cf34e1b7f feat(bench): measure the token economics instead of asserting them

commit 98aceb05393d0fdfc91d977603ae486cf34e1b7f
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 19:14:30 2026 +0000

    feat(bench): measure the token economics instead of asserting them
    
    The adoption claim is token economics, and the differentiator is that ours is
    reproducible: anyone can say they are cheaper, we ship the harness that produces
    the number from committed inputs with no credential and no network.
    
    `mise run token-bench` executes what `bench/tokens/workloads.toml` declares and
    prices it with what `bench/tokens/method.toml` declares — no price, divisor,
    re-run coefficient or workload is baked into the program, because a constant
    written into a benchmark's code is a number nobody re-derives. Every arm runs
    three times and is compared byte-for-byte; an arm that is not byte-stable is
    reported as such rather than averaged, since byte-stability is the property the
    cache claim rests on.
    
    `mise run token-bench-check` is the mechanism that makes "reproducible"
    checkable: it regenerates the table into scratch and diffs it byte-for-byte, and
    it re-reads the published bytes for the honesty predicate — a figure without
    workload, baseline, run count and method is refused, and so is a capability
    reporting "not measured" with no reason. The gate re-reads the artifact rather
    than trusting the generator, which is what a program checking its own arithmetic
    would not do.
    
    Two capabilities carry a measured figure; `log-handle` reports "not measured"
    because the capability is not shipped, and the cross-session cache hit rate
    reports "not measured" because it needs a live provider credential and is a
    property of the world rather than of this commit. Neither borrows a magnitude
    from its neighbour. No aggregate is published: averaging across capabilities
    needs a workload mix nobody here has measured.
    
    `build-warning` is the honest one — Batten wins it by 1.47x, and the saving is
    exactly the discarded `tail` window rather than the log, which `exec` tees in
    full by design.
    
    Named `token-bench` rather than `bench`: CLOUD-207's `mise run bench` measures
    batten's invocation cost and landed under that name first. Two benchmarks with
    two subjects need two names, so the later and more specific one moves, and
    `bench/tokens/` leaves room for the sibling's own inputs beside it.
    
    Refs: CLOUD-119

Rebase locally, and then force push to wenzowski/cloud-282-verify-cannot-run-on-macos.

@wenzowski
wenzowski force-pushed the wenzowski/cloud-282-verify-cannot-run-on-macos branch 2 times, most recently from 8a2dfd4 to 6d84833 Compare August 11, 2026 21:28
@wenzowski

Copy link
Copy Markdown
Contributor Author

/fast-forward

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #330 (comment) by @​wenzowski.

Trying to fast forward main (ac7da09) to wenzowski/cloud-282-verify-cannot-run-on-macos (6d84833).

Target branch (main):

commit ac7da09517068209d6d27197e908d2ef617762ef (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 19:02:37 2026 +0000

    docs(agents): price the metered model call, and index every memory the repo ships
    
    The workflow contract opened with a two-row price list — "Every CI run costs
    real minutes; your own execution costs nothing" — and a token-consuming model
    call is in neither row. It is not local and it is not free, so an agent reading
    only the always-loaded surface correctly concluded its own fan-out was free.
    
    Three categories now: local execution, free; a CI run, metered; a token-consuming
    model call, metered in the same category, a subagent spawn above all. The
    derivation stays out of the always-loaded surface and the clause points at
    `mem:workflow/agent-fanout` for it — which is the memory that had no trigger
    anywhere, along with `core` and `memory_maintenance`. All three get an index row,
    so the routing table now covers every memory the repo ships.
    
    Both were paid for out of reclaimed lines rather than appended: the surface sits
    at its 199-line target with zero headroom, so `land`'s step, the governing
    paragraph and two background paragraphs were repacked and their *why* clauses
    dropped where `.claude/rules/toolchain.md` already carries them. 199 lines before
    and after, 28 insertions against 28 deletions.
    
    Refs: CLOUD-288

Pull request (wenzowski/cloud-282-verify-cannot-run-on-macos):

commit 6d8483336c43b25f22ec970a06a71b3d25cdb9c4 (pull_request/wenzowski/cloud-282-verify-cannot-run-on-macos)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 20:49:54 2026 +0000

    fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
    
    CLOUD-282's six portability rules are scoped to `mise-tasks/*`, a path
    `batten-check`'s glob did not carry. `batten-glob-check` (CLOUD-224, landed on
    main while this branch was in flight) catches exactly that and names the fix:
    without it the gate silently stops running for commits that touch only
    mise-tasks/, so the rows would be feedback-deleted while still passing CI.
    
    Both surfaces of that gate failed identically — the hk step and
    tests/batten-glob-check.bats' 'the committed pair covers itself today' — which
    is the pair working as designed.
    
    Refs: CLOUD-282

Can't fast forward main (ac7da09) to wenzowski/cloud-282-verify-cannot-run-on-macos (6d84833). main (ac7da09) is not a direct ancestor of wenzowski/cloud-282-verify-cannot-run-on-macos (6d84833). Branches appear to have diverged at b1669d6:

* 6d8483336c43b25f22ec970a06a71b3d25cdb9c4 fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
* a8e581c14d0005a994b4b3a2ad65d5868ca5c1ce fix(tests): assign the helper's empty default explicitly
* 1220450dc2deb36759e0a50c36805e9cc54b4fed fix(tests): stop the suites depending on GNU tools and on git's default branch
* e5f33e90dbc982ae050e677c24674b861d9c0b82 fix(gates): run the shell gates under BSD sed and bash 3.2
| * ac7da09517068209d6d27197e908d2ef617762ef docs(agents): price the metered model call, and index every memory the repo ships
|/  
* b1669d6f503804d7102754c992931a9c31359d6d docs(readme): lead with the completion gate, not the policy-engine category

commit b1669d6f503804d7102754c992931a9c31359d6d
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 19:17:41 2026 +0000

    docs(readme): lead with the completion gate, not the policy-engine category
    
    "Policy engine" as the lead noun claims membership in a category whose
    repo-level population measures near-zero, and it invites an expressiveness
    benchmark against authorization engines Batten does not implement and must not
    grow. The category is conformance checking: the subject is always the
    repository's own state, and the question is always whether observed state
    conforms to the committed model of how work lands here. A principal/action/
    resource request shape has no field for "is this ref on `main`" or "did the
    required checks conclude green for this exact SHA".
    
    So the lead becomes the gate itself, hook-first, with CI and pre-commit demoted
    to what they actually are — bypass defense over the same predicate, not two
    more adoption surfaces. "Permission hooks" becomes "conformance gates" for the
    same reason: the hook's allow/deny channel is the only authorization-shaped
    part, and the verdict inside it is a conformance verdict.
    
    Every "done" claim now carries its bound. Landed-plus-green is the minimum
    falsifiable completion predicate: it kills false success, it does not certify
    correctness, and review still gates release. Stated because the evidence
    behind it demonstrates that merge alone is not a verification event — it does
    not establish that the compound predicate certifies anything more.
    
    The token-economics story moves in under the headline as the supporting
    narrative it is, naming the three pains it addresses (tail-calling,
    lost-in-the-middle, context rot) against the two contract properties that
    answer them — pointer-not-payload and byte-stable output — plus the refusal
    that points at the fix. Magnitude is deliberately absent: the benchmark
    carries it, per workload with a stated baseline and run count, and a
    capability with no defensible number reports "not measured" rather than
    borrowing one.
    
    The crate keywords go with the description: "policy" as a discovery term
    recruits exactly the category readers this change is spending effort to stop
    attracting.
    
    Untouched on purpose: the exit-code table and the whole extension-surfaces
    section, both asserted against the compiled binary by tests that would fail if
    a rewrite clipped them.
    
    Refs: CLOUD-120

Rebase locally, and then force push to wenzowski/cloud-282-verify-cannot-run-on-macos.

@wenzowski
wenzowski force-pushed the wenzowski/cloud-282-verify-cannot-run-on-macos branch from 6d84833 to 5c6db70 Compare August 11, 2026 21:34
@wenzowski

Copy link
Copy Markdown
Contributor Author

/fast-forward

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #330 (comment) by @​wenzowski.

Trying to fast forward main (2d3acc3) to wenzowski/cloud-282-verify-cannot-run-on-macos (5c6db70).

Target branch (main):

commit 2d3acc3416b5d9ed3ca9ec5c3280194b11ef757f (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 18:52:11 2026 +0000

    ci(graph-check): make a frontier omission attributable, and say "could not look"
    
    `graph-check` is the scheduler as well as the gate, and its header claims every
    agent computing the frontier independently gets the same answer. It did not:
    `:92` ran ready-lint as `| "$lint" >/dev/null 2>&1 || continue`, so exit 1 ("this
    Ready block is wrong") and exit 2 ("stdin is not a payload with a .description
    field") arrived as the same silent absence — one missing `frontier` line and
    nothing else, exit 0 both times over a 25-payload closure.
    
    The same shape reached the verdict: `:40` required only id and status, so a set
    whose relations the caller projected away was reported an acyclic, non-dangling
    board with no edges in it at all.
    
    Three channels now, not one. `report()` keeps exit 1 for a board signalling
    falsely; `unjudged()` takes exit 2 for anything the gate could not read; `note()`
    attributes an honest exclusion without moving the exit code, because a board full
    of unrefined issues is not an incoherent board. ready-lint's rule ids are
    forwarded rather than re-derived, and its ::error:: summary dropped — annotating
    a failure at an exit code that denies one is the false signal this repo catches.
    
    The missing-blockedBy report is keyed to the `graph` pseudo-id, not to each
    issue: `released`'s `refusal_for` greps this stderr for `^<id> <rule>`, and a
    per-id line would turn every In Review issue in a relations-free sweep into a
    REFUSED. An explicit `blockedBy: []` is data and is judged; only an absent key
    is unjudgeable.
    
    Exit 2 outranks exit 1 when both hold, with both report sets printed: a verdict
    over a set the gate could only partly read is not a verdict, and the caller's
    next action is a re-fetch.
    
    Refs: CLOUD-251

Pull request (wenzowski/cloud-282-verify-cannot-run-on-macos):

commit 5c6db70e056b5720ab56113263f3ee0d4734165a (pull_request/wenzowski/cloud-282-verify-cannot-run-on-macos)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 20:49:54 2026 +0000

    fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
    
    CLOUD-282's six portability rules are scoped to `mise-tasks/*`, a path
    `batten-check`'s glob did not carry. `batten-glob-check` (CLOUD-224, landed on
    main while this branch was in flight) catches exactly that and names the fix:
    without it the gate silently stops running for commits that touch only
    mise-tasks/, so the rows would be feedback-deleted while still passing CI.
    
    Both surfaces of that gate failed identically — the hk step and
    tests/batten-glob-check.bats' 'the committed pair covers itself today' — which
    is the pair working as designed.
    
    Refs: CLOUD-282

Can't fast forward main (2d3acc3) to wenzowski/cloud-282-verify-cannot-run-on-macos (5c6db70). main (2d3acc3) is not a direct ancestor of wenzowski/cloud-282-verify-cannot-run-on-macos (5c6db70). Branches appear to have diverged at ac7da09:

* 5c6db70e056b5720ab56113263f3ee0d4734165a fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
* fbafa127411977d0ca53053735d5e7739a44eb69 fix(tests): assign the helper's empty default explicitly
* 6382b3c2c16b1cf2f263ae1ab31d79801efc34ff fix(tests): stop the suites depending on GNU tools and on git's default branch
* 0236d5d8a149a3988a542613faea190113574a24 fix(gates): run the shell gates under BSD sed and bash 3.2
| * 2d3acc3416b5d9ed3ca9ec5c3280194b11ef757f ci(graph-check): make a frontier omission attributable, and say "could not look"
|/  
* ac7da09517068209d6d27197e908d2ef617762ef docs(agents): price the metered model call, and index every memory the repo ships

commit ac7da09517068209d6d27197e908d2ef617762ef
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 19:02:37 2026 +0000

    docs(agents): price the metered model call, and index every memory the repo ships
    
    The workflow contract opened with a two-row price list — "Every CI run costs
    real minutes; your own execution costs nothing" — and a token-consuming model
    call is in neither row. It is not local and it is not free, so an agent reading
    only the always-loaded surface correctly concluded its own fan-out was free.
    
    Three categories now: local execution, free; a CI run, metered; a token-consuming
    model call, metered in the same category, a subagent spawn above all. The
    derivation stays out of the always-loaded surface and the clause points at
    `mem:workflow/agent-fanout` for it — which is the memory that had no trigger
    anywhere, along with `core` and `memory_maintenance`. All three get an index row,
    so the routing table now covers every memory the repo ships.
    
    Both were paid for out of reclaimed lines rather than appended: the surface sits
    at its 199-line target with zero headroom, so `land`'s step, the governing
    paragraph and two background paragraphs were repacked and their *why* clauses
    dropped where `.claude/rules/toolchain.md` already carries them. 199 lines before
    and after, 28 insertions against 28 deletions.
    
    Refs: CLOUD-288

Rebase locally, and then force push to wenzowski/cloud-282-verify-cannot-run-on-macos.

@wenzowski
wenzowski force-pushed the wenzowski/cloud-282-verify-cannot-run-on-macos branch 2 times, most recently from 5f47075 to 496c574 Compare August 11, 2026 22:00
@wenzowski
wenzowski marked this pull request as draft August 11, 2026 23:34
@wenzowski
wenzowski marked this pull request as ready for review August 11, 2026 23:34
@wenzowski

Copy link
Copy Markdown
Contributor Author

/fast-forward

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #330 (comment) by @​wenzowski.

Trying to fast forward main (a68878a) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574).

Target branch (main):

commit a68878a102c2e4127e98ed0f9c13ead534752e41 (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 22:00:12 2026 +0000

    docs(fanout): price the one land-contention term a cold first lap overstates
    
    CLOUD-122's re-measurement landed on `main` while this branch was lapping the
    same window, and it covers the shape better than the block this commit
    originally carried — same 15 minutes, same two lap-loss shapes, and the
    bot-silence term measured across 16 laps rather than 8. That block is dropped
    rather than restated; two accounts of one measurement is a memory that drifts.
    
    What survives is the term it does not price: cargo caches warm across laps, so
    `verify` fell from ~240s on lap 1 to 86s by lap 8 here. That moves a ~10 minute
    lap to ~7.5 against the same 7.3-minute gap, which is why re-invoking `land`
    after the cap is a different bet from raising `LAND_MAX_LAPS` — the second buys
    attempts at lap-1 odds, the first does not.
    
    Refs: CLOUD-68

Pull request (wenzowski/cloud-282-verify-cannot-run-on-macos):

commit 496c574a837c5e085b04c46c4746a9c7d7a7c112 (pull_request/wenzowski/cloud-282-verify-cannot-run-on-macos)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:59:02 2026 +0000

    fix(checksums): drop the bash-4 mapfile the new portability rule caught
    
    `no-bash4-mapfile` fired on mise-tasks/checksums:82 the first time it ran
    against a tree containing that file, which landed while this branch was in
    flight. The construct is a real defect rather than a false positive: `mapfile`
    is bash 4, macOS ships 3.2 as /bin/bash, and this task builds the checksum
    manifest for release artifacts — including the two Darwin ones.
    
    Same `while IFS= read -r` rewrite the other four sites took, and the producer
    already ends every entry with a newline, so no trailing-newline hazard applies
    here.
    
    Refs: CLOUD-282

Can't fast forward main (a68878a) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). main (a68878a) is not a direct ancestor of wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). Branches appear to have diverged at b913c98:

* a68878a102c2e4127e98ed0f9c13ead534752e41 docs(fanout): price the one land-contention term a cold first lap overstates
* 5eeedd8724a434acc7773023542cf8f00c3a3b6f feat(action): ship a GitHub Action whose empty `with:` block is the whole configuration
| * 496c574a837c5e085b04c46c4746a9c7d7a7c112 fix(checksums): drop the bash-4 mapfile the new portability rule caught
| * 8a54d149f33093c57446c0deba180771e84dc7f7 docs(fanout): name what the land backstop is asking when it stops you
| * 4efe71b2df67fc13226376247a0297f1f99b1801 fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
| * d95b6f5c5135cde59954b0a264571b04a5f4b8d6 fix(tests): assign the helper's empty default explicitly
| * 127658708f08462fa509ffa5909b3094c840d758 fix(tests): stop the suites depending on GNU tools and on git's default branch
| * e687d8f7502ee06cda6cfeafaaced81d918a5891 fix(gates): run the shell gates under BSD sed and bash 3.2
|/  
* b913c980bda0a9ade266915b4bf527918576a4c7 docs(fanout): re-measure land contention — a lap now loses by arithmetic

commit b913c980bda0a9ade266915b4bf527918576a4c7
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:17:30 2026 +0000

    docs(fanout): re-measure land contention — a lap now loses by arithmetic
    
    The measurement recorded three hours earlier had `main` at a 487s mean gap
    against a ~170s `verify`, giving N ≈ 2.9 with the WIP cap at 2 — "at the
    ceiling", and the model held. It no longer does. Over `main`'s ten commits to
    21:09Z the mean gap is 436s while a full lap is `verify` + CI + the
    fast-forward wait, call it 8–10 minutes. CLOUD-122 lost 16 consecutive laps
    across two `mise run land` invocations, every one green on CI.
    
    The interesting half is a lap-loss shape the N model does not price. Three of
    the sixteen were the documented case — `main` moved before CI finished, the
    verdict void, cancelled early and cheap. Five were not: CI went green,
    `/fast-forward` was posted, and the bot then stayed SILENT while `main` moved.
    `land` infers a refusal from `main` moving rather than from the bot answering,
    so the log reads as a refusal that never happened. The bot is not rejecting the
    fast-forward; it is slower than `main`, and that silence is a third term the
    verify + CI lap cost never included.
    
    Raising `LAND_MAX_LAPS` buys more attempts per invocation without changing the
    per-lap odds, so it spends CI minutes against a losing bet. The lever is
    unchanged and now more urgent: shorten the lap, or quiet `main`; never add
    sessions.
    
    Refs: CLOUD-122

Rebase locally, and then force push to wenzowski/cloud-282-verify-cannot-run-on-macos.

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #330 (comment) by @​wenzowski.

Trying to fast forward main (a68878a) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574).

Target branch (main):

commit a68878a102c2e4127e98ed0f9c13ead534752e41 (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 22:00:12 2026 +0000

    docs(fanout): price the one land-contention term a cold first lap overstates
    
    CLOUD-122's re-measurement landed on `main` while this branch was lapping the
    same window, and it covers the shape better than the block this commit
    originally carried — same 15 minutes, same two lap-loss shapes, and the
    bot-silence term measured across 16 laps rather than 8. That block is dropped
    rather than restated; two accounts of one measurement is a memory that drifts.
    
    What survives is the term it does not price: cargo caches warm across laps, so
    `verify` fell from ~240s on lap 1 to 86s by lap 8 here. That moves a ~10 minute
    lap to ~7.5 against the same 7.3-minute gap, which is why re-invoking `land`
    after the cap is a different bet from raising `LAND_MAX_LAPS` — the second buys
    attempts at lap-1 odds, the first does not.
    
    Refs: CLOUD-68

Pull request (wenzowski/cloud-282-verify-cannot-run-on-macos):

commit 496c574a837c5e085b04c46c4746a9c7d7a7c112 (pull_request/wenzowski/cloud-282-verify-cannot-run-on-macos)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:59:02 2026 +0000

    fix(checksums): drop the bash-4 mapfile the new portability rule caught
    
    `no-bash4-mapfile` fired on mise-tasks/checksums:82 the first time it ran
    against a tree containing that file, which landed while this branch was in
    flight. The construct is a real defect rather than a false positive: `mapfile`
    is bash 4, macOS ships 3.2 as /bin/bash, and this task builds the checksum
    manifest for release artifacts — including the two Darwin ones.
    
    Same `while IFS= read -r` rewrite the other four sites took, and the producer
    already ends every entry with a newline, so no trailing-newline hazard applies
    here.
    
    Refs: CLOUD-282

Can't fast forward main (a68878a) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). main (a68878a) is not a direct ancestor of wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). Branches appear to have diverged at b913c98:

* a68878a102c2e4127e98ed0f9c13ead534752e41 docs(fanout): price the one land-contention term a cold first lap overstates
* 5eeedd8724a434acc7773023542cf8f00c3a3b6f feat(action): ship a GitHub Action whose empty `with:` block is the whole configuration
| * 496c574a837c5e085b04c46c4746a9c7d7a7c112 fix(checksums): drop the bash-4 mapfile the new portability rule caught
| * 8a54d149f33093c57446c0deba180771e84dc7f7 docs(fanout): name what the land backstop is asking when it stops you
| * 4efe71b2df67fc13226376247a0297f1f99b1801 fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
| * d95b6f5c5135cde59954b0a264571b04a5f4b8d6 fix(tests): assign the helper's empty default explicitly
| * 127658708f08462fa509ffa5909b3094c840d758 fix(tests): stop the suites depending on GNU tools and on git's default branch
| * e687d8f7502ee06cda6cfeafaaced81d918a5891 fix(gates): run the shell gates under BSD sed and bash 3.2
|/  
* b913c980bda0a9ade266915b4bf527918576a4c7 docs(fanout): re-measure land contention — a lap now loses by arithmetic

commit b913c980bda0a9ade266915b4bf527918576a4c7
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:17:30 2026 +0000

    docs(fanout): re-measure land contention — a lap now loses by arithmetic
    
    The measurement recorded three hours earlier had `main` at a 487s mean gap
    against a ~170s `verify`, giving N ≈ 2.9 with the WIP cap at 2 — "at the
    ceiling", and the model held. It no longer does. Over `main`'s ten commits to
    21:09Z the mean gap is 436s while a full lap is `verify` + CI + the
    fast-forward wait, call it 8–10 minutes. CLOUD-122 lost 16 consecutive laps
    across two `mise run land` invocations, every one green on CI.
    
    The interesting half is a lap-loss shape the N model does not price. Three of
    the sixteen were the documented case — `main` moved before CI finished, the
    verdict void, cancelled early and cheap. Five were not: CI went green,
    `/fast-forward` was posted, and the bot then stayed SILENT while `main` moved.
    `land` infers a refusal from `main` moving rather than from the bot answering,
    so the log reads as a refusal that never happened. The bot is not rejecting the
    fast-forward; it is slower than `main`, and that silence is a third term the
    verify + CI lap cost never included.
    
    Raising `LAND_MAX_LAPS` buys more attempts per invocation without changing the
    per-lap odds, so it spends CI minutes against a losing bet. The lever is
    unchanged and now more urgent: shorten the lap, or quiet `main`; never add
    sessions.
    
    Refs: CLOUD-122

Rebase locally, and then force push to wenzowski/cloud-282-verify-cannot-run-on-macos.

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #330 (comment) by @​wenzowski.

Trying to fast forward main (a68878a) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574).

Target branch (main):

commit a68878a102c2e4127e98ed0f9c13ead534752e41 (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 22:00:12 2026 +0000

    docs(fanout): price the one land-contention term a cold first lap overstates
    
    CLOUD-122's re-measurement landed on `main` while this branch was lapping the
    same window, and it covers the shape better than the block this commit
    originally carried — same 15 minutes, same two lap-loss shapes, and the
    bot-silence term measured across 16 laps rather than 8. That block is dropped
    rather than restated; two accounts of one measurement is a memory that drifts.
    
    What survives is the term it does not price: cargo caches warm across laps, so
    `verify` fell from ~240s on lap 1 to 86s by lap 8 here. That moves a ~10 minute
    lap to ~7.5 against the same 7.3-minute gap, which is why re-invoking `land`
    after the cap is a different bet from raising `LAND_MAX_LAPS` — the second buys
    attempts at lap-1 odds, the first does not.
    
    Refs: CLOUD-68

Pull request (wenzowski/cloud-282-verify-cannot-run-on-macos):

commit 496c574a837c5e085b04c46c4746a9c7d7a7c112 (pull_request/wenzowski/cloud-282-verify-cannot-run-on-macos)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:59:02 2026 +0000

    fix(checksums): drop the bash-4 mapfile the new portability rule caught
    
    `no-bash4-mapfile` fired on mise-tasks/checksums:82 the first time it ran
    against a tree containing that file, which landed while this branch was in
    flight. The construct is a real defect rather than a false positive: `mapfile`
    is bash 4, macOS ships 3.2 as /bin/bash, and this task builds the checksum
    manifest for release artifacts — including the two Darwin ones.
    
    Same `while IFS= read -r` rewrite the other four sites took, and the producer
    already ends every entry with a newline, so no trailing-newline hazard applies
    here.
    
    Refs: CLOUD-282

Can't fast forward main (a68878a) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). main (a68878a) is not a direct ancestor of wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). Branches appear to have diverged at b913c98:

* a68878a102c2e4127e98ed0f9c13ead534752e41 docs(fanout): price the one land-contention term a cold first lap overstates
* 5eeedd8724a434acc7773023542cf8f00c3a3b6f feat(action): ship a GitHub Action whose empty `with:` block is the whole configuration
| * 496c574a837c5e085b04c46c4746a9c7d7a7c112 fix(checksums): drop the bash-4 mapfile the new portability rule caught
| * 8a54d149f33093c57446c0deba180771e84dc7f7 docs(fanout): name what the land backstop is asking when it stops you
| * 4efe71b2df67fc13226376247a0297f1f99b1801 fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
| * d95b6f5c5135cde59954b0a264571b04a5f4b8d6 fix(tests): assign the helper's empty default explicitly
| * 127658708f08462fa509ffa5909b3094c840d758 fix(tests): stop the suites depending on GNU tools and on git's default branch
| * e687d8f7502ee06cda6cfeafaaced81d918a5891 fix(gates): run the shell gates under BSD sed and bash 3.2
|/  
* b913c980bda0a9ade266915b4bf527918576a4c7 docs(fanout): re-measure land contention — a lap now loses by arithmetic

commit b913c980bda0a9ade266915b4bf527918576a4c7
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:17:30 2026 +0000

    docs(fanout): re-measure land contention — a lap now loses by arithmetic
    
    The measurement recorded three hours earlier had `main` at a 487s mean gap
    against a ~170s `verify`, giving N ≈ 2.9 with the WIP cap at 2 — "at the
    ceiling", and the model held. It no longer does. Over `main`'s ten commits to
    21:09Z the mean gap is 436s while a full lap is `verify` + CI + the
    fast-forward wait, call it 8–10 minutes. CLOUD-122 lost 16 consecutive laps
    across two `mise run land` invocations, every one green on CI.
    
    The interesting half is a lap-loss shape the N model does not price. Three of
    the sixteen were the documented case — `main` moved before CI finished, the
    verdict void, cancelled early and cheap. Five were not: CI went green,
    `/fast-forward` was posted, and the bot then stayed SILENT while `main` moved.
    `land` infers a refusal from `main` moving rather than from the bot answering,
    so the log reads as a refusal that never happened. The bot is not rejecting the
    fast-forward; it is slower than `main`, and that silence is a third term the
    verify + CI lap cost never included.
    
    Raising `LAND_MAX_LAPS` buys more attempts per invocation without changing the
    per-lap odds, so it spends CI minutes against a losing bet. The lever is
    unchanged and now more urgent: shorten the lap, or quiet `main`; never add
    sessions.
    
    Refs: CLOUD-122

Rebase locally, and then force push to wenzowski/cloud-282-verify-cannot-run-on-macos.

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #330 (comment) by @​wenzowski.

Trying to fast forward main (a68878a) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574).

Target branch (main):

commit a68878a102c2e4127e98ed0f9c13ead534752e41 (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 22:00:12 2026 +0000

    docs(fanout): price the one land-contention term a cold first lap overstates
    
    CLOUD-122's re-measurement landed on `main` while this branch was lapping the
    same window, and it covers the shape better than the block this commit
    originally carried — same 15 minutes, same two lap-loss shapes, and the
    bot-silence term measured across 16 laps rather than 8. That block is dropped
    rather than restated; two accounts of one measurement is a memory that drifts.
    
    What survives is the term it does not price: cargo caches warm across laps, so
    `verify` fell from ~240s on lap 1 to 86s by lap 8 here. That moves a ~10 minute
    lap to ~7.5 against the same 7.3-minute gap, which is why re-invoking `land`
    after the cap is a different bet from raising `LAND_MAX_LAPS` — the second buys
    attempts at lap-1 odds, the first does not.
    
    Refs: CLOUD-68

Pull request (wenzowski/cloud-282-verify-cannot-run-on-macos):

commit 496c574a837c5e085b04c46c4746a9c7d7a7c112 (pull_request/wenzowski/cloud-282-verify-cannot-run-on-macos)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:59:02 2026 +0000

    fix(checksums): drop the bash-4 mapfile the new portability rule caught
    
    `no-bash4-mapfile` fired on mise-tasks/checksums:82 the first time it ran
    against a tree containing that file, which landed while this branch was in
    flight. The construct is a real defect rather than a false positive: `mapfile`
    is bash 4, macOS ships 3.2 as /bin/bash, and this task builds the checksum
    manifest for release artifacts — including the two Darwin ones.
    
    Same `while IFS= read -r` rewrite the other four sites took, and the producer
    already ends every entry with a newline, so no trailing-newline hazard applies
    here.
    
    Refs: CLOUD-282

Can't fast forward main (a68878a) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). main (a68878a) is not a direct ancestor of wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). Branches appear to have diverged at b913c98:

* a68878a102c2e4127e98ed0f9c13ead534752e41 docs(fanout): price the one land-contention term a cold first lap overstates
* 5eeedd8724a434acc7773023542cf8f00c3a3b6f feat(action): ship a GitHub Action whose empty `with:` block is the whole configuration
| * 496c574a837c5e085b04c46c4746a9c7d7a7c112 fix(checksums): drop the bash-4 mapfile the new portability rule caught
| * 8a54d149f33093c57446c0deba180771e84dc7f7 docs(fanout): name what the land backstop is asking when it stops you
| * 4efe71b2df67fc13226376247a0297f1f99b1801 fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
| * d95b6f5c5135cde59954b0a264571b04a5f4b8d6 fix(tests): assign the helper's empty default explicitly
| * 127658708f08462fa509ffa5909b3094c840d758 fix(tests): stop the suites depending on GNU tools and on git's default branch
| * e687d8f7502ee06cda6cfeafaaced81d918a5891 fix(gates): run the shell gates under BSD sed and bash 3.2
|/  
* b913c980bda0a9ade266915b4bf527918576a4c7 docs(fanout): re-measure land contention — a lap now loses by arithmetic

commit b913c980bda0a9ade266915b4bf527918576a4c7
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:17:30 2026 +0000

    docs(fanout): re-measure land contention — a lap now loses by arithmetic
    
    The measurement recorded three hours earlier had `main` at a 487s mean gap
    against a ~170s `verify`, giving N ≈ 2.9 with the WIP cap at 2 — "at the
    ceiling", and the model held. It no longer does. Over `main`'s ten commits to
    21:09Z the mean gap is 436s while a full lap is `verify` + CI + the
    fast-forward wait, call it 8–10 minutes. CLOUD-122 lost 16 consecutive laps
    across two `mise run land` invocations, every one green on CI.
    
    The interesting half is a lap-loss shape the N model does not price. Three of
    the sixteen were the documented case — `main` moved before CI finished, the
    verdict void, cancelled early and cheap. Five were not: CI went green,
    `/fast-forward` was posted, and the bot then stayed SILENT while `main` moved.
    `land` infers a refusal from `main` moving rather than from the bot answering,
    so the log reads as a refusal that never happened. The bot is not rejecting the
    fast-forward; it is slower than `main`, and that silence is a third term the
    verify + CI lap cost never included.
    
    Raising `LAND_MAX_LAPS` buys more attempts per invocation without changing the
    per-lap odds, so it spends CI minutes against a losing bet. The lever is
    unchanged and now more urgent: shorten the lap, or quiet `main`; never add
    sessions.
    
    Refs: CLOUD-122

Rebase locally, and then force push to wenzowski/cloud-282-verify-cannot-run-on-macos.

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #330 (comment) by @​wenzowski.

Trying to fast forward main (a68878a) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574).

Target branch (main):

commit a68878a102c2e4127e98ed0f9c13ead534752e41 (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 22:00:12 2026 +0000

    docs(fanout): price the one land-contention term a cold first lap overstates
    
    CLOUD-122's re-measurement landed on `main` while this branch was lapping the
    same window, and it covers the shape better than the block this commit
    originally carried — same 15 minutes, same two lap-loss shapes, and the
    bot-silence term measured across 16 laps rather than 8. That block is dropped
    rather than restated; two accounts of one measurement is a memory that drifts.
    
    What survives is the term it does not price: cargo caches warm across laps, so
    `verify` fell from ~240s on lap 1 to 86s by lap 8 here. That moves a ~10 minute
    lap to ~7.5 against the same 7.3-minute gap, which is why re-invoking `land`
    after the cap is a different bet from raising `LAND_MAX_LAPS` — the second buys
    attempts at lap-1 odds, the first does not.
    
    Refs: CLOUD-68

Pull request (wenzowski/cloud-282-verify-cannot-run-on-macos):

commit 496c574a837c5e085b04c46c4746a9c7d7a7c112 (pull_request/wenzowski/cloud-282-verify-cannot-run-on-macos)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:59:02 2026 +0000

    fix(checksums): drop the bash-4 mapfile the new portability rule caught
    
    `no-bash4-mapfile` fired on mise-tasks/checksums:82 the first time it ran
    against a tree containing that file, which landed while this branch was in
    flight. The construct is a real defect rather than a false positive: `mapfile`
    is bash 4, macOS ships 3.2 as /bin/bash, and this task builds the checksum
    manifest for release artifacts — including the two Darwin ones.
    
    Same `while IFS= read -r` rewrite the other four sites took, and the producer
    already ends every entry with a newline, so no trailing-newline hazard applies
    here.
    
    Refs: CLOUD-282

Can't fast forward main (a68878a) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). main (a68878a) is not a direct ancestor of wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). Branches appear to have diverged at b913c98:

* a68878a102c2e4127e98ed0f9c13ead534752e41 docs(fanout): price the one land-contention term a cold first lap overstates
* 5eeedd8724a434acc7773023542cf8f00c3a3b6f feat(action): ship a GitHub Action whose empty `with:` block is the whole configuration
| * 496c574a837c5e085b04c46c4746a9c7d7a7c112 fix(checksums): drop the bash-4 mapfile the new portability rule caught
| * 8a54d149f33093c57446c0deba180771e84dc7f7 docs(fanout): name what the land backstop is asking when it stops you
| * 4efe71b2df67fc13226376247a0297f1f99b1801 fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
| * d95b6f5c5135cde59954b0a264571b04a5f4b8d6 fix(tests): assign the helper's empty default explicitly
| * 127658708f08462fa509ffa5909b3094c840d758 fix(tests): stop the suites depending on GNU tools and on git's default branch
| * e687d8f7502ee06cda6cfeafaaced81d918a5891 fix(gates): run the shell gates under BSD sed and bash 3.2
|/  
* b913c980bda0a9ade266915b4bf527918576a4c7 docs(fanout): re-measure land contention — a lap now loses by arithmetic

commit b913c980bda0a9ade266915b4bf527918576a4c7
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:17:30 2026 +0000

    docs(fanout): re-measure land contention — a lap now loses by arithmetic
    
    The measurement recorded three hours earlier had `main` at a 487s mean gap
    against a ~170s `verify`, giving N ≈ 2.9 with the WIP cap at 2 — "at the
    ceiling", and the model held. It no longer does. Over `main`'s ten commits to
    21:09Z the mean gap is 436s while a full lap is `verify` + CI + the
    fast-forward wait, call it 8–10 minutes. CLOUD-122 lost 16 consecutive laps
    across two `mise run land` invocations, every one green on CI.
    
    The interesting half is a lap-loss shape the N model does not price. Three of
    the sixteen were the documented case — `main` moved before CI finished, the
    verdict void, cancelled early and cheap. Five were not: CI went green,
    `/fast-forward` was posted, and the bot then stayed SILENT while `main` moved.
    `land` infers a refusal from `main` moving rather than from the bot answering,
    so the log reads as a refusal that never happened. The bot is not rejecting the
    fast-forward; it is slower than `main`, and that silence is a third term the
    verify + CI lap cost never included.
    
    Raising `LAND_MAX_LAPS` buys more attempts per invocation without changing the
    per-lap odds, so it spends CI minutes against a losing bet. The lever is
    unchanged and now more urgent: shorten the lap, or quiet `main`; never add
    sessions.
    
    Refs: CLOUD-122

Rebase locally, and then force push to wenzowski/cloud-282-verify-cannot-run-on-macos.

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #330 (comment) by @​wenzowski.

Trying to fast forward main (a68878a) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574).

Target branch (main):

commit a68878a102c2e4127e98ed0f9c13ead534752e41 (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 22:00:12 2026 +0000

    docs(fanout): price the one land-contention term a cold first lap overstates
    
    CLOUD-122's re-measurement landed on `main` while this branch was lapping the
    same window, and it covers the shape better than the block this commit
    originally carried — same 15 minutes, same two lap-loss shapes, and the
    bot-silence term measured across 16 laps rather than 8. That block is dropped
    rather than restated; two accounts of one measurement is a memory that drifts.
    
    What survives is the term it does not price: cargo caches warm across laps, so
    `verify` fell from ~240s on lap 1 to 86s by lap 8 here. That moves a ~10 minute
    lap to ~7.5 against the same 7.3-minute gap, which is why re-invoking `land`
    after the cap is a different bet from raising `LAND_MAX_LAPS` — the second buys
    attempts at lap-1 odds, the first does not.
    
    Refs: CLOUD-68

Pull request (wenzowski/cloud-282-verify-cannot-run-on-macos):

commit 496c574a837c5e085b04c46c4746a9c7d7a7c112 (pull_request/wenzowski/cloud-282-verify-cannot-run-on-macos)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:59:02 2026 +0000

    fix(checksums): drop the bash-4 mapfile the new portability rule caught
    
    `no-bash4-mapfile` fired on mise-tasks/checksums:82 the first time it ran
    against a tree containing that file, which landed while this branch was in
    flight. The construct is a real defect rather than a false positive: `mapfile`
    is bash 4, macOS ships 3.2 as /bin/bash, and this task builds the checksum
    manifest for release artifacts — including the two Darwin ones.
    
    Same `while IFS= read -r` rewrite the other four sites took, and the producer
    already ends every entry with a newline, so no trailing-newline hazard applies
    here.
    
    Refs: CLOUD-282

Can't fast forward main (a68878a) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). main (a68878a) is not a direct ancestor of wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). Branches appear to have diverged at b913c98:

* a68878a102c2e4127e98ed0f9c13ead534752e41 docs(fanout): price the one land-contention term a cold first lap overstates
* 5eeedd8724a434acc7773023542cf8f00c3a3b6f feat(action): ship a GitHub Action whose empty `with:` block is the whole configuration
| * 496c574a837c5e085b04c46c4746a9c7d7a7c112 fix(checksums): drop the bash-4 mapfile the new portability rule caught
| * 8a54d149f33093c57446c0deba180771e84dc7f7 docs(fanout): name what the land backstop is asking when it stops you
| * 4efe71b2df67fc13226376247a0297f1f99b1801 fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
| * d95b6f5c5135cde59954b0a264571b04a5f4b8d6 fix(tests): assign the helper's empty default explicitly
| * 127658708f08462fa509ffa5909b3094c840d758 fix(tests): stop the suites depending on GNU tools and on git's default branch
| * e687d8f7502ee06cda6cfeafaaced81d918a5891 fix(gates): run the shell gates under BSD sed and bash 3.2
|/  
* b913c980bda0a9ade266915b4bf527918576a4c7 docs(fanout): re-measure land contention — a lap now loses by arithmetic

commit b913c980bda0a9ade266915b4bf527918576a4c7
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:17:30 2026 +0000

    docs(fanout): re-measure land contention — a lap now loses by arithmetic
    
    The measurement recorded three hours earlier had `main` at a 487s mean gap
    against a ~170s `verify`, giving N ≈ 2.9 with the WIP cap at 2 — "at the
    ceiling", and the model held. It no longer does. Over `main`'s ten commits to
    21:09Z the mean gap is 436s while a full lap is `verify` + CI + the
    fast-forward wait, call it 8–10 minutes. CLOUD-122 lost 16 consecutive laps
    across two `mise run land` invocations, every one green on CI.
    
    The interesting half is a lap-loss shape the N model does not price. Three of
    the sixteen were the documented case — `main` moved before CI finished, the
    verdict void, cancelled early and cheap. Five were not: CI went green,
    `/fast-forward` was posted, and the bot then stayed SILENT while `main` moved.
    `land` infers a refusal from `main` moving rather than from the bot answering,
    so the log reads as a refusal that never happened. The bot is not rejecting the
    fast-forward; it is slower than `main`, and that silence is a third term the
    verify + CI lap cost never included.
    
    Raising `LAND_MAX_LAPS` buys more attempts per invocation without changing the
    per-lap odds, so it spends CI minutes against a losing bet. The lever is
    unchanged and now more urgent: shorten the lap, or quiet `main`; never add
    sessions.
    
    Refs: CLOUD-122

Rebase locally, and then force push to wenzowski/cloud-282-verify-cannot-run-on-macos.

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #330 (comment) by @​wenzowski.

Trying to fast forward main (a68878a) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574).

Target branch (main):

commit a68878a102c2e4127e98ed0f9c13ead534752e41 (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 22:00:12 2026 +0000

    docs(fanout): price the one land-contention term a cold first lap overstates
    
    CLOUD-122's re-measurement landed on `main` while this branch was lapping the
    same window, and it covers the shape better than the block this commit
    originally carried — same 15 minutes, same two lap-loss shapes, and the
    bot-silence term measured across 16 laps rather than 8. That block is dropped
    rather than restated; two accounts of one measurement is a memory that drifts.
    
    What survives is the term it does not price: cargo caches warm across laps, so
    `verify` fell from ~240s on lap 1 to 86s by lap 8 here. That moves a ~10 minute
    lap to ~7.5 against the same 7.3-minute gap, which is why re-invoking `land`
    after the cap is a different bet from raising `LAND_MAX_LAPS` — the second buys
    attempts at lap-1 odds, the first does not.
    
    Refs: CLOUD-68

Pull request (wenzowski/cloud-282-verify-cannot-run-on-macos):

commit 496c574a837c5e085b04c46c4746a9c7d7a7c112 (pull_request/wenzowski/cloud-282-verify-cannot-run-on-macos)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:59:02 2026 +0000

    fix(checksums): drop the bash-4 mapfile the new portability rule caught
    
    `no-bash4-mapfile` fired on mise-tasks/checksums:82 the first time it ran
    against a tree containing that file, which landed while this branch was in
    flight. The construct is a real defect rather than a false positive: `mapfile`
    is bash 4, macOS ships 3.2 as /bin/bash, and this task builds the checksum
    manifest for release artifacts — including the two Darwin ones.
    
    Same `while IFS= read -r` rewrite the other four sites took, and the producer
    already ends every entry with a newline, so no trailing-newline hazard applies
    here.
    
    Refs: CLOUD-282

Can't fast forward main (a68878a) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). main (a68878a) is not a direct ancestor of wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). Branches appear to have diverged at b913c98:

* a68878a102c2e4127e98ed0f9c13ead534752e41 docs(fanout): price the one land-contention term a cold first lap overstates
* 5eeedd8724a434acc7773023542cf8f00c3a3b6f feat(action): ship a GitHub Action whose empty `with:` block is the whole configuration
| * 496c574a837c5e085b04c46c4746a9c7d7a7c112 fix(checksums): drop the bash-4 mapfile the new portability rule caught
| * 8a54d149f33093c57446c0deba180771e84dc7f7 docs(fanout): name what the land backstop is asking when it stops you
| * 4efe71b2df67fc13226376247a0297f1f99b1801 fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
| * d95b6f5c5135cde59954b0a264571b04a5f4b8d6 fix(tests): assign the helper's empty default explicitly
| * 127658708f08462fa509ffa5909b3094c840d758 fix(tests): stop the suites depending on GNU tools and on git's default branch
| * e687d8f7502ee06cda6cfeafaaced81d918a5891 fix(gates): run the shell gates under BSD sed and bash 3.2
|/  
* b913c980bda0a9ade266915b4bf527918576a4c7 docs(fanout): re-measure land contention — a lap now loses by arithmetic

commit b913c980bda0a9ade266915b4bf527918576a4c7
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:17:30 2026 +0000

    docs(fanout): re-measure land contention — a lap now loses by arithmetic
    
    The measurement recorded three hours earlier had `main` at a 487s mean gap
    against a ~170s `verify`, giving N ≈ 2.9 with the WIP cap at 2 — "at the
    ceiling", and the model held. It no longer does. Over `main`'s ten commits to
    21:09Z the mean gap is 436s while a full lap is `verify` + CI + the
    fast-forward wait, call it 8–10 minutes. CLOUD-122 lost 16 consecutive laps
    across two `mise run land` invocations, every one green on CI.
    
    The interesting half is a lap-loss shape the N model does not price. Three of
    the sixteen were the documented case — `main` moved before CI finished, the
    verdict void, cancelled early and cheap. Five were not: CI went green,
    `/fast-forward` was posted, and the bot then stayed SILENT while `main` moved.
    `land` infers a refusal from `main` moving rather than from the bot answering,
    so the log reads as a refusal that never happened. The bot is not rejecting the
    fast-forward; it is slower than `main`, and that silence is a third term the
    verify + CI lap cost never included.
    
    Raising `LAND_MAX_LAPS` buys more attempts per invocation without changing the
    per-lap odds, so it spends CI minutes against a losing bet. The lever is
    unchanged and now more urgent: shorten the lap, or quiet `main`; never add
    sessions.
    
    Refs: CLOUD-122

Rebase locally, and then force push to wenzowski/cloud-282-verify-cannot-run-on-macos.

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #330 (comment) by @​wenzowski.

Trying to fast forward main (a68878a) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574).

Target branch (main):

commit a68878a102c2e4127e98ed0f9c13ead534752e41 (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 22:00:12 2026 +0000

    docs(fanout): price the one land-contention term a cold first lap overstates
    
    CLOUD-122's re-measurement landed on `main` while this branch was lapping the
    same window, and it covers the shape better than the block this commit
    originally carried — same 15 minutes, same two lap-loss shapes, and the
    bot-silence term measured across 16 laps rather than 8. That block is dropped
    rather than restated; two accounts of one measurement is a memory that drifts.
    
    What survives is the term it does not price: cargo caches warm across laps, so
    `verify` fell from ~240s on lap 1 to 86s by lap 8 here. That moves a ~10 minute
    lap to ~7.5 against the same 7.3-minute gap, which is why re-invoking `land`
    after the cap is a different bet from raising `LAND_MAX_LAPS` — the second buys
    attempts at lap-1 odds, the first does not.
    
    Refs: CLOUD-68

Pull request (wenzowski/cloud-282-verify-cannot-run-on-macos):

commit 496c574a837c5e085b04c46c4746a9c7d7a7c112 (pull_request/wenzowski/cloud-282-verify-cannot-run-on-macos)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:59:02 2026 +0000

    fix(checksums): drop the bash-4 mapfile the new portability rule caught
    
    `no-bash4-mapfile` fired on mise-tasks/checksums:82 the first time it ran
    against a tree containing that file, which landed while this branch was in
    flight. The construct is a real defect rather than a false positive: `mapfile`
    is bash 4, macOS ships 3.2 as /bin/bash, and this task builds the checksum
    manifest for release artifacts — including the two Darwin ones.
    
    Same `while IFS= read -r` rewrite the other four sites took, and the producer
    already ends every entry with a newline, so no trailing-newline hazard applies
    here.
    
    Refs: CLOUD-282

Can't fast forward main (a68878a) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). main (a68878a) is not a direct ancestor of wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). Branches appear to have diverged at b913c98:

* a68878a102c2e4127e98ed0f9c13ead534752e41 docs(fanout): price the one land-contention term a cold first lap overstates
* 5eeedd8724a434acc7773023542cf8f00c3a3b6f feat(action): ship a GitHub Action whose empty `with:` block is the whole configuration
| * 496c574a837c5e085b04c46c4746a9c7d7a7c112 fix(checksums): drop the bash-4 mapfile the new portability rule caught
| * 8a54d149f33093c57446c0deba180771e84dc7f7 docs(fanout): name what the land backstop is asking when it stops you
| * 4efe71b2df67fc13226376247a0297f1f99b1801 fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
| * d95b6f5c5135cde59954b0a264571b04a5f4b8d6 fix(tests): assign the helper's empty default explicitly
| * 127658708f08462fa509ffa5909b3094c840d758 fix(tests): stop the suites depending on GNU tools and on git's default branch
| * e687d8f7502ee06cda6cfeafaaced81d918a5891 fix(gates): run the shell gates under BSD sed and bash 3.2
|/  
* b913c980bda0a9ade266915b4bf527918576a4c7 docs(fanout): re-measure land contention — a lap now loses by arithmetic

commit b913c980bda0a9ade266915b4bf527918576a4c7
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:17:30 2026 +0000

    docs(fanout): re-measure land contention — a lap now loses by arithmetic
    
    The measurement recorded three hours earlier had `main` at a 487s mean gap
    against a ~170s `verify`, giving N ≈ 2.9 with the WIP cap at 2 — "at the
    ceiling", and the model held. It no longer does. Over `main`'s ten commits to
    21:09Z the mean gap is 436s while a full lap is `verify` + CI + the
    fast-forward wait, call it 8–10 minutes. CLOUD-122 lost 16 consecutive laps
    across two `mise run land` invocations, every one green on CI.
    
    The interesting half is a lap-loss shape the N model does not price. Three of
    the sixteen were the documented case — `main` moved before CI finished, the
    verdict void, cancelled early and cheap. Five were not: CI went green,
    `/fast-forward` was posted, and the bot then stayed SILENT while `main` moved.
    `land` infers a refusal from `main` moving rather than from the bot answering,
    so the log reads as a refusal that never happened. The bot is not rejecting the
    fast-forward; it is slower than `main`, and that silence is a third term the
    verify + CI lap cost never included.
    
    Raising `LAND_MAX_LAPS` buys more attempts per invocation without changing the
    per-lap odds, so it spends CI minutes against a losing bet. The lever is
    unchanged and now more urgent: shorten the lap, or quiet `main`; never add
    sessions.
    
    Refs: CLOUD-122

Rebase locally, and then force push to wenzowski/cloud-282-verify-cannot-run-on-macos.

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #330 (comment) by @​wenzowski.

Trying to fast forward main (a68878a) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574).

Target branch (main):

commit a68878a102c2e4127e98ed0f9c13ead534752e41 (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 22:00:12 2026 +0000

    docs(fanout): price the one land-contention term a cold first lap overstates
    
    CLOUD-122's re-measurement landed on `main` while this branch was lapping the
    same window, and it covers the shape better than the block this commit
    originally carried — same 15 minutes, same two lap-loss shapes, and the
    bot-silence term measured across 16 laps rather than 8. That block is dropped
    rather than restated; two accounts of one measurement is a memory that drifts.
    
    What survives is the term it does not price: cargo caches warm across laps, so
    `verify` fell from ~240s on lap 1 to 86s by lap 8 here. That moves a ~10 minute
    lap to ~7.5 against the same 7.3-minute gap, which is why re-invoking `land`
    after the cap is a different bet from raising `LAND_MAX_LAPS` — the second buys
    attempts at lap-1 odds, the first does not.
    
    Refs: CLOUD-68

Pull request (wenzowski/cloud-282-verify-cannot-run-on-macos):

commit 496c574a837c5e085b04c46c4746a9c7d7a7c112 (pull_request/wenzowski/cloud-282-verify-cannot-run-on-macos)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:59:02 2026 +0000

    fix(checksums): drop the bash-4 mapfile the new portability rule caught
    
    `no-bash4-mapfile` fired on mise-tasks/checksums:82 the first time it ran
    against a tree containing that file, which landed while this branch was in
    flight. The construct is a real defect rather than a false positive: `mapfile`
    is bash 4, macOS ships 3.2 as /bin/bash, and this task builds the checksum
    manifest for release artifacts — including the two Darwin ones.
    
    Same `while IFS= read -r` rewrite the other four sites took, and the producer
    already ends every entry with a newline, so no trailing-newline hazard applies
    here.
    
    Refs: CLOUD-282

Can't fast forward main (a68878a) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). main (a68878a) is not a direct ancestor of wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). Branches appear to have diverged at b913c98:

* a68878a102c2e4127e98ed0f9c13ead534752e41 docs(fanout): price the one land-contention term a cold first lap overstates
* 5eeedd8724a434acc7773023542cf8f00c3a3b6f feat(action): ship a GitHub Action whose empty `with:` block is the whole configuration
| * 496c574a837c5e085b04c46c4746a9c7d7a7c112 fix(checksums): drop the bash-4 mapfile the new portability rule caught
| * 8a54d149f33093c57446c0deba180771e84dc7f7 docs(fanout): name what the land backstop is asking when it stops you
| * 4efe71b2df67fc13226376247a0297f1f99b1801 fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
| * d95b6f5c5135cde59954b0a264571b04a5f4b8d6 fix(tests): assign the helper's empty default explicitly
| * 127658708f08462fa509ffa5909b3094c840d758 fix(tests): stop the suites depending on GNU tools and on git's default branch
| * e687d8f7502ee06cda6cfeafaaced81d918a5891 fix(gates): run the shell gates under BSD sed and bash 3.2
|/  
* b913c980bda0a9ade266915b4bf527918576a4c7 docs(fanout): re-measure land contention — a lap now loses by arithmetic

commit b913c980bda0a9ade266915b4bf527918576a4c7
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:17:30 2026 +0000

    docs(fanout): re-measure land contention — a lap now loses by arithmetic
    
    The measurement recorded three hours earlier had `main` at a 487s mean gap
    against a ~170s `verify`, giving N ≈ 2.9 with the WIP cap at 2 — "at the
    ceiling", and the model held. It no longer does. Over `main`'s ten commits to
    21:09Z the mean gap is 436s while a full lap is `verify` + CI + the
    fast-forward wait, call it 8–10 minutes. CLOUD-122 lost 16 consecutive laps
    across two `mise run land` invocations, every one green on CI.
    
    The interesting half is a lap-loss shape the N model does not price. Three of
    the sixteen were the documented case — `main` moved before CI finished, the
    verdict void, cancelled early and cheap. Five were not: CI went green,
    `/fast-forward` was posted, and the bot then stayed SILENT while `main` moved.
    `land` infers a refusal from `main` moving rather than from the bot answering,
    so the log reads as a refusal that never happened. The bot is not rejecting the
    fast-forward; it is slower than `main`, and that silence is a third term the
    verify + CI lap cost never included.
    
    Raising `LAND_MAX_LAPS` buys more attempts per invocation without changing the
    per-lap odds, so it spends CI minutes against a losing bet. The lever is
    unchanged and now more urgent: shorten the lap, or quiet `main`; never add
    sessions.
    
    Refs: CLOUD-122

Rebase locally, and then force push to wenzowski/cloud-282-verify-cannot-run-on-macos.

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #330 (comment) by @​wenzowski.

Trying to fast forward main (a68878a) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574).

Target branch (main):

commit a68878a102c2e4127e98ed0f9c13ead534752e41 (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 22:00:12 2026 +0000

    docs(fanout): price the one land-contention term a cold first lap overstates
    
    CLOUD-122's re-measurement landed on `main` while this branch was lapping the
    same window, and it covers the shape better than the block this commit
    originally carried — same 15 minutes, same two lap-loss shapes, and the
    bot-silence term measured across 16 laps rather than 8. That block is dropped
    rather than restated; two accounts of one measurement is a memory that drifts.
    
    What survives is the term it does not price: cargo caches warm across laps, so
    `verify` fell from ~240s on lap 1 to 86s by lap 8 here. That moves a ~10 minute
    lap to ~7.5 against the same 7.3-minute gap, which is why re-invoking `land`
    after the cap is a different bet from raising `LAND_MAX_LAPS` — the second buys
    attempts at lap-1 odds, the first does not.
    
    Refs: CLOUD-68

Pull request (wenzowski/cloud-282-verify-cannot-run-on-macos):

commit 496c574a837c5e085b04c46c4746a9c7d7a7c112 (pull_request/wenzowski/cloud-282-verify-cannot-run-on-macos)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:59:02 2026 +0000

    fix(checksums): drop the bash-4 mapfile the new portability rule caught
    
    `no-bash4-mapfile` fired on mise-tasks/checksums:82 the first time it ran
    against a tree containing that file, which landed while this branch was in
    flight. The construct is a real defect rather than a false positive: `mapfile`
    is bash 4, macOS ships 3.2 as /bin/bash, and this task builds the checksum
    manifest for release artifacts — including the two Darwin ones.
    
    Same `while IFS= read -r` rewrite the other four sites took, and the producer
    already ends every entry with a newline, so no trailing-newline hazard applies
    here.
    
    Refs: CLOUD-282

Can't fast forward main (a68878a) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). main (a68878a) is not a direct ancestor of wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). Branches appear to have diverged at b913c98:

* a68878a102c2e4127e98ed0f9c13ead534752e41 docs(fanout): price the one land-contention term a cold first lap overstates
* 5eeedd8724a434acc7773023542cf8f00c3a3b6f feat(action): ship a GitHub Action whose empty `with:` block is the whole configuration
| * 496c574a837c5e085b04c46c4746a9c7d7a7c112 fix(checksums): drop the bash-4 mapfile the new portability rule caught
| * 8a54d149f33093c57446c0deba180771e84dc7f7 docs(fanout): name what the land backstop is asking when it stops you
| * 4efe71b2df67fc13226376247a0297f1f99b1801 fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
| * d95b6f5c5135cde59954b0a264571b04a5f4b8d6 fix(tests): assign the helper's empty default explicitly
| * 127658708f08462fa509ffa5909b3094c840d758 fix(tests): stop the suites depending on GNU tools and on git's default branch
| * e687d8f7502ee06cda6cfeafaaced81d918a5891 fix(gates): run the shell gates under BSD sed and bash 3.2
|/  
* b913c980bda0a9ade266915b4bf527918576a4c7 docs(fanout): re-measure land contention — a lap now loses by arithmetic

commit b913c980bda0a9ade266915b4bf527918576a4c7
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:17:30 2026 +0000

    docs(fanout): re-measure land contention — a lap now loses by arithmetic
    
    The measurement recorded three hours earlier had `main` at a 487s mean gap
    against a ~170s `verify`, giving N ≈ 2.9 with the WIP cap at 2 — "at the
    ceiling", and the model held. It no longer does. Over `main`'s ten commits to
    21:09Z the mean gap is 436s while a full lap is `verify` + CI + the
    fast-forward wait, call it 8–10 minutes. CLOUD-122 lost 16 consecutive laps
    across two `mise run land` invocations, every one green on CI.
    
    The interesting half is a lap-loss shape the N model does not price. Three of
    the sixteen were the documented case — `main` moved before CI finished, the
    verdict void, cancelled early and cheap. Five were not: CI went green,
    `/fast-forward` was posted, and the bot then stayed SILENT while `main` moved.
    `land` infers a refusal from `main` moving rather than from the bot answering,
    so the log reads as a refusal that never happened. The bot is not rejecting the
    fast-forward; it is slower than `main`, and that silence is a third term the
    verify + CI lap cost never included.
    
    Raising `LAND_MAX_LAPS` buys more attempts per invocation without changing the
    per-lap odds, so it spends CI minutes against a losing bet. The lever is
    unchanged and now more urgent: shorten the lap, or quiet `main`; never add
    sessions.
    
    Refs: CLOUD-122

Rebase locally, and then force push to wenzowski/cloud-282-verify-cannot-run-on-macos.

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #330 (comment) by @​wenzowski.

Trying to fast forward main (99691f7) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574).

Target branch (main):

commit 99691f7ffb60a6164a18c46b47f505086f28b1dd (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 19:08:09 2026 +0000

    feat(install): ship a single-binary-first install path with a verified download
    
    Releases have carried seven target archives since CLOUD-108, with nothing on the
    consuming side: no install script, no binstall metadata, and nothing asserting
    that the asset name a consumer resolves is the one `mise-tasks/dist` writes.
    "Single-binary-first" was an ordering claim the repo could not make.
    
    install.sh is POSIX sh, assumes only what `curl … | sh` already proves is
    present, and verifies every download against the SHA-256 digest the release API
    reports — a mismatch, or an asset with no digest, installs nothing and there is
    no flag to skip it. Measured: api.github.com answers pretty-printed, so the
    parsing commits to neither wire form. The token reaches curl on stdin rather
    than argv, where ps would show it.
    
    install-check is the gate. dist owns archive naming and install.sh owns its
    target list; the gate calls both rather than scraping either, derives the matrix
    from the workflow that decides it, resolves the binstall template against the
    same answer, and fails on a committed executable.
    
    Refs: CLOUD-65

Pull request (wenzowski/cloud-282-verify-cannot-run-on-macos):

commit 496c574a837c5e085b04c46c4746a9c7d7a7c112 (pull_request/wenzowski/cloud-282-verify-cannot-run-on-macos)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:59:02 2026 +0000

    fix(checksums): drop the bash-4 mapfile the new portability rule caught
    
    `no-bash4-mapfile` fired on mise-tasks/checksums:82 the first time it ran
    against a tree containing that file, which landed while this branch was in
    flight. The construct is a real defect rather than a false positive: `mapfile`
    is bash 4, macOS ships 3.2 as /bin/bash, and this task builds the checksum
    manifest for release artifacts — including the two Darwin ones.
    
    Same `while IFS= read -r` rewrite the other four sites took, and the producer
    already ends every entry with a newline, so no trailing-newline hazard applies
    here.
    
    Refs: CLOUD-282

Can't fast forward main (99691f7) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). main (99691f7) is not a direct ancestor of wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). Branches appear to have diverged at b913c98:

* 99691f7ffb60a6164a18c46b47f505086f28b1dd feat(install): ship a single-binary-first install path with a verified download
* a68878a102c2e4127e98ed0f9c13ead534752e41 docs(fanout): price the one land-contention term a cold first lap overstates
* 5eeedd8724a434acc7773023542cf8f00c3a3b6f feat(action): ship a GitHub Action whose empty `with:` block is the whole configuration
| * 496c574a837c5e085b04c46c4746a9c7d7a7c112 fix(checksums): drop the bash-4 mapfile the new portability rule caught
| * 8a54d149f33093c57446c0deba180771e84dc7f7 docs(fanout): name what the land backstop is asking when it stops you
| * 4efe71b2df67fc13226376247a0297f1f99b1801 fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
| * d95b6f5c5135cde59954b0a264571b04a5f4b8d6 fix(tests): assign the helper's empty default explicitly
| * 127658708f08462fa509ffa5909b3094c840d758 fix(tests): stop the suites depending on GNU tools and on git's default branch
| * e687d8f7502ee06cda6cfeafaaced81d918a5891 fix(gates): run the shell gates under BSD sed and bash 3.2
|/  
* b913c980bda0a9ade266915b4bf527918576a4c7 docs(fanout): re-measure land contention — a lap now loses by arithmetic

commit b913c980bda0a9ade266915b4bf527918576a4c7
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:17:30 2026 +0000

    docs(fanout): re-measure land contention — a lap now loses by arithmetic
    
    The measurement recorded three hours earlier had `main` at a 487s mean gap
    against a ~170s `verify`, giving N ≈ 2.9 with the WIP cap at 2 — "at the
    ceiling", and the model held. It no longer does. Over `main`'s ten commits to
    21:09Z the mean gap is 436s while a full lap is `verify` + CI + the
    fast-forward wait, call it 8–10 minutes. CLOUD-122 lost 16 consecutive laps
    across two `mise run land` invocations, every one green on CI.
    
    The interesting half is a lap-loss shape the N model does not price. Three of
    the sixteen were the documented case — `main` moved before CI finished, the
    verdict void, cancelled early and cheap. Five were not: CI went green,
    `/fast-forward` was posted, and the bot then stayed SILENT while `main` moved.
    `land` infers a refusal from `main` moving rather than from the bot answering,
    so the log reads as a refusal that never happened. The bot is not rejecting the
    fast-forward; it is slower than `main`, and that silence is a third term the
    verify + CI lap cost never included.
    
    Raising `LAND_MAX_LAPS` buys more attempts per invocation without changing the
    per-lap odds, so it spends CI minutes against a losing bet. The lever is
    unchanged and now more urgent: shorten the lap, or quiet `main`; never add
    sessions.
    
    Refs: CLOUD-122

Rebase locally, and then force push to wenzowski/cloud-282-verify-cannot-run-on-macos.

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #330 (comment) by @​wenzowski.

Trying to fast forward main (99691f7) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574).

Target branch (main):

commit 99691f7ffb60a6164a18c46b47f505086f28b1dd (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 19:08:09 2026 +0000

    feat(install): ship a single-binary-first install path with a verified download
    
    Releases have carried seven target archives since CLOUD-108, with nothing on the
    consuming side: no install script, no binstall metadata, and nothing asserting
    that the asset name a consumer resolves is the one `mise-tasks/dist` writes.
    "Single-binary-first" was an ordering claim the repo could not make.
    
    install.sh is POSIX sh, assumes only what `curl … | sh` already proves is
    present, and verifies every download against the SHA-256 digest the release API
    reports — a mismatch, or an asset with no digest, installs nothing and there is
    no flag to skip it. Measured: api.github.com answers pretty-printed, so the
    parsing commits to neither wire form. The token reaches curl on stdin rather
    than argv, where ps would show it.
    
    install-check is the gate. dist owns archive naming and install.sh owns its
    target list; the gate calls both rather than scraping either, derives the matrix
    from the workflow that decides it, resolves the binstall template against the
    same answer, and fails on a committed executable.
    
    Refs: CLOUD-65

Pull request (wenzowski/cloud-282-verify-cannot-run-on-macos):

commit 496c574a837c5e085b04c46c4746a9c7d7a7c112 (pull_request/wenzowski/cloud-282-verify-cannot-run-on-macos)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:59:02 2026 +0000

    fix(checksums): drop the bash-4 mapfile the new portability rule caught
    
    `no-bash4-mapfile` fired on mise-tasks/checksums:82 the first time it ran
    against a tree containing that file, which landed while this branch was in
    flight. The construct is a real defect rather than a false positive: `mapfile`
    is bash 4, macOS ships 3.2 as /bin/bash, and this task builds the checksum
    manifest for release artifacts — including the two Darwin ones.
    
    Same `while IFS= read -r` rewrite the other four sites took, and the producer
    already ends every entry with a newline, so no trailing-newline hazard applies
    here.
    
    Refs: CLOUD-282

Can't fast forward main (99691f7) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). main (99691f7) is not a direct ancestor of wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). Branches appear to have diverged at b913c98:

* 99691f7ffb60a6164a18c46b47f505086f28b1dd feat(install): ship a single-binary-first install path with a verified download
* a68878a102c2e4127e98ed0f9c13ead534752e41 docs(fanout): price the one land-contention term a cold first lap overstates
* 5eeedd8724a434acc7773023542cf8f00c3a3b6f feat(action): ship a GitHub Action whose empty `with:` block is the whole configuration
| * 496c574a837c5e085b04c46c4746a9c7d7a7c112 fix(checksums): drop the bash-4 mapfile the new portability rule caught
| * 8a54d149f33093c57446c0deba180771e84dc7f7 docs(fanout): name what the land backstop is asking when it stops you
| * 4efe71b2df67fc13226376247a0297f1f99b1801 fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
| * d95b6f5c5135cde59954b0a264571b04a5f4b8d6 fix(tests): assign the helper's empty default explicitly
| * 127658708f08462fa509ffa5909b3094c840d758 fix(tests): stop the suites depending on GNU tools and on git's default branch
| * e687d8f7502ee06cda6cfeafaaced81d918a5891 fix(gates): run the shell gates under BSD sed and bash 3.2
|/  
* b913c980bda0a9ade266915b4bf527918576a4c7 docs(fanout): re-measure land contention — a lap now loses by arithmetic

commit b913c980bda0a9ade266915b4bf527918576a4c7
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:17:30 2026 +0000

    docs(fanout): re-measure land contention — a lap now loses by arithmetic
    
    The measurement recorded three hours earlier had `main` at a 487s mean gap
    against a ~170s `verify`, giving N ≈ 2.9 with the WIP cap at 2 — "at the
    ceiling", and the model held. It no longer does. Over `main`'s ten commits to
    21:09Z the mean gap is 436s while a full lap is `verify` + CI + the
    fast-forward wait, call it 8–10 minutes. CLOUD-122 lost 16 consecutive laps
    across two `mise run land` invocations, every one green on CI.
    
    The interesting half is a lap-loss shape the N model does not price. Three of
    the sixteen were the documented case — `main` moved before CI finished, the
    verdict void, cancelled early and cheap. Five were not: CI went green,
    `/fast-forward` was posted, and the bot then stayed SILENT while `main` moved.
    `land` infers a refusal from `main` moving rather than from the bot answering,
    so the log reads as a refusal that never happened. The bot is not rejecting the
    fast-forward; it is slower than `main`, and that silence is a third term the
    verify + CI lap cost never included.
    
    Raising `LAND_MAX_LAPS` buys more attempts per invocation without changing the
    per-lap odds, so it spends CI minutes against a losing bet. The lever is
    unchanged and now more urgent: shorten the lap, or quiet `main`; never add
    sessions.
    
    Refs: CLOUD-122

Rebase locally, and then force push to wenzowski/cloud-282-verify-cannot-run-on-macos.

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #330 (comment) by @​wenzowski.

Trying to fast forward main (99691f7) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574).

Target branch (main):

commit 99691f7ffb60a6164a18c46b47f505086f28b1dd (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 19:08:09 2026 +0000

    feat(install): ship a single-binary-first install path with a verified download
    
    Releases have carried seven target archives since CLOUD-108, with nothing on the
    consuming side: no install script, no binstall metadata, and nothing asserting
    that the asset name a consumer resolves is the one `mise-tasks/dist` writes.
    "Single-binary-first" was an ordering claim the repo could not make.
    
    install.sh is POSIX sh, assumes only what `curl … | sh` already proves is
    present, and verifies every download against the SHA-256 digest the release API
    reports — a mismatch, or an asset with no digest, installs nothing and there is
    no flag to skip it. Measured: api.github.com answers pretty-printed, so the
    parsing commits to neither wire form. The token reaches curl on stdin rather
    than argv, where ps would show it.
    
    install-check is the gate. dist owns archive naming and install.sh owns its
    target list; the gate calls both rather than scraping either, derives the matrix
    from the workflow that decides it, resolves the binstall template against the
    same answer, and fails on a committed executable.
    
    Refs: CLOUD-65

Pull request (wenzowski/cloud-282-verify-cannot-run-on-macos):

commit 496c574a837c5e085b04c46c4746a9c7d7a7c112 (pull_request/wenzowski/cloud-282-verify-cannot-run-on-macos)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:59:02 2026 +0000

    fix(checksums): drop the bash-4 mapfile the new portability rule caught
    
    `no-bash4-mapfile` fired on mise-tasks/checksums:82 the first time it ran
    against a tree containing that file, which landed while this branch was in
    flight. The construct is a real defect rather than a false positive: `mapfile`
    is bash 4, macOS ships 3.2 as /bin/bash, and this task builds the checksum
    manifest for release artifacts — including the two Darwin ones.
    
    Same `while IFS= read -r` rewrite the other four sites took, and the producer
    already ends every entry with a newline, so no trailing-newline hazard applies
    here.
    
    Refs: CLOUD-282

Can't fast forward main (99691f7) to wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). main (99691f7) is not a direct ancestor of wenzowski/cloud-282-verify-cannot-run-on-macos (496c574). Branches appear to have diverged at b913c98:

* 99691f7ffb60a6164a18c46b47f505086f28b1dd feat(install): ship a single-binary-first install path with a verified download
* a68878a102c2e4127e98ed0f9c13ead534752e41 docs(fanout): price the one land-contention term a cold first lap overstates
* 5eeedd8724a434acc7773023542cf8f00c3a3b6f feat(action): ship a GitHub Action whose empty `with:` block is the whole configuration
| * 496c574a837c5e085b04c46c4746a9c7d7a7c112 fix(checksums): drop the bash-4 mapfile the new portability rule caught
| * 8a54d149f33093c57446c0deba180771e84dc7f7 docs(fanout): name what the land backstop is asking when it stops you
| * 4efe71b2df67fc13226376247a0297f1f99b1801 fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
| * d95b6f5c5135cde59954b0a264571b04a5f4b8d6 fix(tests): assign the helper's empty default explicitly
| * 127658708f08462fa509ffa5909b3094c840d758 fix(tests): stop the suites depending on GNU tools and on git's default branch
| * e687d8f7502ee06cda6cfeafaaced81d918a5891 fix(gates): run the shell gates under BSD sed and bash 3.2
|/  
* b913c980bda0a9ade266915b4bf527918576a4c7 docs(fanout): re-measure land contention — a lap now loses by arithmetic

commit b913c980bda0a9ade266915b4bf527918576a4c7
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:17:30 2026 +0000

    docs(fanout): re-measure land contention — a lap now loses by arithmetic
    
    The measurement recorded three hours earlier had `main` at a 487s mean gap
    against a ~170s `verify`, giving N ≈ 2.9 with the WIP cap at 2 — "at the
    ceiling", and the model held. It no longer does. Over `main`'s ten commits to
    21:09Z the mean gap is 436s while a full lap is `verify` + CI + the
    fast-forward wait, call it 8–10 minutes. CLOUD-122 lost 16 consecutive laps
    across two `mise run land` invocations, every one green on CI.
    
    The interesting half is a lap-loss shape the N model does not price. Three of
    the sixteen were the documented case — `main` moved before CI finished, the
    verdict void, cancelled early and cheap. Five were not: CI went green,
    `/fast-forward` was posted, and the bot then stayed SILENT while `main` moved.
    `land` infers a refusal from `main` moving rather than from the bot answering,
    so the log reads as a refusal that never happened. The bot is not rejecting the
    fast-forward; it is slower than `main`, and that silence is a third term the
    verify + CI lap cost never included.
    
    Raising `LAND_MAX_LAPS` buys more attempts per invocation without changing the
    per-lap odds, so it spends CI minutes against a losing bet. The lever is
    unchanged and now more urgent: shorten the lap, or quiet `main`; never add
    sessions.
    
    Refs: CLOUD-122

Rebase locally, and then force push to wenzowski/cloud-282-verify-cannot-run-on-macos.

@wenzowski
wenzowski force-pushed the wenzowski/cloud-282-verify-cannot-run-on-macos branch from 496c574 to b6d0ebe Compare August 11, 2026 23:45
@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #330 (comment) by @​wenzowski.

Trying to fast forward main (99691f7) to wenzowski/cloud-282-verify-cannot-run-on-macos (b6d0ebe).

Target branch (main):

commit 99691f7ffb60a6164a18c46b47f505086f28b1dd (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 19:08:09 2026 +0000

    feat(install): ship a single-binary-first install path with a verified download
    
    Releases have carried seven target archives since CLOUD-108, with nothing on the
    consuming side: no install script, no binstall metadata, and nothing asserting
    that the asset name a consumer resolves is the one `mise-tasks/dist` writes.
    "Single-binary-first" was an ordering claim the repo could not make.
    
    install.sh is POSIX sh, assumes only what `curl … | sh` already proves is
    present, and verifies every download against the SHA-256 digest the release API
    reports — a mismatch, or an asset with no digest, installs nothing and there is
    no flag to skip it. Measured: api.github.com answers pretty-printed, so the
    parsing commits to neither wire form. The token reaches curl on stdin rather
    than argv, where ps would show it.
    
    install-check is the gate. dist owns archive naming and install.sh owns its
    target list; the gate calls both rather than scraping either, derives the matrix
    from the workflow that decides it, resolves the binstall template against the
    same answer, and fails on a committed executable.
    
    Refs: CLOUD-65

Pull request (wenzowski/cloud-282-verify-cannot-run-on-macos):

commit b6d0ebeee5c06bb3c5663037e53f6502102097c8 (pull_request/wenzowski/cloud-282-verify-cannot-run-on-macos)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:59:02 2026 +0000

    fix(checksums): drop the bash-4 mapfile the new portability rule caught
    
    `no-bash4-mapfile` fired on mise-tasks/checksums:82 the first time it ran
    against a tree containing that file, which landed while this branch was in
    flight. The construct is a real defect rather than a false positive: `mapfile`
    is bash 4, macOS ships 3.2 as /bin/bash, and this task builds the checksum
    manifest for release artifacts — including the two Darwin ones.
    
    Same `while IFS= read -r` rewrite the other four sites took, and the producer
    already ends every entry with a newline, so no trailing-newline hazard applies
    here.
    
    Refs: CLOUD-282

Fast forwarding main (99691f7) to wenzowski/cloud-282-verify-cannot-run-on-macos (b6d0ebe).

$ git push origin b6d0ebeee5c06bb3c5663037e53f6502102097c8:main
remote: error: GH013: Repository rule violations found for refs/heads/main.        
remote: Review all repository rules at https://github.com/button-inc/batten/rules?ref=refs%2Fheads%2Fmain        
remote: 
remote: - Required status check "final" is expected.        
remote: 
To https://github.com/button-inc/batten.git
 ! [remote rejected] b6d0ebeee5c06bb3c5663037e53f6502102097c8 -> main (push declined due to repository rule violations)
error: failed to push some refs to 'https://github.com/button-inc/batten.git'

@wenzowski

Copy link
Copy Markdown
Contributor Author

/fast-forward

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #330 (comment) by @​wenzowski.

Trying to fast forward main (cb33457) to wenzowski/cloud-282-verify-cannot-run-on-macos (b6d0ebe).

Target branch (main):

commit cb33457bb0f55404dd0448285a3982e1f130f14a (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 20:57:12 2026 +0000

    fix(cross-check): type-check test code too, so the cross-platform claim covers it
    
    `cargo check` without `--all-targets` compiles the default target set — lib and
    bins. No `#[cfg(test)]` module, nothing under `tests/`. So the gate carrying
    this repository's cross-platform claim had never once type-checked the ~440
    integration tests and the unit suites against `x86_64-pc-windows-gnu`.
    
    That is the half most likely to break. Platform-specific code in the library is
    deliberate and already `#[cfg(unix)]`-gated — 32 sites across exec.rs,
    provision.rs, markers.rs and the suites — while test code reaches for
    `PermissionsExt`, `#!/bin/sh` fixtures and Unix paths as a matter of course. A
    test using a Unix-only API without that gate compiled fine here forever.
    
    Measured before changing anything: `cargo check --workspace --all-targets
    --target x86_64-pc-windows-gnu` already exits 0 on this tree. That is the point
    of adding the flag now rather than later — the property held by luck, and this
    is the mechanism that makes it hold on purpose, before CLOUD-113 puts a real
    Windows runner behind it.
    
    `tests/cross-check.bats` asserts the flag over the committed task body rather
    than over a run, because a green `cross-check` cannot tell the two coverages
    apart — which is exactly how the narrower one survived. It holds every `cargo
    check` in the body, not merely one, so a second triple added later carries the
    same coverage; and it holds the task to `check`, never `build`/`test`/`run`,
    since codegen-to-metadata is what makes a foreign triple affordable on a Linux
    runner with no target linker.
    
    Refs: CLOUD-395

Pull request (wenzowski/cloud-282-verify-cannot-run-on-macos):

commit b6d0ebeee5c06bb3c5663037e53f6502102097c8 (pull_request/wenzowski/cloud-282-verify-cannot-run-on-macos)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:59:02 2026 +0000

    fix(checksums): drop the bash-4 mapfile the new portability rule caught
    
    `no-bash4-mapfile` fired on mise-tasks/checksums:82 the first time it ran
    against a tree containing that file, which landed while this branch was in
    flight. The construct is a real defect rather than a false positive: `mapfile`
    is bash 4, macOS ships 3.2 as /bin/bash, and this task builds the checksum
    manifest for release artifacts — including the two Darwin ones.
    
    Same `while IFS= read -r` rewrite the other four sites took, and the producer
    already ends every entry with a newline, so no trailing-newline hazard applies
    here.
    
    Refs: CLOUD-282

Can't fast forward main (cb33457) to wenzowski/cloud-282-verify-cannot-run-on-macos (b6d0ebe). main (cb33457) is not a direct ancestor of wenzowski/cloud-282-verify-cannot-run-on-macos (b6d0ebe). Branches appear to have diverged at 99691f7:

* b6d0ebeee5c06bb3c5663037e53f6502102097c8 fix(checksums): drop the bash-4 mapfile the new portability rule caught
* c3d6e0f11dcb45f07d3c81a1fa88845ab4bca164 docs(fanout): name what the land backstop is asking when it stops you
* bcf0a12a9a2f21cdd00358f6062839bbfe087544 fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
* 4477edd2651fc4d8f0daa4d842f8c40bff78a385 fix(tests): assign the helper's empty default explicitly
* e2f23439e2aed9899197c5ec18ba17a00203ed49 fix(tests): stop the suites depending on GNU tools and on git's default branch
* 8dabb2b657d8907bba59c4ffe10ba2855289d585 fix(gates): run the shell gates under BSD sed and bash 3.2
| * cb33457bb0f55404dd0448285a3982e1f130f14a fix(cross-check): type-check test code too, so the cross-platform claim covers it
|/  
* 99691f7ffb60a6164a18c46b47f505086f28b1dd feat(install): ship a single-binary-first install path with a verified download

commit 99691f7ffb60a6164a18c46b47f505086f28b1dd
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 19:08:09 2026 +0000

    feat(install): ship a single-binary-first install path with a verified download
    
    Releases have carried seven target archives since CLOUD-108, with nothing on the
    consuming side: no install script, no binstall metadata, and nothing asserting
    that the asset name a consumer resolves is the one `mise-tasks/dist` writes.
    "Single-binary-first" was an ordering claim the repo could not make.
    
    install.sh is POSIX sh, assumes only what `curl … | sh` already proves is
    present, and verifies every download against the SHA-256 digest the release API
    reports — a mismatch, or an asset with no digest, installs nothing and there is
    no flag to skip it. Measured: api.github.com answers pretty-printed, so the
    parsing commits to neither wire form. The token reaches curl on stdin rather
    than argv, where ps would show it.
    
    install-check is the gate. dist owns archive naming and install.sh owns its
    target list; the gate calls both rather than scraping either, derives the matrix
    from the workflow that decides it, resolves the binstall template against the
    same answer, and fails on a committed executable.
    
    Refs: CLOUD-65

Rebase locally, and then force push to wenzowski/cloud-282-verify-cannot-run-on-macos.

@wenzowski
wenzowski force-pushed the wenzowski/cloud-282-verify-cannot-run-on-macos branch from b6d0ebe to e3dc070 Compare August 11, 2026 23:52
@wenzowski

Copy link
Copy Markdown
Contributor Author

/fast-forward

1 similar comment
@wenzowski

Copy link
Copy Markdown
Contributor Author

/fast-forward

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #330 (comment) by @​wenzowski.

Trying to fast forward main (a01f3af) to wenzowski/cloud-282-verify-cannot-run-on-macos (e3dc070).

Target branch (main):

commit a01f3af6654eca5cd2a89c22ac65085c1f259346 (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 19:17:18 2026 +0000

    test(markers): assert the permission drop landed, and audit every site that needs one
    
    `an_unreadable_file_propagates_through_the_walk` wrote a fixture, dropped it
    to `0o000` and asserted the read fails. It passed, and could not have failed:
    the suite runs as root, root ignores the permission bits, `read_to_string`
    succeeded, and the branch under test was never entered. A green suite
    certified the CLOUD-241 fix without exercising it. The early return that
    followed only converted a silent pass into a silent skip.
    
    So a permission drop is treated as a premise, and the order is the discipline:
    drop the bits, assert the drop landed (true for every caller including root),
    read back to decide whether the conclusion is reachable at all, and only then
    assert the conclusion.
    
    `every_permission_drop_asserts_its_own_premise` holds that over every
    `from_mode(0o000)` site in `src/` and `tests/`, and is exercised before it is
    trusted — three inline fixtures, one compliant and two carrying the shapes
    that really shipped, so an audit that cannot fail cannot certify. It refuses a
    scan that read no files or found no site to judge. `from_mode(0o755)` is out
    of scope: a grant that fails to bite fails its own test loudly.
    
    Refs: CLOUD-249

Pull request (wenzowski/cloud-282-verify-cannot-run-on-macos):

commit e3dc070134464a5f918053622f887c3b08013e7e (pull_request/wenzowski/cloud-282-verify-cannot-run-on-macos)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:59:02 2026 +0000

    fix(checksums): drop the bash-4 mapfile the new portability rule caught
    
    `no-bash4-mapfile` fired on mise-tasks/checksums:82 the first time it ran
    against a tree containing that file, which landed while this branch was in
    flight. The construct is a real defect rather than a false positive: `mapfile`
    is bash 4, macOS ships 3.2 as /bin/bash, and this task builds the checksum
    manifest for release artifacts — including the two Darwin ones.
    
    Same `while IFS= read -r` rewrite the other four sites took, and the producer
    already ends every entry with a newline, so no trailing-newline hazard applies
    here.
    
    Refs: CLOUD-282

Can't fast forward main (a01f3af) to wenzowski/cloud-282-verify-cannot-run-on-macos (e3dc070). main (a01f3af) is not a direct ancestor of wenzowski/cloud-282-verify-cannot-run-on-macos (e3dc070). Branches appear to have diverged at cb33457:

* e3dc070134464a5f918053622f887c3b08013e7e fix(checksums): drop the bash-4 mapfile the new portability rule caught
* ab176c915d14b7cc828d02714109319bf19b6b72 docs(fanout): name what the land backstop is asking when it stops you
* 9b61321af9c5bfd97008e700341d32d0ea7040f5 fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
* 694b0770fb26b89da6c3f42b790bd808a47f77ab fix(tests): assign the helper's empty default explicitly
* 419bfc3821a439a5b00b24e8364e8790114c840f fix(tests): stop the suites depending on GNU tools and on git's default branch
* 79658c36c835d5917aa14c69bc6f803808a835b6 fix(gates): run the shell gates under BSD sed and bash 3.2
| * a01f3af6654eca5cd2a89c22ac65085c1f259346 test(markers): assert the permission drop landed, and audit every site that needs one
|/  
* cb33457bb0f55404dd0448285a3982e1f130f14a fix(cross-check): type-check test code too, so the cross-platform claim covers it

commit cb33457bb0f55404dd0448285a3982e1f130f14a
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 20:57:12 2026 +0000

    fix(cross-check): type-check test code too, so the cross-platform claim covers it
    
    `cargo check` without `--all-targets` compiles the default target set — lib and
    bins. No `#[cfg(test)]` module, nothing under `tests/`. So the gate carrying
    this repository's cross-platform claim had never once type-checked the ~440
    integration tests and the unit suites against `x86_64-pc-windows-gnu`.
    
    That is the half most likely to break. Platform-specific code in the library is
    deliberate and already `#[cfg(unix)]`-gated — 32 sites across exec.rs,
    provision.rs, markers.rs and the suites — while test code reaches for
    `PermissionsExt`, `#!/bin/sh` fixtures and Unix paths as a matter of course. A
    test using a Unix-only API without that gate compiled fine here forever.
    
    Measured before changing anything: `cargo check --workspace --all-targets
    --target x86_64-pc-windows-gnu` already exits 0 on this tree. That is the point
    of adding the flag now rather than later — the property held by luck, and this
    is the mechanism that makes it hold on purpose, before CLOUD-113 puts a real
    Windows runner behind it.
    
    `tests/cross-check.bats` asserts the flag over the committed task body rather
    than over a run, because a green `cross-check` cannot tell the two coverages
    apart — which is exactly how the narrower one survived. It holds every `cargo
    check` in the body, not merely one, so a second triple added later carries the
    same coverage; and it holds the task to `check`, never `build`/`test`/`run`,
    since codegen-to-metadata is what makes a foreign triple affordable on a Linux
    runner with no target linker.
    
    Refs: CLOUD-395

Rebase locally, and then force push to wenzowski/cloud-282-verify-cannot-run-on-macos.

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #330 (comment) by @​wenzowski.

Trying to fast forward main (a01f3af) to wenzowski/cloud-282-verify-cannot-run-on-macos (e3dc070).

Target branch (main):

commit a01f3af6654eca5cd2a89c22ac65085c1f259346 (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 19:17:18 2026 +0000

    test(markers): assert the permission drop landed, and audit every site that needs one
    
    `an_unreadable_file_propagates_through_the_walk` wrote a fixture, dropped it
    to `0o000` and asserted the read fails. It passed, and could not have failed:
    the suite runs as root, root ignores the permission bits, `read_to_string`
    succeeded, and the branch under test was never entered. A green suite
    certified the CLOUD-241 fix without exercising it. The early return that
    followed only converted a silent pass into a silent skip.
    
    So a permission drop is treated as a premise, and the order is the discipline:
    drop the bits, assert the drop landed (true for every caller including root),
    read back to decide whether the conclusion is reachable at all, and only then
    assert the conclusion.
    
    `every_permission_drop_asserts_its_own_premise` holds that over every
    `from_mode(0o000)` site in `src/` and `tests/`, and is exercised before it is
    trusted — three inline fixtures, one compliant and two carrying the shapes
    that really shipped, so an audit that cannot fail cannot certify. It refuses a
    scan that read no files or found no site to judge. `from_mode(0o755)` is out
    of scope: a grant that fails to bite fails its own test loudly.
    
    Refs: CLOUD-249

Pull request (wenzowski/cloud-282-verify-cannot-run-on-macos):

commit e3dc070134464a5f918053622f887c3b08013e7e (pull_request/wenzowski/cloud-282-verify-cannot-run-on-macos)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:59:02 2026 +0000

    fix(checksums): drop the bash-4 mapfile the new portability rule caught
    
    `no-bash4-mapfile` fired on mise-tasks/checksums:82 the first time it ran
    against a tree containing that file, which landed while this branch was in
    flight. The construct is a real defect rather than a false positive: `mapfile`
    is bash 4, macOS ships 3.2 as /bin/bash, and this task builds the checksum
    manifest for release artifacts — including the two Darwin ones.
    
    Same `while IFS= read -r` rewrite the other four sites took, and the producer
    already ends every entry with a newline, so no trailing-newline hazard applies
    here.
    
    Refs: CLOUD-282

Can't fast forward main (a01f3af) to wenzowski/cloud-282-verify-cannot-run-on-macos (e3dc070). main (a01f3af) is not a direct ancestor of wenzowski/cloud-282-verify-cannot-run-on-macos (e3dc070). Branches appear to have diverged at cb33457:

* e3dc070134464a5f918053622f887c3b08013e7e fix(checksums): drop the bash-4 mapfile the new portability rule caught
* ab176c915d14b7cc828d02714109319bf19b6b72 docs(fanout): name what the land backstop is asking when it stops you
* 9b61321af9c5bfd97008e700341d32d0ea7040f5 fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
* 694b0770fb26b89da6c3f42b790bd808a47f77ab fix(tests): assign the helper's empty default explicitly
* 419bfc3821a439a5b00b24e8364e8790114c840f fix(tests): stop the suites depending on GNU tools and on git's default branch
* 79658c36c835d5917aa14c69bc6f803808a835b6 fix(gates): run the shell gates under BSD sed and bash 3.2
| * a01f3af6654eca5cd2a89c22ac65085c1f259346 test(markers): assert the permission drop landed, and audit every site that needs one
|/  
* cb33457bb0f55404dd0448285a3982e1f130f14a fix(cross-check): type-check test code too, so the cross-platform claim covers it

commit cb33457bb0f55404dd0448285a3982e1f130f14a
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 20:57:12 2026 +0000

    fix(cross-check): type-check test code too, so the cross-platform claim covers it
    
    `cargo check` without `--all-targets` compiles the default target set — lib and
    bins. No `#[cfg(test)]` module, nothing under `tests/`. So the gate carrying
    this repository's cross-platform claim had never once type-checked the ~440
    integration tests and the unit suites against `x86_64-pc-windows-gnu`.
    
    That is the half most likely to break. Platform-specific code in the library is
    deliberate and already `#[cfg(unix)]`-gated — 32 sites across exec.rs,
    provision.rs, markers.rs and the suites — while test code reaches for
    `PermissionsExt`, `#!/bin/sh` fixtures and Unix paths as a matter of course. A
    test using a Unix-only API without that gate compiled fine here forever.
    
    Measured before changing anything: `cargo check --workspace --all-targets
    --target x86_64-pc-windows-gnu` already exits 0 on this tree. That is the point
    of adding the flag now rather than later — the property held by luck, and this
    is the mechanism that makes it hold on purpose, before CLOUD-113 puts a real
    Windows runner behind it.
    
    `tests/cross-check.bats` asserts the flag over the committed task body rather
    than over a run, because a green `cross-check` cannot tell the two coverages
    apart — which is exactly how the narrower one survived. It holds every `cargo
    check` in the body, not merely one, so a second triple added later carries the
    same coverage; and it holds the task to `check`, never `build`/`test`/`run`,
    since codegen-to-metadata is what makes a foreign triple affordable on a Linux
    runner with no target linker.
    
    Refs: CLOUD-395

Rebase locally, and then force push to wenzowski/cloud-282-verify-cannot-run-on-macos.

@wenzowski
wenzowski force-pushed the wenzowski/cloud-282-verify-cannot-run-on-macos branch from e3dc070 to 650fda8 Compare August 11, 2026 23:59
@wenzowski

Copy link
Copy Markdown
Contributor Author

/fast-forward

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #330 (comment) by @​wenzowski.

Trying to fast forward main (2643c83) to wenzowski/cloud-282-verify-cannot-run-on-macos (650fda8).

Target branch (main):

commit 2643c83493494fed2af86723630c2e8742aa1812 (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 20:26:48 2026 +0000

    chore(completions): regenerate for the merged surface
    
    The rebase put `design audit` and a sibling's `lint brief` into one surface,
    and a generated artifact cannot be resolved by picking a side — neither
    committed copy described the tree that now exists. Regenerated from the
    binary, which is what `completions-check` diffs against.
    
    Refs: CLOUD-53

Pull request (wenzowski/cloud-282-verify-cannot-run-on-macos):

commit 650fda8816fbe24155cc2b56ead3c9bbe305a342 (pull_request/wenzowski/cloud-282-verify-cannot-run-on-macos)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 21:59:02 2026 +0000

    fix(checksums): drop the bash-4 mapfile the new portability rule caught
    
    `no-bash4-mapfile` fired on mise-tasks/checksums:82 the first time it ran
    against a tree containing that file, which landed while this branch was in
    flight. The construct is a real defect rather than a false positive: `mapfile`
    is bash 4, macOS ships 3.2 as /bin/bash, and this task builds the checksum
    manifest for release artifacts — including the two Darwin ones.
    
    Same `while IFS= read -r` rewrite the other four sites took, and the producer
    already ends every entry with a newline, so no trailing-newline hazard applies
    here.
    
    Refs: CLOUD-282

Can't fast forward main (2643c83) to wenzowski/cloud-282-verify-cannot-run-on-macos (650fda8). main (2643c83) is not a direct ancestor of wenzowski/cloud-282-verify-cannot-run-on-macos (650fda8). Branches appear to have diverged at a01f3af:

* 650fda8816fbe24155cc2b56ead3c9bbe305a342 fix(checksums): drop the bash-4 mapfile the new portability rule caught
* 02e5e4b8856942027edf86e4b34a52a08a95307e docs(fanout): name what the land backstop is asking when it stops you
* f4a1b99ec0acae8f7247797abc1c9f6987d1740f fix(hk): cover mise-tasks/* in batten-check's glob, as the new rows demand
* 9a8304f1732dece6db4cc3165b47af31f8daecc6 fix(tests): assign the helper's empty default explicitly
* aea3044139576d14c0be7b6abc0cebcf7633d52e fix(tests): stop the suites depending on GNU tools and on git's default branch
* 7bf20182a38382431189759cc3eeed311c8a7db1 fix(gates): run the shell gates under BSD sed and bash 3.2
| * 2643c83493494fed2af86723630c2e8742aa1812 chore(completions): regenerate for the merged surface
| * 32081573cf28254789cb5e7a27a6ca037cb63385 style(design): rustfmt the module and its suite
| * 274d8dc9f90ccf219040fa684e3cc9abb66c8118 test(design): drive every acceptance bullet through the compiled binary
| * 406d54abd073b4339f5a266973865001d2e5d08a feat(design): audit a design-evidence claim stream for record integrity
|/  
* a01f3af6654eca5cd2a89c22ac65085c1f259346 test(markers): assert the permission drop landed, and audit every site that needs one

commit a01f3af6654eca5cd2a89c22ac65085c1f259346
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 19:17:18 2026 +0000

    test(markers): assert the permission drop landed, and audit every site that needs one
    
    `an_unreadable_file_propagates_through_the_walk` wrote a fixture, dropped it
    to `0o000` and asserted the read fails. It passed, and could not have failed:
    the suite runs as root, root ignores the permission bits, `read_to_string`
    succeeded, and the branch under test was never entered. A green suite
    certified the CLOUD-241 fix without exercising it. The early return that
    followed only converted a silent pass into a silent skip.
    
    So a permission drop is treated as a premise, and the order is the discipline:
    drop the bits, assert the drop landed (true for every caller including root),
    read back to decide whether the conclusion is reachable at all, and only then
    assert the conclusion.
    
    `every_permission_drop_asserts_its_own_premise` holds that over every
    `from_mode(0o000)` site in `src/` and `tests/`, and is exercised before it is
    trusted — three inline fixtures, one compliant and two carrying the shapes
    that really shipped, so an audit that cannot fail cannot certify. It refuses a
    scan that read no files or found no site to judge. `from_mode(0o755)` is out
    of scope: a grant that fails to bite fails its own test loudly.
    
    Refs: CLOUD-249

Rebase locally, and then force push to wenzowski/cloud-282-verify-cannot-run-on-macos.

@wenzowski
wenzowski force-pushed the wenzowski/cloud-282-verify-cannot-run-on-macos branch from 650fda8 to 56a1e7a Compare August 12, 2026 00:05
wenzowski pushed a commit that referenced this pull request Aug 12, 2026
…non-answers

Four defects in one poll, landed together because they are one control flow.

CLOUD-409 / CLOUD-456 — THE VERDICT HAD NO KEY. An `issue_comment` run attaches
to the default-branch tip, so `head_branch` and `head_sha` name `main` on every
one of these and no field on the run object says which PR asked. The filter was
therefore a `SINCE` stamp over a 20-run page — about 90 seconds — and the task's
own comment priced the residual risk as "a concurrent refusal on the same PR
would be read as ours". Measured 2026-08-11: 400 runs in 30 minutes, 243 of them
refusals. The window was not one concurrent refusal on our PR, it was 243
strangers' refusals across the fleet, so a lap polling after commenting would
near-certainly find one and report a refusal nobody gave it. That is how "the
bot is silent or slow" was inferred while the bot was answering every one of 248
attempts inside 23 seconds.

`fast-forward.yml` now mints `run-name: fast-forward #<issue> @<comment-id>`,
which surfaces as `display_title`, and the filter matches it exactly. Both
interpolations are integers from the event payload — never `comment.body`, which
is attacker-controlled. The comment id is the stronger half: it names this lap's
request on this head, so it subsumes the `SINCE` fence against an earlier lap of
the same PR. `created=>=` moves the window server-side so page size stops being
a silent second bound.

CLOUD-408 — THE SUCCESS LINE WAS UNCONDITIONAL. Measured on PR #330: GitHub
answered the secondary rate limit on comment creation, `gh` exited non-zero,
nothing read it, and `land` printed "commented /fast-forward … waiting for the
merge" over a comment that was never created — then blocked waiting for a merge
nothing had been asked to perform. The POST goes through `gh api` now, which
returns the created object, so the message is a consequence of an id existing
and the id is the key the filter above needs.

CLOUD-414 — THE EXIT STATUS WAS NOT READ. On a 403 `gh` writes the error body to
STDOUT; the filter failed on it and the unfiltered body reached `$refused`,
where the test was `[ -z ]`. Any non-empty string was a refusal, so a transport
error was indistinguishable from a verdict — CLOUD-235's shape with the sign
flipped. `2>/dev/null` stays: silencing stderr was never the defect, silently
trusting stdout was.

CLOUD-413 — TWO OUTCOMES WHERE THERE ARE THREE. Every non-success conclusion,
a rate-limited 403 among them, was narrated as "main moved under the branch" and
fell into a full lap. Across 24 laps of one landing that diagnosis was wrong
twice over: 7 of 8 laps in one run reached green CI, and several refusals were
the limit rather than `main`. So the loop's answer to being rate-limited was to
generate more of exactly the request that was rate-limited.

Now: `refused` requires a KEYED failure; `moved` may be set only by
`main-watch`, because that is a fact about a ref and not an inference from a
conclusion; everything else is `unknown` and re-asks. The re-ask is free by
construction on an unmoved `main` — the verify receipt still keys to this HEAD,
`graded_runs` is non-zero so neither the ready nor the `--undo` re-fire can
fire, and the force-push moves nothing so there is no `synchronize` event and no
run. It is bounded by `LAND_ANSWER_MAX_UNKNOWNS`, a COUNT of unreadable answers
in the sense `mem:github-rest-etiquette` calls the one place a retry cap
belongs, never a clock on the poll.

One existing case is REWRITTEN rather than added to: "a cancelled run is a
refusal too" pinned exactly the behaviour CLOUD-413 says is wrong.

Counters move to 20 stops and 13 lap-ending continues.

Refs: CLOUD-408, CLOUD-409, CLOUD-413, CLOUD-414, CLOUD-456

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CzqP3AFxFqCm3F4DfCdS92
claude added 7 commits August 13, 2026 09:56
`verify` is the authorization the whole workflow contract rests on, and on
macOS it could not pass for reasons no branch caused. CI is ubuntu, so CI is
structurally blind to the whole class.

The gates themselves, not only their tests:

  * sed's NUL-separated mode is a GNU extension; BSD sed exits `illegal option
    -- z`. Three files used it to scrub quoted spans across newlines —
    run-shape-guard, stop-posture-check and memory-guard-check, the third of
    which CLOUD-282 does not name. All now use `perl -0777 -pe`, byte-identical
    for all six substitutions, differentially verified against the real bats
    fixtures and both edges the issue names (a leading newline, a blank line
    before a block quote); only `\1` becomes `$1`.
  * `mapfile` is bash 4 and macOS ships 3.2, so gh-guard-check and
    run-shape-guard died on a Mac before judging anything. Both now use the
    `while IFS= read -r` idiom issue-guard and ready-guard already carry. The
    load-bearing half is `printf '%s\n'`: `read` returns false on an
    unterminated final segment, and a single-segment command like `gh pr merge`
    is ALL final segment, so the guard would have allowed everything.
  * xargs' short --no-run-if-empty is a GNU extension. It bought nothing in
    memories-check — the `/dev/null` sentinel already makes a zero-file
    invocation a silent exit 1.
  * target-ensure's prose still called its lock a flock; it has been a mkdir
    mutex since CLOUD-286.

New tests/helpers.bash carries what the suites need and macOS does not ship:
`sed_i` (`-i.bak` plus removal, the one in-place spelling GNU and BSD both
accept) and `run_timeout`, a stand-in for coreutils `timeout(1)`, which is
absent from a stock macOS entirely. Its exit mapping is pinned in
tests/helpers.bats because nine call sites assert the numbers directly: 124
timed out, 137 when the child died of SIGKILL, and the command's own status
otherwise. The 137-on-escalation case was measured against real coreutils
rather than assumed — GNU reports the signal, not the timeout, once the
escalation is what ended the child.

Refs: CLOUD-282
…lt branch

The call-site half of the macOS gap, plus the standing gate.

Twenty-two call sites move onto tests/helpers.bash: eleven in-place sed edits
across ci-local-parity, ci-tools-check and release-assets-check, and nine
`timeout` invocations across ci-wait, main-watch and land — the latter failing
on a MISSING BINARY rather than a flag, since coreutils `timeout` is not on a
stock macOS at all.

The three fixture repos that force-created `main` now name their working branch
instead. `git branch -f main` built the topology these cases need — a second
branch marking the trunk while HEAD stays on the feature branch — only by
accident: it works while git's default is `master`, and git refuses to force
the branch that is checked out, so any developer whose gitconfig sets
`init.defaultBranch=main` (recommended by git since 2.28) failed every case in
all three suites at setup. Measured: `-f` exits 128 under that config, and a
plain `branch main` off `git init -b work` does not.

Not `branch -M main`, which CLOUD-282 proposes: `-M` RENAMES the current
branch, so there is no second branch left to check out, and rewriting them that
way made verified.bats' moved-main case fail. The suites also neutralise
GIT_CONFIG_GLOBAL/SYSTEM now, closing the wider class the same way
crates/batten/tests/common/mod.rs already does — `init.defaultBranch` was one
leak of it and `commit.gpgsign` is the next.

The gate is six `forbid` rows in batten.toml rather than a 50th mise task, per
the engine-first amendment: `batten check` already runs in the shared hk gate
with no glob, so the construct set is config a reviewer can read. Globs are
`mise-tasks/*` and `tests/*.bats`, both anchored at two segments so neither can
match the root batten.toml, and the single-segment test glob keeps the walk out
of the vendored tests/bats submodule. Pinned by
`the_committed_portability_rules_fire_on_every_banned_shape` in cli.rs: a
seeded tree is exit 2 with byte-exact sorted stdout, and the portable spellings
this change adopts are silent.

Refs: CLOUD-282
The re-measurement one commit earlier already prices the lap and names the
bot-silence term. What it does not say is how to read the backstop's own
instruction: `look before lapping again` is asking whether the laps lost for a
REASON — rebase conflict, red CI, failed verify — or purely because main moved.
Only the second is contention, and only the second is safe to re-run unchanged.

Measured on CLOUD-282, which answered that question both ways one invocation
apart: 8 laps to the backstop with every verify green and CI green three times,
then a genuine rebase conflict on the next run.

Refs: CLOUD-282
`no-bash4-mapfile` fired on mise-tasks/checksums:82 the first time it ran
against a tree containing that file, which landed while this branch was in
flight. The construct is a real defect rather than a false positive: `mapfile`
is bash 4, macOS ships 3.2 as /bin/bash, and this task builds the checksum
manifest for release artifacts — including the two Darwin ones.

Same `while IFS= read -r` rewrite the other four sites took, and the producer
already ends every entry with a newline, so no trailing-newline hazard applies
here.

Refs: CLOUD-282
…er them

Three constructs the new CLOUD-282 rows ban landed on main while this branch
was held: `run-shape-guard` grew two more bash-4 array reads and `mutant` a
BSD-incompatible in-place sed. The rows are recursive over `mise-tasks/**` and
`tests/**/*.bats` now, matching `no-bash4-wait-n` and `bats-tests-not-deleted`
rather than inventing a third depth convention — and `batten-glob-check`
subsumes a required glob only verbatim or by a `P/**` prefix, so the
single-segment spelling would have left the step uncovered by hk.pkl's own
`tests/**/*.bats`.

Both array reads keep the property their comments name: the producer terminates
its last line, so a one-stage element is not silently dropped.

Refs: CLOUD-282
…ed-config sibling

`no-conflict-markers` became a kind that runs a configured command, and the
read-effect verb refuses the whole config rather than skipping that one row —
exit 1, pinned by the_committed_config_refuses_to_run_a_spawning_kind_under_
check. CLOUD-282's test was written before that landed and still asked `check`,
so it read the refusal as "no violations found" and failed on the exit code
rather than on anything about portability.

Refs: CLOUD-282
…binary

CLOUD-286 replaced flock(1) with a mkdir mutex and CLOUD-201 moved the mutex out
of target-ensure into this file, carrying one sentence that still named the
binary. `no-util-linux-flock` fires on it — the row cannot tell a live call from
its own history, which is CLOUD-283's exclude gap showing up as a stale
comment rather than as a fixture string.

The three surrounding mentions are `flock(1)` and are left alone: they are the
file's explanation of what it replaced, and the row does not match them.

Refs: CLOUD-282
@wenzowski
wenzowski force-pushed the wenzowski/cloud-282-verify-cannot-run-on-macos branch from 56a1e7a to 58616b7 Compare August 13, 2026 10:00
@sonarqubecloud

Copy link
Copy Markdown

@wenzowski

Copy link
Copy Markdown
Contributor Author

/fast-forward

@wenzowski
wenzowski merged commit 58616b7 into main Aug 13, 2026
8 checks passed
@wenzowski
wenzowski deleted the wenzowski/cloud-282-verify-cannot-run-on-macos branch August 13, 2026 10:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants