Check the staged diff before committing
Scan everything that is currently staged for commit and flag anything that should not
be committed. This is a focused safety gate, not a code review — do not comment on
style, naming, architecture, or correctness. Find only the four classes of problem below,
report each with its file and line and why it matters, and finish with a single verdict.
1. Get the staged diff
Only inspect what is actually staged (--cached). Unstaged changes are out of scope.
git diff --cached --stat # overview of staged files
git diff --cached # full staged diff (read this)
git diff --cached --numstat # added/removed line counts; "-" marks binary files
git diff --cached --name-only --diff-filter=A # newly ADDED files (for size/binary checks)
Read the whole staged diff. Only consider added lines (lines starting with +) for
debug code, secrets, and commented-out blocks — pre-existing lines shown as context are not
introduced by this commit and should not be flagged. For added/binary file checks, inspect
the working-tree files reported as added.
If nothing is staged, say so plainly and stop — there is nothing to check.
2. What to flag
Go through the staged diff against each lens. Most commits trigger only a few — that's
expected. Don't manufacture findings to fill a category; each finding must point at a real
added line or file.
Secrets and API keys
Added lines that look like real credentials, not references to them. Look for:
- Assignments where the value is a literal secret: API keys, tokens, passwords, private
keys, connection strings with embedded credentials.
- Recognisable key shapes:
AKIA… (AWS access key), sk-… / sk-ant-… (OpenAI/Anthropic),
ghp_… / gho_… (GitHub tokens), xox[baprs]-… (Slack), Google AIza…, Stripe
sk_live_… / rk_live_…, JWTs (eyJ…), -----BEGIN … PRIVATE KEY----- blocks.
- Long high-entropy strings assigned to names like
*_KEY, *_SECRET, *_TOKEN,
*_PASSWORD, PASSWD, *_DSN, AUTH, CREDENTIAL.
Distinguish real secrets from safe non-secrets so you don't cry wolf:
- Safe / don't flag: placeholders (
your-api-key-here, xxxxx, changeme, example,
<token>), .env.example entries with empty or dummy values, values read from config
(env('STRIPE_SECRET'), process.env.X, config(...)), obvious test fixtures.
- Flag: a concrete-looking secret value committed in source, and any secret that
appears in a real
.env file staged for commit (a .env with live values should almost
never be committed — call that out specifically).
When unsure whether a string is a live secret, flag it as suspected and explain why —
better to surface it for a human to confirm than to stay silent.
Leftover debug code
Added lines that are clearly debugging scaffolding left behind, judged against the file's
language:
- PHP:
dd(, dump(, ddd(, var_dump(, print_r( (when not returned/used),
ray(, error_log(, \Log::debug( added ad hoc, Debugbar::.
- JS / TS / Vue:
console.log( / console.debug( / console.warn( added for
debugging, debugger;, alert(.
- General:
TODO: remove, FIXME, XXX, temporary sleep(, hardcoded test toggles
like if (true) / return; // skip.
Use judgement: a console.error in a legitimate error handler or a logging call that's part
of the app's real logging is not debug litter. Flag what looks like a forgotten trace.
Large commented-out blocks
Added runs of commented-out code (not explanatory prose). Flag a contiguous block of
roughly 5+ lines of commented-out code — dead code that should be deleted rather than
committed. A short comment, a doc comment, or a one-line note is fine; don't flag those.
Identify it by the file's comment syntax (//, #, /* … */, <!-- … -->) wrapping
things that read as code (statements, function bodies, markup).
Accidentally added large or binary files
From the newly added files (--diff-filter=A):
- Binary files —
git diff --cached --numstat shows - for both add/remove columns on
binary files. Flag added binaries that look unintended: compiled output, archives, images
dumped into source, .zip, .tar, .gz, .pdf, .sqlite, .db, fonts, media. Use
judgement — an intentional asset in an assets directory is fine.
- Large files — check the on-disk size of added files (e.g.
wc -c, or
git cat-file -s :<path> for the staged blob). Flag anything roughly >1 MB, and flag
hard regardless of size if it's the kind of thing that shouldn't be in git at all
(vendor/, node_modules/, *.log, build artefacts, .env with real values, OS junk
like .DS_Store).
3. Report findings
Output Markdown. Lead with the findings grouped by the four categories above; include only
categories that actually have findings. For each finding give:
- File and line —
path/to/file.php:42. Use the line number of the added line in the
new file. For a commented-out block, give the start–end range. For a whole-file problem
(binary/large/.env), the path alone is enough.
- What — the offending snippet (truncate/redact secrets — show enough to locate it, e.g.
STRIPE_SECRET=sk_live_51H… — never echo a full live key).
- Why — one short clause on why it shouldn't be committed.
Keep each finding to a line or two. No preamble, no code-quality asides.
4. Verdict
End with a single bold verdict word — **BLOCK** or **PASS** — and nothing after it. No
trailing summary or explanation; the findings above already say why.
- BLOCK — if there is any secret/API key, or any other finding serious enough that
committing would be a mistake (real
.env, committed credentials, a stray binary/large
file, obvious debug litter). When in doubt about a suspected secret, lean to BLOCK.
- PASS — only if nothing was found, or the only findings are clearly harmless.
Format:
**BLOCK**
or
**PASS**
Never soften a real secret finding — a leaked key in history is expensive to undo.
1---2name: ship-gate3description: Read the staged git diff and flag anything that shouldn't be committed — secrets or API keys, leftover debug code (dd(), console.log, etc.), large commented-out blocks, and accidentally added large or binary files. For each problem show the file and line and why it's a problem, then end with a clear PASS or BLOCK. Use before committing, when the user asks to "check what's staged", "review my staged changes", "anything I shouldn't commit", "scan the diff before I commit", or wants a pre-commit safety check.4---56# Check the staged diff before committing78Scan everything that is currently **staged** for commit and flag anything that should not9be committed. This is a focused safety gate, not a code review — do **not** comment on10style, naming, architecture, or correctness. Find only the four classes of problem below,11report each with its file and line and why it matters, and finish with a single verdict.1213## 1. Get the staged diff1415Only inspect what is actually staged (`--cached`). Unstaged changes are out of scope.1617```18git diff --cached --stat # overview of staged files19git diff --cached # full staged diff (read this)20git diff --cached --numstat # added/removed line counts; "-" marks binary files21git diff --cached --name-only --diff-filter=A # newly ADDED files (for size/binary checks)22```2324Read the **whole** staged diff. Only consider **added** lines (lines starting with `+`) for25debug code, secrets, and commented-out blocks — pre-existing lines shown as context are not26introduced by this commit and should not be flagged. For added/binary file checks, inspect27the working-tree files reported as added.2829If nothing is staged, say so plainly and stop — there is nothing to check.3031## 2. What to flag3233Go through the staged diff against each lens. Most commits trigger only a few — that's34expected. Don't manufacture findings to fill a category; each finding must point at a real35added line or file.3637### Secrets and API keys3839Added lines that look like real credentials, not references to them. Look for:4041- Assignments where the value is a literal secret: API keys, tokens, passwords, private42 keys, connection strings with embedded credentials.43- Recognisable key shapes: `AKIA…` (AWS access key), `sk-…` / `sk-ant-…` (OpenAI/Anthropic),44 `ghp_…` / `gho_…` (GitHub tokens), `xox[baprs]-…` (Slack), Google `AIza…`, Stripe45 `sk_live_…` / `rk_live_…`, JWTs (`eyJ…`), `-----BEGIN … PRIVATE KEY-----` blocks.46- Long high-entropy strings assigned to names like `*_KEY`, `*_SECRET`, `*_TOKEN`,47 `*_PASSWORD`, `PASSWD`, `*_DSN`, `AUTH`, `CREDENTIAL`.4849Distinguish real secrets from safe non-secrets so you don't cry wolf:5051- **Safe / don't flag:** placeholders (`your-api-key-here`, `xxxxx`, `changeme`, `example`,52 `<token>`), `.env.example` entries with empty or dummy values, values read from config53 (`env('STRIPE_SECRET')`, `process.env.X`, `config(...)`), obvious test fixtures.54- **Flag:** a concrete-looking secret value committed in source, **and** any secret that55 appears in a real `.env` file staged for commit (a `.env` with live values should almost56 never be committed — call that out specifically).5758When unsure whether a string is a live secret, flag it as **suspected** and explain why —59better to surface it for a human to confirm than to stay silent.6061### Leftover debug code6263Added lines that are clearly debugging scaffolding left behind, judged against the file's64language:6566- **PHP:** `dd(`, `dump(`, `ddd(`, `var_dump(`, `print_r(` (when not returned/used),67 `ray(`, `error_log(`, `\Log::debug(` added ad hoc, `Debugbar::`.68- **JS / TS / Vue:** `console.log(` / `console.debug(` / `console.warn(` added for69 debugging, `debugger;`, `alert(`.70- **General:** `TODO: remove`, `FIXME`, `XXX`, temporary `sleep(`, hardcoded test toggles71 like `if (true)` / `return; // skip`.7273Use judgement: a `console.error` in a legitimate error handler or a logging call that's part74of the app's real logging is **not** debug litter. Flag what looks like a forgotten trace.7576### Large commented-out blocks7778Added runs of commented-out **code** (not explanatory prose). Flag a contiguous block of79roughly **5+ lines** of commented-out code — dead code that should be deleted rather than80committed. A short comment, a doc comment, or a one-line note is fine; don't flag those.81Identify it by the file's comment syntax (`//`, `#`, `/* … */`, `<!-- … -->`) wrapping82things that read as code (statements, function bodies, markup).8384### Accidentally added large or binary files8586From the newly **added** files (`--diff-filter=A`):8788- **Binary files** — `git diff --cached --numstat` shows `-` for both add/remove columns on89 binary files. Flag added binaries that look unintended: compiled output, archives, images90 dumped into source, `.zip`, `.tar`, `.gz`, `.pdf`, `.sqlite`, `.db`, fonts, media. Use91 judgement — an intentional asset in an assets directory is fine.92- **Large files** — check the on-disk size of added files (e.g. `wc -c`, or93 `git cat-file -s :<path>` for the staged blob). Flag anything roughly **>1 MB**, and flag94 hard regardless of size if it's the kind of thing that shouldn't be in git at all95 (`vendor/`, `node_modules/`, `*.log`, build artefacts, `.env` with real values, OS junk96 like `.DS_Store`).9798## 3. Report findings99100Output Markdown. Lead with the findings grouped by the four categories above; include only101categories that actually have findings. For each finding give:102103- **File and line** — `path/to/file.php:42`. Use the line number of the added line in the104 new file. For a commented-out block, give the start–end range. For a whole-file problem105 (binary/large/`.env`), the path alone is enough.106- **What** — the offending snippet (truncate/redact secrets — show enough to locate it, e.g.107 `STRIPE_SECRET=sk_live_51H…` — never echo a full live key).108- **Why** — one short clause on why it shouldn't be committed.109110Keep each finding to a line or two. No preamble, no code-quality asides.111112## 4. Verdict113114End with a single bold verdict word — `**BLOCK**` or `**PASS**` — and nothing after it. No115trailing summary or explanation; the findings above already say why.116117- **BLOCK** — if there is **any** secret/API key, or any other finding serious enough that118 committing would be a mistake (real `.env`, committed credentials, a stray binary/large119 file, obvious debug litter). When in doubt about a suspected secret, lean to **BLOCK**.120- **PASS** — only if nothing was found, or the only findings are clearly harmless.121122Format:123124```125**BLOCK**126```127128or129130```131**PASS**132```133134Never soften a real secret finding — a leaked key in history is expensive to undo.