/nano -- Plan before building

Every file gets named. Every step gets verified. The plan is a contract.

Scope classification

Before writing the plan, the agent classifies the work into one of three sizes. This determines how detailed the plan needs to be.

  • S -- One to three files, under 100 lines changed. The plan is a short list of steps. No architecture decisions.
  • M -- Four to ten files, moderate complexity. The plan includes file-level breakdown, risk assessment, and step verification.
  • L -- More than ten files, new subsystems, or cross-cutting changes. The plan includes dependency ordering, rollback strategy, and explicit out-of-scope boundaries.

The agent picks the size based on the think summary (if available) and the codebase structure. You can override with --size s, --size m, or --size l.

What the plan includes

The output is .nanostack/plan.json. Five required fields:

{
  "goal": "One sentence from think.json or the user prompt.",
  "planned_files": [
    "src/lib/notify.ts",
    "src/components/StatusDot.tsx",
    "src/hooks/useNotifications.ts"
  ],
  "steps": [
    {
      "description": "Create notification store with unread count",
      "files": ["src/lib/notify.ts"],
      "verify": "Import resolves, types compile"
    },
    {
      "description": "Add StatusDot component",
      "files": ["src/components/StatusDot.tsx"],
      "verify": "Renders red dot when count > 0, hidden when 0"
    }
  ],
  "risks": [
    "Nav re-renders on every notification update"
  ],
  "out_of_scope": [
    "Email delivery",
    "Push notification service",
    "User preferences UI"
  ]
}

How it uses past knowledge

If you have run /compound after previous sprints, the agent checks .nanostack/know-how/solutions/ for relevant patterns. This matters when:

  • A previous sprint solved a similar problem. The plan reuses the approach instead of reinventing it.
  • A previous sprint hit a dead end. The plan avoids the same mistake and notes why.
  • The codebase has established conventions. The plan follows them instead of introducing a new pattern.

Without /compound history, the agent still reads the codebase to detect conventions, but it will not know about past failures.

Why planned_files matters

The planned_files array is not documentation. It is a scope boundary.

During the build phase, if the agent creates or modifies a file that is not in planned_files, the /review phase flags it as scope drift. This catches the most common failure mode in AI-assisted coding: the agent quietly expanding the task.

# In review.json, scope drift appears as:
{
  "scope_drift": {
    "unplanned_files": ["src/utils/format.ts"],
    "severity": "warning",
    "note": "File not in plan.json planned_files"
  }
}

Scope drift is not always wrong. Sometimes you discover a needed utility during implementation. But it forces a conscious decision: either add the file to the plan with justification, or revert the change.

Verification steps

Each step in the plan has a verify field. The agent checks this after completing the step. If verification fails, it stops and reports the issue before moving to the next step.

This prevents cascading failures. A type error in step 1 will break everything in steps 2 through 5. Catching it immediately saves the entire build phase from producing garbage.

Previous/thinkNext/review