6666 *
6767 * ## What is deliberately NOT changed
6868 *
69- * - `cancelled` still passes without counting (#3668). Cancellation is a
70- * run-lifecycle state: with cancel-in-progress on, every superseded push
71- * cancels the in-flight matrix, and #3668 measured (run 30271824408) that a
72- * real shard failure DOMINATES the aggregate over a cancelled sibling — it
73- * reads `failure`, never `cancelled`. So `cancelled` masks no regression,
74- * and demanding credentials there would paint the false red on the
75- * superseded SHA that #3668 removed.
69+ * - `cancelled` with ZERO attestations still passes without counting
70+ * (#3668). Cancellation is a run-lifecycle state: with cancel-in-progress
71+ * on, every superseded push cancels the in-flight matrix, and #3668
72+ * measured (run 30271824408) that a real shard failure DOMINATES the
73+ * aggregate over a cancelled sibling — it reads `failure`, never
74+ * `cancelled`. So a superseded matrix masks no regression, and demanding
75+ * credentials there would paint the false red on the superseded SHA that
76+ * #3668 removed.
77+ * ⛔ That argument covers a shard that RAN AND FAILED. It does not cover a
78+ * shard killed while still executing, which produces no verdict at all —
79+ * there is no `failure` to dominate (#16157, run 34007386254: `Test Core
80+ * (2/6)` cancelled at 35m by its job timeout with the test step still
81+ * `in_progress`, five siblings attested, and the required check went
82+ * green two seconds later over the shard's untested packages). So the
83+ * count splits `cancelled`: with AT LEAST ONE attestation of the leg
84+ * present, the matrix ran, the declared roster is knowable, and it is
85+ * REQUIRED — every missing shard is named and the gate is red. Only the
86+ * zero-attestation shape keeps the pass; `judge()` carries both.
7687 * - `skipped` still passes ONLY when the `filter` job itself succeeded
7788 * (#4928). `skipped` alone cannot separate "the path filter said no core
7889 * paths changed" from "the path filter exploded and took every downstream
@@ -299,12 +310,31 @@ export function judge({ gate, legs, filterResult, present, runId, runAttempt, do
299310 log . push ( ` leg ${ label } — aggregate result: ${ leg . result } ` ) ;
300311
301312 if ( leg . result === 'cancelled' ) {
302- // #3668: a run-lifecycle state, not a shard verdict. Legs that finished
303- // before the cancellation may legitimately have attested, so their
304- // credentials are ALLOWED but none are REQUIRED.
313+ // A run-lifecycle state, not a shard verdict — and it arrives in two
314+ // shapes that the count tells apart (#16157):
315+ //
316+ // - ZERO shards of the leg attested: the whole matrix was superseded
317+ // (cancel-in-progress on a newer push, #3668). No shard produced a
318+ // verdict, the SHA is dead, and demanding credentials would paint
319+ // the false red #3668 removed. Passes without counting.
320+ // - AT LEAST ONE shard attested: the matrix RAN. A sibling that still
321+ // reads `cancelled` was killed mid-suite and produced no verdict, so
322+ // no `failure` exists to dominate the aggregate (run 34007386254:
323+ // shard 2/6 cancelled by its job timeout with the test step
324+ // `in_progress`, five siblings attested). The declared roster is
325+ // knowable from the shards that did attest, so it is REQUIRED —
326+ // the leg falls through to the count below, every missing shard is
327+ // named, and the required check goes red.
305328 for ( const id of roster ) allowed . add ( id ) ;
306- log . push ( ` satisfied (cancelled — run-lifecycle state, #3668; expected attestations: 0)` ) ;
307- continue ;
329+ const attested = roster . filter ( ( id ) => present . has ( id ) ) ;
330+ if ( attested . length === 0 ) {
331+ log . push ( ` satisfied (cancelled — run-lifecycle state, #3668; expected attestations: 0)` ) ;
332+ continue ;
333+ }
334+ log . push (
335+ ` cancelled AFTER ${ attested . length } of ${ roster . length } declared shard(s) attested — not a superseded matrix; ` +
336+ `the roster is REQUIRED and every missing shard is named (#16157)` ,
337+ ) ;
308338 }
309339
310340 if ( leg . result === 'skipped' ) {
@@ -339,8 +369,13 @@ export function judge({ gate, legs, filterResult, present, runId, runAttempt, do
339369 counted += roster . length ;
340370 if ( missing . length > 0 ) {
341371 errors . push (
342- `${ gate } : ${ missing . length } of ${ roster . length } declared shard(s) of ${ leg . job } published no positive attestation ` +
343- `(${ missing . join ( ', ' ) } ). A shard that never ran cannot be counted as passing — see #6082.` ,
372+ leg . result === 'cancelled'
373+ ? `${ gate } : ${ missing . length } of ${ roster . length } declared shard(s) of ${ leg . job } published no positive attestation ` +
374+ `(${ missing . join ( ', ' ) } ) while ${ roster . length - missing . length } sibling(s) did ` +
375+ `(${ roster . filter ( ( id ) => present . has ( id ) ) . join ( ', ' ) } ). The leg was cancelled mid-run, so the missing ` +
376+ `shard(s) produced no verdict at all — an untested shard is not a passing shard, see #16157.`
377+ : `${ gate } : ${ missing . length } of ${ roster . length } declared shard(s) of ${ leg . job } published no positive attestation ` +
378+ `(${ missing . join ( ', ' ) } ). A shard that never ran cannot be counted as passing — see #6082.` ,
344379 ) ;
345380 }
346381 if ( leg . result === 'failure' ) {
@@ -933,7 +968,8 @@ const SELF_TEST_BATTERIES = Object.freeze({
933968 '(iii) N-1 positives + one explicit failure ⇒ red' : 4 ,
934969 '(iv) filter-skipped family ⇒ green with expected-N adjusted to 0' : 1 ,
935970 'the #4928 guard itself must not regress' : 8 ,
936- '#3668 lifecycle: cancelled passes without counting' : 2 ,
971+ '#3668 lifecycle: a superseded matrix (cancelled, zero attestations) passes without counting' : 3 ,
972+ '#16157 partial cancellation: attested shards make the roster REQUIRED' : 14 ,
937973 'dogfood-gate: a matrix leg and a single leg under one context' : 5 ,
938974 'foreign / stale credentials' : 3 ,
939975 '#11998: attempt scoping, in both directions' : 26 ,
@@ -947,7 +983,7 @@ const SELF_TEST_BATTERIES = Object.freeze({
947983
948984// DELETING an entry silences that battery's floor exactly as effectively as
949985// zeroing it, so the roster's own size is pinned too.
950- const SELF_TEST_BATTERY_FLOOR = 15 ;
986+ const SELF_TEST_BATTERY_FLOOR = 16 ;
951987
952988// The key an assertion is filed under when no battery is open. It is not a
953989// declared battery, so it reds by the same set difference rather than silently
@@ -1043,10 +1079,89 @@ async function selfTest() {
10431079 assert ( testGate ( 'skipped' , [ ] , 'cancelled' ) . ok , '#3668: a cancelled filter still lets a skipped leg pass' ) ;
10441080 assert ( ! testGate ( 'skipped' , [ attest ( 'test' , 1 , 3 ) ] ) . ok , 'a credential from a leg that was reported skipped is a contradiction ⇒ red' ) ;
10451081
1046- // ── #3668 lifecycle: cancelled passes without counting ────────────────────
1047- battery ( '#3668 lifecycle: cancelled passes without counting' ) ;
1048- assert ( testGate ( 'cancelled' , [ ] ) . ok , '#3668: a cancelled matrix passes with zero credentials (superseded SHA)' ) ;
1049- assert ( testGate ( 'cancelled' , [ attest ( 'test' , 1 , 3 ) ] ) . ok , '#3668: a leg that attested before the cancellation is allowed, not required' ) ;
1082+ // ── #3668 lifecycle: a superseded matrix passes without counting ──────────
1083+ // The shape #3668 measured: cancel-in-progress killed the whole matrix on a
1084+ // superseded SHA, no shard ran, none attested. That — and only that — is the
1085+ // cancellation the gate passes without counting.
1086+ battery ( '#3668 lifecycle: a superseded matrix (cancelled, zero attestations) passes without counting' ) ;
1087+ const superseded = testGate ( 'cancelled' , [ ] ) ;
1088+ assert ( superseded . ok , '#3668: a cancelled matrix passes with zero credentials (superseded SHA)' ) ;
1089+ assert (
1090+ superseded . log . some ( ( l ) => l . includes ( '#3668' ) && l . includes ( 'expected attestations: 0' ) ) ,
1091+ '#3668: the zero-attestation pass still says so in its own log line, verbatim' ,
1092+ ) ;
1093+ assert (
1094+ superseded . log . some ( ( l ) => l . includes ( 'no shard was expected to run, and none claimed to' ) ) ,
1095+ '#3668: with nothing attested the verdict line may honestly say none claimed to' ,
1096+ ) ;
1097+
1098+ // ── #16157 partial cancellation: attested shards make the roster REQUIRED ─
1099+ // THE MEASURED SEQUENCE (run 34007386254, PR #16131): `Test Core (2/6)` was
1100+ // cancelled at 35m01s by its job timeout with `Run this shard's tests` still
1101+ // `in_progress`; shards 1, 3, 4, 5 and 6 attested; the aggregate read
1102+ // `cancelled`; and the required `Test Core` context went green two seconds
1103+ // later printing `expected attestations: 0` — while the step above it had
1104+ // just downloaded five credentials. A killed shard produces no verdict, so
1105+ // #3668's "failure dominates" argument has nothing to dominate with. The
1106+ // ruling on #16157 (option A) overturns the pin that used to sit here
1107+ // ("a leg that attested before the cancellation is allowed, not required"):
1108+ // once ANY shard of a cancelled leg attested, the roster is REQUIRED.
1109+ battery ( '#16157 partial cancellation: attested shards make the roster REQUIRED' ) ;
1110+ const partialCancel = testGate ( 'cancelled' , [ attest ( 'test' , 1 , 3 ) ] ) ;
1111+ assert ( ! partialCancel . ok , '#16157: a cancelled leg with 1 of 3 attested ⇒ red (the overturned #3668 pin, inverted)' ) ;
1112+ assert (
1113+ partialCancel . errors . some ( ( e ) => e . includes ( 'test-2-of-3' ) && e . includes ( 'test-3-of-3' ) && e . includes ( '#16157' ) ) ,
1114+ '#16157: the error names EVERY missing shard and its issue' ,
1115+ ) ;
1116+ assert (
1117+ partialCancel . errors . some ( ( e ) => e . includes ( 'test-1-of-3' ) && e . includes ( 'sibling' ) ) ,
1118+ '#16157: the error also names the sibling(s) that did attest — the reason the roster is knowable' ,
1119+ ) ;
1120+ assert (
1121+ partialCancel . log . some ( ( l ) => l . includes ( 'cancelled AFTER 1 of 3' ) && l . includes ( 'REQUIRED' ) ) ,
1122+ '#16157: the log states that the leg fell through to the count and why' ,
1123+ ) ;
1124+ assert (
1125+ ! partialCancel . log . some ( ( l ) => l . includes ( 'expected attestations: 0' ) ) ,
1126+ '#16157: a partially attested leg never prints the zero-expectation line that made the transcript contradict itself' ,
1127+ ) ;
1128+ // The measured shape itself, on the real 6-shard roster.
1129+ const sixShard = ( result , ids , runAttempt = '1' ) =>
1130+ judge ( { gate : 'Test Core' , legs : [ { job : 'test' , total : 6 , result } ] , filterResult : 'success' , present : new Map ( ids ) , runId : '99' , runAttempt } ) ;
1131+ const fiveOfSix = [ 1 , 3 , 4 , 5 , 6 ] . map ( ( n ) => attest ( 'test' , n , 6 ) ) ;
1132+ const measuredCancel = sixShard ( 'cancelled' , fiveOfSix ) ;
1133+ assert ( ! measuredCancel . ok , '#16157 measured sequence: shard 2/6 killed mid-run, five siblings attested ⇒ red' ) ;
1134+ assert (
1135+ measuredCancel . errors . some ( ( e ) => e . includes ( '1 of 6 declared shard(s)' ) && e . includes ( '(test-2-of-6) while 5 sibling(s) did' ) ) ,
1136+ '#16157 measured sequence: exactly the killed shard is named as missing, none of the five that attested' ,
1137+ ) ;
1138+ // Both directions of the split: zero attested keeps #3668's pass; a full
1139+ // roster under a late cancellation (a post-step cancelled after every shard
1140+ // attested) is a pass because every shard is accounted for, not because the
1141+ // word `cancelled` waived the count.
1142+ assert ( sixShard ( 'cancelled' , [ ] ) . ok , '#16157 boundary: cancelled with ZERO attestations is still the #3668 pass' ) ;
1143+ const lateCancel = sixShard ( 'cancelled' , [ 1 , 2 , 3 , 4 , 5 , 6 ] . map ( ( n ) => attest ( 'test' , n , 6 ) ) ) ;
1144+ assert ( lateCancel . ok , '#16157: cancelled with 6 of 6 attested ⇒ green — every shard is accounted for' ) ;
1145+ assert (
1146+ lateCancel . log . some ( ( l ) => l . includes ( 'all 6 declared shard(s) published a positive attestation' ) ) ,
1147+ '#16157: that green is a COUNTED verdict (6/6), never "none claimed to"' ,
1148+ ) ;
1149+ // Orthogonal to the dominance experiment: a real failure is still a declared
1150+ // negative, and it still dominates a cancelled sibling in the aggregate, so
1151+ // the `failure` path is untouched by the split.
1152+ const dominated = testGate ( 'failure' , [ attest ( 'test' , 1 , 3 ) , attest ( 'test' , 2 , 3 ) ] ) ;
1153+ assert ( ! dominated . ok && dominated . errors . some ( ( e ) => e . includes ( 'declared negative' ) ) , '#3668 dominance: a real failure over a cancelled sibling still reads `failure` and is red on its own veto' ) ;
1154+ // #11998 interplay: attempt scoping is unchanged. Credentials a declared leg
1155+ // accounts for are counted whichever attempt of this run published them.
1156+ const carriedFull = sixShard ( 'cancelled' , [ 1 , 2 , 3 , 4 , 5 , 6 ] . map ( ( n ) => attest ( 'test' , n , 6 , '99' , '1' ) ) , '2' ) ;
1157+ assert ( carriedFull . ok , '#16157 × #11998: attempt 2 cancelled, all six attempt-1 credentials carried over ⇒ green' ) ;
1158+ const carriedShort = sixShard ( 'cancelled' , [ 1 , 2 , 3 , 4 , 5 ] . map ( ( n ) => attest ( 'test' , n , 6 , '99' , '1' ) ) , '2' ) ;
1159+ assert ( ! carriedShort . ok && carriedShort . errors . some ( ( e ) => e . includes ( '(test-6-of-6)' ) ) , '#16157 × #11998: attempt 2 cancelled with five carried-over credentials ⇒ red naming the sixth' ) ;
1160+ // The final verdict line never contradicts the download step above it.
1161+ assert (
1162+ ! measuredCancel . log . some ( ( l ) => l . includes ( 'none claimed to' ) ) && ! measuredCancel . log . some ( ( l ) => l . includes ( 'satisfied' ) ) ,
1163+ '#16157: a red partial cancellation prints no satisfied line at all' ,
1164+ ) ;
10501165
10511166 // ── dogfood-gate: a matrix leg and a single leg under one context ─────────
10521167 battery ( 'dogfood-gate: a matrix leg and a single leg under one context' ) ;
@@ -1497,7 +1612,7 @@ async function selfTest() {
14971612 process . exit ( 1 ) ;
14981613 }
14991614 console . log (
1500- `✓ check-shard-attestation --self-test: ${ checked } assertions (dominance experiment + both #6082 counter-examples + the #4928 guard + the #6589 classifier pins + the #10889 quoting pins + the #11998 attempt-scoping sequence).` ,
1615+ `✓ check-shard-attestation --self-test: ${ checked } assertions (dominance experiment + both #6082 counter-examples + the #4928 guard + the #6589 classifier pins + the #10889 quoting pins + the #11998 attempt-scoping sequence + the #16157 partial-cancellation split ).` ,
15011616 ) ;
15021617
15031618 return SELF_TEST_VERDICT ;
0 commit comments