Skip to main content

Coding Agents Best Practices III: Verification, TDD, and Hooks

· 6 min read
AI Playbook author

Without a check the agent can run, “looks done” is the only stop signal — and you become the verification loop. Part III covers how Cursor and Claude Code turn tests, builds, screenshots, and hooks into an oracle that stays honest even when context degrades.

TDD loop and hooks for coding agents

1. Why verification is the agent’s only real boss

Advisory rules fade under attention pressure. Tests do not. Anthropic’s guide frames it clearly: give Claude a check it can run — that is the difference between a session you babysit and one you can leave.

StrategyWeak promptStrong prompt
Criteria“Validate emails”Cases: user@example.com true; invalid false; user@.com false; run tests after
UI“Make the dashboard better”Paste mock; implement; screenshot; list diffs; fix
Bugs“Build is failing”Paste error; fix root cause; verify build; don’t suppress

Always ask for evidence: the command, the output, the screenshot — not “all good.”

Verification ladder from soft to hard gates

2. The verification ladder

Raise the gate only as far as the risk requires:

  1. In-prompt — “Run tests and keep going until green.” Works today on any task.
  2. Session goal / evaluator — re-check definition of done each turn (Claude /goal style).
  3. Stop / grind hooks — shell blocks ending until a script passes (with a max-iteration escape).
  4. Second-opinion subagent — fresh context tries to refute the result so the implementer is not the grader.

Layered production systems (e.g. deterministic CI + LLM judge) mirror this: machine oracles first, judgment second.

3. TDD as the default agentic strategy

Cursor and Anthropic both recommend an explicit TDD sequence:

  1. Write tests first — “TDD. No mock implementations of missing behaviour.”
  2. Confirm red — run tests; expect failure.
  3. Commit failing tests — checkpoint so later edits are visible in git.
  4. Implement until green — “Do not modify the tests. Keep going until they pass.”
  5. Commit implementation after human review of the diff.

The commit-before-green step matters: agents sometimes “fix” tests by deleting assertions. The diff exposes that immediately.

Frontend visual loop:

  1. Provide design mock
  2. Implement
  3. Capture screenshot (browser tool / Puppeteer MCP)
  4. Diff vs mock
  5. Iterate

Visual oracles often double effective quality when layout fidelity matters.

4. Hooks: when “please don’t” isn’t enough

Rules are advisory. Hooks are deterministic scripts at lifecycle points.

Typical events

EventUse
PreToolUseBlock rm -rf, pushes to main, writes to migrations/
PostToolUse (Edit/Write)Run Prettier/ESLint/typecheck on touched files
StopRefuse to end until tests pass (cap retries)

Claude Code example (format after edits):

{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "prettier --write \"$CLAUDE_FILE_PATHS\""
}
]
}
]
}
}

Cursor long-running loop pattern (simplified idea): a stop hook that re-prompts until a scratchpad contains DONE or loop_count hits a max — useful for grind-until-tests-pass workflows. See Cursor agent best practices for the full grind example.

Hook design rules

  • Do block destructive Bash and secret-touching paths
  • Do auto-format and lint after writes
  • Don’t block Edit/Write mid-reasoning hard — prefer PostToolUse or pre-commit so multi-step plans aren’t torn mid-thought
  • Don’t create infinite stop hooks — always cap iterations

Ask the agent to author hooks (“Write a hook that blocks writes under infra/prod/”) then review them like production code.

5. Permissions and sandboxes

Permission fatigue causes rubber-stamp approvals. Prefer:

  • Allowlists for safe commands (npm test, git status, gh pr create)
  • Auto / classifier modes that only stop risky actions
  • OS sandboxing so freer execution stays inside a boundary

Auth, payments, and data-deletion diffs stay human-reviewed regardless of green tests.

6. Root cause, not symptom control

Agents love # type: ignore, bare except, skipped tests, and “temporary” stubs that become permanent.

Bake into prompts and rules:

Address the root cause. Do not suppress the error, skip the test,
or add fake fallback data to force green.

If the only way to green is weakening the oracle, stop the session and redesign.

7. Review layers after generation

LayerWhen
Live diff watch + EscapeMid-flight wrong turns
Agent review passAfter a task completes
PR Bugbot / CIBefore merge
Fresh subagent vs PLAN.mdHigh-stakes features
Mermaid architecture diagramLarge design changes

Review speed becomes the bottleneck as agents accelerate. Standardise checklists: correctness, edge cases, security, observability, scope creep.

8. Negative cases you must handle

FailureMitigation
Tests edited to passCommit tests first; review test diffs separately
Flaky greenPin seeds; forbid sleeps; require deterministic fixtures
Mock-only “coverage”Ban mocks for the unit under test in the TDD prompt
Linter silencedHooks / CI fail on new ignores
Irreplaceable files deletedCommit/backup before agent access; deny-list paths
Premature victory (“pre-existing / out of scope”)Stop hook or reviewer that rejects cop-outs

9. Checklist — Part III

  • Every task defines a runnable done-check
  • Behaviour changes ship with new/updated tests
  • TDD sequence used for non-trivial logic
  • Hooks cover must-never-fail safety and format gates
  • Evidence required before accepting “done”
  • Auth/security changes get human review even if CI is green
  • CI is the non-negotiable gate Claude cannot argue with

10. Series map

PartTopic
IPlan-first workflow
IIContext, rules, memory
III (this article)Verification, TDD, hooks
IVParallel agents, review, failure patterns

Next: multiply throughput with worktrees and cloud agents — without multiplying chaos.

Discussion

Comments

Share feedback or questions about this page. No account required.

Loading comments…