Files
pbakaus_impeccable/site/content/reference/config.md
T
776c019041 Add inline, in-file ignore comments for the detector (#283) (#285)
* Add inline, in-file ignore comments for the detector (issue #283)

Complement config ignores with eslint-disable-style waivers that live where
they apply and travel with the file when it leaves the repo. The motivating
case is a generated/exported standalone document that legitimately uses a
first-party brand typeface (on the overused-font list) and is later scanned
without .impeccable/config.json present.

Marker is comment-syntax-agnostic (works in //, /* */, <!-- -->, #, {/* */}):

  impeccable-disable <rule>[, <rule>...] [-- reason | : reason]   whole file
  impeccable-disable-line <rule>...                               same line
  impeccable-disable-next-line <rule>...                          next line

Bare directive or * means every rule; reason is optional and discarded at
scan time. Behavior is suppression, for parity with config ignores.

Implementation:
- New pure module cli/engine/shared/inline-ignores.mjs (parser + filter, no
  Node deps). Static-HTML findings have no line number, so only whole-file
  directives apply there -- exactly the standalone-document case; the
  regex/text engine additionally honors the line-scoped forms.
- Wired into detectText and detectHtml, gated by options.inlineIgnores.
- detect CLI applies inline ignores by default; --no-inline-ignores skips
  just them, --no-config skips config and inline ignores together.

Docs: config.md (new section), detector.md, README. skill/reference/hooks.md
reversed its prior "inline comments are not supported" guidance and now points
the agent to inline waivers for the travels-with-the-file case. Changelog 3.x.

Tests: tests/inline-ignores.test.mjs (parser units, detectText/detectHtml
integration, CLI end-to-end), registered in the detector suite.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Reconcile design hook wording with inline ignores

Two hook-side fixes prompted by review of the new inline-ignore feature:

1. Clean-ack steer line. The old line ("Keep typography hierarchy, spacing
   rhythm, and color contrast intentional on the next change.") read as an
   odd non-sequitur after "No anti-patterns." Reworded the whole clean ack to
   say what it means: a clean scan only clears the deterministic rule set, not
   overall design quality, so keep following the design system and skill
   guidance. Now: "Design hook scanned X. No deterministic design-quality
   issues found. That does not mean the design is good: keep following the
   project design system and the impeccable skill guidance."

2. Directive footer. It still told the agent "Do not add source comments such
   as `impeccable: ignore`; those pollute the code and do not suppress hook
   findings." That is now misleading: the hook runs the same detector engine
   as the CLI, which honors inline `impeccable-disable` waivers, so they DO
   suppress hook findings (consistent with config ignores, which filterFindings
   already honors). Reworded to: don't silence a real finding to skip fixing
   it; suppress only after the user confirms intent; prefer a config ignore,
   and reach for an inline `impeccable-disable <rule>` comment only when the
   waiver must travel with a file that leaves the repo.

Added a hook test asserting an inline `impeccable-disable-line` comment makes
the hook scan the file clean (locks in the cross-cutting behavior), and updated
the clean-ack / footer assertions to the new wording.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Address review on inline-ignores parser

- Case-insensitive fast-path bail-out (Cursor): the cheap substring guard was
  lowercase-only while DIRECTIVE_RE has the `i` flag, so a mixed-case marker
  like `Impeccable-Disable` skipped parsing entirely and never suppressed.
  Switched the guard to `/impeccable-disable/i.test(...)`. Added a regression
  test.
- Removed the unreachable `-->` branch from TRAILING_CLOSER_RE (Greptile):
  `--+>` already matches `-->` and any longer dash run.
- Replaced the always-truthy lazy-match + `if (sep)` reason strip with an
  explicit first-separator slice (Greptile): clearer and drops the dead branch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Align inline-ignore line numbering with the detector (CRLF/CR endings)

parseInlineIgnores split lines with /\r\n|\r|\n/, but detectText numbers lines
with split('\n'). On classic `\r`-only endings the two diverged, so a
disable-line / disable-next-line directive could key a different line than the
finding it should waive (Cursor review). Split on '\n' only, matching the
detector exactly; the directive regex already excludes '\r', so a trailing '\r'
on CRLF files is never captured into the rule list. Added a CRLF regression test
through the real detectText.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 21:41:36 +09:00

5.9 KiB

title, tagline, description, section, order
title tagline description section order
Config and ignores Project settings for detector exceptions, hook behavior, and local overrides. Use .impeccable config for confirmed detector exceptions and runtime settings. Keep product and design intent in PRODUCT.md and DESIGN.md. concepts 2

Impeccable stores runtime settings under .impeccable/. Most users do not need to hand-edit those files. Use the CLI when you want to record a confirmed exception.

Use config for:

  • detector ignores shared by npx impeccable detect and the design hook;
  • private local ignores that should not be committed;
  • hook lifecycle settings such as enabled, quiet mode, and audit logging.

Use PRODUCT.md and DESIGN.md for product and design intent. See Design Context.

The usual path

List the current ignores:

npx impeccable ignores list

Add the narrowest exception that matches the real reason:

npx impeccable ignores add-value design-system-color "#ff00aa" --reason "Campaign accent"
npx impeccable ignores add-file "src/legacy/**"
npx impeccable ignores add-rule side-tab

Remove an exception when the underlying code is fixed:

npx impeccable ignores remove-value design-system-color "#ff00aa"

The same detector config is used by the CLI and the hook, so an ignore behaves consistently in both places.

Shared or local

Default ignores go into .impeccable/config.json. Commit them when they represent team intent: a legacy folder, a confirmed brand exception, or a project-wide rule decision.

Use --local for private work:

npx impeccable ignores add-file "src/private-experiment/**" --local

Local settings go into .impeccable/config.local.json, which Impeccable keeps out of git.

Value ignores

Prefer value ignores when a rule reports a specific value:

npx impeccable ignores add-value overused-font Inter --reason "Brand font"

Fonts, colors, radii, and motion values should usually be suppressed by value, not by whole rule. That keeps the rule useful everywhere else.

Wildcard value ignores are allowed only when scoped to a file:

npx impeccable ignores add-value design-system-color "*" --file "src/demo.css"

That keeps one intentionally experimental file from teaching the whole project that every undocumented color is acceptable.

Inline ignore comments

Config ignores live in .impeccable/config.json, which is the right home for repo-wide policy. They do not follow a file out of the repo, though. When a waiver belongs to one file and needs to travel with it (a generated or exported standalone document, an emailed HTML file, a snippet scanned out of context), put the waiver in the file itself:

<!-- impeccable-disable overused-font: exported brand doc, font is first-party -->

The directive is comment-syntax-agnostic, so the same marker works in //, /* */, <!-- -->, #, and {/* */} comments across HTML, CSS, JSX, TSX, Vue, and Svelte. Three scopes are available:

/* impeccable-disable overused-font */            /* whole file */
.brand { font-family: Inter }  /* impeccable-disable-line overused-font */
/* impeccable-disable-next-line bounce-easing */

List one or more rule ids, comma-separated, or omit them (or use *) for every rule. A reason after : or -- is optional and recommended; it is for the diff, and the scanner discards it. Like config ignores, a matched directive suppresses the finding.

Static HTML findings have no line number, so only whole-file impeccable-disable applies to them. That is the standalone-document case this exists for. The line-scoped forms apply to CSS, JSX, TSX, Vue, and Svelte, where findings carry a line.

Inline directives apply by default. --no-inline-ignores turns them off for one run while keeping config ignores; --no-config turns off config and inline ignores together.

Details when the default path is not enough

What the config file looks like

The shared config lives at .impeccable/config.json. A typical file looks like this:

{
  "detector": {
    "ignoreRules": [],
    "ignoreFiles": [],
    "ignoreValues": [],
    "designSystem": {
      "enabled": true
    }
  },
  "hook": {
    "enabled": true,
    "quiet": false,
    "auditLog": ".impeccable/hook.ndjson"
  }
}

The detector section is shared by manual scans and hooks. The hook section only controls automatic hook execution and hook output.

Disable design-system checks

Design-aware rules run when DESIGN.md exists. Disable them for the project only when the design file is intentionally not authoritative yet:

{
  "detector": {
    "designSystem": {
      "enabled": false
    }
  }
}

For one manual run, keep config but skip the design-system rules:

npx impeccable detect --no-design-system src/

Use --no-config only when you want a raw scan with no project ignores and no DESIGN.md context.

Hook runtime settings

Use /impeccable hooks for normal lifecycle changes:

/impeccable hooks status
/impeccable hooks on
/impeccable hooks off

hook.quiet: true suppresses clean and pending acknowledgements while still surfacing new findings.

hook.auditLog writes one NDJSON line per hook invocation for debugging. Leave it off during normal work.

Environment variables still override config for one shell: IMPECCABLE_HOOK_DISABLED, IMPECCABLE_HOOK_QUIET, and IMPECCABLE_HOOK_LOG.