mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-12 14:16:28 +03:00
The JS engine applied value-level ignore waivers at the tail of
collectBrowserFindings: `_disabledValues` read the entries the live
overlay resolved for the page (skill/scripts/live-browser-ignores.js
sends them as config.disabledValues), and filtered the assembled
findings by the value each one reported, with design-system-color
compared by color value rather than by spelling so a hex waiver
suppressed a finding the browser reported as rgb(...). The Rust port
dropped that stage: `disabledValues` appeared nowhere in the workspace
or in browser-bundle, so a project entry like
[detector]
ignoreValues = [{ rule = "overused-font", value = "geist mono" }]
stopped reaching the overlay. The rules the CLI and the edit hook waive
kept drawing markers and counting toward the badge.
Restore it end to end:
* BrowserConfig gains `disabled_values`, parsed leniently so a
hand-edited __IMPECCABLE_CONFIG__ entry of the wrong shape is dropped
rather than failing the whole config, the way the JS filter did.
* The driver applies the waivers after every pass, so a rule pack's
findings are covered the same way the built-in ones are, honoring the
entries only in extension mode exactly as the JS read them. The
normalizer, the value extractor (including the rule that bounce-easing
without a direct ignoreValue offers no value) and the hex/rgb color
key are ported alongside it.
* collectConfigJson in the in-page bundle and configJson in the
offscreen bundle forward the field. The extension never sends it, so
its behavior is unchanged.
Coverage: two driver unit tests (suppression by font value, by hex
waiver across the rgb spelling, and the extension-mode gate; plus the
config parse and the normalizers), a skipScan test that pins the empty
shape for every stage the core produces, and
crates/wasm/tools/disabled-values-check.mjs, a browser-backed check
ported from the retired tests/detect-antipatterns-browser.test.mjs case
that the swap left without a replacement. Against the previous bundle it
fails on exactly the three waiver assertions and passes the skipScan
one, which is the shape of the regression.
Two related review findings were checked and are not defects. skipScan
is gated on extension mode in both the driver and the bundle, which is
what the JS did (index.mjs#skipScanActive), and the live overlay runs in
extension mode: live-browser.js sets `s.dataset.impeccableExtension` on
the injected /detect.js tag, and the overlay's whole detect toggle
travels over the postMessage loop that 50-scan.js installs only under
EXTENSION_MODE. The visual contrast stage is not leaking either:
collectBrowserFindingsAsync and scan() both consult skipScanActive(),
and the offscreen path skips its visual pass on config.skipScan.
The tracked live asset is regenerated (cargo xtask bundle). The oracle
replays with zero unreviewed differences: the new field defaults empty
and the filter is inert without it, and no CLI path sets extension mode.
AI-assisted change: implemented with Claude Code under maintainer
direction.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vau2X53xGTjjTCXWMVBoNY
browser-bundle: the page-side JavaScript of the detector
Plain JavaScript that runs inside a page or the extension: the DOM probe the
wasm rule core calls back into, the page snapshot producer, the
visual-contrast sampling IO, the overlay UI, the scan API and the extension's
offscreen document. Measurement and presentation only; every rule decision
is a call into the wasm rule core built from crates/core (docs/ENGINE.md).
Two consumers:
crates/browserembeds15-snapshot.js(the snapshot producer the URL engine injects; no WebAssembly runs in the page).crates/bundle(theimpeccable-bundlelibrary) embeds every file here withinclude_str!and concatenates them, in filename order, with the wasm core into the in-page bundle plus the extension'sextension/detector/pieces.cargo xtask bundleis its caller inside this workspace: it writesdist/detect-antipatterns-browser.js, copies that bundle to the trackedcrates/live/assets/detect-antipatterns-browser.jsthe engine embeds, and writes the extension pieces. A downstream crate with its own rule pack calls the library directly (docs/ENGINE.md).
Because the files are embedded, a new one here has to be added to
PAGE_JS in crates/bundle/src/lib.rs (and to the order it is concatenated
in); a test fails when the two lists disagree.
15-snapshot.js lists the computed-style properties the rules read; the
bundle build checks that list against the core's and fails when they drift.