* Fix detector URL and advisory handling
Recover joined URL arguments without splitting local paths, derive advisory behavior from registry severity across consumers, inspect readable linked CSS in URL scans, and report only the dominant primary font.
AI assistance disclosure: Implemented and verified with Codex under maintainer direction.
* Filter linked CSS to rendered selectors
Flatten linked stylesheet grouping rules and collect only selector rules that target the live DOM, preventing unused grouped and selector-less patterns from leaking into URL findings.
AI assistance disclosure: Implemented and verified with Codex under maintainer direction.
* Fix detector review edge cases
AI assistance disclosure: Codex implemented and verified these fixes under maintainer direction.
* Preserve unresolved linked CSS selectors
AI assistance disclosure: Codex implemented and verified this fix under maintainer direction.
* Fix linked CSS selector filtering
Resolve pseudo-element selectors to live hosts, reject unresolvable linked CSS findings, and make the regression assertions independent. Also ignore comment delimiters when recovering CSS rule selectors.
AI assistance disclosure: This commit was prepared with Codex under maintainer direction.
* Skip unresolved container query CSS
Exclude linked container-query groups when their current applicability cannot be resolved, with a browser regression proving inactive styles do not leak.
AI assistance disclosure: This commit was prepared with Codex under maintainer direction.
* Detect active container query CSS
Use a temporary custom-property probe so the browser decides whether a nested style rule actually applies in the current container layout.
AI assistance disclosure: Codex helped implement and test this fix under maintainer direction.
* Filter inactive linked CSS states
Keep valid empty pseudo-class matches authoritative and omit selector-less linked at-rules that cannot be tied to rendered nodes.
AI assistance disclosure: Codex helped implement and test this fix under maintainer direction.
* Parse pseudo-elements without rewriting literals
Preserve quoted attribute values and escaped identifiers while resolving real pseudo-elements to live hosts.
AI assistance disclosure: Codex helped implement and test this fix under maintainer direction.
* Restore live linked keyframes
AI assistance disclosure: Codex helped implement and verify this fix under maintainer direction.
* Handle grouped linked keyframes
AI assistance disclosure: Codex helped implement and verify this fix under maintainer direction.
* Respect keyframe definition order
AI assistance disclosure: Codex helped implement and verify this fix under maintainer direction.
* Resolve effective linked keyframes
AI assistance disclosure: Codex helped implement and verify this fix under maintainer direction.
* Fix keyframe easing detection
Serialize effective per-keyframe easing back into the linked stylesheet corpus so overshoot motion is detected. Add a browser regression with a neutral animation name.\n\nAI assistance disclosure: Codex helped implement and test this fix under maintainer direction.
Em-dashes are used legitimately by humans, so em-dash-overuse fired far too
often. Reclassify it as the first advisory-tier rule: detected, but never a
failure.
Engine
- Add `advisory: true` to the rule metadata schema (em-dash-overuse is the
first). findings.mjs stamps `advisory: true` on advisory findings so every
consumer can partition without a registry lookup. Rule count stays 58.
- Raise the firing threshold from a flat 5 dashes to two gates: an absolute
floor of 8 and a density of about one dash per 500 characters of body text.
A long article that uses a few em-dashes no longer trips; a short,
dash-per-clause page still does. Entity decoding (mdash, numeric, hex) is
unchanged. Thresholds live in shared/constants.mjs so every engine agrees.
Browser parity
- The browser bundle carried a registry entry but no logic, so the overlay and
extension could never flag it. Add checkEmDashOveruse / checkEmDashOveruseDOM
in rules/checks.mjs (reads rendered text, no entity decoding needed), wire it
into the injected page-level pass, and carry the advisory flag through
serializeFindings so the overlay/extension can render it with the mildest
affordance.
CLI
- Advisory findings print under a separate dimmed "Advisory" section, are
excluded from the failure count, and never change the exit code (an
advisory-only scan exits 0). JSON keeps them with `"advisory": true`.
`--no-advisory` suppresses them entirely.
Hook
- Advisory rules are skipped by default in both the per-edit and Stop deep-pass
hooks, so the hook never nags about them. Opt in with
`.impeccable/config.json` -> `detector.advisoryRules: "include"`.
Tests
- Fixture + threshold + browser-adapter coverage; advisory-skip default and
opt-in for the hook; formatFindings partitioning. The em-dash-overuse stand
for a deferred copy rule in the tier tests is swapped to marketing-buzzword.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Four changes driven by human design review of eval artifacts:
1. Static engine contrast fidelity (nav-CTA cascade miss):
- parseAnyColor evaluates color-mix() (premultiplied sRGB mix; exact
for the dominant `color-mix(in oklab, C n%, transparent)` chip form)
- extractStaticColor captures color-mix() balanced instead of plucking
"transparent" out of the expression
- resolveBackground composites translucent layers over the opaque base
in both engines instead of skipping (static) or returning them
as-if-opaque (browser)
- NEW hover pass in the static cascade: :hover rules are matched via
state-stripped selectors, merged per-property against the resting
cascade with real specificity, and checked for WCAG contrast on
styled controls (checkHoverContrast). Catches the recurring miss
where a broader selector (.nav-links a:hover) beats the CTA's own
hover color and drops the pair below AA.
2. New `radial-halo` slop rule: chromatic radial-gradient wash (visible
saturated center -> transparent) as a decorative background on a dark
page. Exempts achromatic vignettes, opaque-end sheens, px-stop dot
textures, url() photo layers, and translucent (<0.7 alpha) staged-
light washes. Separate id from dark-glow so dashboards track the
gradient-drawn variant independently.
3. side-tab horizontal variant: 3-12px chromatic border-top/bottom (and
top/bottom-anchored full-width pseudo stripes) on cards/badges flag as
side-tab. Exempt: tablist/nav/aria-selected underlines, link/button
affordances, table cells, hr, state-conditional pseudo stripes, and
>12px bands. Badge-shaped spans (own visible background) participate.
4. CLI: file:// URLs route to the Puppeteer browser engine (~2s on a
50KB page), and detect --json findings now carry the registry
`category` field so downstream QA loops can separate mechanical slop
tells from judgment calls.
Fixture policy update: flat 3px top-accent cards moved from should-pass
to flag columns; tablist-underline and 16px-band pass cases added.
Browser bundle regenerated.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>