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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions .github/workflows/release-plz.yml
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,63 @@ jobs:
- run: mise exec -- cargo nextest run --no-run --workspace
if: steps.rust-cache.outputs.cache-hit != 'true'

# The warm side of `rust.yml`'s `macos` leg. It exists because that job reads
# with `save-if: false`, and a read-only family with no writer on the trunk is
# an entry nothing ever fills — `ci-cache-declared` calls that orphaned, and it
# is right to: every pull request would pay a cold build of the whole
# dependency set forever.
cache-warm-macos:
name: cache-warm-macos
runs-on: macos-latest
# Grandfathered for the `macos` leg's own reason: no run of this job exists
# to derive a quantile from. `cache-warm-windows` above carries the same
# marker for the same reason.
timeout-minutes: 30 # budget: grandfathered measured=2026-09-09
continue-on-error: true
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- uses: jdx/mise-action@3c2e0cf82a5b2e5249f0d3635a4d83d0ae861518 # v4.2.5 (CLOUD-404 retry fix, now a release)
with:
# Pinned to `batten.toml`'s `[[provision]]` version (CLOUD-1672). The
# digest above pins the ACTION; this pins the MISE it installs, which
# is a separate resolution the digest does not reach.
version: 2026.9.1
# Exactly what the `macos` job installs, minus the tools only its
# assertions need: the cache being filled is a cargo target dir.
install_args: rust github:nextest-rs/nextest
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
# The `id` is load-bearing, not decoration: the compile step below reads
# this step's `cache-hit` output to decide whether there is anything to
# warm. `ci-local-parity` property 17 holds the pair together.
id: rust-cache
with:
# Must match `rust.yml`'s `macos` job exactly or this writes an entry
# that job cannot read.
shared-key: macos-
# COMPILE ONLY WHEN THERE IS NOTHING TO RESTORE. `cache-hit` is true only
# on an EXACT key match, which is precisely the case where the post-run
# save would be a no-op — so this pays the full compile when the key moves
# (a dependency bump or a toolchain change, which is what makes a pull
# request miss) and only a runner boot and a restore otherwise. CLOUD-840
# measured the ungated version: every warm cycle after the first restored,
# recompiled and wrote nothing.
#
# The failure direction is safe by construction: if the action ever stops
# emitting `cache-hit` the expression is empty, `!= 'true'` holds, and the
# compile runs as it does today. The silent rot is the opposite one — the
# `id` disappearing while the `if` still names it — and property 17
# refuses that.
#
# `--no-run` builds without executing: this job fills a cache and is not a
# test leg, and `foreign-cargo-is-the-declared-spelling` excludes a
# `--no-run` line from its drift comparison for exactly that reason.
- run: mise exec -- cargo nextest run --no-run --workspace
if: steps.rust-cache.outputs.cache-hit != 'true'

release-plz:
runs-on: ubuntu-latest
timeout-minutes: 15 # budget: grandfathered measured=2026-08-10
Expand Down
157 changes: 157 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -732,3 +732,160 @@ jobs:
# that statement, so the two spellings can no longer drift apart silently.
# `mise-tasks/no-doctests.sh` covers the half nextest does not run.
- run: mise exec -- cargo nextest run --workspace

# THE SUITE HAS NEVER RUN ON DARWIN, and that is the whole argument for this
# job rather than any defect it has already caught.
#
# Every `#[cfg(unix)]` case in this workspace runs on Linux and only Linux:
# Windows cannot execute them, and macOS never did — `test.yml` exercises the
# shipped ACTION on `macos-latest` behind a `paths:` filter that no ordinary
# pull request trips, and `darwin-link` cross-links on `ubuntu-latest` through
# zigbuild without ever executing a Darwin binary. So the platform where
# process-group handling, `temp_dir`, a case-insensitive filesystem and
# BSD-versus-GNU tool defaults differ from Linux is the one platform nothing
# runs on.
#
# CLOUD-282 is what makes this worth doing NOW rather than in principle. It
# made `verify` macOS-capable — `perl -0777` for `sed -zE`, six `forbid` rows
# including `no-util-linux-flock`, `tests/helpers.bash` — and closed with the
# line that is this job's whole case: nobody has run `mise run verify` on a
# Mac. The portability work exists and is unproven, which is the state a gate
# is for.
#
# ONE LEG, arm64, AND THE OTHER TARGET IS NAMED AS UNEXECUTED RATHER THAN
# COUNTED AS COVERED. `macos-latest` is arm64, which is the target
# `darwin-link` already cross-links and the one most contributors run.
# `x86_64-apple-darwin` is ALSO a shipped release target and this job does not
# execute it — stated here because CLOUD-364's rule is that a cap is never
# silent, and "macOS is tested" would otherwise read as both. The wider free
# Intel runners (`macos-15-intel`, `macos-26-intel`, 4-core/14GB against this
# leg's 3-core/7GB) are where that leg goes if it is ever added.
#
# EXPECT THE FIRST RUNS TO BE RED, AND THAT IS THE JOB WORKING — the posture
# CLOUD-113 recorded for `windows`, which shipped red and stayed red until the
# genuine portability defects it exposed were fixed. Failures under `crates/**`
# are their own rows, not a reason to soften this leg.
macos:
name: macos
if: ${{ github.event.pull_request.draft == false }}
runs-on: macos-latest
# GRANDFATHERED, AND HONESTLY SO: no run of this job exists, so there is no
# quantile to derive from and any number here would be invented. It matches
# `windows`'s ceiling as the nearest measured analogue while carrying a
# different host budget (3-core/7GB arm64 against 4-core/16GB), and
# `mise run timeout-drift` re-derives it once the series is long enough to
# have a p95. A ceiling taken from n=0 is exactly what `windows`'s own
# comment above records going wrong.
timeout-minutes: 50 # budget: grandfathered measured=2026-09-09
# `actions: write` for one call only: cancelling THIS run when the landing
# lease does not authorise the branch (CLOUD-420). A job that could not
# cancel itself would have to fail, and a failed job concludes the run
# `failure` rather than `cancelled` — which reds `final` and makes `land`
# re-draft a healthy PR.
permissions:
contents: read
actions: write
steps:
# CLOUD-420: THE LANDING LEASE, ENFORCED WHERE THE MONEY IS SPENT. First
# step, before any checkout or toolchain install, so a run this branch is
# not authorised to make costs the rounding rather than a matrix. Body
# fetched from `main`, never from this head, and `|| exit 0` on every line
# so a body that will not parse cannot red the first step of every job.
- name: Landing lease precondition
# EXPLICIT even though bash is the macOS default, because the step's
# correctness must not depend on a runner default that GitHub is free to
# change — the same reason `windows` says so, arrived at there by having
# its body handed to pwsh.
shell: bash
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
LEASE_HEAD_REF: ${{ github.head_ref }}
# The HEAD sha, never `github.sha`: on a pull_request event that is the
# merge commit, whose tree is trunk's wherever this head did not touch
# it — and the staleness read asks about the head's own landing paths.
LEASE_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
LEASE_RUN_ID: ${{ github.run_id }}
run: |
installer=$(gh api -H "Accept: application/vnd.github.raw" \
"repos/$GH_REPO/contents/install.sh?ref=main") || exit 0
printf '%s\n' "$installer" | \
BATTEN_VERSION_FROM_REF=main BATTEN_INSTALL_DIR="$RUNNER_TEMP/batten-bin" \
BATTEN_ALLOW_OFF_PATH=1 BATTEN_REQUIRE="lease guard" sh || exit 0
# THE POLICY IS TRUNK'S TOO. This step runs BEFORE any checkout, so the
# directory the guard stands in is empty and `config::load` would find
# nothing — `[lease] landing_paths` reading as *no paths declared* is
# the silence the row was written to end. Fetched from `main` for the
# installer's own reason: a head must not pin the policy it is judged
# by.
mkdir -p "$RUNNER_TEMP/batten-config" || exit 0
gh api -H "Accept: application/vnd.github.raw" \
"repos/$GH_REPO/contents/batten.toml?ref=main" \
>"$RUNNER_TEMP/batten-config/batten.toml" || exit 0
"$RUNNER_TEMP/batten-bin/batten" --config-in "$RUNNER_TEMP/batten-config" \
lease guard \
"$LEASE_HEAD_SHA" "$LEASE_HEAD_REF" "$LEASE_RUN_ID" || exit 0

- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
# The OS must be the only variable, which is this leg's entire value.
# A missing `tests/bats` would be a second one — `crates/batten/tests`
# carries a suite about that path — and it would read as a Darwin
# finding, which is the misattribution this job exists to avoid.
submodules: true
- uses: jdx/mise-action@3c2e0cf82a5b2e5249f0d3635a4d83d0ae861518 # v4.2.5 (CLOUD-404 retry fix, now a release)
with:
# Pinned to `batten.toml`'s `[[provision]]` version (CLOUD-1672). The
# digest above pins the ACTION; this pins the MISE it installs, which
# is a separate resolution the digest does not reach.
version: 2026.9.1
# THE SAME LIST `windows` INSTALLS, and for the reason its own comment
# records rather than by copying: `tests/cli.rs` materializes fixtures
# carrying this repository's `batten.toml`, whose `no-conflict-markers`
# rule is `hk util check-merge-conflict`, so a fixture that loads that
# config cannot evaluate ANY rule without hk. `jq` is read at runtime
# by the mise tasks three more command rules invoke. Neither is about
# the OS, which is why both belong on every leg that runs the suite.
install_args: rust hk aqua:jqlang/jq github:nextest-rs/nextest
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
with:
# A DISTINCT FAMILY, for `windows`'s reason rather than by analogy:
# this target dir is built by a different host toolchain than any
# linux job's, so an entry shared with one would thrash rather than
# warm. SHARED rather than keyed, so a job in another workflow can
# fill it (CLOUD-840) — without `shared-key` the job id enters the key
# and a warm job under any other name computes a different one.
shared-key: macos-
# READ-ONLY: `cache-warm-macos` on `main` is this family's one writer.
# A write from a `pull_request` run lands under `refs/pull/N/merge`
# where no other pull request can read it, which is a cache that costs
# a save and is never hit.
save-if: false
# A JOB THAT DECLARES A TOOL MUST BE ABLE TO REACH IT, asserted before the
# suite rather than discovered inside it — `ci-tools-check` holds these
# names against `mise.toml`, which cannot know whether a runner resolves
# one. The alternative is measured on `windows`: three `tests/cli.rs`
# cases reporting an exit code about a missing tool while naming the rule
# they meant to test, each costing a round trip to attribute.
- name: Assert the declared tools resolve
shell: bash
run: |
set -euo pipefail
echo "PATH=$PATH"
for tool in hk jq cargo cargo-nextest; do
if ! resolved=$(command -v "$tool"); then
echo "::error::$tool is declared in install_args but does not resolve on PATH" >&2
exit 1
fi
echo "$tool -> $resolved"
done
hk --version

# `mise exec`, matching `windows`, and here it is parity rather than the
# workaround it is there: `[tasks."test:cargo"]`'s body is bash and macOS
# runs bash, so `mise run test:cargo` would work — but property 16 of
# `ci-local-parity` (CLOUD-662) reads that task's single cargo statement
# and requires a foreign leg's line to be `mise exec -- ` plus exactly
# that statement. Two foreign legs spelling it two ways is the drift that
# property exists to refuse.
- run: mise exec -- cargo nextest run --workspace
6 changes: 4 additions & 2 deletions .serena/memories/core.md
Original file line number Diff line number Diff line change
Expand Up @@ -846,8 +846,10 @@ repo config > default`, declared as data in `SETTINGS` (per-key env var/flag),
budget is not).
`git2` is excluded by `macos-link-check` rule 1 — a COST, not a constraint:
cross-linking Darwin frameworks needs an SDK the build declines because macOS
runners bill at 10x on a **private** repo, which CLOUD-737 revisits when the
repo goes public.
runners carry a billing multiplier. That is a PRICE, and it moves with the
repository's visibility and plan — so this note names the dependency instead
of a rate that would go stale silently. CLOUD-737 owns re-deciding it, and
`rust.yml`'s `macos` job is where a Darwin leg's cost is actually paid.
- `state.rs` — out-of-tree state dir (`<data-dir>/<app>/<segment>/`, CLOUD-23), via
`etcetera`; the segment derived at runtime, never baked in (rule 1). Since
CLOUD-296 the segment is `<dir-name>-<12 hex>`, not the bare directory name: the
Expand Down
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,16 @@ container's setup step, an agent sandbox:

- **A token is read if one is set**, from `BATTEN_GITHUB_TOKEN`, `GH_TOKEN`,
`GITHUB_TOKEN` or `GITHUB_PERSONAL_ACCESS_TOKEN`, in that order. A public
release needs none of them. **This repository is private today**, so a fetch
needs a token with release-read scope until that changes; a host carrying
several tokens that are not equivalent names the working one through
`BATTEN_GITHUB_TOKEN`, which wins.
release needs none of them; a release only a credential can read needs one
granting **read access to the repository's contents** — `contents: read` on a
fine-grained token, or `repo` on a classic one. Release assets are served
under that permission rather than a release-specific one, which is why there
is no narrower grant to ask for. Whether a given repository's releases need it
at all is a property of that repository rather than of this page: an
unauthenticated fetch of the download URL answers it in one command, and keeps
answering it correctly after a visibility change no sentence here would
notice. A host carrying several tokens that are not equivalent names the
working one through `BATTEN_GITHUB_TOKEN`, which wins.
- **A proxy that re-terminates TLS is handled** by honouring the CA bundle the
environment already declares — `CURL_CA_BUNDLE`, else `SSL_CERT_FILE`. Nothing
is disabled and an unproxied host is untouched. Set one of those rather than
Expand Down
4 changes: 2 additions & 2 deletions mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ _.path = ["tests/bats/bin", "target/release"]
# alone — the fan-in. This roster is what `ci-wait` WAITS ON before landing, and
# waiting only on `final` would strand every landing on a check that fans in from
# eighteen. Two sets, two purposes; neither derives the other.
CI_REQUIRED_CHECKS = "ci,batten-check,bats,cross,commit-lint,zizmor,darwin-link (aarch64-apple-darwin),semver,perf,windows,final,action (ubuntu-latest),action (macos-latest),action (windows-latest),action-violation,action-deny,action-usage,action-internal (ubuntu-latest),action-internal (macos-latest),action-final"
CI_REQUIRED_CHECKS = "ci,batten-check,bats,cross,commit-lint,zizmor,darwin-link (aarch64-apple-darwin),semver,perf,windows,macos,final,action (ubuntu-latest),action (macos-latest),action (windows-latest),action-violation,action-deny,action-usage,action-internal (ubuntu-latest),action-internal (macos-latest),action-final"
Comment thread
coderabbitai[bot] marked this conversation as resolved.

# ─── THE LAP'S READY PHASE (CLOUD-1148) ───────────────────────────────────────
#
Expand Down Expand Up @@ -519,7 +519,7 @@ LEASE_STOP_NOTE = "mise-tasks/reclaim-census.sh note x land-stopped"
# that one success as the whole roster, and `land` posted /fast-forward into a
# branch protection still listing the other six as expected. The bot was
# rejected. A stall is recoverable; a false green is not (CLOUD-337).
CI_ABSENT_OK_CHECKS = "zizmor,cross,darwin-link (aarch64-apple-darwin),semver,windows,action (ubuntu-latest),action (macos-latest),action (windows-latest),action-violation,action-deny,action-usage,action-internal (ubuntu-latest),action-internal (macos-latest),action-final"
CI_ABSENT_OK_CHECKS = "zizmor,cross,darwin-link (aarch64-apple-darwin),semver,windows,macos,action (ubuntu-latest),action (macos-latest),action (windows-latest),action-violation,action-deny,action-usage,action-internal (ubuntu-latest),action-internal (macos-latest),action-final"
# The conclusions that CONSTITUTE AN ANSWER about a required check, written once
# and read by `checks-green` and by `land`'s `graded_runs` — for exactly the
# reason CI_REQUIRED_CHECKS is written once (CLOUD-327), and against exactly the
Expand Down