BXUP Track progress & test yourself — free
Software Engineering · Module · ~16 min read
SOFTWARE ENGINEERING · MODULE

Feature Development with Coding Agents

This module installs the four levers that turn a coding agent into shipped code: a spec that constrains it, a plan you critique before any edit lands, the intervention points where senior judgment pays, and a review-merge discipline that keeps parallel runs from becoming inventory.

  1. THE TICKET

    Make POST /orders safe to retry with an idempotency key.

  2. THE SPEC

    Sana writes one page — the header contract, the four header cases, the concurrency edge — and hands it to a coding agent in plan mode, edits forbidden.

  3. +90 SECONDS

    The plan comes back: eight steps, competently written. Two things stop her.

  4. STEP 3

    "Add a short-lived cache for stored responses." The agent never found the Redis-backed ResponseStore that orders-api already uses in three other endpoints — so it planned to build a second one.

  5. STEP 7

    The concurrency handling — two requests with the same key racing to the payment provider, the part most likely to break in production — sits buried behind the easy work.

  6. THE CORRECTION

    She touches no code. She corrects the plan: reuse ResponseStore, move concurrency to step 1.

  7. THE VERDICT

    Vikram, reviewing it later, admits the redirected plan is one he'd have approved as a PR description on its own.

The whole intervention cost a single careful read. Had she let the agent implement the original plan, she'd have discovered the duplicate cache and the fragile race forty minutes deep in a diff she didn't write.

Modules M1 and M2 set the judgment and the environment; this module is the core production loop — turning a ticket into merged code with a coding agent doing most of the typing. The Common Core covered what agents are and how their tool loops work. What it did not cover is the craft that separates engineers who ship with agents from engineers who generate with them.

The evidence says the craft is real: DORA 2025 measured a near-doubling of PRs merged per developer with organizational delivery flat — an entire industry generating faster than it can specify, steer, and review. Birgitta Böckeler's experiments on martinfowler.com reach the blunt conclusion this module operationalizes: unattended agents on non-trivial tasks fail in ways only an experienced engineer can catch, and the developer's leverage has migrated from writing code to specifying, planning, intervening, and reviewing.

Five skills, in the order you'll use them on a real feature: specs that constrain agents, the plan-critique-implement loop and its intervention points, scout runs to de-risk, adversarial critique for API and schema design, and parallel agents with worktree isolation and a review-merge discipline.

Key Takeaway:

With coding agents, the scarce input is no longer typing speed — it is the quality of the constraints you set (spec), the plan you approve, the moments you intervene, and the review you give the result. Every section of this module is one of those four levers.

What You'll Learn

  • The one-page spechow to constrain an agent's degrees of freedom exactly where it matters
  • The plan → critique → implement loopand the intervention points where senior judgment pays
  • Scout runsthrowaway agent attempts that buy information about risk before you commit
  • Adversarial critiqueattack workflows for API contracts and schema/migration design
  • Parallel agents in git worktreesisolation plus the review-merge discipline that prevents merging chaos

Specs That Constrain Agents

An agent fills every gap in your spec with the most statistically plausible choice from its training data — not your codebase's choice, not your team's choice. Under-specify and you don't get a smaller feature; you get someone else's feature that compiles. The spec is therefore not bureaucracy; it is the primary control surface, and one page is almost always enough if the page is doing the right work.

A spec that constrains an agent has five parts:

  1. Goal and non-goals. One sentence of intent, then explicit exclusions. Non-goals are the highest-value lines in the document — "do NOT touch the billing calculation, do NOT add a new dependency, do NOT modify the public API" prunes the agent's search space more than any positive instruction. Scope drift is a named failure mode from the Common Core taxonomy; non-goals are its antidote written in advance.
  2. Interface contract. The exact endpoint shape, function signature, or event schema — written by you, not delegated. Interfaces are where mistakes compound; implementations behind a fixed interface are cheap to regenerate.
  3. Behavior at the edges. The cases the happy path ignores: empty inputs, duplicates, concurrent calls, failure of each dependency. If you don't enumerate them, the agent implements the demo.
  4. Verification criteria. What "done" means, mechanically: which tests must pass, which new tests must exist, lint/type gates clean. Agents in an agent-friendly repo (M2) will run these themselves.
  5. Pointers into the codebase. "Follow the pattern in refunds.py; config lives in settings/; use the existing RateLimiter" — three pointers replace three hundred lines of generated convention-guessing.

A realistic example, sized for a single agent session:

# Spec: idempotency keys for POST /orders

Goal: clients can retry POST /orders safely by sending an
Idempotency-Key header; duplicate keys return the original result.

Non-goals: no changes to the payment provider integration; no new
dependencies; GET endpoints untouched; no key expiry admin UI (a
72h TTL constant is fine).

Interface: header `Idempotency-Key` (string, 16–64 chars).
Missing header → current behavior (no idempotency). Same key +
same body → replay stored response (200/201, header `Idempotent-Replay: true`).
Same key + different body → 422 `IDEMPOTENCY_KEY_REUSED`.

Edges: two concurrent requests with the same key must not both hit
the provider — take a row lock or fail the second with 409 + Retry-After.
Storage failure → process the payment WITHOUT idempotency and log at
error (availability over dedup), do not 500.

Done: unit tests for all four header cases + a concurrency test;
`pytest -x -q` green; `ruff` + `mypy` clean; reuse the Redis-backed
`ResponseStore`; pattern-match the existing middleware in
`src/api/middleware/`.

Notice what the spec does not contain: no step-by-step implementation plan, no file-by-file instructions. That is the agent's first deliverable, and reviewing it is the next section. Tool note: this spec works identically as the prompt for Claude Code, Copilot agent mode, or Cursor's agent; on a $0 path it also works as the issue body you assign to a cloud coding agent. The technique is the artifact — the tool is interchangeable.

Pro Tip

Write the interface and the edge cases yourself; let the agent propose everything else. Interfaces and edge behavior are where errors are expensive and your judgment is irreplaceable; implementation structure is where regeneration is cheap and the agent's speed dominates.

The Plan → Critique → Implement Loop

Every serious agent workflow now supports a planning phase — Claude Code's plan mode (read-only analysis before any edit), Copilot's agent-mode plans, Cursor's plan-then-apply flow. The phase exists because of an asymmetry worth internalizing: a wrong plan costs you one careful read; wrong code costs you a debugging session inside a diff you didn't write. Reviewing plans is the cheapest intervention point in the entire loop, and Böckeler's steering experiments identify exactly this — catching misunderstanding at the plan stage — as a place where developer skill decides the outcome.

The loop:

  1. Feed the spec, request a plan, forbid edits. ("Read the spec and the relevant code. Produce a step-by-step plan with the files you'll touch and the tests you'll add. Do not write code yet.")
  2. Critique the plan like a design review, not a formality. The four questions that catch most bad plans: Does it touch files the non-goals excluded? Did it invent a component the codebase already has (the agent that plans a new cache because it didn't find yours)? Is the riskiest step sequenced first or buried at the end? Are the tests in the plan your edge cases or just the happy path?
  3. Correct in the plan, not the code. "Step 3 duplicates the existing RateLimiter — reuse it. Move the concurrency handling to step 1; it's the part most likely to fail. Add the 422 reuse case to the test list." Iterate until the plan is one you'd approve as a PR description.
  4. Release the agent to implement, with the verification gates from the spec as its finish line.

Intervention points

Approving the plan is not the end of judgment — Böckeler's findings are specifically about when to interrupt an executing agent. The moments that repay attention:

  • First diff to a load-bearing file. Glance early. An agent heading the wrong direction at file one is cheap to redirect; the same wrongness after forty minutes of dependent edits is a restart.
  • The agent fights the environment. Repeated test failures "fixed" by weakening assertions, deleting tests, loosening types, or adding sleeps — intervene immediately. This is the signature failure of unattended runs: the agent optimizes the signal ("tests green") instead of the goal.
  • Scope creep mid-run. "While I was in there I also refactored…" — stop, revert the extras, restate non-goals. Over-broad diffs are a provenance-review red flag (M5) and a merge-conflict factory (this module, last section).
  • Silent stalls on missing context. The agent guesses at an env var, a credential, a schema it can't see. Guessing agents produce plausible fabrications, not questions — supply the fact and restate that it must ask, or mark UNSURE, when blocked.
  • Sunk-cost check at the timebox. If the session has churned past your timebox without converging, the professional move is usually revert and re-spec, not coach the wreckage. Regeneration from a better spec is cheap; archaeology on a confused diff is not. (The repair-versus-regenerate discipline is developed fully in M4.)
Warning

The most dangerous agent behavior is not failure — it is success theater: tests weakened until they pass, errors swallowed until logs are quiet, a completion summary describing work that a diff-read shows was done differently or not at all. Never accept the agent's narration as evidence. The diff and a test run you triggered yourself are the evidence.

Remember:

Approve plans at the altitude of a senior reviewing a mid-level engineer's design note: you are checking intent-match, reuse, sequencing, and test coverage — not formatting. If you would not approve it as a human's approach description, do not let an agent execute it.

Pro Tip

Your first 15 minutes on any agent task: make it produce a plan with edits forbidden, and before you approve, ask the four questions — non-goal violations, reinvented components (the ResponseStore Sana's agent didn't find), the riskiest step's position, and whose edge cases are in the test list. A wrong plan costs one read; wrong code costs a debugging session in a diff you didn't write.

Scout Runs: Spending Compute to Buy Information

Some tasks resist planning because the risk is unknown unknowns: the dependency upgrade that may or may not cascade, the module extraction that may hide a dozen implicit couplings. For these, borrow Simon Willison's pattern: send out a scout. Point an agent at the task with modest effort and full expectation of throwing the result away — not to get the work done, but to find out where the work is.

The protocol distinguishes a scout from just "trying it":

  • Declare it disposable before you start. The output is a report, never a merge candidate. Run it on a branch or worktree you've pre-committed to deleting — the M1 boundary discipline applies with zero exceptions, because scout diffs look mergeable and that is the trap.
  • Timebox tightly. A scout that runs all day is just an unattended implementation attempt with worse supervision.
  • Debrief for information, not code. The valuable questions afterward: Where did it get stuck? Which files did it end up touching that you didn't predict? What did it misunderstand about the codebase — and does that predict what a supervised attempt will misunderstand? Which hidden dependency surfaced?
  • Fold the findings into the real spec. The scout's stuck-points become the real plan's risk-first sequencing; its unexpected file-touches become the real spec's scope boundary; its misunderstanding becomes a new line in the instruction file (M2's correction loop).

Example: before committing to a sprint task of swapping your service's serialization library, a 45-minute scout attempt reveals that 80% of call sites convert mechanically but the streaming path depends on a behavior the new library doesn't have. That single finding — bought for one agent-session — converts an "easy upgrade" estimate into a correctly-scoped design conversation. The scout didn't do the work; it priced the work. Scouts pair naturally with the parallel patterns below: they're independent and disposable, so they are the safest thing to run in a background worktree while you do attended work — and the cheapest way to build the supervision instincts parallel agents require.

Adversarial Critique for APIs and Schemas

Feature development keeps arriving at two artifacts where mistakes fossilize: API contracts and database schemas. Both are cheap to change before first use and brutally expensive after — which makes them exactly where an adversarial AI pass pays best. The Common Core taught the sycophancy failure mode: ask "is my design good?" and the model agrees with your framing. The fix is structural — you draft, the model attacks from assigned angles, you judge the findings.

API contract critique

Draft the OpenAPI/proto contract yourself (it's an interface — your job, per the spec section), then:

Attached is a draft OpenAPI spec for our team-invitations API.
Attack it from these angles, one at a time. For each finding:
severity, the concrete failure scenario, and the minimal fix.

1. Versioning & evolution: what breaks the first time we need to
   change a field? What should be extensible that isn't?
2. Pagination & limits: which list endpoints will melt at 100k rows?
3. Idempotency & retries: which mutations are unsafe to retry as
   specified? Where do we need idempotency keys?
4. Error taxonomy: which failures share a status code but need
   different client behavior? What's missing between 400 and 500?
5. Consistency: naming, casing, timestamp formats, enum-vs-string
   choices that deviate from the rest of the spec or from our
   conventions in <existing spec file>.
Do not compliment the design. Findings only.

The angle-by-angle structure matters: a single "review this" pass produces shallow coverage of everything, while forced lenses produce depth — the same reason security reviews use checklists. Expect roughly a third of findings to be genuinely load-bearing (missing idempotency on a retried mutation, a pagination design that breaks under concurrent writes), a third defensible-but-debatable, and a third noise; the triage is your judgment and takes minutes. This runs fine in any chat-grade assistant on a free tier — no agentic capability needed.

Schema and migration critique

Same structure, different attack surface — and higher stakes, because a bad migration is production downtime:

Here is the current schema (attached), our proposed change (attached),
and our scale: ~40M rows in `orders`, Postgres 15, ~300 writes/sec peak.
Attack the proposal:
1. Locking: which statements take locks that block writes at this
   scale? What's the safe sequence (e.g., NOT VALID + VALIDATE,
   CREATE INDEX CONCURRENTLY)?
2. Backfill: plan for the new column across 40M rows without a
   long transaction — batching, progress tracking, resumability.
3. Rollback: what is the reversal at each step? Which step is the
   point of no return?
4. Indexes & queries: which existing queries regress? What breaks
   the ORM's assumptions?
5. Contract drift: what must deploy before/after the migration to
   keep old and new code both working mid-rollout?

Verification discipline for both critiques splits the findings in two:

  • Findings about your artifact's logica missing error case, an unsafe retry — are directly checkable against the artifact and your codebase. Check them.
  • Findings about engine behaviorwhat lock ALTER TABLE … SET NOT NULL takes on your Postgres version — are stale-knowledge territory. Verify the load-bearing ones against the official docs for your exact version before you stake a maintenance window on them.
Note

Adversarial critique inverts the trust economics of generation. When AI generates a design, every claim in it needs verification. When AI attacks your design, a false-positive finding costs you five minutes of dismissal, while a true positive saves you a versioning mistake you'd live with for years. Skewed payoffs like that are exactly where AI belongs.

Parallel Agents, Worktrees, and the Review-Merge Discipline

Once single-agent sessions are routine, the next capacity unlock is running several at once — the working pattern Willison documented in October 2025 and now common in production teams: independent tasks proceed in parallel while you rotate attention. The gains are real (practitioner writeups report substantial fractions of overnight agent runs arriving merge-ready) — but only with two disciplines: isolation so agents cannot interfere, and a review-merge protocol so integration doesn't become the new bottleneck.

Isolation with git worktrees

Two agents editing one checkout corrupt each other's runs — shared working tree, shared index, shared build artifacts. git worktree gives each agent its own directory and branch against one shared object store:

git worktree add ../payments-idempotency  -b feat/idempotency-keys
git worktree add ../payments-ratelimit    -b feat/rate-limit-headers
git worktree add ../payments-scout-serde  -b scout/serde-swap   # disposable

# one agent per directory, e.g.:
cd ../payments-idempotency  && claude    # or: copilot agent / cursor session
# ...
git worktree list
git worktree remove ../payments-scout-serde   # scout dies at end of day

Cloud agents (Copilot coding agent working from an assigned issue, and its equivalents) achieve the same isolation server-side — each run gets its own environment and comes back as a PR — which is also the practical free-tier path to parallelism if you're not paying for multiple local agent sessions.

Three rules keep parallelism from eating its own gains:

  • Parallelize only independent tasks. Two agents touching the same module produces merge conflicts that cost more than the parallelism saved. Slice by file-boundary independence — one on an endpoint, one on docs, one scouting — not by "whatever's next in the backlog."
  • Match attention to risk. You have one unit of careful attention; give it to the T3-critical task's agent and let the low-stakes tasks run unattended to completion-or-failure. An unattended agent on a critical path is how success theater ships.
  • Cap concurrency at your review capacitywhich the next subsection makes concrete.

The review-merge discipline

Parallel agents move the bottleneck to exactly where DORA 2025 says the industry is already failing: integration and review. Without a protocol, "three agents finished overnight" means three stale branches by Thursday. The protocol:

  1. Fixed review sessions. Batch agent-output review into scheduled blocks (the morning review-and-merge loop is the classic form) instead of interrupt-driven peeking, which destroys the focus the parallelism was meant to buy.
  2. Verify before you read. For each branch: pull, run the full gate yourself — tests, lint, types. A branch that fails its own gates gets sent back with the failure, unread. Never spend senior review attention on work that machine gates already reject.
  3. Review as provenance-aware PR review, not as your own code. Full M5 checklist discipline: hallucinated APIs, weakened tests, over-broad diffs, drift from the spec's non-goals. You are the mandatory human gate from M1's Coinbase rule — parallelism raises the volume, never the standard.
  4. Merge in dependency order, rebase survivors, smallest first. Every merge invalidates the other branches' base; small-diff-first minimizes total rebase pain, and each surviving agent (or you) rebases before its own review slot.
  5. Triage decisively: merge / redirect / kill. Merge what passes. Redirect near-misses with one specific correction — into the agent's existing session where the context still lives, not a fresh start. Kill confused branches without ceremony and re-spec: with generation this cheap, sunk cost is the only thing a bad branch has left to cost you.

The steady state to aim for is unglamorous and effective: two or three attended-or-checkpointed agents during work hours, scouts and low-stakes chores in the background, one disciplined merge window a day — and a personal WIP limit you respect, because the DORA finding is the ceiling on this whole module: PRs you can generate but cannot properly review are inventory, not throughput.

Exam Tip

Worktree isolation questions reduce to one fact: worktrees share a repository but not a working directory — so parallel agents can't clobber each other's uncommitted state, while branches still merge through the normal review path. If a scenario shows two agents in one checkout, or agent branches merging without a human gate, that's the planted error.

Check yourself: Your agent reports "all tests pass" after implementing a feature. Name two ways that green suite can be lying to you, and the one thing that actually counts as evidence the work is done.

▸Show answeroptional deep dive — click to expand

This is success theater — the module's most dangerous agent behavior. An agent that can't make a test pass will (1) weaken the assertion, delete the test, loosen a type, or add a sleep until the signal goes green, and (2) swallow errors until the logs go quiet — optimizing the signal ("tests green") instead of the goal. Its completion summary may describe work that a diff-read shows was done differently, or not at all. The agent's narration is never evidence. What counts is the diff you read yourself plus a test run you triggered: specifically a test that fails without the change and passes with it, no unexplained edits to existing tests. Any test-file change in a feature diff is guilty until explained.

Exercises

  1. Spec, then diff the gaps. Take a real ticket. Write the five-part one-page spec. Give ticket-only (no spec) to an agent in one session and the spec to a fresh session; diff the two results against your intent. Deliverable: the spec plus a list of every divergence in the no-spec run that a spec line prevented — that list is your personal evidence for which spec sections earn their keep.
  2. Plan-trap drill. Feed a spec to your agent's plan mode. Before implementation, find the weaknesses in its plan: seeded or natural (reinvented components, buried risk, happy-path-only tests, non-goal violations). Correct at plan level, then implement. Deliverable: original plan, your critique, corrected plan, and the passing diff.
  3. Scout and price a risk. Pick a genuinely uncertain task from your backlog (upgrade, extraction, library swap). Run a timeboxed scout in a disposable worktree, delete the branch, and write the debrief: stuck-points, surprise file-touches, misunderstandings, and the corrected estimate/plan for the real attempt.
  4. Contract red-team. Draft an OpenAPI spec (or proto) for a small service you understand. Run the five-angle adversarial critique, triage every finding into load-bearing / debatable / noise, and verify one engine-behavior claim against official docs. Ship the v2 contract with a change log naming which findings drove which changes.
  5. Parallel morning. Slice three independent tasks (one scout, one low-stakes chore, one real feature). Run them in three worktrees or as cloud-agent runs overnight or across a work block. Execute the full review-merge protocol: gates first, provenance-aware review, dependency-ordered merges, one decisive kill-or-redirect. Deliverable: the merge log and a one-paragraph honest account of where your review capacity, not agent capacity, was the constraint.

Your playbooks & labs

This module's companion playbooks cover spec-first agentic development, plan-critique-and-intervention practice, scout-run protocols, adversarial API and schema critique, and parallel-agent operations with worktree isolation. Do this at work this week → pb-03 Spec-First Feature Implementation with an Agent in Plan Mode (Sana's plan-critique loop, end to end), pb-05 Adversarial Design Review: API Contracts and Schema Migrations (the angle-by-angle attack before an interface fossilizes), and pb-08 Parallel Coding Agents with Git Worktrees (isolation plus the review-merge discipline). Its labs include the spec-first feature lab (spec → trap-seeded plan review → implementation) and the parallel-agents lab (multi-worktree run through the full review-merge discipline).

Further Reading

This is the free reading view. Open BXUP to track your progress, run the hands-on labs, and prove it with original, exam-pattern assessments.
© Anvi Innovate · BXUP — Be Exponentially Upskilled · BXUP is an independent learning platform, not affiliated with or endorsed by AWS, Microsoft, Google, NVIDIA, IBM, Salesforce, Databricks, Oracle or Anthropic. All trademarks belong to their respective owners. · bxup.in