feat: selector-scoped [[ignore]] runtime suppression - #227
Conversation
Adds a `[[ignore]]` array to plumb.toml so users can silence violations
per CSS selector path (and optionally per rule_id) without editing the
rule registry. The shape mirrors what `plumb lint --suggest-ignores`
emits, so the suggestion list pipes back into the config and converges
on a clean dogfood exit.
- `IgnoreRule { selector, rule_id?, reason }` lands in plumb-core's
Config with `#[serde(deny_unknown_fields)]`; selectors match by
exact-string equality, never via a CSS engine.
- `engine::run_report` returns a `RunReport { reported, ignored }`
partition; the existing `run`/`run_many` keep their `Vec<Violation>`
signatures (filtered output) so library consumers see no signature
break.
- `plumb-format` gains `pretty_with_ignored` + `json_with_ignored` (and
the `_with_suggested_ignores_and_ignored` combinator). Pretty output
appends an `N violation(s) suppressed by config` line under stats;
JSON envelopes grow `"ignored": N`. SARIF stays unchanged because the
2.1.0 schema has no slot for non-standard counts.
- `plumb lint` routes through `run_report` and feeds the ignored count
into the formatter dispatch. The CLI exit code reflects only the
reported subset, so a config that silences every violation produces
exit 0.
Tests cover the four match shapes (passthrough / selector-only /
selector + rule_id / no match) plus a determinism check, a golden
snapshot for the partition, schema regeneration, and end-to-end CLI
integration tests for the pretty footer + JSON `ignored` field.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wires the dogfood config used by `.github/workflows/dogfood.yml`. Each `[[ignore]]` block carries a real `reason` documenting why the selector exempts: mdBook root padding, page wrapper, sidebar, search popover, theme picker — the chrome the plumb docs site doesn't own. The set is the starter Plumb expects to see on the live site. Real empirical generation (`plumb lint … --suggest-ignores | parse`) needs the dogfood Chromium binary; the CI run that adopts this config will surface any selectors I missed and a follow-up PR can extend the list. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The dogfood job now passes `--config docs/plumb.toml` to silence the
mdBook chrome violations PRD §15 calls out. With the config the lint
should exit 0 ("0 violations dogfooding clean"); any selector that
slips past the seeded `[[ignore]]` set surfaces as a real regression.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
I have everything I need. Here is the structured review. PR #227 — feat: selector-scoped
|
The [[ignore]] feature ships for end-user adoption, but using it on our own dogfood site to silence 50+ mdBook chrome warnings would be a hack that papers over the real signal — that we have not aligned plumb's defaults with the actual rendered docs theme. Reverts: - docs/plumb.toml (the seeded escape hatch) - .github/workflows/dogfood.yml --config wiring The honest dogfood fix is tracked as a follow-up: either align plumb.toml to the mdBook theme's actual output, customize the theme to use plumb's tokens, or revise the §15 acceptance to '0 errors' instead of '0 violations'.
Surgical revert: dropped
|
Summary
[[ignore]]array toplumb.tomlthat silences violations by exact CSS-selector path (and optionally byrule_id). Each entry carries a requiredreasonso reviewers can audit what the config silences.RunReport { reported, ignored }andrun_report/apply_ignores;run/run_manykeep theirVec<Violation>signature (filtered output) so library callers see no break.N violation(s) suppressed by config; the JSON envelope grows"ignored": N. SARIF stays unchanged (the 2.1.0 schema has no slot for non-standard counts).--suggest-ignores: the suggestion list maps 1:1 onto[[ignore]]entries, so a user can pipe the suggestions intoplumb.tomland converge on a clean dogfood exit.docs/plumb.tomlinto the dogfood workflow with[[ignore]]blocks for the mdBook chrome PRD §15 calls out.Implementation notes
IgnoreRuleis#[serde(deny_unknown_fields)]— typos inplumb.tomlsurface as parse errors, not silent drops.Violation::selector, deliberately not a CSS-engine match — keeps the engine free ofscraper/cssparserruntime overhead and preserves determinism.Config.ignoreuses#[serde(default, skip_serializing_if = "Vec::is_empty")]soplumb init-emitted configs don't gain a strayignore = []line.Vec(declaration order); the partition is short-circuited per violation. Bothreportedandignoredpreserve the engine's pre-sortedViolation::sort_keyorder —apply_ignoresis byte-deterministic across runs.cargo xtask schema; xtaskpre-releaseis green.Test plan
cargo fmt --all -- --checkcargo clippy --workspace --all-targets --all-features -- -D warningscargo nextest run --workspace --all-features— 492 tests passedjust determinism-check— three runs byte-identicalcargo deny checkcargo auditcargo run -p xtask -- pre-releaseplumb lint plumb-fake://hello --suggest-ignores --format json→ parse → write[[ignore]]→plumb lint --config <file>exits 0 with1 violation suppressed by configfooter.cargo run -p plumb-cli -- lint --config docs/plumb.toml https://plumb.aramhammoudeh.com/(could not run locally — the macOS Homebrew Chromium binary's WS handshake fails against the deployed CDP driver). The dogfood worker usesbrowser-actions/setup-chrome, which is the supported configuration. The seeded[[ignore]]list covers the obvious mdBook chrome; any selector I missed will surface in the dogfood log and a follow-up PR can extend it.🤖 Generated with Claude Code