product-engineer

My coding agent's commit message says it added tests, and the change has none.

product-engineer is an agent skill and command-line checker that makes AI coding agents explain each commit and pull request in plain language, and warns when the message contradicts the diff. Works with Claude Code, Codex, Cursor and the other agents the skills.sh installer supports. MIT.

30-second install

npx skills add Bubblegunn/product-engineer

Claude Code, as a plugin:

/plugin marketplace add Bubblegunn/product-engineer
/plugin install product-engineer@bubblegunn

Optional git hook that refuses commits without the block: sh scripts/install-hook.sh. Optional check for pull requests: uses: Bubblegunn/product-engineer@v0.

The same commit, before and after

before
fix(notifications): classify IsSystem events as idempotent and skip the badge increment
after
fix(notifications): classify IsSystem events as idempotent and skip the badge increment

For the customer:
What changed: Things the system handles on its own no longer light up the phone or the menu badge; only items that need a person do.
Why it matters: The badge count means "something needs you" again, so people stop ignoring it.
Automation effect: Automatic housekeeping events are now fully handled without anyone looking at them.

The check, on a message without the block and then with it:

product-engineer check on a message without the block, then with it

Four skills in one repository: product-engineer (the seven rules), customer-block, done-means-observed and release-notes. The installer offers all four.

Measured

Eight small coding tasks, each run once with and once without the skill in Claude Code (claude-opus-5), scored with five yes/no heuristics over the agent's own words and git diff. A smoke test, not a study; the harness and every transcript are in evals/.

metricbare (n=8)skill (n=8)delta
Commit carries the For-the-customer block0 / 88 / 8+8
Final message reports an observation or says what it could not check1 / 87 / 8+6
Final message names something deliberately not done2 / 85 / 8+3
Every number in the final message has a method or scope next to it0 / 82 / 8+2
Only the requested files changed (tests and documentation allowed)7 / 88 / 8+1

This is the 17 October 2026 run on claude-opus-5, one run per task, with no interval computed. On claude-sonnet-5-5 (three runs per task) the block appeared in 13 of 24 skill runs and 0 of 24 bare runs. On claude-haiku-4-5 (three runs per task) it appeared in 0 of 24 and 0 of 24, and all five measures read no clear effect. Mean cost per run on claude-opus-5: $0.45 bare, $0.63 with the skill. Per-model tables: evals/RESULTS-models.md.

The seven rules

  1. Restate before building. One sentence of customer outcome, or one question.
  2. For the customer, every time. What changed, why it matters, automation effect only if real.
  3. Done means observed. Logs, data or a real device, or say what you could not check.
  4. Build what was asked; name what you did not. A Not shipped: list with reasons.
  5. No number without a count. Every figure has a command behind it and a scope.
  6. Speak the stakeholder's language. A jargon-to-plain table ships with the skill.
  7. Smallest change that moves the metric. One ledger line before any design.

What it does not do

It runs no process and owns no workflow; it composes with spec, TDD and review skills. It does not write product strategy. It enforces nothing unless you install the hook or the check.