Skip navigation

PublicArticle

When to turn on --deep and --tdd for /ak-plan

Use --deep when scope is wide, add --tdd when old behavior must survive, and turn on both only when both risks apply. A billing extraction example shows when each option is worth the cost.

19 min read · v1.0.0 · Updated 22/05/2026

VI · Khi nào nên bật --deep và --tdd cho /ak-plan · Read in Vietnamese

Interactive version

This piece comes with an interactive page: diagrams, scenarios and sample sessions. The link is created fresh on every click.

Quick summary: Use --deep when the scope is wide, add --tdd when existing behavior must survive, and turn on both only when both risks apply. --deep gives the plan a detailed map for each phase. --tdd makes the agent capture current behavior in tests before refactoring. Small tasks and brand-new code need neither.

Not every task needs the heavy mode. A big refactor rarely breaks on the first line of code. It usually breaks because the plan did not see enough scope, and by the time /ak-cook runs, the missing tests, migrations, or background jobs have already been skipped.

Disclosure: I maintain AgentKit and have an affiliate relationship with it: the AgentKit link in this post is an affiliate link; buying through it gets you 30% off.

Note: the current AgentKit beta (since 3.0.0-beta.35, October 21, 2026) changed skill names from ak:<name> to ak-<name>, and the commands in this post use the new names: Claude Code calls /ak-plan, Codex calls $ak-plan. On an older version, swap ak- back to ak: to get the matching command.

/ak-plan is the planning command in AgentKit (formerly ClaudeKit). Command names follow AgentKit as of October 2026; older ClaudeKit installs use the /ck: prefix for the same commands. I use one running example, extracting billing from a monolith, to show when these two options are worth the cost and when they only slow you down.

Running example: extracting the billing module

Billing is spread across API routes, database models, background jobs, retry logic, invoice status, webhook handlers, and the admin UI. The task sounds simple enough: "extract billing into its own module, keep the old behavior." But once the agent starts running, the real questions surface:

  • Which files actually belong in scope: API, jobs, database, UI, or webhooks?
  • Which behaviors must stay identical: retry, idempotency (running twice gives the same result), invoice status, payment failure?
  • How much of the current behavior is actually under test?
  • Does this phase depend implicitly on a migration or a background job?
  • If the new code builds but diverges on an edge case, who catches it?

For small tasks, /ak-plan --fast or plain /ak-plan is usually enough. For complex tasks that are not a full major refactor, --hard is usually the better fit. For large tasks, missing context upfront becomes cost at the end: cook has to guess scope again, phase files stay vague, tests get written after the code, and regressions only surface once the refactor is done.

Neither option is a "stronger mode" you switch on to make things better. They address two specific risks: not knowing enough scope and not protecting existing behavior.

OptionUse when
--deepScope is wide and each phase needs a map
--tddExisting behavior must survive the refactor
--deep --tddBoth risks apply

Mode and flag are different things

Before going further, one distinction worth making: /ak-plan takes two kinds of arguments.

TypeExampleEffect
Mode--fast, --hard, --deep, --parallel, --twoSelects the planning pipeline. One mode per command.
Composable flag--tdd, --no-tasksAn add-on that pairs with any mode.

--deep is a mode, so it changes the whole planning pipeline. --tdd is a flag, so it keeps whichever mode you chose and adds a tests-first structure to the phase file and the cook step.

The argument hint in the skill definition reads:

text
argument-hint: "[task] [--fast|--hard|--deep|--parallel|--two] [--tdd|--no-tasks]"

The | between modes means pick one. --tdd sits in its own group, so it composes. That is why --deep --tdd is valid and --deep --hard is not.

--deep: when the plan needs a map for each phase

This section covers the problem --deep solves, the steps in its pipeline, and what it adds to each phase file.

The problem --deep solves

Large tasks usually touch many areas of code at once. For the billing module, scope can span:

  • API routes: create invoice, retry payment, refund, webhook callback.
  • Database: invoice table, payment attempt table, status history.
  • Background jobs: retry scheduler, reconciliation job, webhook replay.
  • Admin UI: invoice detail, manual retry, refund action.
  • Shared contracts: frontend API response, webhook payload, event names.

These tasks need more than a list of steps. They need a map:

QuestionIn the billing example
Which files are created, modified, or deleted?Route, service, job, migration, UI action
Which tests cover the old behavior?Retry, idempotency, refund, webhook replay
Which phase depends on which?Migration before service, service before UI
Which interfaces need test protection?API response, webhook payload, job input
Which dependency edges are risky?A job reads the old status while the service has changed the enum

--deep fits when the cost of a wrong plan is higher than the cost of planning carefully. The mode rule in the skill says:

text
Major refactor, 5+ areas, architectural debt -> use --deep

If you only touch a few files, --fast or plain /ak-plan is usually enough. If the scope is complex but the architecture is still clear, --hard is a better fit. --deep earns its cost when a wrong plan would mean hours of reworking phases, tests, and ownership.

The --deep pipeline

It starts from broad context and narrows into each phase:

  1. Researcher pass: two to three passes over the architecture and affected areas.
  2. Full-scope scout: docs, core modules, existing tests, major dependencies.
  3. Per-phase scout: each phase gets a file inventory, test gaps, and interfaces to preserve.
  4. Phase files: the planner feeds the scout data into each phase.
  5. Red team: catches scope leaks, wrong phase order, and implementation risks.
  6. Validation: checks that the plan has the commands, dependencies, and success criteria it needs.
  7. Tasks: creates the task list, unless you pass --no-tasks.
  8. Cook handoff: prints /ak-cook {path}/plan.md.

Compared with --hard, which usually scouts once for the whole plan, --deep adds a pass for each phase. It costs more, and in return the phase files are more specific: which files get touched, which tests are missing, which dependencies are risky.

What a phase file gains with --deep

  • File inventory table: action (create, modify, delete), rough size, test impact.
  • Test scenario matrix: critical, high, and medium paths.
  • Dependency map: which other phases this one links to.
  • Function and interface checklist: which functions or interfaces need test protection.

This is the main difference. A phase does not just say "refactor billing service." It spells out which files, which tests, which edge cases, and which phase it depends on.

--tdd: when you fear a refactor will break what is running

This section covers the problem --tdd solves, when it pays off, and what it changes in both the plan step and the cook step.

The problem --tdd solves

The default cook flow is familiar: read the plan, implement each task, type-check after each file, then run a separate testing step. That works for greenfield code. For refactoring live code, it is not safe enough.

In the billing example, old behavior might include:

  • Retry runs at most 3 times, then moves the invoice to failed.
  • A webhook with the same event_id is applied only once.
  • A refund cannot run if the invoice is already voided.
  • The admin UI still shows the correct status history after the service is extracted.

The happy path may still pass while the bug hides in an edge case. --tdd puts a regression gate in place before the code changes. TDD (test-driven development) here means capturing current behavior before refactoring, rather than writing tests for a new feature.

When --tdd is most valuable

SituationUse it?In the billing example
Brand-new greenfield codeUsually notNo invoice or retry behavior exists yet to capture
Refactoring a module with live usersYesRetry, idempotency, and status transitions must hold
Switching payment provider while keeping the contractYesEasy to drift on API responses or webhook behavior
A 1 to 2 line fix with a known causeUsually notFor example, fixing a typo in an admin UI label
Throwaway prototypeNoA test gate is not worth the cost

--tdd is most valuable in modules with async patterns, stateful workflows, database transactions, or public API contracts. Billing has all of them: background jobs, status transitions, transaction boundaries, webhook payloads, admin actions.

At plan time

Section in the phase fileRole
Tests before refactorWrite regression coverage before changing code, to record current behavior.
RefactorDescribe the code being changed, protected by the tests above.
Tests afterAdd tests for any new behavior in this phase.
Phase gateA concrete compile and test command that must pass after the refactor.

A phase that uses --tdd usually reads in this order:

  1. Write tests that protect current behavior.
  2. Extract a small dependency seam if the old code is hard to test.
  3. Refactor the code.
  4. Run compile and tests again.

Making old code testable is the step people skip. Sometimes legacy code cannot be tested directly: a long function calls the database internally, dependencies cannot be injected, output cannot be isolated. You first extract a small seam that keeps behavior identical but makes the code testable, and only then do the real refactor.

At cook time

When /ak-cook runs with --tdd, the order is:

  1. Write tests first: record current behavior before changing code.
  2. Refactor: restructure, extract modules, make old code testable if needed.
  3. Run the gate: tests that protect the old behavior must still pass along with the compile step.

Put simply, tests written first are the baseline for old behavior. If that baseline fails after the refactor, cook should stop and fix the drift before moving on.

When I wrote this post, I checked it against the ak-plan and ak-cook skill source in a beta build of the Engineer Kit (check your installed version with ak --version). If either skill's workflow changes later, the mode tables in this post may drift.

Why --deep and --tdd often go together

The two options address two different layers of risk. When a task has both, turn on both.

Two-axis matrix: scope of the change, narrow or wide across five or more areas, and whether existing behavior must be kept; the four cells are /ak-plan, /ak-plan --deep, /ak-plan --tdd and --deep --tdd, with the last cell highlighted
Wide scope adds --deep, existing behavior to keep adds --tdd; a task with both risks turns on both.
RiskWhat you needOption
Not knowing enough scopePer-phase scout, file inventory, dependency map--deep
Refactor drifts from old behaviorTests before refactor, regression gate during cook--tdd

--deep gives you the map and --tdd gives you the verification layer. A major refactor usually needs both. For example, a request like this:

text
Extract billing module from the monolith.
Keep current API contract for the frontend.
Preserve existing behavior for retry, idempotency, invoice status.
Touches database schema, background jobs, API routes, admin UI.

This task needs --deep because the scope is wide and has many dependencies. It also needs --tdd because retry, idempotency, refunds, and webhooks are all old behavior that has to survive.

With only --deep, the plan may be very clear, but the refactor still lacks a regression gate. With only --tdd, the test flow may be right, but the phase files stay vague: what to test, where, which modules are affected, and which dependencies must come first.

Quick rule: wide task, use --deep. Old behavior to keep, add --tdd. Both risks, turn on both.

When to run /ak-brainstorm or /ak-scout first

A common mistake is reaching for --deep --tdd while the approach is still unclear. Planning modes do not resolve ambiguity. They only turn an approach you already chose into more concrete steps.

For example, if you have not decided yet:

  • Extract a real service, or just modularize inside the monolith?
  • Add a new queue, or keep the current background jobs?
  • Keep the current invoice status enum, or move to a clearer state machine?
  • Rewrite the admin UI flow, or refactor it piece by piece?

In that case, run /ak-brainstorm first to settle the approach, then plan.

There is one more layer: /ak-scout. Think of it as a context-gathering step, not a decision step. Scout fits when you are not sure where the code lives, which modules are involved, or which tests cover current behavior. When the brief is still vague, do not jump straight into planning:

  1. Scout: find the real code, real tests, real dependencies.
  2. Brainstorm: choose an approach and its trade-offs before locking the plan.
  3. Plan: use --deep --tdd once the approach is clear enough.
text
/ak-scout "billing retry flow, invoice status, background jobs, admin UI"
/ak-brainstorm "Extract billing module while keeping the current API contract"
/ak-plan --deep --tdd "Refactor billing module per agreed approach..."

Once you know the relevant code and the main trade-offs, you can skip the separate /ak-scout pass, since /ak-plan --deep already scouts as part of its pipeline. When the brief is still too broad, scouting first avoids a quiet failure: the agent reasons plausibly while working from the wrong map of the project.

SituationStart with
Project context unclear, code location unknown/ak-scout, then /ak-brainstorm
You know what and how/ak-plan directly
You know what, not sure how/ak-brainstorm, then /ak-plan
Not sure whether to do it/ak-brainstorm, decide, then plan or drop it

Command picker

In short: unclear scope, /ak-scout first; unclear approach, /ak-brainstorm first; major refactor, /ak-plan --deep --tdd. In full:

SituationCommand
Project context unclear/ak-scout first, then brainstorm or plan
Approach uncertain/ak-brainstorm first
Small fix in 1 or 2 files/ak-plan --fast
Medium new feature/ak-plan (auto mode)
Complex feature, unfamiliar domain/ak-plan --hard
3 or more independent modules in parallel/ak-plan --parallel
Torn between 2 specific approaches/ak-plan --two
Refactor across 5 or more areas, architectural debt/ak-plan --deep
Refactoring live or dogfooded code, fear of regressionsAny mode plus --tdd
Major refactor on a codebase with behavior to preserve/ak-plan --deep --tdd

The --deep --tdd pair is not one mechanism; it is two different jobs running together. Planning costs more, but cook guesses less about scope and has a clearer regression gate.

Inside: how the two options work

This section goes deeper into how --deep and --tdd affect plan time, cook time, and run cost.

--deep costs more because of researchers and per-phase scouting

ModeResearchersRed teamValidationPer-phase scout
--fast000No
--hard2YesOptionalNo
--deep2 to 3YesYesYes
--parallel2YesOptionalNo
--two2 or moreAfter selectionAfter selectionNo

The cost of --deep comes mostly from two to three researchers for high-level architecture analysis, the red-team review, the validation step, and the per-phase re-read. Put simply, each phase is examined on its own before the plan is locked: which files it touches, which phase it depends on, which tests are missing, which edge cases are easy to miss.

Do not misread the word "scout" here. It refers to the reading and checking that has to happen for each phase, not a promise that a separate agent always spawns at runtime. What matters is that --deep forces the plan through several smaller checks instead of looking at scope once from a high level.

--tdd does not create a new agent

--tdd does not change the mode you chose. It is an add-on flag: you still run --fast, --hard, or --deep as usual, with a tests-first structure added. It changes exactly two things:

  • The phase file at plan time. A normal phase has an overview, requirements, architecture, related files, implementation steps, success criteria, and a risk assessment. With --tdd, the phase also gets tests before refactor, tests after refactor, and a phase gate.
  • Execution order at cook time. Write tests that protect old behavior first, refactor second, then rerun the compile and test gate.

--tdd costs much less than --deep, since it mostly adds structure to the phase file and changes the execution order during cook.

The regression gate needs a concrete command

The cook spec requires the regression gate to be a concrete compile or test command. For a Go project, for example:

text
Regression Gate: go test ./... && go vet ./...

If the phase file only says "run tests to verify," the verification step weakens because cook has no exact command to anchor on. The --tdd flag does not guarantee it guesses the right tooling in every repo. If the project uses its own commands, state them in the task description or the plan file:

text
Project uses go test ./..., frontend uses npm test, E2E uses Playwright.

When the task names the tooling, the plan has a basis for writing the right gate into each phase.

How to run it: a general template

The template below follows the skill source of ak-plan and ak-cook: plan receives the task plus mode and flags, and cook receives the plan path and carries --tdd forward if the plan enabled it.

text
/ak-plan [mode] [--tdd] "[What needs to happen].
Scope: [modules/files/stack being touched].
Preserve: [API contract, existing behavior, compatibility].
Touches: [database, jobs, routes, UI, shared types].
Tooling: [concrete compile/test command].
Known bugs / out of scope: [if any]."

If the plan uses --tdd, pass it to cook as well:

text
/ak-cook /absolute/path/to/plan.md --tdd

Applying the template to a few common situations.

--deep for an inventory phase

text
/ak-plan --deep "Build an inventory plan to prepare extracting billing into its own package.
Scope: API routes, invoice service, payment jobs, admin UI, database schema.
Output must include: file inventory, dependency map, phase ownership, risk list.
Not refactoring live behavior in this round."

--hard --tdd for refactoring running code

text
/ak-plan --hard --tdd "Refactor invoiceStatusService: move transition rules
to a separate file, keep exact behavior for retry, failed, refunded, voided."

--deep --tdd for a major refactor with behavior to preserve

text
/ak-plan --deep --tdd "Extract billing module from the monolith.
Keep API contract for frontend, preserve retry/idempotency/refund/webhook behavior.
Touches: database schema, payment jobs, API routes, admin UI. Project uses
go test ./..., frontend uses npm test."

A good task description usually covers:

  • Scope: which files, modules, or stack.
  • Constraints: what must not break, what must stay compatible.
  • Tooling: test and compile commands, which matter most for --tdd.
  • Expected outcome: short but concrete.

Vague input such as "refactor billing" produces a vague plan. Without a concrete anchor, scouting easily returns generic output.

Do this, avoid that

These two groups cover where people stumble most with --deep --tdd: what to do before cook, and the mistakes to avoid.

Do before cook

Keep the worktree clean before planning

If your working directory has uncommitted changes from another task, scouting can mix current code with half-finished work. Before a big plan, commit or stash. Better still, create a separate worktree with /ak-worktree.

Review the phase files before cook

A --deep --tdd plan takes a while to run, so do not cook before rereading plan.md and the phase files it created. Check five questions:

  • File inventory: is there any file you do not want the agent to touch?
  • Test scenario matrix: does it miss a race condition or an edge case such as a duplicate webhook?
  • Phase order: are the phases really independent, or does the migration have to run before the job?
  • Regression gate: is it the right tool and the right test subset?
  • Known bugs: should they be fixed, or should the old behavior be preserved?

Declare test commands in the task

With --tdd, if the repo uses less common tools such as bun instead of npm, mise instead of asdf, or task instead of make, declare them up front:

text
Project uses go test ./..., frontend uses npm test, E2E uses Playwright.

If you do not, the agent guesses. A wrong command weakens the regression gate.

Run /clear between plan and cook

Planning context for a large task is usually heavy: research output, scout data, red-team feedback. The recommended flow: finish the plan, run /clear, reopen, then run /ak-cook {absolute-path}/plan.md --tdd. Cook rereads the plan file and does not need the old planning context.

Avoid

MistakeWhy it breaksDo this instead
Forgetting --tdd on /ak-cookCook still reads the tests-before-refactor section but does not enforce tests first, so tests may get written after the code.Use the cook command the plan suggests at the end.
Using --deep on small tasksBelow roughly five files, the per-phase scouting is usually wasted.Use --hard or --fast instead.
Using --tdd on greenfield codeNew code has no behavior to keep, the tests-before-refactor section is nearly empty, and the agent tends to write token tests.Use --hard and let tests be written in the normal flow.
Trusting the phase files blindly--deep scouts more thoroughly but can still miss hidden dependencies.Before cooking, ask whether a later phase quietly relies on something an earlier phase has not created yet.
Letting --tdd lock in an existing bugIf the tests capture an old bug (for example a duplicate webhook creating two payment attempts) as "current behavior," a refactor that accidentally fixes it fails the gate, and the agent may "fix" the code back to the bug.List known bugs in the task, or split into two plans: fix the bug first, refactor second.
Trying to combine --deep with --parallelBoth are modes, so they do not compose.For parallel agents, use --parallel --tdd with very clear ownership and test scope; if unsure, drop --parallel and keep --deep --tdd.

In short

--deep --tdd is not for every task. It is for tasks with two signs:

  1. The scope is large enough that a normal plan is likely to miss the map.
  2. The current code has behavior that must survive the refactor.

--deep makes planning slower and in return gives clearer phase files: file inventory, test gaps, dependency map, function and interface checklist. --tdd makes cook slower and in return gives the refactor a regression gate: write tests first, refactor, then verify.

If you are in a PM, founder, or product role, you only need to know these two options exist. When the team is about to refactor a large module like billing, ask whether the plan has per-phase scouting and a regression gate.

If you are a developer, try it on your next large task. It may feel slower the first time. But once a test written up front catches one hidden regression, the extra cost becomes much easier to accept.

One last note: --tdd works with any mode in principle, but pairing it with --fast is usually not worth it, since you already chose to move fast.

If you are new to AgentKit, read the AgentKit beginner's guide for Claude Code. To compare ak-plan with Plan mode in Oh-my-pi (OMP), see OMP Plan mode vs AgentKit ak-plan.

Use this piece in your agent

Get an API key

Copy the text below and paste it into Claude Code, Codex or whichever agent you use. The agent reads the piece and checks it against the repo you have open.

Paste into your agent
Read "When to turn on --deep and --tdd for /ak-plan" on modernEngineer and apply it to this repo.
1. Call the content_get tool of the modernengineer MCP server with locale "en", slug "ck-plan-deep-tdd-when-to-use". If MCP is not connected or access is refused, read the page https://modernengineer.dev/en/library/ck-plan-deep-tdd-when-to-use instead.
2. Summarize the main steps of the piece and point out which apply to this repo.
3. Propose concrete changes and ask me before editing any file.
Connect MCP in Claude Code (once)
terminal
claude mcp add --transport http modernengineer \
  https://api.modernengineer.dev/mcp \
  --header "Authorization: Bearer <API key>"
How to connect Codex, Cursor and other clients

This piece is open to everyone: without MCP, the agent can still read it straight from the link.

Version
v1.0.0
Updated
22/05/2026
Licence
All rights reserved
Slug
ck-plan-deep-tdd-when-to-use