Files
pbakaus_impeccable/crates/live/assets
Paul BakausandClaude Fable 5.1 1d214f1e48 Add detector.ignoreSelectors: one component-level opt-out instead of an attribute per instance
An author who wants a rule off for one component has had two choices: put
`data-impeccable-ignore` on every instance, or silence the rule (or the
file) for the whole project. On impeccable-site #34 that meant eleven
attributes on eleven copies of the same 10px label for `undersized-ui-text`,
25 opt-out attributes in all. The count is the problem: the markup carries
noise, and the reviewer never sees how much was waived.

`detector.ignoreSelectors` is the declared twin of that attribute. One entry,
`{ rule, selector }`, waives the rule for every element the selector matches
and for that element's subtree, the same waiver the attribute grants the
element carrying it:

    impeccable ignores add-selector undersized-ui-text ".ks-tag" \
      --reason "10px mono index labels, confirmed"

The waiver is never silent. The engines stamp a waived finding with
`ignoredBy: "<selector>"` instead of dropping it; the config layer drops and
counts, and every scan prints one line per entry on stderr, in `--json` runs
too, so stdout stays the findings array:

    3 undersized-ui-text hits ignored by detector.ignoreSelectors on .ks-tag.

Where it applies: the browser engine (`BrowserConfig.ignoreSelectors`, also
readable from `window.__IMPECCABLE_CONFIG__`), the static HTML engine
(`DetectHtmlOptions.ignore_selectors`, and the `ignoreSelectors` option of
the wasm `detect_html_source_json` export), the detect CLI, and the design
hook. The text engine has no DOM and ignores the key. Entries can be scoped
with `files` globs like `ignoreValues`; `--no-config` disables them; `doctor`
validates their rule ids alongside `ignoreRules`. Nothing changes for a
project without the key: the engines stamp nothing, the CLI prints nothing,
the config writer does not add an empty `ignoreSelectors`, and the
per-instance attribute keeps working exactly as before.

Coverage: `crates/html/tests/selector_ignores.rs` (component, subtree,
wrong-rule, `*`, attribute parity), driver tests over the fake DOM,
`crates/detect` config tests (normalize, merge, per-target narrowing, the
tally), and oracle cases `detect-selector-ignore-*` / `ignores-selector-*`
over a new workspace. The eight re-recorded context/doctor goldens differ
only in the recognized-detector-keys sentence, which now lists the new key.

Assisted-by: Claude Code
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LQBUunp8QttxZqihybNmtL
2026-09-11 12:22:16 -07:00
..

Live browser assets

Two generated files, both tracked, both rewritten by cargo xtask bundle. Do not hand-edit either one.

detect-antipatterns-browser.js is the in-page detector bundle: the rule core (crates/core) compiled to WebAssembly by crates/wasm, concatenated with the page JS in browser-bundle/ and the module embedded as base64. crates/live/src/browser_assets.rs embeds it with include_str! and the live server hands it to the browser as /detect.js, so the binary has to carry it.

antipatterns.json is the rule registry (crates/foundation/src/registry.rs) as [{ id, name, category, description }], the same slice cargo xtask bundle vendors into the extension's extension/detector/. It is tracked because extension/detector/ is not: a consumer working from a source checkout or a repo tarball (impeccable.style counts and renders the rules from it) has no other way to read the registry without a Rust toolchain.

cargo xtask bundle          # rewrites both (and extension/detector/)
cargo xtask bundle --check  # fails when either is stale

The other browser scripts the live server serves (live-browser*.js, modern-screenshot.umd.js) are not copied here: they are embedded straight from skill/scripts/, the one copy the build also ships to every provider.