fix: make the audit-ui value contract unfakeable

The value baseline was satisfied by the string appearing anywhere in the
built CSS. Task 15e attempt 3 exploited exactly that: it dropped the 880px
and 1050px media queries, then added `--legacy-audit-width-880` and
`--legacy-audit-width-1050`, referenced by nothing, purely to put the
strings back in the sheet. The audit reported success.

Two changes close it:

- Custom-property declarations nothing references via `var()` are stripped
  before the value scan. A declaration nothing reads cannot style anything,
  so it should not be able to satisfy a styling contract.
- A `breakpoints` bucket, scanned from `@media` preludes only, so a
  breakpoint has to be an actual query condition. Baselined to the nine
  breakpoints in the legacy stylesheets; extra ones are allowed, losing one
  is not.

Both were tested against a rebuilt dist with the 880px queries removed:
the dead-token form fails on `sizes`, and the live-but-outside-a-query form
fails on `breakpoints`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Marcos Paulo
2026-09-06 08:16:13 +00:00
parent 12c32d2fd7
commit 9cb1e0d242
2 changed files with 25 additions and 2 deletions
+11
View File
@@ -288,5 +288,16 @@
"1960px",
"2200px",
"2880px"
],
"breakpoints": [
"520px",
"560px",
"600px",
"800px",
"880px",
"1050px",
"1100px",
"1600px",
"2200px"
]
}
+14 -2
View File
@@ -25,9 +25,21 @@ const builtCss = walk('dist/_astro')
.filter((path) => path.endsWith('.css'))
.map((path) => readFileSync(path, 'utf8'))
.join('\n');
// A declaration nothing references cannot style anything. Dropping the dead ones
// before the value scan is what stops a lost value from being "restored" with an
// unreferenced token that exists only to put the string back into the sheet.
const referenced = uses(builtCss);
const liveCss = builtCss.replace(/(--[\w-]+)\s*:[^;}]*[;}]/g, (declaration, name) =>
referenced.has(name) ? declaration : '',
);
const colorPattern = /#[0-9a-fA-F]{3,8}\b|(?:rgba?|hsla?)\([^)]*\)/g;
const sizePattern = /\b\d+(?:\.\d+)?(?:px|rem|em|vw|vh)\b/g;
// Only the media prelude, so a breakpoint has to be an actual query condition.
const mediaPreludes = (builtCss.match(/@media[^{]+/g) || []).join('\n');
const builtValues = {
colors: new Set(builtCss.match(/#[0-9a-fA-F]{3,8}\b|(?:rgba?|hsla?)\([^)]*\)/g) || []),
sizes: new Set(builtCss.match(/\b\d+(?:\.\d+)?(?:px|rem|em|vw|vh)\b/g) || []),
colors: new Set(liveCss.match(colorPattern) || []),
sizes: new Set(liveCss.match(sizePattern) || []),
breakpoints: new Set(mediaPreludes.match(sizePattern) || []),
};
if (!builtCss) throw new Error('Astro build emitted no CSS assets to audit');
// Captured from origin/main after its Astro build. This catches a value that is