Skip to content

Control Techniques

Agents default to confident action under ambiguity. Control techniques are prompt (and mode) patterns that interrupt that default: force questions, force a plan, constrain the blast radius, and demand evidence. Use them on every non-trivial Claude Code task; skip them only for mechanical, fully-specified edits.

The control stack (modes + prompts)

LeverWhat it constrainsWhen to tighten
Plan modeEdits until you approve a planAnything with >1 file or an undecided design choice
Permission modeTool auto-approvalUnfamiliar repos, prod-adjacent paths, migrations
Prompt controlsBehavior inside an allowed runAlways — modes don't encode your acceptance criteria
Repo steering (CLAUDE.md)Every sessionRecurring mistakes, never-dos, command recipes

Modes are the seatbelt; the techniques below are the driving instructions. See Prompt Anatomy for the full prompt skeleton these techniques plug into.

1. Questions-first

Weak:

text
Add webhook retries for failed Stripe events.

Strong:

text
Add webhook retries for failed Stripe events.

Before writing any code:
1. List open questions and undecided decisions (at least: retry policy,
   idempotency, storage, which events, dead-letter behavior).
2. For each, propose a default AND the risk if that default is wrong.
3. Stop. Do not implement until I answer.

Do not invent product behavior to fill gaps.

Why the delta matters: The weak prompt silently decides six product/ops choices. The strong prompt surfaces them as a reviewable list — usually cheaper than reversing a wrong retry store two days later.

Checklist — questions-first

  • [ ] Prompt explicitly says "list questions before code"
  • [ ] Prompt forbids inventing product/ops behavior
  • [ ] You actually answer (or write answers into a spec) before allowing implementation

2. Plan-before-code

Claude Code plan mode is the primary lever. Reinforce it in the prompt so the plan is shaped the way you review:

Weak:

text
Refactor the invoice PDF generation to be async.

Strong:

text
Refactor invoice PDF generation to be async.

Plan mode. Produce a plan that includes:
- Current call sites (file:line) and the proposed new flow
- Queue/worker choice and failure/retry behavior
- Migration path for in-flight requests
- Files you will touch (allowlist) and files you will not
- Verification steps (commands + manual checks)

Do not edit until I approve the plan. If the plan exceeds ~8 steps,
split into sequenced PRs and stop after proposing the split.

Why the delta matters: "Async" without a plan often means "fire-and-forget in the request handler" or a new queue library you didn't ask for. The plan forces call-site inventory and an allowlist before the blast radius expands.

Checklist — plan-before-code

  • [ ] Plan mode on (or equivalent "plan only, no edits")
  • [ ] Plan names files, risks, and verification — not just vibes
  • [ ] You approve, amend, or reject before any edit

3. Incremental implementation

Weak:

text
Implement the full billing proration spec.

Strong:

text
Implement specs/012-billing-proration.md in increments.

Increment 1 only: pure proration function + unit tests for the examples
in the spec. No HTTP, no DB, no Stripe.

When increment 1 passes `make check`, stop and show:
- Diff summary
- Test output
- Open questions discovered

Do not start increment 2 until I say so.

Why the delta matters: A full-spec run in one shot buries a wrong formula under layers of wiring. Incremental stops give you a human gate at the cheapest failure point. For work bigger than context, see Large Tasks.

Checklist — incremental

  • [ ] First increment is the riskiest pure logic or the thinnest vertical slice — pick one deliberately
  • [ ] Explicit stop between increments
  • [ ] Each increment has its own verification command

4. Stop-and-ask

Weak:

text
Follow existing patterns. Use your best judgment on edge cases.

Strong:

text
Constraints:
- If a decision is not in specs/012-billing-proration.md or CLAUDE.md,
  STOP and ask. Do not invent.
- You MAY decide: local variable names, test fixture shape, log message text.
- You may NOT decide: HTTP status codes, error taxonomy, money rounding,
  idempotency keys, or new dependencies.

If you hit a blocker, output: BLOCKER: <question> and wait.

Why the delta matters: "Best judgment" is permission to invent requirements. An allowlist/denylist of decision classes is enforceable in review: any new dependency or status-code change without a question is a process failure.

Checklist — stop-and-ask

  • [ ] Decision allowlist and denylist are explicit
  • [ ] "STOP and ask" appears as a hard rule, not a suggestion
  • [ ] Reviewer greps the diff for denylist items (deps, status codes, schema)

5. Constrained file scope

Weak:

text
Fix the N+1 query on the invoice list endpoint. Clean up anything nearby.

Strong:

text
Fix the N+1 on GET /invoices.

Touch only:
- src/api/invoices/list.ts
- src/api/invoices/list.test.ts
- src/db/queries/invoices.ts (if query lives there)

Do NOT:
- Rename modules
- "Improve" unrelated handlers
- Add a repository abstraction
- Change response JSON shape

If the fix requires files outside this allowlist, stop and propose an
amended allowlist before editing.

Why the delta matters: "Clean up anything nearby" is how architecture erosion lands in a one-line bugfix. Scope is a first-class acceptance criterion.

Checklist — file scope

  • [ ] Allowlist present for any bugfix / small feature
  • [ ] Explicit do-not list for common agent temptations (renames, new layers)
  • [ ] Diff reviewed against allowlist before merge

6. Evidence requirements

Weak:

text
Make sure tests pass and nothing else broke.

Strong:

text
When done, provide evidence — not claims:
1. Paste the exact command(s) run and their full exit output
   (`make check`, plus any targeted test file).
2. Cite call sites checked for breakage (file:line) or `rg` output
   showing no remaining old symbol.
3. If you did not run a check, say NOT RUN and why.

"Should be fine" / "tests pass" without output is incomplete.

Why the delta matters: Agents hallucinate green builds. Pasted output is cheap; trusting a sentence is expensive. See Hallucination and False Confidence.

Checklist — evidence

  • [ ] Prompt demands pasted command output
  • [ ] Claims about "no callers" require search evidence
  • [ ] You spot-check at least one command yourself on non-trivial PRs

Composing techniques (default recipe)

For a typical feature or non-trivial fix, stack them:

text
Read CLAUDE.md and <spec path>.

1. QUESTIONS FIRST: list open questions; stop if any block implementation.
2. PLAN MODE: plan with file allowlist, risks, verification; wait for approval.
3. IMPLEMENT incrementally per approved plan; STOP-AND-ASK on denylist decisions.
4. EVIDENCE: paste `make check` (and targeted tests) output; cite paths touched.

Out of scope: <list>
Do not touch: <paths>
Task typeMinimum controls
Rename / mechanical editFile scope + evidence
Bug fixFile scope + evidence + stop-and-ask
Feature from specAll six (plan mode mandatory)
Legacy changeCharacterization tests first + all six — see Legacy Refactor
Recovery from bad outputContext reset + tighter scope — see Recovery

Failure modes these techniques prevent

SymptomMissing controlFix
PR invents product behaviorQuestions-first / stop-and-askAmend spec; reject silent decisions
20-file "cleanup" in a bugfixFile scopeRevert drive-bys; re-run with allowlist
"Tests pass" but CI redEvidenceRequire pasted local output; run yourself
Wrong design fully implementedPlan-before-codePlan mode; reject and re-plan
Session digresses into adjacent refactorsIncremental + scopeReset context; one increment only

A field manual for AI-native software engineering.