DEV Community

mohammed faizan mohiuddin
mohammed faizan mohiuddin

Posted on

I gave my AI coding agent 10 senior-dev instincts


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?
Enter fullscreen mode Exit fullscreen mode

Top comments (0)