← The Machine Room · Case File 005 — audit-kit At the v1.0 gate · --:--:-- GST · Sheet 1 of 7
CASE FILE · AUDIT-KIT · DESIGN-SYSTEMS QA / DEVTOOLS DWG NO. AH-CS-005

audit-kit turns "the spacing looks off" into evidence: which computed styles drifted from the tokens, and the line of CSS that caused it.

Fifteen single-purpose CLI tools under one JSON envelope. A headless probe records what actually rendered — and which declaration won the cascade — so every drift two reviewers used to argue about becomes a deterministic, citable finding an agent can act on.

PROBE → COMPARE → ATTRIBUTE → GATE · EXIT 0–6
15 TOOLS · ONE ENVELOPE · SCHEMAVERSION 1.0.0 — NEVER MOVED
FINDING IDS — 12-HEX CONTENT HASH, CITABLE ACROSS MACHINES

FIRST PATIENT: THE MACHINE FROM CASE FILE 002
DOGFOODED ON THE AUTHOR'S OWN CRM
4,306 raw findings
250
GROUPED BY THE DECLARATION THAT CAUSED THEM
MEASURED ON A REAL PROJECT — MY OWN CRM  VERIFIED · DOGFOOD
Drawn byAbu Huraira Mukhtar
RoleArchitect & Sole Author
Build window2026-04-24 → 04-25 · ~2 Days
Scale4,306 : ≈250
LicenseMIT Declared · File Pending
StatusAt the v1.0 Gate · v0.5.0
Source17,606 LOC + 13,538 Test
Sheet1 of 7
SHEET 2 OF 7 · ABSTRACTGENERAL NOTES APPLY

01 · Evidence, not vibes

Ask audit-kit whether the spacing is off and it answers with a list: route, selector, property, observed value, nearest legal token — and the source declaration that caused it.

Fifteen tools speak one contract. A humans-first Markdown report and an agents-first JSON envelope come out of the same run; every finding carries a 12-hex content-hash id, so "this exact drift" means one thing forever, on any machine. Wire one parser and you can consume every tool the kit will ever ship — the envelope's schemaVersion has never moved off 1.0.0, by decision, not by luck.

It was born inside another drawing in this ledger: the consistency audit of KorCRM, Case File 002. That machine was this machine's first patient. And the kit is project-agnostic by enforcement, not intention — a lint rule treats any hardcoded client reference in the source as a bug.

GENERAL NOTES
1 · 15 TOOLS · 17 BINARIES INCL. META-CLI + MCP SERVER VERIFIED
2 · 16-VALUE CATEGORY ENUM · 5 SEVERITY TIERS · CLOSED
3 · 703/704 TESTS · 50 FILES · TESTS ≈43% OF ~31K LOC
4 · 51 ADRS · 64 GOTCHAS LOGGED IN TWO DAYS
SHEET 3 OF 7 · FIELD NOTESTHE BEFORE-STATE

02 · "Looks off" isn't evidence

Somewhere this week, two senior reviewers are disagreeing about a two-pixel gap, and both are right that neither can prove it.

The real scene behind this drawing: 127 screenshots across 19 directories, scrubbed by eye. One card sits at an 18px gap in a sea of 16s. A button ships #6d28d9 where the token says #7c3aed — two purples no human eye can split across two screenshots, which is exactly why "that's not our purple" starts a forty-minute argument and ends it with nothing.

FIG. 1 shows the loop as observed. It runs on opinion, produces no artifact, and exits nowhere. What it lacked was not taste — both reviewers had plenty — but evidence either of them could cite.

OBSERVED
SCREENSHOTS — 127 PNG · 19 DIRS
CARD GAP — 18 PX IN A FIELD OF 16 PX
BUTTON — #6D28D9 VS TOKEN #7C3AED
ARTIFACT PRODUCED — NONE
127 PNG · 19 DIRS "THE SPACING LOOKS OFF" REVIEWER A "LOOKS FINE TO ME" REVIEWER B VS MEETING · 40 MIN NO ARTIFACT — VERDICT DEFERRED LOOP RE-OPENS NEXT SPRINT
FIG. 1 — THE MANUAL REVIEW LOOP, AS OBSERVEDSCALE — ONE DISPUTED PIXEL : 40 MIN
SHEET 4 OF 7 · SECTION A-ACUT THROUGH THE RUNNING PIPELINE

03 · Attribution, not suppression

DOM-PROBE · PLAYWRIGHT CDP — WHICH DECLARATION WON +16 MS / +3% · 50-NODE ROUTE METRICS.JSON TOKENS COMPUTED TOKEN-AUDIT SPACING · LINT 4,306 RAW FINDINGS 782 SPACING · 2,714 LINT 656 TOKEN · 154 OTHER 1 CAUSE · .GAP-3 → 12PX SHARED PRIMITIVE · SOURCEMAPPED AFFECTED NODES: 272 → 1 FINDING ≈250 GROUPED CAUSES A FEW DOZEN DECLARATIONS EXIT THE GATE 0 CLEAN 1 DRIFT EXIT CODES 2–6 ONE CODE EACH AGENT · MCP MARK №BOXES --VERIFY <ID> EVERY FINDING ARCS BACK TO THE DECLARATION THAT CAUSED IT ONE ENVELOPE END TO END · STDOUT JSON, STDERR LOGS · SAME ANSWER ON EVERY MACHINE
FIG. 2 — SECTION A-A · THE AUDIT PIPELINE, V0.5EVERY COUNT ON THIS FIGURE IS A DOGFOOD MEASUREMENT
BEAT 1 · DOM-PROBE · PLAYWRIGHT + CDP

1Probe

A headless browser crawls the route list and records, per element, what actually rendered — every computed style, every bounding box. Since v0.5 it also asks the Chrome DevTools Protocol which CSS declaration won each property, and walks that answer back through sourcemaps to the file you wrote. Cost: +16 ms on a 50-node route. If CDP won't attach, the run degrades to a diagnostic — it never crashes.

BEAT 2 · ONE METRICS FILE, MANY JUDGES

2Compare

token-audit, spacing-audit, tokens-lint, a11y-audit, semantic-diff — all read the same metrics.json, all emit the same envelope. A drift finding names route, selector, property, observed value and the nearest legal token. Sixteen categories, five severities, closed enums: no surprise strings, ever.

BEAT 3 · THE FIRST HONEST RUN

3Drown

Pointed at a real app — my own CRM — the first full run returned 4,306 findings: 782 spacing, 2,714 lint, 656 token, 154 other. Every one technically true; collectively unreadable. At four thousand findings nobody acts, human or agent. This is the wall where most linters go to be ignored.

BEAT 4 · CAUSE FINGERPRINT · ADR-050/051/052

4Attribute

The fix was not suppression — a mute button hides real drift. It was attribution: trace each finding to the source declaration that caused it, and group by that cause. One .gap-3 in a shared primitive cascading to 272 nodes becomes one finding with affectedNodeCount: 272. The 4,306 collapse to roughly 250 grouped findings pointing at a few dozen declarations — the to-do list the report always should have been.

BEAT 5 · EXIT CODES 0–6, DETERMINISTIC

5Gate

Every tool exits the same way every time: 0 clean, 1 drift found, 2–6 each a distinct failure mode an agent can branch on without parsing prose. tokens-lint hard-bans raw hex and px in critical properties — three high-severity violations and the build fails at exit 1. Opinions don't gate; exit codes do.

BEAT 6 · MCP · MARK · --VERIFY

6Close the loop

An MCP server exposes all fifteen tools to agents; mark draws numbered boxes on screenshots so a multimodal model can point at finding №7 and mean it. Because every id is a content hash, --verify <id> re-checks one finding and returns the same answer on any machine. The dashed arc is the whole product: every finding arcs back to the one declaration that caused it.

DETAIL B · SEE FIG. 2, FINDING IDS

An id that refuses to be unique

The obvious design: a UUID per finding. It demos fine and makes "is this drift still open from yesterday?" permanently unanswerable.

Chose id = sha256 of tool, category, route, selector, property, observed and expected value — first 12 hex — with boundingBox and timestamps deliberately excluded, because a review tool needs "this exact drift" to mean one thing forever, across runs and machines. Cost: a genuinely new instance of an identical drift on the same selector collapses into the same id. Revisit when instance-tracking matters more than citability — so far it hasn't. ADR-005
DETAIL C · SEE FIG. 2, ENVELOPE

The contract that never moves

The shared envelope is upstream of every tool and every downstream agent. One rename there is a fifteen-tool cascade and a broken parser somewhere you can't see.

Chose an append-only contract after Phase A — schemaVersion has never left 1.0.0 — because the first broken downstream agent costs more than every convenience a v2 would buy. Cost, paid knowingly: a known --help description bug ships unfixed, and flow duplicates dom-probe's selector list rather than import it — sealed-tool isolation outranks DRY here. Revisit at a major version, never mid-flight. ADR-003 · ADR-007
SHEET 5 OF 7 · REVISION HISTORYALL ENTRIES TRACEABLE

04 · What broke, by revision

Real toolchains carry a revision history because real contracts get tested. Five of these rows closed inside the two-day sprint; the sixth is still open, and it's the funny one.

The pattern across them: when something broke, the fix was attribution or contract — never a mute button, never a patch on the symptom.

REV
DATE
WHAT BROKE
THE FIX
TRACE
A
2026-04-25
NOISEThe first real run emitted 4,306 findings against ~30–50 actual root-cause declarations. Top offenders: 4px ×295 and 12px ×272 — stock Tailwind .gap-1/.gap-3. Nobody reads a 4,306-line report.
ATTRIBUTION, NOT SUPPRESSIONCDP records which declaration won, sourcemaps walk it home, findings group by cause fingerprint. Coverage survives as affectedNodeCount and per-instance metadata. 4,306 → ≈250.
ADR-050 / 051 / 052
B
2026-04-24
IDENTITYRandom UUIDs made findings untrackable across runs — "still open or new regression?" had no answer. Monotonic integers leaked ordering that reshuffled with input order.
CONTENT HASH12-hex sha256 of the finding's identity fields; boundingBox and timestamps excluded on purpose. Stability over instance-uniqueness — a citable drift beats a unique one.
ADR-005
C
2026-04-25
SAFETYExecutable rule configs for tokens-lint would hand every agent-authored ruleset an eval surface inside a tool that runs in CI.
PURE JSONDeclarative rule schema with a closed matcher set, no executable escape hatch. An agent can write rules; no rule can write back.
ADR-021
D
2026-04-25
STREAMPino log lines intermixed with NDJSON frames on stdout. For plain JSON, parsers survived by reading the last line; for a frame stream it was a hard break — agent parsers crashed on untyped lines.
SPLIT CHANNELSLogs go to stderr, always; stdout carries only the envelope or frames. Every line on stdout is parseable, by contract.
ADR-026
E
2026-04-25
LEAKPlaywright storageState paths — where auth sessions live on disk — could reach envelopes, manifests and streams that get pasted into tickets.
REDACT AT SOURCEPaths are rewritten to a redaction marker before any output channel sees them. Secret-adjacent strings never enter an artifact.
ADR-011
F
STILL OPEN
LICENSEpackage.json declares MIT and lists LICENSE in its files array — but no LICENSE file exists. npm pack doesn't warn; it would silently ship the tarball without the license text. The tool that fails builds over a missing token is missing its own license.
PENDINGAdd the MIT text at the root. One of three items at the v1.0 gate, with the pixel-diff default-engine flip and a real publish CI step.
GOTCHA 63 OPEN

One number a skeptic should push on, answered before the interview: 4,306 → ≈250 is a dogfood measurement. Baseline and result were measured on the same real application — my own CRM, Case File 002 — with the same probes, and the raw breakdown above is from the decision log, not memory. It is not an external benchmark, and this page doesn't dress it as one.

VERIFICATION
703 / 704 TESTS · 50 FILES · VITEST, ISOLATED
STRICT TS — NOUNCHECKEDINDEXEDACCESS ON
CI MATRIX — NODE 20/22 × UBUNTU/MACOS
DRY-RUN PUBLISH GATE IN CI · REAL PUBLISH — NOT YET
SHEET 6 OF 7 · APPROVAL PLATEPROVENANCE ON EVERY NUMBER

05 · Measured on its own author

4,306 ≈250Raw findings grouped to actionable causes on a real project — the author's own CRMVERIFIED · DOGFOOD
15Single-purpose tools speaking one JSON envelope — wire one parser, consume everythingVERIFIED
1.0.0The schemaVersion that has never moved — the shared contract is append-only, by decisionVERIFIED
12-hexDeterministic finding ids — the same drift hashes the same on every machine, foreverVERIFIED · MECHANISM
+16 msCost of recording which CSS declaration won, per 50-node route — +3% over baselineVERIFIED
0–6Deterministic exit codes — drift is exit 1; an agent never guesses what happenedVERIFIED
SPECIMEN — REAL CAPTURED OUTPUT, 2026-07 · FRAMES ABBREVIATED · THE [HIGH] ROWS ARE A LIGHT REFORMAT OF THE REAL FINDINGS[]; SEVERITIES, ROUTES, SELECTORS, RULES AND VALUES ARE VERBATIM
$ dom-probe --config audit.config.json --out metrics.json ↳ crawled 4 routes · 4 nodes · cdp-css on $ token-audit --metrics metrics.json --tokens tokens.json --format ndjson --out drift.json {"type":"start","tool":"token-audit","schemaVersion":"1.0.0"} {"type":"finding","finding":{"severity":"medium","category":"color","location":{"route":"/pricing","selector":".cta-button"},"title":"Computed value drifts from token system","observed":{"value":"#6d28d9"},"expected":{"anyOf":["color.brand (#7c3aed)","color.surface (#0b0b0f)"]}}} {"type":"finding","finding":{"severity":"medium","category":"typography","location":{"route":"/pricing","selector":".cta-button"},"observed":{"value":"18px"}}} {"type":"finding","finding":{"severity":"medium","category":"shadow","location":{"route":"/dashboard","selector":".stat-tile"},"observed":{"value":"0 4px 12px rgba(0,0,0,0.15)"}}} ··· 7 more finding frames ··· {"type":"summary","summary":{"totalFindings":10,"bySeverity":{"high":0,"medium":10,"low":0},"score":80,"passed":true}} {"type":"end","exitCode":0} $ tokens-lint --metrics metrics.json tool: tokens-lint | passed: false | score: 85 | total: 3 bySeverity: {"critical":0,"high":3,"medium":0,"low":0,"info":0} [high] /pricing .cta-button — no-hex-in-color (backgroundColor: #6d28d9) [high] /pricing .cta-button — no-px-in-font-size (fontSize: 18px) [high] /dashboard .stat-tile — no-raw-shadow (boxShadow: 0 4px 12px rgba(0,0,0,.15)) ✗ 3 high-severity violations — exit 1
THE FLARE
SHIPPED #6D28D9 VS TOKEN #7C3AED — TWO PURPLES A HUMAN EYE CANNOT SPLIT ACROSS TWO SCREENSHOTS
NO SWATCH IS DRAWN ON THIS SHEET. TAKE THE MACHINE'S WORD FOR IT — THAT IS THE PRODUCT
STDOUT — ENVELOPE ONLY · PINO LOGS → STDERR (ADR-026)

What that buys a team: "the spacing looks off" stops costing a forty-minute meeting and starts costing a command. Your reviewer cites a finding id instead of a feeling; your agent fixes one declaration instead of 272 symptoms; and the next run either closes the case or reopens it — deterministically, either way.

Point this at your design system →
SHEET 7 OF 7 · CLOSE-OUTPLAIN VOICE

06 · One user, no LICENSE, no remote

A dossier about a drift auditor should audit itself, so here is its own finding list, ungrouped.

This tool has one user: me. "Used in practice" means dogfooded on my own CRM — a real application, but mine. It is not on npm; it sits at the v1.0 gate behind three items, one of which is that the package declares MIT and ships no LICENSE file. The repository has no remote — the cleanest, most publishable code in this ledger currently exists on exactly one machine. It was built in a compressed two-day multi-agent sprint at the end of April, and it has not been touched since.

I think that's the honest state of a two-day-old power tool, not a confession of abandonment. What those two days bought was not polish — it was contract discipline: 51 logged decisions, 703 passing tests, an envelope that never moved, and a rule that treats any client reference in the source as a bug. The next project doesn't rebuild any of it; it runs one install and inherits a witness.

This is the quiet promise: the drift you could only feel becomes evidence you can cite, and the screenshot ends the argument.

UNRESOLVED
LICENSE FILE — MISSING · GOTCHA 63
NPM PUBLISH — GATED BEHIND V1.0
GIT REMOTE — NONE · LOCAL ONLY
USERS — 1 · THE AUTHOR
PIXEL-DIFF ENGINE FLIP + PUBLISH CI — PENDING
DRAWN & BUILT BY
ABU HURAIRA MUKHTAR · SOLO · 2026-04-24 → 04-25
A. H. M.
SHEET 7 OF 7
END OF CASE FILE 005
THE DRAWING OFFICE · AFTER HOURS

Your design system deserves a witness, not a debate.

Bring the review that always ends in opinions. Point the probe at one route and by the second coffee you'll know exactly what drifted, which declaration caused it, and whether it was ever worth a meeting.

Start a conversation → ← Back to the machine room
NEXT CASE FILE · 006 Factory OS → SHEET 1 OF —