Fix: harden live overlay detector waivers (#639 follow-up)

Read waiver config from every live root (appRoot, contextRoot, repoRoot),
so monorepo projects whose config lives at the repo root reach the
overlay; serialize served roots and page identities repo-relative there.

Resolve each page URL to its actual serving file via the inject config's
resolved page list before applying file-scoped waivers; ambiguous URLs
keep the conservative common-ancestor fallback (PR #645 review
discussion r3840011436).

Honour detector.ignoreFiles: a wholly waived page now scans to zero
findings in the overlay, matching the CLI and the edit hook.

Guard the resolver call so a throwing resolver degrades to an unfiltered
scan instead of breaking the detect toggle.

Match design-system-color waivers by color value across hex and rgb()
spellings, and stop extracting font values for bounce-easing findings,
mirroring extractFindingIgnoreValue. Regenerate the browser bundle.

AI-assisted change: reviewed, planned, and implemented with Claude Code
under maintainer direction.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Abdul Wahab
2026-08-28 18:38:36 +05:00
committed by Abdul Wahab
co-authored by Claude Fable 5
parent 09506a9bb5
commit 152d6940b0
12 changed files with 643 additions and 90 deletions
+22 -10
View File
@@ -11147,20 +11147,32 @@ void main() {
// filters the same findings the CLI and the edit hook do (issue #639).
// live-browser-ignores.js resolves .impeccable config for this page:
// ignoreRules suppress outright, wildcard ignoreValues suppress their
// rule in the files they name, and the rest match on the finding's own
// value inside the detector. Guarded so a stale cached live.js without
// the resolver part still scans, just unfiltered as before.
// rule in the files they name, ignoreFiles that name the page skip the
// scan wholesale, and the rest match on the finding's own value inside
// the detector. Guarded twice: a stale cached live.js without the
// resolver part still scans, and a resolver that throws must not brick
// the detect toggle; both degrade to an unfiltered scan.
const ignoresApi = window.__IMPECCABLE_LIVE_IGNORES__;
const ignores = typeof ignoresApi?.resolveDetectIgnores === 'function'
? ignoresApi.resolveDetectIgnores({
ignores: window.__IMPECCABLE_PROJECT_IGNORES__,
pathname: location.pathname,
})
: { disabledRules: [], disabledValues: [] };
let ignores = { disabledRules: [], disabledValues: [], skipScan: false };
if (typeof ignoresApi?.resolveDetectIgnores === 'function') {
try {
ignores = ignoresApi.resolveDetectIgnores({
ignores: window.__IMPECCABLE_PROJECT_IGNORES__,
pathname: location.pathname,
}) || ignores;
} catch (e) {
ignores = { disabledRules: [], disabledValues: [], skipScan: false };
}
}
window.postMessage({
source: 'impeccable-command',
action: 'scan',
config: { scanId, disabledRules: ignores.disabledRules, disabledValues: ignores.disabledValues },
config: {
scanId,
disabledRules: ignores.disabledRules || [],
disabledValues: ignores.disabledValues || [],
skipScan: ignores.skipScan === true,
},
}, '*');
}