BXUP Track progress & test yourself — free
Software Engineering · Playbook · Core · ~4 min read
SOFTWARE ENGINEERING · PLAYBOOK · CORE

Spec-First Feature Implementation with an Agent in Plan Mode

Letting a coding agent free-run on "add rate limiting" produces a plausible diff that quietly picks a strategy, a store, and failure semantics for you.

Tier: Core · Workflow area: Feature development

The professional pattern is spec-first: you write a short spec, the agent proposes a plan, you review and correct the plan, and only then does it touch code — with you steering at checkpoints instead of auditing a 900-line surprise diff.

When to use

  • Features with real design decisions (a rate limiter, an export pipeline, a webhook retry system) — anything where "how" matters as much as "what".
  • You will delegate implementation to an agent but must own correctness.
  • Multi-file changes where a wrong early assumption compounds.

Skip it for one-file changes you could write faster than the spec.

Prerequisites

  • A coding agent with a plan/preview mode (or the discipline to enforce "plan first, no edits" via prompt).
  • A repo with working tests — the agent's implement loop needs a red/green signal.
  • 15 minutes to write a real spec. If you cannot spec it, you cannot review it.

The workflow

  1. Write the spec as constraints, not vibes. Example for an Express API:

    SPEC: per-API-key rate limiting for /api/* routes.
    - Sliding window, 100 req/min per key; Redis-backed (ioredis is already
      a dependency); key = `rl:{apiKey}:{minuteBucket}`.
    - On limit: 429 with Retry-After header and JSON error body matching
      our errorResponse() helper in src/http/errors.ts.
    - Redis unavailable => fail OPEN (allow request, log warn). Never 500.
    - Exempt: /api/health, internal service keys (isInternal flag).
    - Middleware lives in src/middleware/, wired in src/app.ts.
    - Tests: unit-test window math with a fake clock; integration test the
      429 path and the fail-open path.
    Non-goals: per-route limits, dashboards, config UI.
    
  2. Ask for a plan, not code. In plan mode (or prefixed with "Do not edit files yet"):

    Read the spec and the relevant code. Produce an implementation plan:
    ordered steps, files touched per step, and the test you will add per
    step. Flag anything in the spec that conflicts with existing code.
    
  3. Review the plan like a design doc. Check: did it find errorResponse()? Did it notice the existing auth middleware exposes the API key? Is fail-open actually handled or hand-waved? Correct the plan in chat — plan edits cost one sentence; code edits cost a review cycle.

  4. Implement step-by-step with checkpoints. Approve implementation one or two steps at a time. After each step, make the agent run the tests and show output. If your tool supports it, keep edits gated on your approval.

  5. Intervene early and loudly. The moment a diff drifts from the spec (different key scheme, swallowed Redis errors), stop, restate the constraint, and have it redo that step. Steering beats salvaging.

  6. Final pass: diff-vs-spec review. Read the full diff against the spec line by line, then ask: List every spec requirement and where in the diff it is satisfied. Mark any requirement you did not implement. Unimplemented items become your punch list.

Key Takeaway:

The spec is the contract and the plan review is the negotiation — by the time code exists, there should be nothing left to argue about except details.

Tool variants

  • Terminal agent with native plan mode (Claude Code): plan mode enforces read-only planning; approve, then let it implement with test runs.
  • Copilot agent mode / coding agent: paste the spec into the issue or chat; require the plan as its first response, and review before saying "proceed".
  • Cursor (or similar IDE agent): keep the spec open as a file (SPEC.md) and reference it in every instruction; use checkpoint/review UI between steps.

Verification

  • Every spec constraint maps to a visible line in the diff (step 6 output, spot-checked by you).
  • New tests fail when you revert the implementation (quick git stash check) — proving they test the feature, not themselves.
  • You manually exercised the two failure paths: limit exceeded (429 + Retry-After) and Redis down (fail-open, warn logged).
  • Diff contains no unrequested "improvements" — drive-by refactors get their own PR.

Pitfalls

  • Spec-shaped wishes. "Handle errors gracefully" is not a constraint; "fail open, never 500" is. Vague specs reproduce the free-run problem with extra steps.
  • Approving the plan without reading the flagged conflicts. The agent's "note: existing middleware also writes headers" line is where the real bug lives.
  • Batch-approving all steps. One checkpoint at the end equals no checkpoints.
  • Letting the agent weaken tests to go green. If a test changes, the agent must justify it against the spec, not against convenience.

Restricted-environment variant

  • Prefer the client-sanctioned agent (Copilot Business agent mode, or an Azure OpenAI/Bedrock-backed internal assistant) inside their tenancy; the workflow is identical.
  • No sanctioned agent: keep the spec-first discipline manually — use a local model (Ollama + a coder model) to draft the plan from the spec plus pasted signatures, then implement yourself using it for per-function drafts.
  • Never paste client API keys, real customer identifiers, or production Redis URLs into the spec; use placeholders.

Success criteria

  • Zero "wait, why did it do that?" moments after implementation started — surprises were caught at plan stage.
  • Total review effort felt like several small reviews, not one archaeology dig.
  • The spec file lives in the repo/PR and a teammate could re-derive the feature from it.
  • You shipped with both failure paths tested, not just the happy path.
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