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:
@@ -288,5 +288,16 @@
|
||||
"1960px",
|
||||
"2200px",
|
||||
"2880px"
|
||||
],
|
||||
"breakpoints": [
|
||||
"520px",
|
||||
"560px",
|
||||
"600px",
|
||||
"800px",
|
||||
"880px",
|
||||
"1050px",
|
||||
"1100px",
|
||||
"1600px",
|
||||
"2200px"
|
||||
]
|
||||
}
|
||||
|
||||
+14
-2
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user