Skip to main content
skill CX Codex

audit · rainmanjam — Claude Code skill: find footguns in existing code

Scans code that already exists for spots where a wrong move slips through quietly: swapped arguments, silent fallbacks, deletes with no guard.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add rainmanjam/poka-yoke --skill audit -a claude-code
Open on GitHub

What audit does

The skill starts from what is already in the repo. With no path given it reads git diff HEAD, the uncommitted work. A clean tree sends it to git diff HEAD~5..HEAD. A full-repo pass happens only on request, because it is slow and buries the important findings under volume; when it does go wide, it heads for code touching money, auth, deletion or overwriting, migrations, external I/O, concurrency, and anything named admin, force, bulk, sync or delete.

A script does the mechanical part. scripts/detect_hazards.py flags adjacent parameters of the same type, boolean flag arguments, unbounded deletes, money stored as float, unvalidated request bodies and retries without an idempotency key. Invoke it with python3 ../../scripts/detect_hazards.py --diff; other forms include --paths src/ lib/, --staged, --since HEAD~10, --json, --severity high. The author calls it a fast first pass with real false positives, so treat each hit as a lead and read the surrounding code. Bare except and mutable default arguments stay off unless you pass --all.

Then comes the part no script covers: reading public interfaces against three questions. Can the wrong value fit? Can an incomplete set pass? Can the steps run out of order? Findings get ranked by blast radius, not by count: one delete_users(filter) with an empty filter outranks a hundred stringly-typed helpers. Nothing is edited until you approve, and applied devices get a poka-yoke: marker plus a test run.

What it helps with

  • catch swapped arguments in public signatures
  • review a diff or PR for ways to misuse it
  • spot deletes and other irreversible calls with no guard
  • rank a silent wrong answer above a crash
  • cut the finding list down to what actually hurts

Example prompts for the agent

  • Check my uncommitted diff and start with the worst one
  • Run the audit over src/ and lib/ and write the report
  • Look at this PR for arguments that are easy to swap

How to install audit

1Skills CLI (Vercel)

npx skills add rainmanjam/poka-yoke --skill audit -a claude-code

2Manually: put the files in place

~/.claude/skills/audit/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/audit/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about audit

How do I install audit in Claude Code?

Run npx skills add rainmanjam/poka-yoke --skill audit -a claude-code. The skill file lands at ~/.claude/skills/audit/SKILL.md.

What does audit do?

It hunts for spots in existing code where a wrong action is easy, silent and plausible-looking, then proposes changes that close them. Findings are ordered by how much damage they allow.

How is audit different from design and retro?

audit reviews code that already exists. design is for code not yet written, retro for something that has already broken.

Source text

SKILL.md · MIT
---
name: audit
description: >-
  Find footguns in code that already exists: swappable arguments, silent fallbacks, unguarded deletes, signatures that are easy to misuse. Use when someone asks "what could bite us here", "what is easy to misuse", "poka-yoke this repo", or wants a diff or PR reviewed for ways to get it wrong. Ranks by blast radius. For code not yet written use design; for something that already broke use retro.
---

# Poka-Yoke Audit

Find the mistakes that are *available* in this code, then close them. You are not looking for
bugs: a bug is a mistake that already happened. You are looking for **affordances for
mistakes**: places where doing the wrong thing is easy, silent, and looks correct.

The load-bearing question throughout: *if a competent, tired engineer used this at 4pm on a
Friday, what would go wrong and would anything stop them?*

## 1. Establish scope

Default, when the user names no path:

1. `git diff HEAD`: uncommitted work. This is what they are most likely asking about.
2. If the tree is clean, `git diff HEAD~5..HEAD`: recent commits.
3. If neither yields anything (fresh repo, no git), fall back to the risk surfaces below and
   say that's what you did.

Widen to the whole repo only when asked ("audit the whole codebase", "full audit"). It is
slow and it buries the important findings in volume. When you do go wide, prioritize by
**risk surface** rather than by directory, go straight to code that touches money,
authentication, authorization, deletion or overwriting, migrations, external I/O,
concurrency, and anything with `admin`, `force`, `bulk`, `sync`, or `delete` in its name.

State the scope you chose in one line before you start, so the user can redirect you cheaply.

## 2. Run the detector, then think

```bash
python3 ../../scripts/detect_hazards.py --diff   # path is relative to this SKILL.md
```

Other useful forms: `--paths src/ lib/`, `--staged`, `--since HEAD~10`, `--json`,
`--severity high`, `--id C1 M2` to filter to specific rules. Run `--help` for the full set.

The script finds the mechanically detectable shapes, adjacent same-type parameters, boolean
flag arguments, unbounded deletes, money held as a float, unvalidated request bodies, retries
without an idempotency key. Shapes a real linter already covers, bare `except`, mutable
default arguments, `any` escape hatches, are off by default and named in the footer; `--all`
runs them too. It is a **fast first pass with real false positives**, not an oracle. Treat
each hit as a question to investigate, and read the surrounding code before you believe it.

Then do the part the script cannot: read the interfaces and run the three lenses over them.

**Contact, can the wrong thing fit?** Look at every public signature. Are two adjacent
parameters the same type? Could a caller pass an order ID where a user ID belongs, cents
where dollars belong, a raw string where a validated one belongs? Does the boundary accept
`any` / `dict` / `interface{}` and hope?

**Fixed-value, can an incomplete or wrong-sized set pass?** Is every enum branch handled,
and will adding a variant break the build or silently fall through? Can a bulk operation run
with an empty or unexpectedly huge set? Is config validated as a whole, or discovered
missing at 3am? Are required fields actually required, or optional-with-a-default?

**Motion-step, can the order be wrong?** Must something be called before something else, with
nothing enforcing it? Can a retry double-charge? Can a resource leak on the error path? Can
two callers interleave between a check and the act that depends on it?

The script only sees text. These three questions are where the audit's value comes from.

## 3. Classify every finding

Each finding gets four fields. Fill all four: an unclassified finding is just an opinion.

- **Mistake**: the specific wrong thing a person can do, stated as an action.
  *"Call `transfer(dst, src)` with the accounts reversed."*
- **Consequence**: what happens when they do, and how loudly. Silence is the aggravator: a mistake that throws immediately is far less dangerous than one that returns a plausible
  wrong answer.
- **Current rung**: what exists today, Control / Warning / Detection / **None**.
- **Proposed device + rung**: the specific change, and the rung it reaches. If you're
  proposing Warning, say what would be needed for Control and why you didn't.

## 4. Rank by expected damage, not by count

Priority is **blast radius × ease of mistake**, and nothing else. A hundred stringly-typed
internal helpers matter less than one `delete_users(filter)` where `filter` can be empty.

Blast radius, descending: irreversible data loss or money movement → security or
authorization bypass → silent data corruption → wrong output the user acts on → crash →
degraded experience. A crash ranking *below* silent wrong output is deliberate and worth
saying out loud: loud failures are cheap, quiet ones compound.

Ease of mistake, descending: silent and plausible-looking → requires only forgetting → needs
an unusual-but-reachable input → needs deliberate misuse.

Report the top findings in priority order and stop somewhere sensible, ten well-argued
findings beat forty. Say how many you set aside and why.

## 5. Report

Use this structure. It is short on purpose; the detail lives per-finding.

```markdown
# Poka-Yoke Audit · <scope> · <YYYY-MM-DD>

**Scope**: <what was examined, e.g. "uncommitted diff, 7 files, 340 lines">
**Verdict**: <one sentence, the single most important thing they should fix>

## Findings

### 1. <Short name of the mistake> · <Blast radius>/<Ease>
**Where**: `path/to/file.ts:42`
**Mistake**: <the wrong action a person can take>
**Consequence**: <what happens, and whether it is silent>
**Today**: <Control | Warning | Detection | None>
**Device**: <the specific change> → **<Control | Warning | Detection>**

<a short diff or code sketch>

<if not Control: one line on what Control would cost>

### 2. …

## Set aside
<n low-priority hazards, one line each, or "none">
```

Write it to `docs/poka-yoke/audit-YYYY-MM-DD.md` in the user's repo. If they'd rather not
have a file, keep it in the conversation, ask if it isn't obvious.

## 6. Propose, then apply

Present the findings and wait. Do not edit files yet. These changes alter interface shapes
and ripple through call sites; people reasonably want to see the plan first.

When they approve some or all of it: apply each device, leave a `poka-yoke:` marker comment
at it saying which mistake it blocks, and run the tests.

## Recording what a device is for

Devices only stay valuable if people know they are load-bearing. Without a record, the next
person deletes the "redundant" check or relaxes the "annoying" constraint, and the mistake
comes back. A device that has never fired looks like dead weight precisely because it is
working.

The obvious answer, keep a registry file listing every device, is **wrong, by this skill's
own argument.** A Markdown file someone must remember to update is training, not a device. It
goes stale exactly when it matters: the moment someone removes a constraint without touching
the doc. Do not ask anyone to maintain one.

**Put the reason where the device is.** A marker comment at the constraint travels with it,
gets read by the person about to delete it, and cannot drift out of sync because it is not a
separate thing:

```python
# poka-yoke: rejects a second charge for the same idempotency key   [control]
UNIQUE (account_id, idempotency_key)
```

```ts
// poka-yoke: forgetting to await this write would lose it silently [warning]
"@typescript-eslint/no-floating-promises": "error",
```

The bracketed rung is optional. What earns its place is the clause after the colon: the
*mistake*, stated as something a person could do. "Uniqueness constraint" tells a future
engineer nothing; "rejects a second charge for the same key" tells them what breaks if they
drop it.

**If someone wants an index, generate it.** Never hand-maintain it:

```bash
python3 ../../scripts/device_registry.py --write docs/poka-yoke/registry.md
python3 ../../scripts/device_registry.py --check   # CI: fails if stale
```

Delete a device and its row disappears; move it and the row follows. That is the difference
between a record that is a device and a record that is a chore.

## Staying useful

The failure mode of this audit is turning into a generic style review. Style findings, naming, formatting, structure, "this could be more readable", do not belong here unless the
unreadability is itself the hazard. If you cannot name a specific wrong action a person could
take, it is not a poka-yoke finding, and including it dilutes the ones that are.

Read `../../references/hazard-catalog.md` for the recurring hazard shapes and their standard
devices, and the matching `../../references/lang-*.md` for what the language can actually
enforce.

© rainmanjam · MIT · rainmanjam/poka-yoke

Similar skills

All skills for Code review and refactoring →

audit by other authors comes first.

audit jsmastery-pro Scans codebases to generate and gap fill AGENTS.md context files. Helps bootstrap shared rules for AI assistants on greenfield or legacy repos. CX Codex +1 4,300installs audit educlopez Runs a technical UI audit across accessibility, performance and responsiveness, then hands back a prioritized findings table. CX Codex +1 929installs audit calm-north This skill walks a site through five layers of SEO review: technical foundation, on-page work, content quality, link profile and competitive position. CX Codex +1 6,400installs audit official OpenAI Walks through product flows step by step, captures verified screenshots, and flags UX and accessibility issues in chat. CX Codex GP ChatGPT 10installs audit aladicf Runs code-level checks on accessibility, performance, theming, responsive design and anti-patterns. Returns a scored report with a fix plan. CX Codex +1 625installs improve-codebase-architecture Matt Pocock This skill scans a codebase for architectural friction, then builds a visual HTML report with refactoring candidates. Use it before a deeper architecture review. 1,163,035installs tdd Matt Pocock Guides the red-green TDD loop: ensures tests are written first, keep them at public interfaces, and avoid coupling to implementation details. 1,141,062installs triage Matt Pocock This skill moves issues and external PRs through triage states, verification, and agent briefs. It fits maintainers managing an issue queue. 990,453installs codebase-design Matt Pocock This skill helps design modules with small interfaces and hidden complexity. Use it when refactoring code, choosing a seam, or making tests easier to write. 850,344installs code-review Matt Pocock Reviews changes from a chosen reference point against repository standards and the originating spec. Use it for a branch, PR, or work in progress. 789,521installs implement Matt Pocock Implements work from a specification or tickets, following a test-driven flow and ending with review and a commit. Use it when a coding task needs a defined delivery routine. 774,700installs

From the same set7

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor