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
test(pm): pin the derived non-PR-event half of check-expected-skips
The recogniser admits only its one exact shape and refuses a pull_request /
push / merge_group term, a negation and every live mixed if:; the derivation
refuses a shared, a listed and an untellable name; the measured #20748 head
judges 0 with its raw-named canary and 4 with a genuinely unexpected skip
beside it, both in-process and through the CLI on a payload file.
Claude-Session: https://claude.ai/code/session_01KTZmMfzVzjNvyaLyQ8mHvg
Co-authored-by: Claude <noreply@anthropic.com>
@@ -1185,6 +1247,104 @@ export function selfTest() {
1185
1247
t('fixture: a null payload → NOT MEASURED',verdictExit(judgeCheckRuns(null)),3);
1186
1248
t('fixture: a roster override is honoured (the judge is pure over its roster)',verdictExit(judgeCheckRuns({total_count: 1,check_runs: [fixtureRun('Build Core','skipped')]},[])),4);
1187
1249
1250
+
// ---- the derived half: the recogniser, one exact shape ---------------------
t("derive: the measured canary if: reads as schedule | workflow_dispatch",gate("github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'"),BOTH);
1254
+
t('derive: …the same, wrapped whole in one ${{ }}',gate("${{ github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' }}"),BOTH);
1255
+
t('derive: …the same, one term per line (a folded block scalar)',gate("github.event_name == 'schedule'\n || github.event_name == 'workflow_dispatch'\n"),BOTH);
1256
+
t('derive: a single schedule term is admitted',gate("github.event_name == 'schedule'"),'["schedule"]');
1257
+
t('derive: a repeated term de-duplicates',gate("github.event_name == 'schedule' || github.event_name == 'schedule'"),'["schedule"]');
1258
+
t('derive: NARROWNESS — a pull_request term beside schedule is NOT admitted',gate("github.event_name == 'schedule' || github.event_name == 'pull_request'"),'null');
1259
+
t('derive: …nor a push term (push fires on a PR branch)',gate("github.event_name == 'schedule' || github.event_name == 'push'"),'null');
1260
+
t('derive: …nor merge_group (the queue build is a verdict, not a skip)',gate("github.event_name == 'merge_group'"),'null');
1261
+
t("derive: …nor a negation (scaffold-local's live `!= 'schedule'` runs on every PR)",gate("github.event_name != 'schedule'"),'null');
t('derive: …nor a label read',gate("github.event_name == 'schedule' || contains(github.event.pull_request.labels.*.name, 'nightly')"),'null');
1271
+
t('derive: …nor a parenthesised term (the allow-list names one bare comparison)',gate("(github.event_name == 'schedule')"),'null');
1272
+
t("derive: …nor a case-folded event (GitHub's == folds case; the recogniser refuses rather than folds)",gate("github.event_name == 'Schedule'"),'null');
1273
+
t('derive: …nor a double-quoted literal (not a GitHub string)',gate('github.event_name == "schedule"'),'null');
1274
+
t('derive: …nor two ${{ }} blocks joined outside an expression',gate("${{ github.event_name == 'schedule' }} || ${{ github.event_name == 'workflow_dispatch' }}"),'null');
1275
+
t('derive: …nor an empty or absent if:',gate('')==='null'&&gate(undefined)==='null'&&gate(true)==='null',true);
1276
+
1277
+
t('derive: a matrix name is kept verbatim, raw',skippedCheckRunName('registry-canary',{name: CANARY_RAW_NAME,strategy: {matrix: {template: ['blank']}}}).name,CANARY_RAW_NAME);
1278
+
t('derive: a job with no name: is named by its key',skippedCheckRunName('nightly',{if: "github.event_name == 'schedule'"}).name,'nightly');
1279
+
t('derive: a name holding a non-matrix expression is refused (its skipped spelling is unmeasured)','refused'inskippedCheckRunName('x',{name: 'Nightly ${{ inputs.target }}'}),true);
1280
+
t('derive: a matrix reference on a job with no strategy.matrix is refused','refused'inskippedCheckRunName('x',{name: 'N: ${{ matrix.os }}'}),true);
1281
+
t('derive: a non-string name: is refused','refused'inskippedCheckRunName('x',{name: 42}),true);
1282
+
1283
+
// A synthetic tree: every admission and every refusal the derivation claims.
t('derive: the synthetic tree admits exactly the schedule/dispatch-only matrix job',JSON.stringify(derivedSyn.rows.map((r)=>`${r.workflow} › ${r.job} › ${r.name}`)),JSON.stringify(['a.yml › canary › Nightly: ${{ matrix.os }}']));
1304
+
t('derive: …as a derived row with the non-pr-event gate and its events',derivedSyn.rows[0]?.derived===true&&derivedSyn.rows[0]?.gate.kind==='non-pr-event'&&JSON.stringify(derivedSyn.rows[0]?.gate.events)===BOTH,true);
1305
+
t('derive: …whose reason names the raw template',derivedSyn.rows[0]?.reason.includes('raw `name:` template'),true);
1306
+
t('derive: the mixed pull_request + schedule job is neither admitted nor refused (it is simply not this shape)',derivedSyn.rows.some((r)=>r.job==='mixed')||derivedSyn.refused.some((r)=>r.job==='mixed'),false);
1307
+
t('derive: a name two jobs carry is refused (a skip of the other would read expected)',refusedAt('weekly').includes('2 jobs in the tree carry'),true);
1308
+
t("derive: a name the listed roster carries is refused (derive, don't list)",refusedAt('listed').includes("derive, don't list"),true);
1309
+
t('derive: a name that cannot be told is refused, with the reason',refusedAt('opaque').includes('inputs.target'),true);
1310
+
t('derive: an unreadable workflow is refused by file',derivedSyn.refused.some((r)=>r.workflow==='c.yml'&&r.job===null),true);
1311
+
t('derive: …and the scan counts every file handed to it',derivedSyn.scanned,3);
t('derive: NARROWNESS — the mixed pull_request + schedule job skipped still judges exit 4',verdictExit(judgeCheckRuns({total_count: 1,check_runs: [fixtureRun('Mixed','skipped')]},synRoster)),4);
1315
+
t('derive: …and so does the refused shared name',verdictExit(judgeCheckRuns({total_count: 1,check_runs: [fixtureRun('Shared','skipped')]},synRoster)),4);
1316
+
1317
+
// ---- the derived half on this checkout's workflows ---------------------------
t('live derive: the workflow listing is not vacuous',liveFiles.length>0&&live.derivation.scanned===liveFiles.length,true);
1322
+
t(`live derive: nothing refused on this tree (${live.derivation.refused.map((r)=>`${r.workflow} › ${r.job}: ${r.reason}`).join(' | ')||'none'})`,live.derivation.refused.length,0);
1323
+
t('live derive: scaffold-e2e.yml › registry-canary is derived under its raw name',live.derivation.rows.find((r)=>r.workflow==='scaffold-e2e.yml'&&r.job==='registry-canary')?.name,CANARY_RAW_NAME);
1324
+
t(
1325
+
"live derive: the measured refusals stay out (release.yml version-pr, merged-branch-reaper.yml reap, scaffold-e2e.yml's PR-running scaffold-local)",
t('live derive: the listed and derived halves share no name',live.derivation.rows.some((r)=>EXPECTED_SKIPS.some((l)=>l.name===r.name)),false);
1330
+
t('live derive: the joined roster is frozen and duplicate-free',Object.isFrozen(live.roster)&&newSet(live.roster.map((r)=>r.name)).size===live.roster.length,true);
1331
+
1332
+
// ---- the measured #20748 head: the card's pins -------------------------------
t('measured #20748: the raw-named skipped canary judges exit 0 against the joined roster',verdictExit(m20748),0);
1335
+
t('measured #20748: 8 skipped, every one expected',m20748.expected.reduce((n,e)=>n+e.count,0)===8&&m20748.unexpected.length===0,true);
1336
+
t('measured #20748: …the canary read as a derived expected skip',m20748.expected.find((e)=>e.name===CANARY_RAW_NAME)?.derived,true);
1337
+
t('measured #20748: …and the report tags it derived',renderReport(m20748).some((l)=>l.includes(CANARY_RAW_NAME)&&l.includes('; derived')),true);
1338
+
t('measured #20748: the LISTED half alone still answers exit 4 on it (the derivation is what moved it)',judgeCheckRuns(measured20748Payload()).unexpected[0]?.name,CANARY_RAW_NAME);
1339
+
constm20748Control=judgeCheckRuns(measured20748Payload([fixtureRun('TypeScript Type Check','skipped',99276458889)]),live.roster);
1340
+
t('measured #20748 CONTROL: a genuinely unexpected skip beside the canary still judges exit 4',verdictExit(m20748Control),4);
1341
+
t('measured #20748 CONTROL: …naming only it',JSON.stringify(m20748Control.unexpected.map((u)=>u.name)),'["TypeScript Type Check"]');
1342
+
t(
1343
+
"measured #20748 CONTROL: the canary's PR-running sibling skipped still judges exit 4",
1344
+
verdictExit(judgeCheckRuns(measured20748Payload([fixtureRun('Scaffold with repo dist','skipped',99276458880)]),live.roster)),
t('cli: the measured #20748 head on disk (raw-named skipped canary) → exit 0',canary.status,0);
1423
+
t('cli: …with the canary on stdout as a derived expected skip',canary.stdout.includes(`${CANARY_RAW_NAME} [scaffold-e2e.yml › registry-canary; derived]`),true);
t('cli: CONTROL — the same head plus a genuinely unexpected skip → exit 4',canaryControl.status,4);
1428
+
t('cli: …naming it under the ⛔ heading',canaryControl.stdout.includes('⛔ unexpected skips (1)')&&canaryControl.stdout.includes('Lint & Repo Gates'),true);
1257
1429
}finally{
1258
1430
rmSync(dir,{recursive: true,force: true});
1259
1431
}
@@ -1286,8 +1458,12 @@ export function selfTest() {
1286
1458
'declared gate kinds — and its truth on this checkout\'s workflows, with the audit driven red on a deleted, renamed, un-gated and '+
1287
1459
"re-gated job, a lost || 'true' widening and an unreadable workflow; the judge on the measured 39-run head and on fixtures for an "+
1288
1460
'expected skip, an unexpected skip named as a filter miss, a same-suite failure read as a dependency skip, a raw matrix template, '+
1289
-
'other conclusions, a pending run and an empty head; read classification for 422 / 404 / 401 / 403 / 5xx / network; argv; the real '+
1290
-
'CLI on payload files for 0 / 4 / 3 and --json; and the structural no-write-path, single-sourced transport and SKILL.md pointer pins).',
1461
+
'other conclusions, a pending run and an empty head; the derived half — the non-PR-event recogniser admitting only its one shape and '+
1462
+
'refusing a pull_request / push / merge_group term, a negation and every live mixed if:, the raw-name rule, and the derivation '+
1463
+
'refusing a shared, a listed and an untellable name — on a synthetic tree and on this checkout\'s workflows; the measured #20748 '+
1464
+
'head judged 0 with its raw-named canary and 4 with a genuinely unexpected skip beside it; read classification for 422 / 404 / 401 / '+
1465
+
'403 / 5xx / network; argv; the real CLI on payload files for 0 / 4 / 3 and --json; and the structural no-write-path, '+
1466
+
'single-sourced transport and SKILL.md pointer pins).',
0 commit comments