Audit
SkillSecurityEight audit modes (codebase — owns "audit the codebase" — docs/process, performance, threat-model, motion, SEO, debt). Triggers "nuclear review", "whole codebase review", "adversarial audit", "fable audit", "correctness audit", "audit the docs", "doc drift", "process audit", "perf audit", "why is it slow", "bundle audit", "threat model", "attack surface", "motion audit", "seo audit", "aeo", "llms.txt", "debt ledger", "shortcut ledger". Single-page CWV routes to /lighthouse.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Audit skill
What this skill tells your AI
The instructions your AI receives, as published by darkroomengineering/cc-settings in skills/audit/SKILL.md and read by ahel’s review.
Standalone Codex host branch
Claude frontmatter, TLDR, agent teams, dynamic workflows, codex-verifier, and
codex-run.ts do not apply in standalone Codex. Keep source inspection
read-only. Map with rg --files, rg -n, direct import/caller searches, focused
file reads, and the repo's own diagnostics; never claim TLDR ran. Use Context7
only when the user configured that MCP. Otherwise inspect pinned manifests and
lockfiles, consult official package documentation through native browsing when
available, and label currency or API claims unverified when neither source is
reachable. This package does not auto-run unpinned registry MCP packages.
For fan-out, create each new reader with spawn_agent, continue a live reader
with send_message, trigger another turn for an idle existing reader with
followup_task, wait with wait_agent, and stop its current turn with
interrupt_agent only when necessary. Only read-only reviewers
may overlap. Writers share the working tree unless the live host explicitly
offers isolation, so the main session writes the final report after readers
finish; any implementer and test-writer phases must be serialized with
non-overlapping ownership.
One skill, eight whole-repo audit modes. Seven of them share a skeleton: read the surface in full (never sample), hunt with explicit categories, and ship a prioritized, executable report or plan set. Six families of question:
- Codebase — one merged audit, two lenses on the same read. The structure lens (ported from Cursor's internal
thermo-nuclear-code-quality-reviewskill, reported by Eric Zakariasson as Cursor's most-used internal skill; formerly this skill's standalone Maintainability mode) asks should this code exist? — 1k-line sprawl, thin wrappers, code-judo deletions, dependency freshness via context7. The behavior lens (adapted from the fable audit goal-spec trio, gistdiegomarino/04970a2b8d9cc419de3ba05b9a03db5a; formerly the separate Codebase mode) asks does it do what it promises? — correctness, incoherences, affordance gaps. Merged August 2026: both modes fanned the same whole-repo readers over the same files and shipped near-identical reports, so they now run as one pass with two hunt lists. The July 2026 cc-settings audit ran the behavior lens and produced 28 findings, ~all confirmed and fixed. - Docs and Process — from the same fable audit trio. Truth and structure of the docs (docs), walkable end-to-end journeys (process). The mechanics that made the July 2026 audit work (stable IDs, CONFIRMED/PLAUSIBLE, concrete failure scenarios, design tensions vs line findings, open questions for the maintainer) are the contract for these modes.
- Performance — asks where is time actually going, measured? Empirical-only: a finding does not exist until a number confirms it. Covers client runtime (via the same Lighthouse protocol
/lighthouseuses), bundle and build, server and data, and code-level hot paths, adapting to what the repo actually is (web app vs CLI vs library). - Threat-Model — adapted from openai/skills
security-threat-model(Apache-2.0). Asks what can go wrong, and who would exploit it? — trust boundaries, attacker capability, abuse paths tied to attacker goals, mitigations mapped to components. - Motion — adapted from emilkowalski/skills
improve-animations(MIT). Asks where does animation work have the highest leverage? — purpose/frequency, easing/duration, physicality/origin, interruptibility, performance, accessibility, cohesion, and missed opportunities, turned into self-contained implementation plans rather than a findings report. - SEO — distilled from shipped Darkroom work (satus PRs #348/#405/#413 and darkroomengineering/website PRs #40/#65, which converged independently on the same architecture). Asks will this site be found, ranked, and cited? — canonical integrity, sitemap reachability, per-content metadata, structured data, and the AEO surfaces (llms.txt, named AI crawlers, machine-view routes) that answer engines read.
Codebase mode's structure lens should push to be ambitious — do not merely identify local cleanup opportunities, actively search for "code judo" moves. Every adversarial mode holds no loyalty to the current design — hunt defects, drift, dead ends, and abuse paths rather than confirm things work.
The eighth mode, Debt, is the odd one out: a mechanical grep that collects SHORTCUT: markers into a ledger. It shares none of the skeleton above and makes no judgement — see Mode: Debt at the end of this file.
Mode Router
The bare phrase "audit the codebase" routes straight to Codebase mode — the merge removed the old maintainability-vs-correctness question, because one pass now carries both lenses.
Trigger phrases by mode:
| Mode | Phrases |
|---|---|
| Codebase | "audit the codebase", "nuclear review", "thermonuclear review", "code judo", "deep code quality audit", "harsh maintainability review", "whole codebase review", "should this exist", "adversarial audit", "fable audit", "expectation gaps", "correctness audit" |
| Docs | "audit the docs", "docs audit", "doc drift" |
| Process | "process audit", "audit the workflows", "walk the journeys", "end-to-end audit" |
| Performance | "perf audit", "performance audit", "why is the app slow", "bundle audit", "build is slow", "speed audit" |
| Threat-Model | "threat model", "STRIDE", "attack surface", "abuse paths" |
| Motion | "motion audit", "audit the animations", "improve the animations" |
| SEO | "seo audit", "aeo", "ai engine optimization", "answer engine", "discoverability audit", "rank better", "llms.txt" |
| Debt | "debt ledger", "shortcut ledger", "what did we defer", "what corners did we cut" |
One remaining ambiguity, Performance vs /lighthouse: a page-speed ask scoped to a URL or a target score ("check page speed on /", "improve web vitals", "get LCP under 2.5s") is /lighthouse — it measures one page and loops fixes until targets are met. A repo-wide ask ("performance audit", "why is the app slow") is this skill's Performance mode — it measures every surface and ships a report. When the phrasing genuinely fits both, ask which the user wants; don't guess.
Debt mode is a mechanical grep — run it standalone or as a cheap first pass before Codebase mode.
When to use vs other review skills
/review— per-diff Darkroom checklist (TypeScript / React / a11y / perf / security), now including an animation checklist when the diff touches motion. Every change./audit(this skill) — periodic whole-repo audit, eight modes. Codebase mode asks "should this code exist, and does it do what it promises?"; docs and process modes ask whether the docs tell the truth and the journeys walk end-to-end; performance mode asks "where is time actually going, measured?"; threat-model mode asks "what can go wrong, and who would exploit it?"; motion mode asks "where does the animation work have the highest leverage?"; seo mode asks "will this site be found, ranked, and cited?"; debt mode asks "what did we defer on purpose?" Run codebase mode on major version cuts, after extended velocity sprints, before a load-bearing migration. Docs and process modes shine before releases and after feature bursts. Performance mode fits before a launch, after a dependency-heavy sprint, or whenever "the site feels slow" comes up without a number attached. Threat-model mode fits before a security-sensitive launch or a new internet-facing surface. Motion mode fits after a UI-heavy sprint or before a client showcase. SEO mode fits before a site launch and as a first pass on any client marketing/content site./lighthouse— single-page CWV measurement plus a fix-until-targets-met loop. Performance mode delegates its client-runtime measurements to the same Lighthouse protocol and hands findings back to/lighthouseor/refactorfor execution; it never duplicates the loop./zero-tech-debt— rework a specific patch to its intended end-state. Not a review — it edits./verify— adversarial check of a single change/claim, not a repo sweep.
A typical sequence: /audit codebase produces findings → engineers cherry-pick the highest-leverage ones → the right executor by finding type: dead code and duplication go to the deslopper agent (auto-removes what's provably dead, stages consolidations for approval), structural rework to /zero-tech-debt or /refactor, client-runtime perf findings to /lighthouse.
Claude Code only (v2.1.154+): standalone Codex skips this tip and the Workflow command below. In Claude, run
/effort ultracodebefore invoking this skill. Whole-repo audits are the canonical shape that benefits from dynamic workflows — phase state lives in the workflow script rather than Claude's context window, individual areas can be reviewed in parallel (up to 16 concurrent), and the run can resume from cached agent results within the session. Dynamic workflows default to a medium size guideline, aiming for fewer than 15 agents (v2.1.219) — it's advisory, not enforced, but a repo with more modules than that is worth raisingworkflowSizeGuidelinefor explicitly before the fan-out phase rather than silently exceeding the default.A ready-made example for codebase mode's structure lens ships at
references/nuclear-review.workflow.js(installed to~/.claude/skills/audit/references/). It is opt-in, not a dependency — the mode works with no Workflow tool. Run it withWorkflow({ scriptPath: "~/.claude/skills/audit/references/nuclear-review.workflow.js" }), or copy it into.claude/workflows/. It maps the repo, fans out one structural reviewer per module, audits dependencies, and synthesizes one report. Treat it as a template — adapt its module list, schemas, and phases to the repo at hand rather than running it verbatim.
Shared Contract (Codebase, Docs, Process, Threat-Model, SEO, and Performance modes)
Role. No loyalty to the current design/structure/flows. Act simultaneously as a senior staff engineer, a skeptical first-time consumer, and an adversarial reviewer. Understand deeply enough to challenge, not merely validate.
Method.
- Per area, state how it SHOULD behave, then read (or run) to confirm or refute. Every expectation-vs-reality gap is a finding.
- Every finding needs a concrete scenario: specific inputs/state leading to the wrong or surprising result. No vague "could be improved."
- Mark each finding CONFIRMED (traced or reproduced) or PLAUSIBLE (suspected). Try to disprove yourself first; discard findings that don't survive. (Performance mode tightens this: PLAUSIBLE does not exist there — see its evidence rule.)
- Where something is sound, say so once and move on — spend effort where it isn't.
Cross-model + intent passes. In Claude, run the shared procedures in
references/audit-contract.md (§1 Codex cross-model pass via codex-verifier
on the finding list, §2 team-knowledge reconciliation). Both are gated and fail
open. Standalone Codex never uses the bridge; it may use a fresh native
read-only reviewer under the lifecycle above. The one-line invariants: reconcile
AFTER findings exist, and a documented decision reclassifies severity, never
deletes a finding.
Output. Write the full report to docs/audits/[mode]-audit-YYYY-MM-DD.md (create the dir; leave uncommitted — the maintainer owns git). Structure top-heavy:
- Summary table: ID | severity | area | one-line issue | file:line | CONFIRMED/PLAUSIBLE.
- Map (system map / doc map / process state machine — per mode below).
- Findings by hunt category, severity order. Each: stable ID (H1/M1/L1 by severity, or C/D/P prefix per mode), location, one-line issue, concrete scenario, status, recommended direction.
- Design tensions: the 3-5 deepest structural issues ("the approach, not a line"), each with the alternative you'd weigh.
- Open questions: what the artifact alone can't resolve — maintainer answers required.
- Considered & rejected: candidate findings you investigated and disproved (or reclassified as by-design), each with a one-line reason. This ledger is what stops the next audit from re-litigating them — check it before hunting.
Chat reply = exec summary only: counts by severity + top 3-5 findings + report path.
Optional issue filing. When the maintainer wants findings executable by agents, file each as a GitHub issue (one per finding, severity labels, CONFIRMED/PLAUSIBLE in the body, an epic for the design tensions, question-labeled issues for the open questions). This is how the July 2026 cc-settings remediation ran: issues → parallel fix agents → PRs citing the IDs.
Mode: Codebase
One merged audit, two lenses on one whole-repo read: structure (should this code exist?) and behavior (does it do what it promises?). Rides the Shared Contract above.
Scope
The entire codebase, not the current diff:
- All source modules — application code, libraries, scripts, hooks, configs
- The dependency manifest (
package.json+ lockfile) — every direct dependency - Folder structure, module boundaries, top-level architectural surfaces (routes, providers, exported APIs)
- Entry points and real (not documented) execution paths; module contracts, explicit and implied
- Data models, invariants, and where they're enforced vs assumed
- External surfaces (APIs, CLIs, config, env vars, file formats, network calls) and the onboarding path a newcomer would actually follow
Skip vendored code, generated files, and node_modules.
Workflow
Phase 0 — Map the codebase
Establish ground truth before judging anything.
# Top-level structure
fd -t d -d 2 --hidden -E node_modules -E .git -E dist -E build
# File-size distribution (largest first) — find the 1k-line crossings
fd -t f -E node_modules -E .git -E dist -E build \
-e ts -e tsx -e js -e jsx -e py -e go -e rs \
-x wc -l {} \; | sort -rn | head -50
# Direct dependency count
jq '.dependencies + .devDependencies | length' package.json
# Direct deps with versions
jq '.dependencies + .devDependencies' package.json
In Claude, if the project uses tldr, prefer it for the call graph + dead-code pass. Standalone Codex skips these commands and uses the native searches in its host branch:
tldr arch .
tldr dead . --entry-points "main,test_"
If dead returns unsupported-by-native-engine (the default engine does not implement it), say
the dead-code pass did not run — do not record "no dead code" as a finding. An empty result from
dead or impact is not evidence; confirm with Grep before acting on it.
If the opt-in tldr-code CLI is installed (~/.claude/code-intel/tldr-code/0.4.0/tldr — see
docs/tldr-cheatsheet.md), prefer it for the dead-code pass instead:
~/.claude/code-intel/tldr-code/0.4.0/tldr dead . --lang typescript
It exits 0 even on errors — never trust its exit code. Check that stdout parses as JSON and
that functions_analyzed > 0; non-JSON stdout or functions_analyzed: 0 means the scan did not
run and must be reported as "scan unavailable", never as "no dead code". dead_functions from
tldr-code is ADVISORY ONLY — confirm every candidate with Grep before recording it as a
finding. Its MCP path (tldr-mcp, not used here) was measured reporting live symbols as dead
code; the CLI was measured accurate, which is why it's used here instead.
When the project depends on deslop-cli (check package.json — it's the same advisory probe
/proof-of-work runs), add it as a second dead-code signal: npx deslop-cli. Same rule as
tldr-code: advisory only, Grep-confirm every candidate. Two scanners agreeing upgrades conviction;
either one alone still needs confirmation.
Phase 1 — Dependency audit (Context7 when configured)
For each direct dependency in package.json, use the context7 MCP server to
verify when it is configured. Standalone Codex otherwise uses the native/manual
fallback in its host branch and does not execute an unpinned registry MCP:
- Currency — is the installed version current, or stale? Note major-version gaps.
- Usage quality — is the codebase using the dependency in the way the maintainers currently recommend? Old APIs, deprecated patterns, missing newer affordances?
- Necessity — could it be replaced by a platform built-in, an existing canonical helper, or a smaller dependency?
- Overlap — does it duplicate the role of another dependency? (Two date libraries, two state managers, two HTTP clients.)
- Footprint cost — for any dependency contributing >50KB to the client bundle, is the usage scope worth the cost? Could it be code-split, lazy-loaded, or replaced?
Use context7 in two steps per dependency:
mcp__context7__resolve-library-id { libraryName: "<package>", query: "<what we use it for>" }
mcp__context7__query-docs { libraryId: "<resolved id>", query: "current recommended usage vs <pattern we use>" }
Cap context7 calls at 3 per dependency (per the server's own guidance). Batch the audit: pick the top 10–20 by either bundle weight or surface-area coverage rather than auditing every transitive dep.
Output for each flagged dep: current version → recommended version, deprecated APIs in use, suggested fix.
Phase 2 — The hunt, both lenses
Walk the largest files first, then the modules with the most outbound dependencies, then the entry points. Apply both lists to every meaningful surface in one pass.
Structure lens — non-negotiable standards:
- Be ambitious about structural simplification. Do not stop at "this could be a bit cleaner." Look for reframings that make whole branches, helpers, modes, conditionals, or layers disappear entirely. Assume there is often a "code judo" move available — a re-organization that uses the existing architecture more effectively and makes the surface dramatically simpler. Prefer the solution that feels inevitable in hindsight; if you see a path to delete complexity rather than rearrange it, push hard for that path.
- Flag every file over 1k lines. A strong code-quality smell by default; prefer extracting helpers, subcomponents, or modules. Waive only for a compelling structural reason with the file still clearly organized.
- Do not tolerate spaghetti. Ad-hoc conditionals, scattered special cases, one-off branches in otherwise cohesive flows — a design problem, not a stylistic nit. Push logic into a dedicated abstraction, helper, state machine, or module instead of tangling existing paths.
- Bias toward cleaning the design, not preserving working code. If behavior can stay the same while structure gets meaningfully cleaner, push for the cleaner version. Prefer simplifications that remove moving pieces over refactors that spread the same complexity around.
- Prefer direct, boring code over hacky or magical code. Flag thin abstractions, identity wrappers, pass-through helpers, and generic mechanisms that hide simple data-shape assumptions.
- Push hard on type and boundary cleanliness. Question unnecessary optionality,
unknown,any, cast-heavy code, and silent fallbacks papering over unclear invariants; prefer explicit typed models and shared contracts. - Keep logic in the canonical layer and reuse existing helpers. Call out feature logic leaking into shared paths, details leaking through APIs, and bespoke one-offs where a canonical utility exists.
- Treat unnecessary sequential orchestration and non-atomic updates as design smells. Serialized-for-no-reason work and updates that can leave state half-applied — flag both without over-indexing on micro-optimizations.
- Dependencies must be current and well-used. Flag deprecated majors, superseded usage patterns, role-duplicating deps, disproportionate footprints, and deps a platform primitive could replace.
Behavior lens — hunt categories:
- Correctness — logic errors, races, off-by-one, unhandled edges, silently swallowed failures, wrong error propagation.
- Alternative/unintended paths — second call? concurrent calls? empty/null/huge input? partial failure mid-op? retries? the "holding it wrong" path?
- Incoherences — names that lie about behavior, two modules solving one problem differently, config honored here and ignored there, duplicated sources of truth that can drift, dead code, contradictory defaults.
- Affordance mismatches — "I expected to do X this way but can't, or it does something else." Where does the API shape promise a capability the code doesn't deliver? Where is the easy path also the dangerous one?
- Missing functionality — what a reasonable user expects (validation, idempotency, cleanup, observability, cancellation, timeouts) but is absent.
- Boundary and safety — leaky abstractions, invariants in the wrong layer, unvalidated input crossing a boundary; injection, path traversal, unbounded growth, resource leaks, missing authz, exposed secrets — only where real.
- Documentation — README/docstrings/comments that are wrong, stale, or contradict the code; undocumented public behavior/params/errors/side effects; examples that wouldn't run.
- Developer experience — can a newcomer build, run, test, and debug from the docs alone? Confusing errors, silent misconfig, setup footguns.
Phase 2b — Claude-only cross-model structural pass (when the Codex bridge is available)
Standalone Codex skips this phase. In Claude, run the shared cross-model
procedure (references/audit-contract.md §1) with this mode's audit prompt:
bun "$HOME/.claude/src/scripts/codex-run.ts" ask "Audit this repository for structural problems: files over ~1000 lines, thin wrappers that don't earn their keep, logic leaked across boundaries, and duplicated abstractions. Walk the largest files and the modules with the most outbound dependencies first. Report the highest-leverage 'code judo' restructurings — ones that delete whole branches rather than rearrange them — ordered by conviction."
Fold Codex's findings into Phase 3 per the contract: convergence = high-conviction, divergence noted not dropped, gated and fails open.
Phase 2c — team-knowledge reconciliation (when the corpus is reachable)
Phases 2 and 2b judge structure intent-blind, so deliberate design reads as debt. Run the shared reconciliation procedure — references/audit-contract.md §2: generate findings blind FIRST, then cross-reference the corpus; a documented decision reclassifies severity, never suppresses a finding; gated, fails open.
SHORTCUT: markers (AGENTS.md Laziness Ladder) get the same treatment as team-knowledge notes: a marked deferral is a documented decision, not ordinary debt — cite the marker instead of re-litigating it, and escalate only if its stated upgrade trigger has actually fired. Debt mode owns the full ledger; this mode just respects it.
Phase 3 — Synthesis
Produce the Shared Contract report, with two mode-specific additions: open with a one-line verdict — CLEAN / NEEDS RESTRUCTURING / NEEDS MAJOR REWORK — and lead the findings with a Code-Judo Opportunities section (dramatic simplifications: what to delete, not just polish). The map section includes an "expectation gaps" list: short "expected X, found Y" entries for affordance/docs/DX. Prioritize ruthlessly — a smaller number of high-conviction findings beats a long list; do not flood the report with nits when larger structural issues exist.
Severity ordering within the report: structural regressions and missed code-judo moves first, then correctness/incoherence findings, then dependency staleness with material impact, then boundary/type-contract problems, then file-size and legibility concerns.
Phase 4 — Documentation updates (after fixes land)
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 44
- Forks
- 3
- Last commit
- Sep 2026
- Hacker News mentions
- 20
Advanced
- Catalog kind
- skill
- Gateway key
audit-darkroomengineering- Source
- github.com/darkroomengineering/cc-settings