fix(ci): correct three unfounded claims, and two gates the work exposed (CLOUD-1431) - #851
Merged
Merged
Conversation
Three corrections to PR #847's own prose, plus the matched-pair experiment that should have preceded it. ## The speed claim was never measured The `ci` job justified carrying a stale `timeout-minutes` with "the expected direction is faster". Nothing here has measured that. The figure traces to CLOUD-1416's title — "up to 40% faster", imported from outside and never reproduced — and every number PR #847 took afterwards measures the CACHE-KEY fix instead: `mise run ci` 498s cold to 315s warm on the SAME architecture, which is build-versus-no-build and swamps any per-core difference. Two lines above the claim, the same comment says these runners "carry identical specifications to their x64 counterparts", which is not a reason to expect a speedup either. `arch-probe.yml` is the experiment that decides it: two jobs, one run, one commit, same steps, same minute, differing only in `runs-on`. Cold on both arms because a warm pair is not available even in principle — each architecture is its own rust-cache family and `cache-warm-linux` writes one of them. `workflow_dispatch` only, so it joins no required check and costs nothing until asked. ## The slack this repository's own change spent `batten-check` stayed cold on the grounds that "a job running in parallel with a 1730s pole has ~1200s of slack". True when written, and falsified by CLOUD-1410 removing the pole. Measured on run 33845451921, the first warm arm64 run of a real `crates/**` change: `ci` 364s, `bats` 271s, and `batten-check` 683s — 1.9x the next longest, and the critical path. The declined trade is unchanged (a second warm writer doubles the cache families against a store already 10.72 GiB over a 10 GiB ceiling), so the answer is CLOUD-1431 or a revert to x64, not a second writer. ## A step whose gate retired out from under it `claim-race-check.sh` is now `batten claim race`, and `race::identify` matches the head COMMIT against the pull-request listing rather than reading a branch. The step created a local branch and changed no commit, so it fed nothing from the moment that landed. Deleting it surfaces what it was obscuring: `race.rs` says "a SHA survives a detached checkout", which holds for a checkout at the PR's head sha and not for one at the MERGE commit — the only kind a `pull_request` event produces. PR #848's merge ref is a31c22b against a head sha of 54789fe, and from that checkout the verb exits 0 with "no open pull request has this commit as its head". A clean pass, byte-identical to a real one, on every PR. That is CLOUD-1433's class in code that landed hours ago. Refs: CLOUD-1416, CLOUD-1422, CLOUD-1433 Admits: 9c04bd4f08b4d23ad6d1588f90715fc118672398f3c8d798f7e4c1e1790ffe9b Admits-rule: protected-mutation Admits-verdict: path write refused Admits-subject: .github/workflows/ci.yml Admits-head: bd36b7a Admits-epoch: be72180d0e5d686be5f83ae25a69845e36834e40619359fc87c6a00d876a7718 Admits-author: alec@wenzowski.com Admits-prev: d85c0573cc0897eb61f37263183978a7214dd7baec96b192528ca57bda214d8e Admits-answer-lost: Three false statements stay in the file a reviewer reads to understand why these jobs sit where they do, and one step keeps running for a reason that no longer exists. The timeout justification is the worst of them: it excuses a number the row already owes a re-derivation for, on grounds nothing measured. Leaving the dead step also hides a real finding — that `batten claim race` abstains in CI on every pull_request run, because a merge-commit checkout matches no PR head SHA — by making it look like the branch-naming step is what handles that case. Admits-answer-precondition: Three corrections to prose and one dead step, all inside .github/workflows/ci.yml, and every one of them is only expressible there because the defective text IS that file's comments. (1) The `ci` job justifies carrying a stale timeout-minutes with "the expected direction is faster" — an unmeasured expectation doing load-bearing work, which arch-probe.yml now exists to replace with a reading. (2) The `batten-check` job justifies staying cold with "a job running in parallel with a 1730s pole has ~1200s of slack" — falsified by this repository's own change: the pole is 364s and that job is now the 683s critical path. (3) The "Name the checkout's branch" step is dead: claim-race-check.sh retired onto `batten claim race`, whose `race::identify` matches the head COMMIT against the PR listing rather than reading a branch, so the step changes nothing it was added for. Admits-answer-rejected-route: config read first: rejected because the defect is comment text and a step in a workflow, not a batten.toml key; no config surface can correct prose or delete a step. patch run first: rejected because there is nothing upstream to restore — this file is this repository's own, and the text being corrected was written by this same session in PR #847. Admits: fb398a57c8d4a23224f10e7a1177749bd49310a1d2d6ed62985c6477692371b6 Admits-rule: protected-mutation Admits-verdict: path write refused Admits-subject: .github/workflows/arch-probe.yml Admits-head: bd36b7a Admits-epoch: be72180d0e5d686be5f83ae25a69845e36834e40619359fc87c6a00d876a7718 Admits-author: alec@wenzowski.com Admits-prev: - Admits-answer-lost: The arm64 decision stays unfalsifiable. CLOUD-1416 moved four jobs on an imported "up to 40% faster" figure never reproduced here, and every number PR #847 took afterwards measures the cache-key fix instead — `mise run ci` 498s cold to 315s warm on the SAME architecture. Without this pair there is no way to tell whether arm64 earns its place or whether reverting `runs-on` to `ubuntu-latest` is the cheaper answer than CLOUD-1431, and the ripsecrets constraint stays owned for a benefit nobody has measured. Admits-answer-precondition: The change is a new workflow that measures a runner class: two jobs, one commit, same steps, differing only in `runs-on`. No config surface can express it — a matched cold pair of GitHub-hosted runners is a workflow or it is nothing, and `batten.toml` has no key that schedules work on a runner. It is `workflow_dispatch` only, so it joins no required check and costs nothing until asked. The write is one file a reviewer reads whole. Admits-answer-rejected-route: config read first: rejected because no batten.toml key can dispatch work to a runner class; reading the config tells you which checks are required, not how fast a CPU is. patch run first: rejected because nothing is being restored — no probe exists, and the two arms cannot be derived from history: there is no cold x64 reading at 4 vCPU for the same work, since the pre-change p95 of 1730s was taken on 2-vCPU runners and mixes cache hits with misses.
|
Warning Review limit reachedNext included review available in 33 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (9)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
`ci-hygiene`'s `cache-warm-compile-is-guarded` reads `--no-run` as its proxy for "a compile that fills a cache" and demands the step be guarded on a `cache-hit` output. That proxy is one-sided: `--no-run` says the step compiles and runs nothing, never that a cache is involved. Measured on `.github/workflows/arch-probe.yml`, added in this bundle to time a cold build on two runner architectures. It matched identically and carries no cache action, so the demanded guard is UNSATISFIABLE rather than missing: with no cache step, `steps.<id>.outputs.cache-hit` resolves to empty, the guard admits everything, and naming an id no step carries is this rule's other arm. Both routes out are worse than the finding. The rule's measured harm needs the cache to exist — "two cache entries carrying the SAME key across five merges... the restore skips saving when the key already exists" is a statement about a restore. With no restore there is nothing to skip. So the primary arm gains one conjunct: the job must carry a cache action. The `cache name unknown` arm is untouched — it already requires a guard to exist and name a missing id, which is a defect wherever it appears. ## The direction of the miss Keyed on `uses` containing `cache`, the ecosystem's own spelling, naming no consumer. A caching action whose name omits it now goes unjudged — but such a job could not express the guard either, since the guard reads a `cache-hit` output only a cache action emits. The rule was unenforceable there before this conjunct, not after it. ## Two cases, and one of them covered nothing before `an_unguarded_cache_warm_compile_is_still_refused` is the anti-vacuity mirror, and the primary arm had NO case of its own until now: narrowing it could have switched the whole arm off and both existing clean-side cases would still have passed. A rule that refuses nothing satisfies every green assertion ever written about it. `a_build_only_job_with_no_cache_is_not_asked_to_guard_on_a_cache_hit` is the new behaviour. ## Why the probe keeps `--no-run`, which is the part worth reading Two committed predicates read those five characters and want opposite things. `ci-parity`'s `foreign-cargo-is-the-declared-spelling` EXEMPTS a line containing ` --no-run`, on reasoning that fits this probe exactly: "a build that compiles and executes nothing cannot go green on work it no longer covers, because it covers none." Drop `--no-run` and the step is refused for not being `test:cargo`'s declared argv — which it must not be, since it measures a build and runs no suite. Writing the step in a third spelling to slip between the two rules was the first attempt and it was a dodge: it satisfied neither predicate's intent and traded a false positive for a differently-shaped one. The rule was wrong, so the rule moved. Refs: CLOUD-1161, CLOUD-1416 Admits: e27d78c299949cdb730436c493551228db35fa11ec65839630ddc3bff75a958d Admits-rule: protected-mutation Admits-verdict: path write refused Admits-subject: .github/workflows/arch-probe.yml Admits-head: 6697599 Admits-epoch: be72180d0e5d686be5f83ae25a69845e36834e40619359fc87c6a00d876a7718 Admits-author: alec@wenzowski.com Admits-prev: fb398a57c8d4a23224f10e7a1177749bd49310a1d2d6ed62985c6477692371b6 Admits-answer-lost: The probe cannot land, so the matched arm64-versus-x64 pair CLOUD-1416 owes is never taken and the arm64 decision stays unfalsifiable. The alternatives are both worse: faking a `cache-hit` guard on a job with no cache step resolves to empty and would then trip the preset's own `cache name unknown` arm, and waiving the rule suppresses a gate that is correct about every real cache-warm job in the tree. Admits-answer-precondition: One step's command and its comment, in the workflow this same branch adds. The `ci-hygiene` preset's `cache-warm-compile-is-guarded` reads `--no-run` as its proxy for a cache-filling compile and fired on this file; the step is a measurement compile with no cache step at all, so the fix is to stop using the spelling that marks a cache-warm step. No config surface can express that — the command is a line in a workflow. Admits-answer-rejected-route: config read first: rejected because the refusal is over a workflow step's command string, not a batten.toml key; reading the config identified which preset fires, it cannot change what the step runs. patch run first: rejected because there is nothing to restore — the file is new on this branch and the text being corrected was written by this session minutes ago.
…n serve
We publish seven release targets and nothing in the tree relates that
list to what a `[[provision]]` platform table can resolve. So a consumer
who installs the `aarch64-unknown-linux-gnu` binary we ship, declares a
`secrets` rule and runs `batten enforce` gets exit 1:
provision ripsecrets: no artifact for linux-aarch64;
the entry pins linux-x86_64, macos-aarch64, macos-x86_64
Measured on job 100903936005, as a red required check rather than as a
consumer report, because moving `batten-check` to `ubuntu-24.04-arm` made
this repository the first arm64 consumer of its own engine.
## The runtime is already right, which is why this is a config gate
`provision.rs` says it in as many words: "Never a silent skip: an entry
that cannot be installed here is a manifest this host cannot satisfy, and
reporting it as fresh would let a gate depending on the tool pass without
the tool." Exit 1 is the correct direction and is unchanged here. What was
missing is AUTHORING-TIME detection, so the pairing is decided on the
change that introduces it.
## Why no standing gate caught it, which is the generalisable half
`lock-complete` holds every `[tools]` entry to three mandatory platforms,
linux-arm64 among them — which is why CLOUD-1416 read the tool surface as
proven, soundly, for the surface it names. `ripsecrets` is not on that
surface: it is the only `[[provision]]` row in the config, and
`[[provision]]` carries no platform-completeness requirement of any kind.
Two pinned-tool surfaces, one gated for arm64 and one not, and the ungated
one holding exactly one entry is why the asymmetry went unseen.
## Building the mapping found a second live instance
`x86_64-pc-windows-gnu` has been in exactly this state for its whole life.
The platform table has no Windows key either, and no runner ever revealed
it. CLOUD-1431 was written about arm64 because an arm64 runner surfaced
arm64; that is the argument for the gate rather than for the one fix.
## What the declared gaps are, and what they are not
`linux-aarch64` and `windows-x86_64` are declared with their reason:
upstream publishes three binaries and has since v0.1.2 —
`aarch64-apple-darwin`, `x86_64-apple-darwin`,
`x86_64-unknown-linux-gnu` — verified against its releases rather than
inferred from the refusal, and `no-source-built-tool` forbids compiling
one. A declared gap does not make the platform work: `enforce` there still
exits 1, fail-closed and loud, which is a refusal rather than scanning.
The durable answer is a scanner that ships those platforms, which is
CLOUD-59's evaluation and its licence question.
## Three arms, and the third is the trigger
The parity refusal; `input.tree.missing`, written rather than left to
abstention; and a target the mapping does not name, which REDDENS rather
than passing — so a newly added release target trips the gate until the
map names it. Reading an unknown triple as covered is the dead-gate shape
this whole file guards against.
The mapping is a static object because regorus reads a multi-arm function
as a multi-value rule and the module would not load, and `-gnu`/`-musl`
collapse to one key because `platform_key()` carries no libc flavour. Both
documents are read INLINE: a top-level rule whose value carries a `deny`
key at any depth silences the whole module, which left `ci-parity` dead
over this repository's own tree, and `batten.toml` is a policy authority
full of the word.
## The tier
`crates/batten/tests/it/release_provision_parity.rs`, over the compiled
binary. This row reads two documents of different formats and depths to
reach one verdict — a `strategy.matrix.include[].target` out of parsed
YAML and a `[provision.platforms.<key>]` sub-table's KEYS out of parsed
TOML — which is exactly what a `with input as` case cannot answer, because
it fabricates the structures in question.
`this_repository_is_clean_today` is the case that carries it, over the real
documents. Its vocabulary must be a directory holding only this module:
`verdicts_in` collects the tokens `.rego` files RAISE and never reads a
config, and registry equality runs in both directions — the real checkout
over-declares and an empty directory under-declares. Both failure modes
measured while writing it.
Refs: CLOUD-1431, CLOUD-1416, CLOUD-59
Admits: 14d7139fd8f80de594179fa148a33e318ba4c195eae1c15d7c36ed4ffe604ee6
Admits-rule: protected-mutation
Admits-verdict: path write refused
Admits-subject: batten.toml
Admits-head: d0a5369
Admits-epoch: be72180d0e5d686be5f83ae25a69845e36834e40619359fc87c6a00d876a7718
Admits-author: alec@wenzowski.com
Admits-prev: 2256f2ccd0da7712842c0753b903fdec2278ac1fe21fd05d1d82ecc39bbf5743
Admits-answer-lost: CLOUD-1431 stays a row instead of a gate. We publish seven release targets, three arm64 plus one Windows, and nothing in the tree relates that list to what a `[[provision]]` platform table can resolve — so a consumer on an uncovered platform meets it as an opaque exit 1 and the next added target or provisioned tool drifts the same way in silence. Building the mapping already surfaced a second live instance nobody had noticed: `x86_64-pc-windows-gnu` has been in exactly this state for its whole life, with no runner to reveal it.
Admits-answer-precondition: Registering a new consumer policy module: one `[[rule]]` row declaring `policy/release-provision-parity.rego` with its `sources`, and one `[[verdict]]` row declaring the `release cover partial` token with its class and route. Both are `batten.toml`'s own surface by construction — a module that is not registered there is never loaded, and a token no `[[verdict]]` row declares fails the load and names the key. There is no other file either statement can live in.
Admits-answer-rejected-route: config read first: rejected because reading the config is what identified the gap; a rule and a verdict row cannot be declared anywhere but in the config that loads them. patch run first: rejected because there is nothing to restore — the module is new, and the upstream artifact the gap is about does not exist to pin (ripsecrets v0.1.11 publishes three binaries and no linux-arm64 or windows one, verified against its releases).
Admits: 8ffa20576d35bb3f9d8952878abeb7d4e111fe74002273bfe4d9c53e58bdd638
Admits-rule: protected-mutation
Admits-verdict: path write refused
Admits-subject: batten.toml
Admits-head: d0a5369
Admits-epoch: 5e7891b43e37f9775a7048bf205db41cf48eb56617efe539e049c96fc151b50a
Admits-author: alec@wenzowski.com
Admits-prev: 14d7139fd8f80de594179fa148a33e318ba4c195eae1c15d7c36ed4ffe604ee6
Admits-answer-lost: The module cannot load, so the rule row beside it is inert and CLOUD-1431 stays a row rather than a gate. Nothing would then relate the seven targets `release-artifacts.yml` publishes to what a `[[provision]]` table can resolve, and the second live instance this work surfaced — `x86_64-pc-windows-gnu`, uncovered for its whole life with no runner to reveal it — goes back to being invisible.
Admits-answer-precondition: The second half of the same registration: the `[[verdict]]` row declaring `release cover partial`, with its gloss, class and route. A module raising a token no row declares fails to load and says which key, so this write is what makes the rule row already added in this commit loadable at all. A verdict row has no other home than the config that reads it.
Admits-answer-rejected-route: config read first: rejected because reading the config is what established the token is undeclared; only a write declares it. patch run first: rejected because nothing is being restored — the class is new, named from the declared `[vocabulary]` subject `release`, action `cover` and condition `partial`.
Admits: 772e0f46eb675359c98018731c124e3dab7ef0348c135dbd7abc1132b7d3ff20
Admits-rule: protected-mutation
Admits-verdict: path write refused
Admits-subject: policy/release-provision-parity.rego
Admits-head: d0a5369
Admits-epoch: 3a306f0d91b6df1d0580cfd3355a2f150b7c86658ca46e55e82d9f45e95aa485
Admits-author: alec@wenzowski.com
Admits-prev: -
Admits-answer-lost: The gate cannot load clean, so the whole of CLOUD-1431's mechanism stays out of the tree: nothing relates the seven targets `release-artifacts.yml` publishes to what a `[[provision]]` row can resolve, and the second instance this work surfaced — `x86_64-pc-windows-gnu`, uncovered for its whole life with no runner to reveal it — goes back to being invisible. Landing the module untested would also make the declared-gap arm unfalsifiable, and that arm is the only thing between this gate and a red tree.
Admits-answer-precondition: The module's own `test_` rules — the load-time tier `batten policy test` demands and which it just refused this file for: `predicate-unexercised release-target-has-a-provisioned-scanner` and `module-untested policy/release-provision-parity.rego`. A module's load-time tier lives inside the module by construction; there is no other file it can be written in, and the coverage binds on the predicate id literal inside the violation. The file became protected only because registering it in `batten.toml` put it in the union `hook.rs` builds from every registered policy rule.
Admits-answer-rejected-route: config read first: rejected because a module's `test_` rules are Rego in the module, not a `batten.toml` key; the config is what registered the module and thereby protected it. patch run first: rejected because there is nothing to restore — the module and its tests are both new in this commit.
wenzowski
marked this pull request as ready for review
September 4, 2026 10:55
wenzowski
force-pushed
the
claude/ci-warm-both-poles-cg7jpu
branch
from
September 4, 2026 10:55
4a5ed95 to
c09fc87
Compare
|
❌ The last analysis has failed. |
Contributor
Author
|
/fast-forward |
This was referenced Sep 4, 2026
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.
Three commits. The first corrects claims PR #847 landed and adds the experiment
that should have preceded it; the second and third are gates the first one's work
exposed, fixed here rather than filed for later.
DO-NOT-CLOSE CLOUD-1416
DO-NOT-CLOSE CLOUD-1422
DO-NOT-CLOSE CLOUD-1433
DO-NOT-CLOSE CLOUD-1161
Closes CLOUD-1431
CLOUD-1416 is not closed: its acceptance is a reading this PR makes possible
rather than takes —
arch-probe.ymlisworkflow_dispatchand cannot bedispatched until it is on
main.1. The speed claim was never measured, and it was doing load-bearing work
The
cijob justified carrying a staletimeout-minuteswith "the expecteddirection is faster." Nothing here has ever measured that.
from outside and never reproduced.
architecture:
mise run ci498s cold to 315s warm on the same architecture.specifications to their x64 counterparts — 4 CPUs, 16 GB RAM, 14 GB storage."
So arm64's benefit is written as unknown, and
arch-probe.ymlis the matchedpair that decides it: two jobs, one run, one commit, same steps, same minute,
differing only in
runs-on. Cold on both arms because a warm pair is impossiblein principle —
runnerOS-runnerArchsits inside rust-cache's restore prefix, soeach architecture is its own family and
cache-warm-linuxwrites exactly one.--no-runis load-bearing in two directions at once, which is what turned aworkflow tweak into a rule fix.
ci-parity'sforeign-cargo-is-the-declared-spellingexempts it, on reasoning that fits this probe exactly;
ci-hygiene'scache-warm-compile-is-guardedtriggers on it. Writing the step in a thirdspelling to slip between them was the first attempt and it was a dodge.
The slack this change spent
batten-checkstayed cold on the grounds that "a job running in parallel with a1730s pole has ~1200s of slack". True when written; falsified by CLOUD-1410
removing the pole. Run 33845451921, first warm arm64 run of a real
crates/**change:
ci364s,bats271s,batten-check683s — the critical path, 1.9×the next longest. The declined trade is unchanged, so the answer is CLOUD-1431 or
a revert to x64, not a second warm writer.
And a step whose gate retired out from under it
claim-race-check.shis nowbatten claim race, andrace::identifymatches thehead commit rather than reading a branch, so the
Name the checkout's branchstep fed nothing. Deleted — which surfaces what it obscured:
race.rssays "a SHAsurvives a detached checkout", true at the PR's head sha and false at the merge
commit, the only kind
pull_requestproduces. PR #848's merge ref isa31c22b3against head
54789fe9, and from that checkout the verb exits 0 withno open pull request has this commit as its head. A clean pass, byte-identical to a real one,on every PR. Recorded on CLOUD-1433.
2. A cache guard is demanded only where a cache exists
cache-warm-compile-is-guardedread--no-runas its proxy for a cache-fillingcompile. The proxy is one-sided, and for a cacheless job the demanded guard is
unsatisfiable rather than missing:
steps.<id>.outputs.cache-hitresolves toempty, the guard admits everything, and naming an id no step carries is the rule's
other arm. Its measured harm is a statement about a restore, and there is no
restore to skip.
One conjunct on the primary arm; the
cache name unknownarm is untouched. Andthe primary arm had no test at all — narrowing it could have switched the whole
arm off with both existing clean-side cases still passing, so
an_unguarded_cache_warm_compile_is_still_refusedis the anti-vacuity mirror.3. What we publish against what a provision row can serve
We publish seven release targets and nothing related that list to what a
[[provision]]platform table can resolve. A consumer installing theaarch64-unknown-linux-gnubinary we ship, with asecretsrule, getsprovision ripsecrets: no artifact for linux-aarch64.The runtime is already right —
provision.rs: "Never a silent skip… reportingit as fresh would let a gate depending on the tool pass without the tool." Exit 1
is the correct direction and is unchanged. What was missing is authoring-time
detection.
Why no standing gate caught it:
lock-completeholds every[tools]entry tothree mandatory platforms, which is why CLOUD-1416 read the tool surface as proven
— soundly, for the surface it names.
[[provision]]has no such requirement andholds one entry.
Building the mapping found a second live instance.
x86_64-pc-windows-gnuhasbeen in exactly this state for its whole life, with no runner to reveal it. That is
the argument for the gate rather than for the one fix.
Declared gaps carry their reason and do not pretend to fix anything: upstream
publishes three binaries and has since v0.1.2, verified against its releases
rather than inferred, and
no-source-built-toolforbids compiling one.enforceon those platforms still exits 1 — a refusal, not scanning. The durable answer is
a scanner that ships them, which is CLOUD-59's evaluation.
Three arms, and the third is the trigger: the parity refusal, the
input.tree.missingclause, and a target the mapping does not name — whichreddens rather than passing, so a newly added release target trips the gate
until the map names it.
Still owed
Dispatching
arch-probe.ymland recording the pair on CLOUD-1416. The resultdecides whether arm64 stays, and if it comes back flat, reverting
runs-ontoubuntu-latestacross the family is cheaper than CLOUD-1431's fix — it returnsbatten-checkto a family with a warm writer and deletes the ripsecretsconstraint instead of declaring around it.