Skip to content

Commit 0eb90c0

Browse files
committed
test(cli): derive the os build --json exit count from compile.ts, so an honest new exit cannot red main at night
`build-json-failure-{warnings,conversions}.e2e.test.ts` each froze three integers read off `packages/cli/src/commands/compile.ts` — 11 payload literals, 10 `success: false`, 1 `success: true`. All six were correct; the defect is the shape. Both files are nightly-tier by name, so the pull request that adds an honest twelfth exit cannot collect them (measured: `OS_TEST_TIERS` unset collects 267 files in this package with zero of these two among them, `=nightly` collects 68 with both), merges green, and leaves `main` red until a cron says so — the #18848 incident, pre-staged. Ported from the shape PR #18880 landed on the `validate-json-failure-*` pair: the count is derived (`toHaveLength(callSites.length)` against a word-boundary `emitJson` call-site match over the same masked source the extractor reads), the old integer is demoted to a `toBeGreaterThanOrEqual(10)` floor that rots only in the exits-are-removed direction, and one partition assertion (`success: true` ×1, `success: false` = `literals.length - 1`) replaces the two frozen counts. The verdict key was re-derived rather than copied: `compile.ts` spells it `success:`, not the `valid:` of `validate.ts` — measured over the 11 masked payload literals, `success: false` 10 / `success: true` 1 / `valid:` 0. Claude-Session: https://claude.ai/code/session_01DvvamiacK328idtBYJBxV3 Co-authored-by: Claude <noreply@anthropic.com>
1 parent f112a74 commit 0eb90c0

2 files changed

Lines changed: 138 additions & 17 deletions

File tree

‎packages/cli/test/build-json-failure-conversions.e2e.test.ts‎

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -428,15 +428,78 @@ describe('#12125 — the contract is exhaustive over `compile.ts`, not just over
428428
expect(found[1]).toContain('conversions: conversionNotices');
429429
});
430430

431-
it('all 11 `emitJson` exits carry `conversions` — 10 failure exits and the success payload', () => {
431+
it('every `emitJson` exit carries `conversions` — the exit count is READ OFF the source, never an integer', () => {
432432
const literals = payloadLiterals(SRC);
433-
// The tenth failure exit is ADR-0130 D4's per-package author-time rule leg
434-
// (#14439): a multi-package artifact runs the same rule table once per
435-
// package, and its refusal is an exit like any other — which is exactly
436-
// what this count exists to notice.
437-
expect(literals, 'the `emitJson` exit count moved — a new exit must carry `conversions` too').toHaveLength(11);
438-
expect(literals.filter((p) => p.includes('success: false'))).toHaveLength(10);
433+
434+
// ⭐ #18894 — these three lines read `toHaveLength(11)` / `10` / `1`. All
435+
// three were CORRECT on the day this card was filed, and that is the point:
436+
// the defect is the SHAPE, not a stale number. The identical shape on the
437+
// `validate.ts` pair put `main` in the red with no run to say so (#18848)
438+
// the moment `validate.ts` gained a seventh, entirely legitimate exit
439+
// (#18769) — the CONTRACT held throughout and only the COUNT was stale.
440+
// Because this file is nightly-tier by NAME (`*.e2e.test.ts` —
441+
// `scripts/nightly-tiers.mjs`), no pull request and no merge-queue run can
442+
// collect it: measured on the branch that landed this, `OS_TEST_TIERS`
443+
// unset collects 267 files in this package with ZERO of them this one, and
444+
// `=nightly` collects 68 with this one in it. An integer that only a cron
445+
// can read is a pin with no reader at the moment it matters — the honest
446+
// new exit merges green and `main` is red from that moment until a cron
447+
// says so.
448+
//
449+
// ⛔ So the count is not re-pinned to 12 — that just re-arms the same trap
450+
// for exit thirteen. It is DERIVED: the extractor read every `emitJson`
451+
// call site the file has, whatever today's number is. An honest new exit
452+
// stays green here and is still held to the contract below and to the
453+
// sink loop further down; a needle that stopped matching one reddens HERE
454+
// instead of quietly turning that negative into a vacuous pass over fewer
455+
// exits than the file has.
456+
//
457+
// Both sides read the MASKED source, which is what keeps them symmetric AND
458+
// keeps prose out of both (#18520, applied to this file by #18924).
459+
// Measured on the commit that landed this: `compile.ts` carries 13 raw
460+
// occurrences of the identifier, of which 2 are prose the mask blanks and 1
461+
// is the `import { … emitJson, … }` line — which carries no paren and so
462+
// matches neither side — leaving raw and masked agreeing on the same 11
463+
// payload literals and the same 11 call sites. ⚠️ That agreement is a
464+
// reading, not a law: `emitJson` is IMPORTED here, never declared, so the
465+
// looser `\bemitJson\s*\(` cannot match a `function emitJson(` definition
466+
// and over-count. A future file that declares it would break the symmetry
467+
// and reddens HERE, which is the correct place to find that out.
468+
const callSites = SRC.match(/\bemitJson\s*\(/g) ?? [];
469+
expect(
470+
literals,
471+
'an `emitJson(` call site the payload extractor could not read — the contract below would skip it',
472+
).toHaveLength(callSites.length);
473+
474+
// The one integer left, and it rots only in the direction that has to be
475+
// reviewed anyway: exits being REMOVED. Ten is the population the ruling in
476+
// this file's header was made over — nine failure exits plus the terminal
477+
// success payload, the count `#12285` pinned on the day it landed — not a
478+
// count of today. (Today is eleven: the tenth FAILURE exit is ADR-0130 D4's
479+
// per-package author-time rule leg, #14439, a multi-package artifact
480+
// running the same rule table once per package. It arrived after the ruling
481+
// and is an exit like any other — which is exactly what a derived count
482+
// exists to absorb and a frozen one exists to trip over.) It is also the
483+
// floor under the one vacuum the derived pair shares — an `emitJson`
484+
// renamed out of existence takes BOTH sides to zero and every assertion
485+
// here with them.
486+
expect(
487+
literals.length,
488+
'`os build --json` publishes fewer exits than the ruling above was made over',
489+
).toBeGreaterThanOrEqual(10);
490+
491+
// Exactly one success payload; every other exit is a failure exit. The
492+
// second count is derived from the length, so the two together also assert
493+
// the PARTITION — an exit carrying neither literal reddens.
494+
//
495+
// ⚠️ The verdict key here is `success:`, NOT the `valid:` the sibling pair
496+
// over `validate.ts` reads — the two commands do not share it. Measured on
497+
// the commit that landed this, over the 11 masked payload literals of
498+
// `compile.ts`: `success: false` 10, `success: true` 1, `valid: false` 0,
499+
// `valid: true` 0. A verbatim port of the sibling's two lines would assert
500+
// over an empty population.
439501
expect(literals.filter((p) => p.includes('success: true'))).toHaveLength(1);
502+
expect(literals.filter((p) => p.includes('success: false'))).toHaveLength(literals.length - 1);
440503

441504
const bare = literals.filter((p) => !p.includes('conversions:'));
442505
expect(

‎packages/cli/test/build-json-failure-warnings.e2e.test.ts‎

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -507,19 +507,77 @@ describe('#11772 — the contract is exhaustive over `compile.ts`, not just over
507507
expect(found[1]).toContain('warnings: warningsSoFar()');
508508
});
509509

510-
it('all 11 `emitJson` exits carry `warnings` — 10 failure exits and the success payload', () => {
510+
it('every `emitJson` exit carries `warnings` — the exit count is READ OFF the source, never an integer', () => {
511511
const literals = payloadLiterals(SRC);
512-
// The enumeration measured on this card, three MORE than the filing card's
513-
// table listed: it missed the protocol-parse exit, the `--no-runtime-bundle`
514-
// refusal, and the bottom catch-all.
512+
513+
// ⭐ #18894 — these three lines read `toHaveLength(11)` / `10` / `1`. All
514+
// three were CORRECT on the day this card was filed, and that is the point:
515+
// the defect is the SHAPE, not a stale number. The identical shape on the
516+
// `validate.ts` pair one field over put `main` in the red with no run to
517+
// say so (#18848) the moment `validate.ts` gained a seventh, entirely
518+
// legitimate exit (#18769) — the CONTRACT held throughout and only the
519+
// COUNT was stale. Because this file is nightly-tier by NAME
520+
// (`*.e2e.test.ts` — `scripts/nightly-tiers.mjs`), no pull request and no
521+
// merge-queue run can collect it: measured on the branch that landed this,
522+
// `OS_TEST_TIERS` unset collects 267 files in this package with ZERO of
523+
// them this one, and `=nightly` collects 68 with this one in it. An
524+
// integer that only a cron can read is a pin with no reader at the moment
525+
// it matters — the honest new exit merges green and `main` is red from
526+
// that moment until a cron says so.
527+
//
528+
// ⛔ So the count is not re-pinned to 12 — that just re-arms the same trap
529+
// for exit thirteen. It is DERIVED: the extractor read every `emitJson`
530+
// call site the file has, whatever today's number is. An honest new exit
531+
// stays green here and is still held to the contract below and to the
532+
// `warningsSoFar()` loop further down; a needle that stopped matching one
533+
// reddens HERE instead of quietly turning that negative into a vacuous
534+
// pass over fewer exits than the file has.
535+
//
536+
// Both sides read the MASKED source, which is what keeps them symmetric AND
537+
// keeps prose out of both (#18520, applied to this file by #18924).
538+
// Measured on the commit that landed this: `compile.ts` carries 13 raw
539+
// occurrences of the identifier, of which 2 are prose the mask blanks and 1
540+
// is the `import { … emitJson, … }` line — which carries no paren and so
541+
// matches neither side — leaving raw and masked agreeing on the same 11
542+
// payload literals and the same 11 call sites. ⚠️ That agreement is a
543+
// reading, not a law: `emitJson` is IMPORTED here, never declared, so the
544+
// looser `\bemitJson\s*\(` cannot match a `function emitJson(` definition
545+
// and over-count. A future file that declares it would break the symmetry
546+
// and reddens HERE, which is the correct place to find that out.
547+
const callSites = SRC.match(/\bemitJson\s*\(/g) ?? [];
548+
expect(
549+
literals,
550+
'an `emitJson(` call site the payload extractor could not read — the contract below would skip it',
551+
).toHaveLength(callSites.length);
552+
553+
// The one integer left, and it rots only in the direction that has to be
554+
// reviewed anyway: exits being REMOVED. Ten is the population the 2026-08-25
555+
// ruling in this file's header was made over — the count `#12079` pinned on
556+
// the day it landed option 1 — not a count of today. (Today is eleven: the
557+
// tenth FAILURE exit is ADR-0130 D4's per-package author-time rule leg,
558+
// #14439, a multi-package artifact running the same rule table once per
559+
// package. It arrived after the ruling and is an exit like any other —
560+
// which is exactly what a derived count exists to absorb and a frozen one
561+
// exists to trip over.) It is also the floor under the one vacuum the
562+
// derived pair shares — an `emitJson` renamed out of existence takes BOTH
563+
// sides to zero and every assertion here with them.
564+
expect(
565+
literals.length,
566+
'`os build --json` publishes fewer exits than the ruling above was made over',
567+
).toBeGreaterThanOrEqual(10);
568+
569+
// Exactly one success payload; every other exit is a failure exit. The
570+
// second count is derived from the length, so the two together also assert
571+
// the PARTITION — an exit carrying neither literal reddens.
515572
//
516-
// The tenth failure exit is ADR-0130 D4's per-package author-time rule leg
517-
// (#14439): a multi-package artifact runs the same rule table once per
518-
// package, and its refusal is an exit like any other — which is exactly
519-
// what this count exists to notice.
520-
expect(literals, 'the `emitJson` exit count moved — a new exit must carry `warnings` too').toHaveLength(11);
521-
expect(literals.filter((p) => p.includes('success: false'))).toHaveLength(10);
573+
// ⚠️ The verdict key here is `success:`, NOT the `valid:` the sibling pair
574+
// over `validate.ts` reads — the two commands do not share it. Measured on
575+
// the commit that landed this, over the 11 masked payload literals of
576+
// `compile.ts`: `success: false` 10, `success: true` 1, `valid: false` 0,
577+
// `valid: true` 0. A verbatim port of the sibling's two lines would assert
578+
// over an empty population.
522579
expect(literals.filter((p) => p.includes('success: true'))).toHaveLength(1);
580+
expect(literals.filter((p) => p.includes('success: false'))).toHaveLength(literals.length - 1);
523581

524582
const bare = literals.filter((p) => !p.includes('warnings:'));
525583
expect(

0 commit comments

Comments
 (0)