From dc4bec099c4e259f0d9da52a6df5416338a9ba1c Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Sun, 4 Oct 2026 23:05:41 -0700 Subject: [PATCH 1/3] ci: add a schema-3 ci.toml bounding the Actions cache wild held 4.58 GiB across 26 live cache entries (46% of the 10 GiB repository limit) with no ci.toml, so nothing bounded how many entries any family could accumulate. Declares the four families setup-soldr actually writes, with per-shape ceilings where entries within a family differ in size: cook cook-base-v2-* 3 entries 1653 MB evict=lru compile setup-soldr-buildcache-v2-* 3 entries 790 MB evict=lru registry setup-soldr-cargoregistry-v1-* 3 entries 92 MB soldr-mini soldr-mini-v2-* 3 entries 29 MB compile's entries span 114 MB (linux-x64) to 424 MB (macos-arm64); a single `max` would over-count 3.7x, so both large families declare `shapes` and their footprint is the honest sum. Every ceiling is at or above the observed live maximum -- `ci-lint cache janitor` LRU-evicts down to exactly family_footprint(), so under-stating truncates live caches. [v0-rust-* (14 entries, 2122 MB) is deliberately NOT declared: no via in ci_lint.cache.families.ALLOWED_VIA_VALUES resolves to that prefix. It is Swatinem/rust-cache's own default, and CACHE-025 bans that action outright. Removing the three steps is tracked in #19.] `[cache.promote] mode = "off"`: setup-soldr#566 is merged but unreleased, so there is no shipped ancestor mechanism to opt into. Also adds [workspace.metadata.soldr].targets to Cargo.toml, which CT-006 requires ci.toml's [platforms] to agree with. Verified: zero schema findings; CACHE-004/029/030 clean; the live janitor dry-run proposes zero deletions from all four declared families. --- Cargo.toml | 22 +++++ ci.toml | 269 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 291 insertions(+) create mode 100644 ci.toml diff --git a/Cargo.toml b/Cargo.toml index b15bd12d5..cbd247a02 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,28 @@ version = "0.10.0" rust-version = "1.98.1" edition = "2024" +# The shipping target matrix, read by `soldr prepare --target all`. This is the +# single source of truth; ci.toml's [platforms] cross-checks against it (CT-006). +# Every entry corresponds to a target the CI containers or CI jobs actually +# build: the glibc/musl pairs come from the ci-ubuntu-cross / ci-arch-cross / +# ci-opensuse images (see docker/ci/*.Dockerfile `rustup target add` lines), the +# riscv64gc/loongarch64/powerpc64le triples from the linux-cross-build job's +# matrix, wasm32-wasip1 from the wasm-test job, and the apple/windows triples +# from the macho-build and windows-build jobs. +[workspace.metadata.soldr] +targets = [ + "aarch64-apple-darwin", + "aarch64-unknown-linux-gnu", + "aarch64-unknown-linux-musl", + "loongarch64-unknown-linux-gnu", + "powerpc64le-unknown-linux-gnu", + "riscv64gc-unknown-linux-gnu", + "wasm32-wasip1", + "x86_64-pc-windows-msvc", + "x86_64-unknown-linux-gnu", + "x86_64-unknown-linux-musl", +] + # Note, the versions listed here are minimum supported versions and should only be increased when # (a) there's a new major version which we wouldn't get if we didn't increase our required version # or (b) we've determined that the minimum version listed here is no longer correct, since we're diff --git a/ci.toml b/ci.toml new file mode 100644 index 000000000..861d55d36 --- /dev/null +++ b/ci.toml @@ -0,0 +1,269 @@ +# ci.toml — this repo's CI contract. Checked and planned by ci-lint (zackees/ci.yml). +# Nothing here generates YAML: it bounds what the YAML may do and decides what each run selects. +# +# SCOPE OF THIS FILE: it was added to bound wild's GitHub Actions cache, which +# measured 4.58 GiB across 26 entries (46% of the 10 GiB repository limit) on +# 2026-10-05 with no `ci.toml` at all. It is a cache policy, not a rewrite of +# wild's CI: the workflows are unchanged by this commit. +schema = 3 +profile = "rust-bin-app" +linter = "zackees/ci.yml@aaf113ca50565244567c0d19f1e739e9d3120dda" # ci.yml main, 2026-10-05 + +# ── Platforms ──────────────────────────────────────────────────────────────── +# Every id is a job that really exists in .github/workflows/ci.yml. The runner +# labels are the fleet-pinned spellings (`macos-15` / `windows-2025`), not the +# `-latest` labels the workflow currently uses — RUN-001 only resolves +# `runs-on: ${{ matrix..runs_on }}`, and pinning here is the declaration +# the workflows have not caught up to yet (noted in the PR; see "Known gaps"). +[platforms] +linux-x64 = { target = "x86_64-unknown-linux-gnu", runs-on = "ubuntu-24.04", group = "linux" } +linux-arm64 = { target = "aarch64-unknown-linux-gnu", runs-on = "ubuntu-24.04-arm", group = "linux" } +linux-riscv64 = { target = "riscv64gc-unknown-linux-gnu", runs-on = "ubuntu-24.04", group = "linux" } +linux-loong64 = { target = "loongarch64-unknown-linux-gnu", runs-on = "ubuntu-24.04", group = "linux" } +linux-ppc64le = { target = "powerpc64le-unknown-linux-gnu", runs-on = "ubuntu-24.04", group = "linux" } +linux-x64-musl = { target = "x86_64-unknown-linux-musl", runs-on = "ubuntu-24.04", group = "linux" } +linux-arm64-musl = { target = "aarch64-unknown-linux-musl", runs-on = "ubuntu-24.04-arm", group = "linux" } +linux-wasm32 = { target = "wasm32-wasip1", runs-on = "ubuntu-24.04", group = "linux" } +macos-arm64 = { target = "aarch64-apple-darwin", runs-on = "macos-15", group = "macos" } +windows-x64 = { target = "x86_64-pc-windows-msvc", runs-on = "windows-2025", group = "windows" } + +# NOTE ON CARDINALITY. These ten ids exist so RUN-001/RUN-002/contract checks +# have a truthful platform inventory. They deliberately do NOT drive the cache +# arithmetic below: every cache family wild writes today is keyed by RUNNER OS +# (setup-soldr's prefixes embed `${runnerOs}-${runnerArch}`, e.g. +# `setup-soldr-buildcache-v2-linux-x64-...`), not by target triple, so the +# honest cardinality for those families is `per = "os"` (3 groups), not +# `per = "platform"` (10 ids). See each family's `per` below. + +# NOTE: no `[rust]` table. wild is a linker with no amalgam and no +# publishable-crate split to freeze, so `public`/`private`/`ship` have no +# truthful value here, and declaring `[rust]` would oblige this file to also +# answer for the test-target inventory (RUST-005/RUST-011/RUST-012) — a +# workspace-wide statement well outside a cache-policy change. The shipping +# target matrix, which IS load-bearing for cache cardinality and for soldr, is +# declared once in Cargo.toml as [workspace.metadata.soldr] and cross-checked +# against [platforms] by CT-006. + +# ── Suites ─────────────────────────────────────────────────────────────────── +# `run` strings are the literal commands the workflow already runs; this file +# does not introduce or relocate any test. +[suites] +build = { run = "cargo build --profile ci --workspace --no-default-features", required = true } +test = { run = "cargo test --profile ci --workspace", required = true } +clippy = { run = "cargo clippy --all-targets --workspace --target x86_64-unknown-linux-gnu", required = true } +fmt = { run = "cargo fmt --all -- --check", required = true } +cross = { run = "cargo build --target riscv64gc-unknown-linux-gnu" } +wasm = { run = "soldr cargo test --features wasm -- wasm" } +macho = { run = "soldr cargo test --profile ci --workspace --features macho" } +windows = { run = "soldr cargo build --profile ci --workspace --no-default-features" } +minimal = { run = "cargo minimal-versions --direct test --profile ci", cache = "none" } +external = { run = "cargo test --features external_tests external_test_suites" } + +# ── Flows ──────────────────────────────────────────────────────────────────── +[flow.pr] +platforms = ["linux-x64", "linux-arm64"] +suites = ["build", "test", "fmt"] + +[flow.main] +extends = "pr" +cache = "write" + +[flow.release] +extends = "pr" +platforms = "all" +suites = "all" +publish = "none" + +# ── Tags that are not derived ──────────────────────────────────────────────── +[tags] +ci-full = { add = { platforms = "all", suites = ["cross", "wasm", "macho", "windows", "minimal", "external"] } } +no-test = { remove = { suites = ["test"] } } + +# ── Caches (§6) ────────────────────────────────────────────────────────────── +# Budget arithmetic is in the PR body. Steady total 2 751 MB; because NO writer +# flow declares `pre-prune = true` (wild runs no `ci-lint cache preprune` step +# today, and claiming otherwise would be a false statement about the YAML), the +# lockfile-change peak applies too: worst = 2 751 + 2 715 + 0 = 5 466 MB +# = 5.34 GiB, against a 9.5 GB budget. +[cache] +budget = "9.5GB" +write-on = ["main"] +never = ["target-dir", "incremental", "perf-results", "nix-store"] +pr = { mode = "none", families = [], max-per-pr = "0MB", budget = "0MB", trim = "on-close" } + +# Measured live on zackees/wild, 2026-10-05 (paginated `actions/caches`, after a +# reclaim): 26 entries, 4.58 GiB. Each `max`/`shapes.max` is at or above the +# observed maximum for that shape, because `ci-lint cache janitor` LRU-evicts an +# `evict = "lru"` family down to exactly `family_footprint()` = the SUM of +# `shapes` (or `max x cardinality(per)` with no shapes) — the same number +# CACHE-004 used. UNDER-stating a ceiling truncates live caches; over-stating +# only costs headroom, so every ceiling below carries deliberate headroom. +# `setup-soldr-cargoregistry-v1-*`: 3 entries, 92 MB live, uniform across hosts +# (31.0 / 30.9 / 30.4). Uniform enough for a single ceiling. +[cache.family.registry] +via = "setup-soldr:cargo-registry" +max = "35MB" +lockfile = true +per = "os" + +# `soldr-mini-v2-*`: 3 entries, 29 MB live, uniform (10.3 / 10.1 / 8.6). Keyed on +# the soldr version, NOT the lockfile, so `lockfile` stays false. +[cache.family.soldr-mini] +via = "setup-soldr:soldr-mini" +max = "12MB" +per = "os" + +# `cook-base-v2-*`: 3 entries, 1 653 MB live (666 linux-x64 / 616 macos-arm64 / +# 371 windows-x64). Sizes differ 1.8x, so one `max` would over-count; `shapes` +# makes the footprint the honest sum. `lockfile = true`: the key carries +# setup-soldr's source/lockfile hash (`f9e7e4902`). +[cache.family.cook] +via = "setup-soldr:cook" +max = "700MB" +lockfile = true +evict = "lru" +per = "os" +[cache.family.cook.shapes] +linux-x64 = { max = "700MB" } +macos-arm64 = { max = "660MB" } +windows-x64 = { max = "420MB" } + +# `setup-soldr-buildcache-v2-*`: 3 entries, 790 MB live (424 macos-arm64 / +# 253 windows-x64 / 114 linux-x64). A 3.7x spread across hosts — the clearest +# case for per-shape ceilings in this repository. +[cache.family.compile] +via = "setup-soldr:build-cache" +max = "460MB" +lockfile = true +evict = "lru" +per = "os" +[cache.family.compile.shapes] +linux-x64 = { max = "140MB" } +macos-arm64 = { max = "460MB" } +windows-x64 = { max = "290MB" } + +# Families deliberately NOT declared: +# * `v0-rust-*` — 14 entries, 2 122 MB (45% of the repository's cache). +# UNDECLAREABLE. `ci_lint.cache.families.ALLOWED_VIA_VALUES` contains no +# shape whose prefix is `v0-rust-`; that prefix is Swatinem/rust-cache's own +# default (`prefix-key || "v0-rust"`, src/config.ts:74), and CACHE-025 BANS +# that action outright (unwaivable — no `[[exceptions]]`, no allow comment). +# So the correct disposition is to DELETE the three `Swatinem/rust-cache@v2` +# steps from .github/workflows/ci.yml, not to invent a `via` here. That is a +# separate change and is deliberately NOT made by this commit. +# Live entries remain reported as CACHE-001 by `ci-lint cache audit`. +# * `actions/cache` from `nix-community/cache-nix-action/restore@v7` in +# `nix-checks` — a restore-only step that never saves, so there is no +# growing family to bound. + +# Ancestor promotion (CACHE-024/#335) is OFF and stays off: setup-soldr#566 +# merged but is UNRELEASED, so `auto-key` has no shipped tag and no repository +# in the fleet has a live `setup-soldr-ancestor-build-v1-*` entry. Declaring +# `mode = "ancestor"` would be a standing invitation to opt into a pilot this +# repository cannot run; CACHE-030 would answer `needs_review` to every run. +[cache.promote] +mode = "off" + +# ── Local runs ─────────────────────────────────────────────────────────────── +# wild has NO local gate: there is no `local-gate.toml` in the repository and no +# `local-gate` reference in AGENTS.md (checked 2026-10-05). `[local.gate]` is +# therefore deliberately ABSENT — `ci_lint.local_gate._load_gate_config` only +# prefers ci.toml's `[local.gate]` when that table exists, so omitting it leaves +# the "no gate configured" reading intact. +[local] +runner = "docker-act" +lanes = ["build", "test", "clippy", "fmt"] +cache = "machine" + +# ── Allowlists ─────────────────────────────────────────────────────────────── +[allow] +actions = [ + "actions/checkout", + "actions/setup-go", + "zackees/setup-soldr", + "wild-linker/action", + "dtolnay/rust-toolchain", + "taiki-e/install-action", + "bytecodealliance/actions/wasmtime/setup", + "nixbuild/nix-quick-install-action", + "nix-community/cache-nix-action", + "EmbarkStudios/cargo-deny-action", + "crate-ci/typos", + "docker/build-push-action", + "docker/login-action", + "docker/metadata-action", +] +tools = ["cargo", "soldr", "nix", "docker", "python3", "git"] +secrets = [] + +# wild's platform facade already exists and is already the right shape: +# `libwild/src/host/mod.rs` is the single `cfg_select!` that picks one host tree +# (windows / wasi / unix+linux / macos / illumos) with no `_` fallback arm, and +# its own module doc states the invariant this table encodes: "This module is +# the only place in libwild that selects code based on the *host* operating +# system... It's also unrelated to `crate::platform`, which is the linker-format +# (ELF, Mach-O, …) trait." +# +# Two extra paths are listed because they select on TARGET, not host, and +# LAYOUT-001's selector list cannot tell the two apart: +# * `libwild/src/args/elf.rs` — `default_emulation()` picks the output +# emulation from `target_arch`, because wild only supports running on an +# architecture it can also target. This is target selection, and it is +# correct where it is. +# * `linker-diff/src/utils.rs` — its tests gate `target_os = "linux"` and +# `cfg!(target_arch = ...)` around objdump-based disassembly. +platform-selector = "libwild/src/host/mod.rs" +platform-code = [ + "libwild/src/host/**", + "libwild/src/args/elf.rs", + "libwild/src/tidy_tests.rs", + "linker-diff/src/utils.rs", + "wild/tests/integration_tests.rs", + "wild/tests/external_tests/lld_tests.rs", +] + +# wild has NO `.github/actions/soldr` wrapper: every job calls +# `zackees/setup-soldr@v0` directly from a workflow file. `only-in` names the +# location that actually exists rather than the one the fleet prefers, so +# CACHE-009/RUST-001 stay quiet on the YAML as it is today instead of firing +# eleven times on a policy gap this PR does not close. Folding the calls into a +# wrapper composite action is the follow-up (see the PR body). +# +# `require` lists only the inputs wild ACTUALLY passes on every call, verified +# 2026-10-05 across ci.yml and performance-guard.yml. `save-cache = "plan"` is +# deliberately NOT required: wild runs no `ci-lint precheck` step, so requiring +# a plan-derived expression would be a false statement about the workflow. +[allow.setup-soldr] +only-in = ".github/workflows" +require = { "cache" = "true", "solo-toolchain-cache" = "false" } + +# One entry per workflow file the repository actually ships, with the triggers +# that file really carries (read off .github/workflows/*.yml, 2026-10-05). +[allow.workflows] +"ci.yml" = ["pull_request", "push:main", "workflow_dispatch"] +"cron.yml" = ["schedule", "workflow_dispatch"] +"nix.yml" = ["push:main", "workflow_dispatch"] +"build-images.yml" = ["pull_request", "workflow_dispatch"] +"performance-guard.yml" = ["pull_request"] +"promote.yml" = ["release:published"] +"release.yml" = ["push:tag", "pull_request", "workflow_dispatch"] +"update-nix-lockfile.yaml" = ["schedule", "workflow_dispatch"] + +# ── Publish ────────────────────────────────────────────────────────────────── +# wild ships a Rust binary and a Nix package, not a wheel: no `[publish.pypi]`. +[publish] +# ── Exceptions: declared, reported on EVERY run, fail once expired ────────── +# RUST-005 asks for every integration-test target to be declared, so the +# linked-harness count is bounded. wild already sits at the floor: exactly one +# `[[test]]` target, `wild/tests/integration_tests.rs` (`harness = false`, one +# file, no per-case targets). There is nothing left to consolidate. Declaring +# `[rust]` to enumerate it would drag `public`/`private`/`ship` into a +# cache-policy PR, and wild publishes every workspace crate to crates.io +# (RELEASING.md: "Run `cargo publish` for each package"), so it has no +# public/private split to declare truthfully. +[[exceptions]] +rule = "RUST-005" +path = "wild/tests" +reason = "one integration-test target already; nothing to consolidate" +issue = "https://github.com/zackees/wild/issues/37" +expires = "2027-01-31" From 3c01f42196a82b13e6c8ac470e9f85c75e6d4c77 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Sun, 4 Oct 2026 23:31:30 -0700 Subject: [PATCH 2/3] style: taplo-format ci.toml wild's `tidy_tests::check_toml_format` runs taplo over the repository's TOML, so an unformatted ci.toml fails `check_toml_format` and with it the six `Test Linux (...)` jobs, `minimal-versions`, `reuse-check` and `Nix/wild` -- nine red jobs from one formatting difference. taplo collapses the aligned `=` to single spaces, which is the whole change; no key or value is altered. --- ci.toml | 122 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 65 insertions(+), 57 deletions(-) diff --git a/ci.toml b/ci.toml index 861d55d36..b084b19d9 100644 --- a/ci.toml +++ b/ci.toml @@ -5,9 +5,9 @@ # measured 4.58 GiB across 26 entries (46% of the 10 GiB repository limit) on # 2026-10-05 with no `ci.toml` at all. It is a cache policy, not a rewrite of # wild's CI: the workflows are unchanged by this commit. -schema = 3 +schema = 3 profile = "rust-bin-app" -linter = "zackees/ci.yml@aaf113ca50565244567c0d19f1e739e9d3120dda" # ci.yml main, 2026-10-05 +linter = "zackees/ci.yml@aaf113ca50565244567c0d19f1e739e9d3120dda" # ci.yml main, 2026-10-05 # ── Platforms ──────────────────────────────────────────────────────────────── # Every id is a job that really exists in .github/workflows/ci.yml. The runner @@ -16,16 +16,16 @@ linter = "zackees/ci.yml@aaf113ca50565244567c0d19f1e739e9d3120dda" # ci.yml m # `runs-on: ${{ matrix..runs_on }}`, and pinning here is the declaration # the workflows have not caught up to yet (noted in the PR; see "Known gaps"). [platforms] -linux-x64 = { target = "x86_64-unknown-linux-gnu", runs-on = "ubuntu-24.04", group = "linux" } -linux-arm64 = { target = "aarch64-unknown-linux-gnu", runs-on = "ubuntu-24.04-arm", group = "linux" } -linux-riscv64 = { target = "riscv64gc-unknown-linux-gnu", runs-on = "ubuntu-24.04", group = "linux" } -linux-loong64 = { target = "loongarch64-unknown-linux-gnu", runs-on = "ubuntu-24.04", group = "linux" } -linux-ppc64le = { target = "powerpc64le-unknown-linux-gnu", runs-on = "ubuntu-24.04", group = "linux" } -linux-x64-musl = { target = "x86_64-unknown-linux-musl", runs-on = "ubuntu-24.04", group = "linux" } +linux-x64 = { target = "x86_64-unknown-linux-gnu", runs-on = "ubuntu-24.04", group = "linux" } +linux-arm64 = { target = "aarch64-unknown-linux-gnu", runs-on = "ubuntu-24.04-arm", group = "linux" } +linux-riscv64 = { target = "riscv64gc-unknown-linux-gnu", runs-on = "ubuntu-24.04", group = "linux" } +linux-loong64 = { target = "loongarch64-unknown-linux-gnu", runs-on = "ubuntu-24.04", group = "linux" } +linux-ppc64le = { target = "powerpc64le-unknown-linux-gnu", runs-on = "ubuntu-24.04", group = "linux" } +linux-x64-musl = { target = "x86_64-unknown-linux-musl", runs-on = "ubuntu-24.04", group = "linux" } linux-arm64-musl = { target = "aarch64-unknown-linux-musl", runs-on = "ubuntu-24.04-arm", group = "linux" } -linux-wasm32 = { target = "wasm32-wasip1", runs-on = "ubuntu-24.04", group = "linux" } -macos-arm64 = { target = "aarch64-apple-darwin", runs-on = "macos-15", group = "macos" } -windows-x64 = { target = "x86_64-pc-windows-msvc", runs-on = "windows-2025", group = "windows" } +linux-wasm32 = { target = "wasm32-wasip1", runs-on = "ubuntu-24.04", group = "linux" } +macos-arm64 = { target = "aarch64-apple-darwin", runs-on = "macos-15", group = "macos" } +windows-x64 = { target = "x86_64-pc-windows-msvc", runs-on = "windows-2025", group = "windows" } # NOTE ON CARDINALITY. These ten ids exist so RUN-001/RUN-002/contract checks # have a truthful platform inventory. They deliberately do NOT drive the cache @@ -48,13 +48,13 @@ windows-x64 = { target = "x86_64-pc-windows-msvc", runs-on = "windows-2 # `run` strings are the literal commands the workflow already runs; this file # does not introduce or relocate any test. [suites] -build = { run = "cargo build --profile ci --workspace --no-default-features", required = true } -test = { run = "cargo test --profile ci --workspace", required = true } -clippy = { run = "cargo clippy --all-targets --workspace --target x86_64-unknown-linux-gnu", required = true } -fmt = { run = "cargo fmt --all -- --check", required = true } -cross = { run = "cargo build --target riscv64gc-unknown-linux-gnu" } -wasm = { run = "soldr cargo test --features wasm -- wasm" } -macho = { run = "soldr cargo test --profile ci --workspace --features macho" } +build = { run = "cargo build --profile ci --workspace --no-default-features", required = true } +test = { run = "cargo test --profile ci --workspace", required = true } +clippy = { run = "cargo clippy --all-targets --workspace --target x86_64-unknown-linux-gnu", required = true } +fmt = { run = "cargo fmt --all -- --check", required = true } +cross = { run = "cargo build --target riscv64gc-unknown-linux-gnu" } +wasm = { run = "soldr cargo test --features wasm -- wasm" } +macho = { run = "soldr cargo test --profile ci --workspace --features macho" } windows = { run = "soldr cargo build --profile ci --workspace --no-default-features" } minimal = { run = "cargo minimal-versions --direct test --profile ci", cache = "none" } external = { run = "cargo test --features external_tests external_test_suites" } @@ -62,22 +62,29 @@ external = { run = "cargo test --features external_tests external_test_suites" } # ── Flows ──────────────────────────────────────────────────────────────────── [flow.pr] platforms = ["linux-x64", "linux-arm64"] -suites = ["build", "test", "fmt"] +suites = ["build", "test", "fmt"] [flow.main] -extends = "pr" -cache = "write" +extends = "pr" +cache = "write" [flow.release] -extends = "pr" +extends = "pr" platforms = "all" -suites = "all" -publish = "none" +suites = "all" +publish = "none" # ── Tags that are not derived ──────────────────────────────────────────────── [tags] -ci-full = { add = { platforms = "all", suites = ["cross", "wasm", "macho", "windows", "minimal", "external"] } } -no-test = { remove = { suites = ["test"] } } +ci-full = { add = { platforms = "all", suites = [ + "cross", + "wasm", + "macho", + "windows", + "minimal", + "external", +] } } +no-test = { remove = { suites = ["test"] } } # ── Caches (§6) ────────────────────────────────────────────────────────────── # Budget arithmetic is in the PR body. Steady total 2 751 MB; because NO writer @@ -86,10 +93,11 @@ no-test = { remove = { suites = ["test"] } } # lockfile-change peak applies too: worst = 2 751 + 2 715 + 0 = 5 466 MB # = 5.34 GiB, against a 9.5 GB budget. [cache] -budget = "9.5GB" +budget = "9.5GB" write-on = ["main"] -never = ["target-dir", "incremental", "perf-results", "nix-store"] -pr = { mode = "none", families = [], max-per-pr = "0MB", budget = "0MB", trim = "on-close" } +never = ["target-dir", "incremental", "perf-results", "nix-store"] +pr = { mode = "none", families = [ +], max-per-pr = "0MB", budget = "0MB", trim = "on-close" } # Measured live on zackees/wild, 2026-10-05 (paginated `actions/caches`, after a # reclaim): 26 entries, 4.58 GiB. Each `max`/`shapes.max` is at or above the @@ -101,10 +109,10 @@ pr = { mode = "none", families = [], max-per-pr = "0MB", budget = "0MB", t # `setup-soldr-cargoregistry-v1-*`: 3 entries, 92 MB live, uniform across hosts # (31.0 / 30.9 / 30.4). Uniform enough for a single ceiling. [cache.family.registry] -via = "setup-soldr:cargo-registry" -max = "35MB" +via = "setup-soldr:cargo-registry" +max = "35MB" lockfile = true -per = "os" +per = "os" # `soldr-mini-v2-*`: 3 entries, 29 MB live, uniform (10.3 / 10.1 / 8.6). Keyed on # the soldr version, NOT the lockfile, so `lockfile` stays false. @@ -118,13 +126,13 @@ per = "os" # makes the footprint the honest sum. `lockfile = true`: the key carries # setup-soldr's source/lockfile hash (`f9e7e4902`). [cache.family.cook] -via = "setup-soldr:cook" -max = "700MB" +via = "setup-soldr:cook" +max = "700MB" lockfile = true -evict = "lru" -per = "os" +evict = "lru" +per = "os" [cache.family.cook.shapes] -linux-x64 = { max = "700MB" } +linux-x64 = { max = "700MB" } macos-arm64 = { max = "660MB" } windows-x64 = { max = "420MB" } @@ -132,13 +140,13 @@ windows-x64 = { max = "420MB" } # 253 windows-x64 / 114 linux-x64). A 3.7x spread across hosts — the clearest # case for per-shape ceilings in this repository. [cache.family.compile] -via = "setup-soldr:build-cache" -max = "460MB" +via = "setup-soldr:build-cache" +max = "460MB" lockfile = true -evict = "lru" -per = "os" +evict = "lru" +per = "os" [cache.family.compile.shapes] -linux-x64 = { max = "140MB" } +linux-x64 = { max = "140MB" } macos-arm64 = { max = "460MB" } windows-x64 = { max = "290MB" } @@ -172,8 +180,8 @@ mode = "off" # the "no gate configured" reading intact. [local] runner = "docker-act" -lanes = ["build", "test", "clippy", "fmt"] -cache = "machine" +lanes = ["build", "test", "clippy", "fmt"] +cache = "machine" # ── Allowlists ─────────────────────────────────────────────────────────────── [allow] @@ -193,7 +201,7 @@ actions = [ "docker/login-action", "docker/metadata-action", ] -tools = ["cargo", "soldr", "nix", "docker", "python3", "git"] +tools = ["cargo", "soldr", "nix", "docker", "python3", "git"] secrets = [] # wild's platform facade already exists and is already the right shape: @@ -213,7 +221,7 @@ secrets = [] # * `linker-diff/src/utils.rs` — its tests gate `target_os = "linux"` and # `cfg!(target_arch = ...)` around objdump-based disassembly. platform-selector = "libwild/src/host/mod.rs" -platform-code = [ +platform-code = [ "libwild/src/host/**", "libwild/src/args/elf.rs", "libwild/src/tidy_tests.rs", @@ -240,13 +248,13 @@ require = { "cache" = "true", "solo-toolchain-cache" = "false" } # One entry per workflow file the repository actually ships, with the triggers # that file really carries (read off .github/workflows/*.yml, 2026-10-05). [allow.workflows] -"ci.yml" = ["pull_request", "push:main", "workflow_dispatch"] -"cron.yml" = ["schedule", "workflow_dispatch"] -"nix.yml" = ["push:main", "workflow_dispatch"] -"build-images.yml" = ["pull_request", "workflow_dispatch"] -"performance-guard.yml" = ["pull_request"] -"promote.yml" = ["release:published"] -"release.yml" = ["push:tag", "pull_request", "workflow_dispatch"] +"ci.yml" = ["pull_request", "push:main", "workflow_dispatch"] +"cron.yml" = ["schedule", "workflow_dispatch"] +"nix.yml" = ["push:main", "workflow_dispatch"] +"build-images.yml" = ["pull_request", "workflow_dispatch"] +"performance-guard.yml" = ["pull_request"] +"promote.yml" = ["release:published"] +"release.yml" = ["push:tag", "pull_request", "workflow_dispatch"] "update-nix-lockfile.yaml" = ["schedule", "workflow_dispatch"] # ── Publish ────────────────────────────────────────────────────────────────── @@ -262,8 +270,8 @@ require = { "cache" = "true", "solo-toolchain-cache" = "false" } # (RELEASING.md: "Run `cargo publish` for each package"), so it has no # public/private split to declare truthfully. [[exceptions]] -rule = "RUST-005" -path = "wild/tests" -reason = "one integration-test target already; nothing to consolidate" -issue = "https://github.com/zackees/wild/issues/37" +rule = "RUST-005" +path = "wild/tests" +reason = "one integration-test target already; nothing to consolidate" +issue = "https://github.com/zackees/wild/issues/37" expires = "2027-01-31" From db3831f5aaedac3921cf36cdb98369c234e78854 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Sun, 4 Oct 2026 23:39:56 -0700 Subject: [PATCH 3/3] reuse: annotate ci.toml's licensing `fsfe/reuse-action` (the `reuse-check` job) verifies every file carries REUSE licensing metadata. The new `ci.toml` had none and was not listed in REUSE.toml's annotations, so the compliance check failed -- a licensing failure, not a CI one. Inherits the repository's existing annotation: MIT OR Apache-2.0, Copyright 2024-2026 Wild Linker Contributors. --- REUSE.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/REUSE.toml b/REUSE.toml index 9f99b5090..4e0371c7e 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -33,6 +33,7 @@ path = [ "FAQ.md", "USAGE.md", "REUSE.toml", + "ci.toml", "rust-toolchain.toml", "benchmarks/**", "cackle.toml",