Repository navigation
ci: add a schema-3 ci.toml bounding the cache budget (85 entries / 8.48 GB = 83%) - #603
Merged
Merged
Conversation
zackees
added a commit
to forge-ci/ci.yml
that referenced
this pull request
Oct 5, 2026
…t blocks it (#344) **Merged:** forge-ci/reld#218 (ac71f0b), worst case 5.92 GiB against a 9.5 GB budget. 7 entries stay undeclared -- no via exists for msys2-pkgs, llvm-ld-coff, linkers-Linux or setup-soldr-targetcache-thin-v2. **Open drafts:** - forge-ci/bosn#513 -- draft because adding a ci.toml surfaces **461 pre-existing findings** (LAYOUT-001 x208, SEC-004 x148) that were invisible while there was no ci.toml. The agent also corrected my premise: bosn is NOT 221 distinct builds. It is 13 live build-cache entries under 4 toolchain digests -- setup-soldr#237 deliberately dropped the per-commit SHA so caches survive across commits -- plus 196 tiny ci-lint attestation caches. A janitor dry-run plans 9.86 -> 2.07 GB. - zackees/mimalloc-pprof#603 -- draft because a local gate exists. Declared families fit at 8.02 GiB vs 9.5 GB, but 3.58 GiB (42%) is UNDECLARABLE, see below. - FastLED/fbuild#1652 -- fits at 9.75 GB against 9.5 GB, 448 MB headroom. **Structural:** FastLED/FastLED#4703 applies `save: 'false'` on PR board jobs so they restore without writing. It does NOT apply `cache-mode: 'split'` -- verified available (it is on fbuild main and FastLED pins @main, a floating ref) but genuinely broken: setup runs before the compile step synthesises platformio.ini, and fbuild install hard-fails on apollo3_red, clone and kitchensink. Shipping it would turn board jobs red. Stops the leak at ~120 GiB; does not reach 10 GiB. **A bug in my own #334**, found independently by the reld, fbuild and mimalloc-pprof agents: `shapes` made CACHE-004 sum the shape maxima while `_lru_evictions` still used `max x cardinality(per)`. Where they diverge the janitor is stricter, so it evicted live entries precheck had approved. Fixed in #343; both paths now call `family_footprint`. **Next blocker, now the top ci.yml item:** `ALLOWED_VIA_VALUES` has no entry for shapes setup-soldr actually emits, so they can never be declared and are reported undeclared forever -- setup-soldr-targetcache-thin-v2-, setup-soldr-prepare-* without its v3 segment, setup-soldr-tarball-*, setup-soldr-cargo-registry-v2-*, cook-base-v1-*. That is 42% of mimalloc-pprof's cache and blocks reld and fbuild too. Refs #153, #334, #343 Local-Gate: v1 tree=d3697bb3c8052b2e0a9ad339e012e0772ca4c929 secs=73
mimalloc-pprof runs at 85 cache entries / 8.48 GB = 83% of GitHub's 10 GiB per-repo cap, with no ci.toml to bound it. Every family's `max x cardinality(per)` is at or above its measured live footprint, because `ci-lint cache janitor` LRU-evicts down to exactly that product. Verified live against all 85 entries on 2026-10-05: every declared family's budget exceeds its live bytes, so the janitor reclaims nothing live. `shapes` (forge-ci/ci.yml#334) is deliberately not used -- `family_footprint` honours it but `cache.ops._lru_evictions` still computes `max x cardinality` and ignores it, so declaring shapes would make CACHE-004's arithmetic look right while the janitor evicted down to a smaller number. `[cache.promote] mode = "off"`: nearest-ancestor promotion is unreleased. No [local.gate] key: this repository already ships local-gate.toml, and adding a ci.toml makes ci-lint read gate config from ci.toml, so an incomplete [local.gate] would be worse than none. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Local-Gate: v1 tree=607f48cac3d49c6d9f5efe265d422468921271f9 secs=35 lanes=lint:run Ci-Attestation: {"at":1791193741,"gate":"python/all/lint","host":"linux-x86_64","key":"ee5a79f4784ef8fc9f863999530b31520321ac19d0a8f5dccb995bb5ef035d03","lane":"lint","parents":["1118b0674b127f9f2c88646da5359bc582b6d132"],"secs":35,"stamp":"b2a4065d7bbd4785ddcf17c38edbf4ef","tree":"607f48cac3d49c6d9f5efe265d422468921271f9","v":1,"via":"run"}
zackees
force-pushed
the
ci/cache-policy
branch
from
October 5, 2026 09:49
512b6e6 to
4377fe4
Compare
zackees
marked this pull request as ready for review
October 5, 2026 10:23
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Opened as a DRAFT because this repository already ships a
local-gate.tomland adding aci.tomlchanges whereci-lint local-gatereads gate config from. I did not add any[local.gate.*]key —ci_lint/local_gate.py:293-306only prefersci.toml [local.gate]when that table is present, so with it absentlocal-gate.tomlstays the sole declaration. Verified:local-gate lintreports the identical result with and without this file (1 violation, 3 other findings — all pre-existing, and three of them are just "PyYAML not importable" parser gaps).Why
mimalloc-pprof runs at 85 cache entries / 8.48 GB = 83% of GitHub's 10 GiB per-repo cap, with no
ci.tomlto bound it. A toolchain bump lands on top of that.The critical constraint, and how it is met
ci-lint cache janitorLRU-evicts eachevict = "lru"family down tomax x cardinality(per). Under-stating that product makes the janitor delete live caches. So every family's product is at or above its measured live footprint. Verified against all 85 live entries:shapesdeliberately not used, despite #334shapeswas merged in forge-ci/ci.yml#334 and works inci_lint.rules.cache_static.family_footprint— butci_lint.cache.ops._lru_evictions(line 210) still computesmax x cardinality(per)and ignores it. Declaringshapeshere would make CACHE-004's arithmetic look correct while the janitor evicted down to a smaller number — precisely the truncation hazard this PR is meant to avoid.max+perkeeps both paths in agreement. This looks like a gap in #334 worth its own issue:ops._lru_evictionsshould route throughfamily_footprint.Budget arithmetic
8.02 GiB worst case vs a 9.5 GiB budget. It fits, with ~1.4 GiB of headroom for the lockfile generations a setup-soldr bump produces before the janitor reclaims them.
per = "platform"(7) rather than"os"(3) for the four families that need it:cardinality()has no per-lockfile axis, and the live check (_check_family_live_excess) compares live entry count againstcardinality(per) x2. Withper = "os"four families fired CACHE-004 needs_review at 10/14/15/8 live entries against a model of 6.Live audit (
ci-lint cache audit, ci.yml@92106df)Counts: 27 CACHE-001, 2 CACHE-004 needs_review, 16 CACHE-005, 12 CACHE-006, 1 GEN-009. None of these are static-proof failures of this document —
load_ci_tomlis 0 findings and CACHE-004/029/030 are each 0 findings statically. They describe the existing cache state.Two things the task brief got wrong, and one real finding
1.
soldr-prepare-*is NOTsetup-soldr:cross-targets. The brief said it was. It isn't:The live keys are
soldr-prepare-<triple>-<sha>— nov3segment, so noviavalue classifies them. All 1.87 GB is therefore correctly reported undeclared, not silently bound to a family. Declaring it ascross-targetswould have been a lie the audit couldn't catch.2.
msys2-pkgs-upd:*andbenchmark-*are hand-writtenactions/cachekeys, not any sanctioned action's output. Same conclusion: undeclareable viavia.3. The
undeclaredrow is 3.58 GiB — 42% of the repository's cache. Breaking it down:setup-soldr-targetcache-thin-v2-viaexists for itsoldr-prepare-*benchmark-allocators-*msys2-pkgs-upd:*benchmark-references-*/benchmark-fork-*solo-toolchain-v2-*legacy_prefixSo no
ci.tomlcan currently get this repository under budget, and I'm not claiming otherwise.ci-lintneedsviaentries forsetup-soldr-targetcache-thin-v2-and thesoldr-prepare-*shape before 3.58 GiB can be declared rather than left unbounded. That's a ci.yml follow-up, not something to fudge here.Other choices
[cache.promote] mode = "off"— nearest-ancestor promotion is unreleased (setup-soldr#566); claiming it would be a promise nothing implements (CACHE-030).cook-deltadeclared as a family, not under[cache].retired: setup-soldr 0.9.27 still writes it, so retiring would fire CACHE-009 against 3 live entries.[cache.pr] mode = "none", budget0MB— no PR-scoped cache is declared today.platform-selector = "src/prim/prim.c",platform-code = ["src/prim/{osx,unix,windows,wasi,emscripten}/**"]— the C library's real OS-branch layout.allow.setup-soldr.only-in = ".github/actions/soldr"names a directory that does not exist: setup-soldr is called directly from ~15 workflows with no composite wrapper. It's deliberately non-matching rather than naming a fiction. Creating the wrapper is a follow-up.cross.yml's build+test matrices andmacos-bundles.yml's cross matrix.aarch64-pc-windows-msvcis excluded:cross.ymlbuilds it but has no runner for it.What I did NOT do
cache janitorrun, not a side effect of adding a policy file.[local.gate],local-gate.toml, or any workflow.[[exceptions]]. The 3 GEN-003 needs_review findings onci.tomlare the known "required suite's run command isn't in a literalrun:line" case; they resolve to needs_review by design, not a defect to suppress.Reviewer checklist
shapesgap inops._lru_evictionsis worth its own ci.yml issue (it makes bench: hole-purging chart under jemalloc, upstream mimalloc, Bun mimalloc and mimalloc-pprof (Performance section) #334 unusable for exactly the families it was built for).undeclaredfamilies should block adopting a budget at all — 42% of this repo's cache is currently unbounded by any document.[allow]should be populated this loosely for a repo with no ci.toml history, or whether this should land as a minimal cache-only document first.