You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
The release gate's denominator is read from the artifact it judges: a package whose bake breaks silently leaves the check, so the fleet keeps rolling onto releases it has not baked #3441
Maintainer, 2026-09-06: "let's see that the deploy rolls only when all packages of all plugins are baked" — "we kept rolling without edu being properly baked."
The release-availability gate (#1754) already asks the right question and already holds the roll when the answer is no. It nonetheless let environments roll onto releases whose Education content was not baked, while reporting a clean pass. The defect is its DENOMINATOR.
The defect
ReleaseAvailabilityService.RequiredPackages builds the gate's package list from the environment's install records — a mesh query, genuinely independent, and correct. It then decides per package whether a baked bundle is required:
HasContentis the denominator, and it is read from the artifact store the gate is about to judge. So:
Education's bake stops producing a sealed publication;
its packages leave adoptedToday;
leaving adoptedToday sets HasContent: false — "ships no content";
a package that ships no content cannot have a missing bake, so it is exempt;
every later roll is green about precisely the packages that regressed.
The denominator erodes, and it erodes exactly where the gate is needed. A package broken today is exempt tomorrow and cannot re-enter the set on its own.
The limiting case is worse
If the live identity has no sealed publication at all (a fresh storage target, a bake lane pointed at the wrong share, a BAKE_PUBLISH_TARGETS that stopped being written), adoptedToday is empty, every installed package becomes non-content-bearing, and the content half of the gate checks nothing while answering "updatable" — a green tick over zero evidence, with nothing anywhere saying the expected set was empty. That is the 0 expected, 0 found, green shape AGENTS.md forbids in CI gates, living in the runtime.
Fix shape
Take the denominator from every framework identity the published root holds — i.e. from publications written by earlier CD waves, which the run under judgement cannot have produced — and make it MONOTONE: what this environment has ever been able to adopt, it must still be able to adopt. The exemption that motivated the old reading is preserved: a package that has never sealed a bundle under any identity (module-only, NodeType-less) is still not demanded, because demanding one would freeze the environment forever. And "this root serves no bakes at all" becomes a stated NotEnforced with its reason rather than a silent pass.
Scope
Complementary to #3429 (install-time adoption silently adopting nothing) and #3424 (the bake never exercising content assets) — this is the ROLL gate, not the bake or the adoption. It cannot make a bake complete; it refuses to roll onto an incomplete one.
Known blind spot to record with the fix: the denominator is monotone only while old identity directories are retained — see #3438 (ACR retention deleting pinned digests) for the adjacent shape.
Activity
docs(#3441): SealedBundlesForIdentity no longer has a production call…
fix(#3441): the denominator reads the seal's declaration, not every b…
fix(#3441): an absent published root refuses — it must not read as 's…
docs(#3441): name the cost of a monotone denominator