
AI coding agents are like a junior who read every textbook and shipped nothing:
fast, confident, and wrong in ways that cost you an afternoon.
The senior engineers I've learned the most from aren't valuable because they type
fast. It's their instincts — the things they do before and after the code:
- they push back when you ask for the wrong thing
- they don't say "done" until they've actually run it
- they try to break their own code before it ships
- they ask the one question that saves a week of building the wrong feature
So I bottled ten of those into Bullpen — a set of skills for AI coding agents
(built for Claude Code). You call them in by name, at the intensity you want.
The roster
| Skill | The instinct |
|---|---|
skeptic |
Pushes back when the request is the wrong idea |
closer |
Won't claim "done" until it ran the code |
attacker |
Red-teams its own code before shipping |
fact-checker |
Verifies an API exists before calling it |
interrogator |
Asks the few decisive questions first |
stop-digging |
After two failed fixes, re-diagnoses instead of thrashing |
doorman |
Justifies every new dependency |
historian |
Checks why odd code exists before deleting it |
chameleon |
Matches the existing codebase's style |
explainer |
Splits work into reviewable commits |
Each has lite / full / ultra intensity.
One example: /attacker
Ask an agent for "an endpoint to fetch an invoice by id" and it'll hand you this,
then say "Done":
js
app.get('/invoice/:id', async (req, res) => {
const invoice = await db.query(
`SELECT * FROM invoices WHERE id = ${req.params.id}`);
res.json(invoice);
});
Hit /invoice/2 as user 1 and you read another tenant's invoice. The id
concatenates straight into SQL. With /attacker, it breaks into its own code
first — and fixes it at the boundary:
app.get('/invoice/:id', async (req, res) => {
const id = Number(req.params.id);
if (!Number.isInteger(id)) return res.status(400).json({ error: 'bad id' });
const invoice = await db.query(
'SELECT * FROM invoices WHERE id = $1 AND owner_id = $2', [id, req.user.id]);
if (!invoice) return res.status(404).end();
res.json(invoice);
});
▎ Attacked: /invoice/2 as user 1 → leaked another tenant's row, added owner filter · non-numeric id → 500 with a stack trace, now 400 · SQL parameterized, held.
It never claims "secure." It reports what it tried.
Install
/plugin marketplace add faizanmohiuddin482/bullpen
/plugin install bullpen@bullpen
Open source (MIT), one canonical SKILL.md per skill — no hooks, no bloat.
Repo → https://github.com/faizanmohiuddin482/bullpen
Inspired by Ponytail (https://github.com/DietrichGebert/ponytail) — one lazy
senior dev. Bullpen is the whole room. 🧢
What senior-dev instinct would you add?
Top comments (0)