Move the slop defects back into the craft floor

The detector-blind slop review existed because the AI-tell rules had been
stripped out of SKILL.md and nothing carried them. The floor is a better
home: it loads after concept ideation and immediately before editing UI,
which is the placement that made stripping them necessary in the first
place. Models tread lightly when a ban list is present during ideation;
by the time the floor loads, the direction is already committed.

- Rename build-floor.md to craft-floor.md and restore the absolute bans
  (side-stripes, gradient text, glassmorphism, hero-metric, identical card
  grids, eyebrow-on-every-section, numbered markers, text overflow), the
  codex and gemini defect lists, and the reflexes no scanner catches.
  Rule ids match the ones the ablation catalog already knows.
- Delete lib/slop-review.mjs and both injections. The Stop hook is now
  purely a mechanical pass and stays silent with nothing to report.
- context.mjs replaces AI_SLOP_REVIEW_REQUIRED with the narrower
  MANUAL_DETECTOR_REQUIRED, emitted only when a session has no hook at
  all. A per-edit hook already covers the mechanical gap, and the floor
  covers the judgment one either way.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Paul Bakaus
2026-07-21 02:04:36 -07:00
co-authored by Claude
parent d7d10277d1
commit 153b416f2e
9 changed files with 87 additions and 118 deletions
-24
View File
@@ -1,24 +0,0 @@
# Build floor
Apply this only after analysis and direction are settled. Build without announcing the checklist. <!-- rule:skill-craft-floor -->
- **Contrast:** body and placeholder text ≥4.5:1; large text ≥3:1. On colored surfaces, tint secondary text from that hue or the foreground instead of using gray. <!-- rule:skill-color-verify-contrast -->
- **Depth:** shadows describe light with offset and soft blur; zero-offset colored halos are decoration. <!-- rule:skill-color-no-glow-halo -->
- **Spacing:** tight groups, generous separation, no cramped containers; space above a heading exceeds space below. Verify computed values. <!-- rule:skill-layout-spacing-rhythm -->
- **Type:** body measure 6575ch; display max 6rem and tracking floor -0.04em; balance headings; use clear scale/weight contrast; test overflow at every breakpoint. <!-- rule:skill-typo-floor -->
- **Motion:** author one coherent moment instead of scattered effects. Use exponential ease-out and an already-visible default. Premium motion may add focus, depth, masks, light, or material change through blur/filter, backdrop-filter, clip-path/masks, or shadow when smooth; do not rely on transform/opacity alone. <!-- rule:skill-motion-floor --> <!-- rule:skill-motion-materials-palette -->
- **Shipping:** real content, working controls, responsive composition, keyboard focus, and the states users hit: hover, disabled, loading, error, and empty. <!-- rule:skill-floor-shipping -->
- **Copy:** use the product's language; controls name their action, errors name the problem and recovery. <!-- rule:skill-copy-design-material -->
- **Coverage:** every brief requirement must exist and be findable within seconds. <!-- rule:skill-floor-brief-coverage -->
Before finishing changed UI, follow the quality guidance supplied by `context.mjs` and hooks. Context requests a manual scan only when no automatic detector is active; never add a second detector pass. <!-- rule:skill-llm-only-slop-check --> <!-- rule:skill-detector-finish-mode -->
<codex>
- Display tracking stops at -0.04em; -0.02 to -0.03em is usually enough. <!-- rule:skill-typo-codex-tracking-repeat -->
- Declare elevation once: border or shadow, not both as decoration. Keep container radii modest; reserve pills for small controls. <!-- rule:skill-codex-elevation-radius -->
- Use real illustration or none. Treat backgrounds as surfaces and add texture only from the subject's world. Claims, evidence, and configuration come from supplied truth; label illustrative behavior and unresolved values honestly. <!-- rule:skill-codex-material-honesty -->
</codex>
<gemini>
Never animate `<img>` elements on hover, directly or through a parent. Give the card itself feedback instead. <!-- rule:skill-interaction-gemini-no-image-hover -->
</gemini>
+51
View File
@@ -0,0 +1,51 @@
# Craft floor
Apply this only after analysis and direction are settled. Build without announcing the checklist. A pinned brief or the committed visual world beats every line below; your own reflex does not. <!-- rule:skill-craft-floor -->
## Floor
- **Contrast:** body and placeholder text ≥4.5:1; large text ≥3:1. On colored surfaces, tint secondary text from that hue or the foreground instead of using gray. <!-- rule:skill-color-verify-contrast -->
- **Depth:** shadows describe light with offset and soft blur; zero-offset colored halos are decoration. <!-- rule:skill-color-no-glow-halo -->
- **Spacing:** tight groups, generous separation, no cramped containers; space above a heading exceeds space below. Verify computed values. <!-- rule:skill-layout-spacing-rhythm -->
- **Type:** body measure 6575ch; display max 6rem and tracking floor -0.04em; balance headings; use clear scale/weight contrast; test overflow at every breakpoint. <!-- rule:skill-typo-floor -->
- **Motion:** author one coherent moment instead of scattered effects. Use exponential ease-out and an already-visible default. Premium motion may add focus, depth, masks, light, or material change through blur/filter, backdrop-filter, clip-path/masks, or shadow when smooth; do not rely on transform/opacity alone. <!-- rule:skill-motion-floor --> <!-- rule:skill-motion-materials-palette -->
- **Shipping:** real content, working controls, responsive composition, keyboard focus, and the states users hit: hover, disabled, loading, error, and empty. <!-- rule:skill-floor-shipping -->
- **Copy:** use the product's language; controls name their action, errors name the problem and recovery. <!-- rule:skill-copy-design-material -->
- **Coverage:** every brief requirement must exist and be findable within seconds. <!-- rule:skill-floor-brief-coverage -->
## Absolute bans
Match and refuse. If you are about to write one of these, rewrite the element with different structure.
- **Side-stripe borders.** `border-left` or `border-right` above 1px as a colored accent on cards, list items, callouts, or alerts. Never intentional. Use full borders, background tints, leading numbers or icons, or nothing. <!-- rule:skill-ban-side-stripe-borders -->
- **Gradient text.** `background-clip: text` over a gradient. Decorative, never meaningful. One solid color; emphasis through weight or size. <!-- rule:skill-ban-gradient-text -->
- **Glassmorphism as default.** Blur and glass panels used as decoration. Rare and purposeful, or nothing. <!-- rule:skill-ban-glassmorphism-default -->
- **The hero-metric template.** Big number, small label, supporting stats, accent treatment. <!-- rule:skill-ban-hero-metric -->
- **Identical card grids.** Same-sized cards carrying icon plus heading plus text, repeated as the page structure. Cards are the lazy answer; nested cards are always wrong. <!-- rule:skill-ban-identical-card-grids --> <!-- rule:skill-layout-cards-lazy -->
- **A tiny tracked uppercase eyebrow above every section.** Small all-caps with wide tracking ("ABOUT", "PROCESS", "PRICING") shows up on most generations regardless of brief, which is what makes it a tell. One named kicker as a deliberate system is voice; an eyebrow on every section is AI grammar. <!-- rule:skill-ban-eyebrow-on-every-section -->
- **Numbered section markers as scaffolding (01 / 02 / 03).** The eyebrow trope one tier deeper. Numbers earn their place when the section really is a sequence and the order carries information the reader needs. <!-- rule:skill-ban-numbered-section-markers -->
- **Text that overflows its container.** Long heading words plus large clamp scales plus narrow grids overflow on tablet and mobile. Test the real copy at every breakpoint, then reduce the clamp max or rewrite the line. The viewport is part of the design. <!-- rule:skill-ban-text-overflow -->
## Detector-blind reflexes
No scanner catches these, and they are where an otherwise competent build still reads as generated. Inspect the rendered result for them.
- Monospace used to signal "technical" or "developer" rather than to show code, data, or measurement. <!-- rule:skill-reflex-mono-as-technical -->
- Light or dark chosen by category habit instead of the real use scene: who uses this, where, under what ambient light. <!-- rule:skill-reflex-theme-by-habit -->
- Decorative sparklines, meaningless progress rings, and rounded rectangles with soft shadows standing in for content. <!-- rule:skill-reflex-decorative-chrome -->
- A modal reached for when the task needs neither interruption nor protected focus. <!-- rule:skill-reflex-modal-by-reflex -->
- One uniform entrance animation applied to every section. Staggering items within a single list is legitimate; the reflex is the identical reveal, not motion itself. <!-- rule:skill-motion-no-section-fade -->
Run the mechanical detector once over the changed web UI, and only when this session has no automatic hook: `node {{scripts_path}}/detect.mjs --json <changed targets>`. Never add a second detector pass, and never run it during concept selection. <!-- rule:skill-detector-finish-mode -->
<codex>
- Display tracking stops at -0.04em; -0.02 to -0.03em is usually enough. <!-- rule:skill-typo-codex-tracking-repeat -->
- Declare elevation once: border or shadow, not both as decoration. A 1px border paired with a soft shadow past 16px blur is the ghost-card tell. Keep container radii modest, 1216px on cards; reserve pills for small controls. <!-- rule:skill-codex-elevation-radius --> <!-- rule:skill-ban-codex-ghost-card --> <!-- rule:skill-ban-codex-over-round -->
- Use real illustration or none. Hand-drawn SVG scenes, `loose-sketch` / `doodle` class names, and `feTurbulence` paper-grain filters read as amateurish rather than whimsical. <!-- rule:skill-ban-codex-sketchy-svg -->
- Treat backgrounds as surfaces and add texture only from the subject's world. `repeating-linear-gradient` stripes and two-axis CSS grid overlays are decoration unless the surface really is a canvas, map, blueprint, or measurement tool. <!-- rule:skill-ban-codex-stripes --> <!-- rule:skill-ban-codex-grid-backgrounds -->
- Claims, evidence, and configuration come from supplied truth; label illustrative behavior and unresolved values honestly. Naming a concept and then layering an ironic modifier is not a claim. <!-- rule:skill-codex-material-honesty --> <!-- rule:skill-ban-codex-x-theater -->
</codex>
<gemini>
Never animate `<img>` elements on hover, directly or through a parent. That includes Tailwind's `.group:hover .group-hover\:scale` / `:rotate` / `:translate` reaching a child image. The image is not an action target, so the motion carries nothing. Give the card itself feedback instead. <!-- rule:skill-interaction-gemini-no-image-hover -->
</gemini>
+3 -1
View File
@@ -4,7 +4,9 @@ Manage the **design detector hook** for the current project.
The hook runs the impeccable design detector on direct file edits to design-relevant files (`.tsx`, `.jsx`, `.html`, `.vue`, `.svelte`, `.astro`, `.css`, `.scss`, `.sass`, `.less`, `.ts`, `.js`). Claude Code, Codex, and GitHub Copilot use a post-tool-use hook and push a short system reminder into the agent's context after the edit; findings get a correction prompt, pending issues get a re-nudge, and clean UI-ish files get a short ack unless quiet mode is on (`hook.quiet` in config). Plain `.ts` and `.js` files are still scanned, but stay quiet unless the detector finds something. Cursor uses `preToolUse` to block bad proposed writes before they land and stays silent when it allows a clean write.
The detector rules run in two tiers. The per-edit hook surfaces only the immediate tier: mechanical, unambiguous problems worth interrupting an edit for, such as broken images, overflowing or clipped content, contrast and legibility failures, gradient text, glow shadows, and design-system drift. Everything else (copy cadence, palette and typography taste, layout rhythm) is deferred to a deep pass on the `Stop` hook event, which runs the full rule set over every UI file touched in the session and surfaces the remaining findings once, deduplicated against what the per-edit pass already reported. That Stop message also asks for one authored review of detector-blind model reflexes. A session that touched no UI files stops silently. Set `hook.perEditRules` to `"all"` in `.impeccable/config.json` to restore the full rule set on every edit. The Stop deep pass is wired for Claude Code and Codex, which both dispatch a native `Stop` hook event. Cursor does not get one (its stop hook is not consistently dispatched; the pre-write gate covers it), and GitHub Copilot's stop-style events do not feed context back to the model, so they keep the full detector per edit while `context.mjs` supplies the detector-blind review. When no automatic hook is active, `context.mjs` instead supplies that review plus one manual detector command.
The detector rules run in two tiers. The per-edit hook surfaces only the immediate tier: mechanical, unambiguous problems worth interrupting an edit for, such as broken images, overflowing or clipped content, contrast and legibility failures, gradient text, glow shadows, and design-system drift. Everything else (copy cadence, palette and typography taste, layout rhythm) is deferred to a deep pass on the `Stop` hook event, which runs the full rule set over every UI file touched in the session and surfaces the remaining findings once, deduplicated against what the per-edit pass already reported. A session with nothing left to report stops silently. Set `hook.perEditRules` to `"all"` in `.impeccable/config.json` to restore the full rule set on every edit. The Stop deep pass is wired for Claude Code and Codex, which both dispatch a native `Stop` hook event. Cursor does not get one (its stop hook is not consistently dispatched; the pre-write gate covers it), and GitHub Copilot's stop-style events do not feed context back to the model, so they keep the full detector per edit.
Every hook is a mechanical pass. The reflexes no scanner catches live in [craft-floor.md](craft-floor.md), which the skill loads before it edits UI, so they apply whether or not a hook is wired. A session with no automatic hook gets one `MANUAL_DETECTOR_REQUIRED` directive from `context.mjs` asking for a single detector run at the end.
This command toggles the hook **per project** by editing `.impeccable/config.json` (the unified Impeccable config; hook runtime settings live under its `hook` key, and shared detector ignores live under `detector`). Per-developer overrides, including the install consent decision (`hook.consent`) the CLI records, live in the gitignored `.impeccable/config.local.json`. Set `hook.enabled: false` to turn the hook off, `hook.quiet: true` to silence the clean/pending acks, or `hook.auditLog` to a file path for an NDJSON log. The legacy `IMPECCABLE_HOOK_DISABLED`, `IMPECCABLE_HOOK_QUIET`, and `IMPECCABLE_HOOK_LOG` env vars are still honored and override these config values when set.