Repository navigation
ci: generated stylesheet self-tests reject legitimate producer drift #2373
Description
Out of scope
Do not refresh frozen qualification hashes merely to admit current source, weaken source/installation drift refusal, remove assertions, or change the mount guard in #2370. No browser retention or timing claim is authorized by fixture repair.
Context
PR #2372 for #2370 changes local preflight only. Ready run 39074969929, attempt 1, unit (1) job 117520549643 fails temporary theme output binds the audited command, copied theme and installed compiler: expected the two CSS inputs, received undefined (test, tests/generated-theme-inputs.test.ts:11-16). The actual job checkout is e420f4155d10a93405b3505666c67333e3dcff22, parents main 498270fbdc4ef2788fdd3babb259b647d77f6c77 and head d9917869c4fca11b8040ac903b8dace6b5c20cd6, tree 8f0f4f12f6bd12e985bdb088a58434e146544ce4.
The theme fixture copies current producer files (fixture, tests/generated-theme-inputs.test.ts:10). The shared binder correctly checks frozen exact producer hashes (auditedProducer, scripts/generated-build-inputs.ts:8-20; generatedCssInputs, scripts/generated-build-inputs.ts:22-33). The only changed producer is scripts/check-pr.ts: frozen/base SHA-256 ed29d8dbb2e8b9982b502ad663045992339088dd8db766335b0b7ed2ba2436f6, candidate 0c98b4e67ad8d5ed29e08877565d946389e1ae44eefdc3d8cf6bea464b2bb941. Refusal is the correct result of that drift.
Local Bun 1.4.2 controls on the candidate reproduce five failing assertions across tests/generated-theme-inputs.test.ts, tests/generated-build-inputs.test.ts and tests/inclusion-inputs.test.ts. The latter fixtures also copy current producer files (fixture, tests/generated-build-inputs.test.ts:10-16; test, tests/inclusion-inputs.test.ts:79-95). Replacing only check-pr.ts temporarily with the actual base bytes yields 19 passing tests / 77 assertions across those three files, exit 0. The candidate file was restored byte-for-byte immediately afterward. This attributes the failures to the legitimate caller change rather than a tool or installation failure.
#2365 covers the analogous native-diagram self-test, with different fixtures and qualification ownership. This issue owns the generated CSS/theme and inclusion fixtures. Duplicate searches for generated-theme-inputs and generated stylesheet found no existing exact report.
Scope
Correct these self-tests to use independently owned frozen positive fixtures and genuine current-source drift negatives. Preserve the exact binder and real offline compiler controls. Include every occurrence of current-source copying that assumes frozen producer identity in the three affected test files.
Acceptance criteria
- Preserve the original hosted failure and candidate/base attribution above.
- A real frozen positive control verifies generated CSS/theme binding and installed-asset fingerprint participation without assuming arbitrary current caller bytes match a historical audit.
- Legitimate current producer drift refuses binding and selects fresh proof without failing generic self-tests. Added source, producer content/mode/path identity, command/order, importer and installed-asset negatives remain protected where applicable.
- No production qualification hash refresh or weakened refusal substitutes for fixture correctness.
- A guard mutation fails the corresponding named negative assertion; corrupting positive fixture ownership fails its positive assertion. Restore both and record receipts.
- All three affected test files pass on fix(ci): refuse slow Linux sandbox setup before local preflight #2372's legitimate changed source, followed by required preflight and complete selected hosted proof. Keep actual source/head/base/job identities.
Verification
Run bun run test tests/generated-theme-inputs.test.ts tests/generated-build-inputs.test.ts tests/inclusion-inputs.test.ts through the ordinary offline wrapper, plus bun run check:pr --base origin/main. Keep the real locked offline Tailwind compiler tests. Existing failed evidence remains failed.
Contract impact
None. Internal self-test fixture ownership only. Blocks #2370 / PR #2372; same priority p2. No epic membership is inferred from this shared dependency.
2026-10-18 additional hosted receipt: the same ready run's unit (2), job 117520549685, fails the three generated-build-inputs assertions already reproduced locally: generated stylesheet imports own source and checked producer, without current dist artifacts, copied theme and kit token exports bind their source without admitting nonexistent react tokens, and only audited filesystem reader commands bind the generated stylesheet cwd. The expected binding is absent. Its actual checkout log names the same merge e420f4155d10a93405b3505666c67333e3dcff22 with the recorded base/head. This confirms the existing fixture-drift scope; it adds no independent blocker and does not justify rerunning unchanged source.
2026-10-18 final original-candidate receipt: unit (3), job 117520549668, fails validated installed asset bytes and mode join immutable source fingerprints at its first inclusion calculation: Unresolved immutable layout inputs require fresh proof, naming the generated stylesheet read. This is the fifth assertion already reproduced in the three-file local control. Its actual checkout is the same recorded merge. Aggregate proof job 117524398456 correctly refuses unit: selected proof did not pass (failure) and prints the matching BRAIN_CANDIDATE_RECEIPT. The original run is complete: 12 jobs succeed, the three unit jobs and proof fail. No independent failure class or unchanged retry is inferred. #2372 is now draft with a separate timing-based revision implementing the maintainer's revised #2370 scope; the original failed run does not qualify that new revision. Frozen fixture repair remains necessary.
2026-10-18 implementation: PR #2388 preserves raw-Git positive fixtures owned by audited main 498270fbdc4ef2788fdd3babb259b647d77f6c77, with current producer bytes tested separately. Original fixtures reproduce their failures against #2372 changed check-pr.ts; corrected controls pass 20 tests / 88 assertions on both ordinary and changed caller bytes. Producer-digest bypass fails the negative controls, and changed positive ownership fails the positive controls; mutations are restored. Local preflight and strict types pass at head 36853df836c959500484c6bcaed64a99ab4e8aed, base b7a0885181445125d576e02f61c562d704c81099. Live main advanced only through #2384 native proof deadline composition; that change does not alter this generated-fixture domain. Ready confirmation requests actual base 775eb17aab740fa759c2182f306c38fc17acbcbe, synthetic merge 572ffe715849438f7481fde256e14167611be40e, tree b484cba973ae052cf8d9cd6b6e6ca7691ae1089a. Selected hosted proof and actual delivery remain pending; no production audit hash or runtime refusal changed.
Activity
schlessera commentedon Oct 18, 2026
Claim
chain2373-20261018, branchfix/2373-frozen-generated-fixtures. Resuming the explicitly requested blocker chain. Preserve the generated binding audit and real offline compiler controls; separate independently owned frozen positives from current producer drift, with mutation receipts and complete candidate proof. No production qualification hashes will be refreshed.schlessera commentedon Oct 18, 2026
Hosted qualification failure — 2026-10-18
Blocked by #2373
Ready run 39082082794, attempt 1, unit (4) 117541134817 fails
temporary theme output binds the audited command, copied theme and installed compilerattests/generated-theme-inputs.test.ts:13: expected two CSS input paths, received undefined. Metadata and the failing job actually checked out82ff45bf3b0ff50b34a233c817464c6c513300a3, parents base775eb17aab740fa759c2182f306c38fc17acbcbeand head0d48379f0a7dece1032b18f012d56d4a8a4f3e12, treeef5e48c7109942706749fb67df89bb8f6dea5dcc; immutable Git API and artifact identity agree. Early candidate admission itself passed and emitted the matching receipt before product dispatch.The self-test copies current producer files but requires a frozen positive identity. All eleven base producer hashes match; the candidate changes only the workflow pin: frozen/base
0664eae990558d400c8b34b8d1fe9d687ff2b9e82e906ad2480e10bf42d9fc32, candidate683f816a8b5267d2253c25b08a81197d17099d4c8c95dba35306970767a690d0. All other ten producer pins match. Correct refusal of the changed workflow makes this generic positive fixture fail. Existing #2373 owns this fixture class; its independently owned repair #2388 remains with its current worker. Do not refresh production hashes to admit the candidate.Clean isolated-install offline controls across the three affected files give 14 pass / 5 fail / 57 assertions on the candidate (5.715 s). Substituting only exact base workflow bytes gives 19 pass / 0 fail / 77 assertions (5.266 s). Restoring the candidate byte-for-byte repeats the same five failures (4.118 s). The checkout is clean and no pins, assertions or product code were changed. These bounded causal controls are distinct from an unchanged CI retry.
Artifact
unit-proof-4ID 12119152972 is downloaded and SHA-256 verified:738ff13bcd76b4b8e5201fbcbef3ca3052e2e9425b4748dafbb789a603e062a0. Worker 2 XML records 1,697 cases / 10,645 assertions, one failure and no skips. Worker 1 has no final XML: its later Git fixture error follows worker 2 exit by 4 ms, then its wrapper exits 143. The runner stops sibling process groups after failure; this supports a cancellation cascade rather than an independently established Git defect. Incomplete worker 1 proof is not green.Failed shard cost: 858 job-wall seconds; its resource receipt records 805.536 proof seconds / 2,107.43 VM active CPU seconds, with sampled used memory peak 4,386,660,352 bytes. This is qualification cost, not a saving. The run has now completed: 12 jobs succeeded; unit (1), unit (3), unit (4) and the aggregate failed. Unit (1), job 117541134816, fails
validated installed asset bytes and mode join immutable source fingerprintsattests/inclusion-inputs.test.ts:88. Unit (3), job 117541134813, has the three matching generated-stylesheet failures attests/generated-build-inputs.test.ts:20,33,50. These complete the same five failures reproduced in the controlled local experiment. Both additional shard resource receipts name the same merge/head/base/tree above.The aggregate, job 117544461002, independently rejects
Candidate became stale: the live PR head, readiness or base changed; request confirmation again. Head and readiness remained unchanged during this investigation; main advanced to68e12f27eb249c9fe7262a498a0397c04bbda8f4via #2389 at 00:19:36Z, after successful initial admission and before final validation. Preserving this final refusal is part of #2118's required behavior. The old run does not prove the new combined tree.Final cost across all 16 jobs is 9,449 summed job-wall seconds, including setup and teardown, excluding queue. Unit (1)/(3)/(4) respectively cost 1,006 / 1,092 / 858 job-wall seconds; their proof resource receipts total 2,822.500 proof seconds / 7,471.07 VM active CPU seconds. These are failed qualification costs, not savings. No unchanged retry was requested. Return #2176 to draft now that the original run has completed. Resume after #2373 is delivered: assess live main, integrate the fixture repair, rerun affected preflight and request fresh complete candidate confirmation.
Release coordinating claim
e1849-2118-r3-20261018for this blocked handoff; preserve the resumable branch and draft PR. Release 0.44.0 and the original acceptance criteria remain. No merge, completed issue or whole-CI improvement is claimed.schlessera commentedon Oct 18, 2026
Delivered by #2388, squash
fcb7d5c5357c550f74300a53b5af5c46570b215f, verified on fetched main. Its parent is the qualified live base68e12f27eb249c9fe7262a498a0397c04bbda8f4; delivered tree63d5f502f85c5a76722451a29ed329fb98cd550cexactly matches the tested synthetic checkout. Ready run 39085115921 attempt 1 passes metadata, strict/fast verification, all four selected unit shards and aggregate; every selected job log names checkout2b355c03d1bbc3114c1a98c989ede59bcba56c2f. Requested base, both immutable parents and aggregate BRAIN_CANDIDATE_RECEIPT agree. Remaining category skips are planner-intended. No audit hash or refusal guard was changed. Issue closure and PR/issue milestone 0.44.0 are verified. #2372 now needs its own refreshed preflight and candidate confirmation; this delivery does not qualify that dependent PR. Automatic main-push proof is checked separately.