Skip to content

Adopting an Existing Codebase

Gregor Biswanger edited this page Aug 26, 2026 · 4 revisions

Adopting an Existing Codebase

"Can I use FeatherSpec on existing software?" — yes, and not as an afterthought. The wizard's first question after the documentation language is whether this is a new project or existing software, and the existing-software answer leads into /sdd-architecture-scan: a deep, resumable analysis that turns your codebase into the lean architecture: fingerprint every later command navigates by.

The point of the fingerprint is to replace exploration. An agent that can answer "where do I add X?" from AGENTS.md alone does not spend its first ten tool calls rediscovering your folder layout — in either tool, in every session. And it scales: from a single service to large enterprise repositories — the worklist gate, the depth tiers and unmapped: keep even big scans affordable (see the FAQ below).

Installing into an existing repository

An existing project does not start from "Use this template" — you copy the template's files into your repository instead. Fetch the template next to your project (npx degit GregorBiswanger/featherspec featherspec-tmp, or a plain clone) and copy:

  • AGENTS.md and CLAUDE.md — if you already have an AGENTS.md, merge FeatherSpec's sections into yours rather than replacing it; it is the single source of truth for both tools
  • .claude/ (rules, command bodies, the scout agent, shared settings)
  • .github/prompts/ and .github/agents/ — merged into your existing .github/
  • .specs/ and .memory-bank/ (empty scaffolds)
  • .vscode/settings.json — merge the keys if you have your own
  • the template's .gitignore entries (the local-settings block and .sdd-scan/)

That is the whole installation — no build, no dependencies. This exact overlay is what this feature's validation used on dotnet/eShop. Then run /sdd-setup and answer existing software.

What the scan produces — and what it deliberately does not

Produced, all behind their normal gates:

  • the architecture: snapshot in AGENTS.md — written only through /sdd-architecture-update's confirmation gate, never by the scan itself
  • .memory-bank/techContext.md — stack, build, run and test facts read from the code
  • .memory-bank/systemPatterns.md — observed, undocumented decisions, dated and source-linked
  • optionally .architecture/<unit>.md — curated per-module maps, but only when the snapshot's line cap would otherwise evict navigation facts (see the budget cascade below)
  • on partial coverage: a coverage: figure and an unmapped: list, so agents know where the map ends and exploration begins

Deliberately not produced: generated API docs, file inventories, or anything an agent can infer from the code in seconds. Uncurated context files measurably hurt agents; everything that survives the scan is decision-relevant navigation knowledge, stated as path patterns rather than path lists.

How a scan runs

With /sdd-setup the fork looks like this: the wizard states its guess ("substantial source files, snapshot still TBD — this looks like existing software"), asks, then collects only the three steps a human must answer (project name, users, coding preferences), and hands over to the scan. The scan answers the stack, architecture-style, entrypoint and quality-gate questions from the code.

The scan itself moves through three phases:

Inventory (Phase A). Git only — git ls-files for the tree shape and manifests, git rev-list --count per folder for change frequency as a priority signal. Facts go to .sdd-scan/_inventory.md; proposed analysis units with priorities go to .sdd-scan/_worklist.md.

The worklist gate. Unit boundaries — and each unit's depth tier (deep / standard / shallow: roots get the full read ladder, periphery gets heads only, honestly declared) — need human interpretation, so the scan stops and shows you what it guessed:

Proposed analysis units (confirm, or tell me what to merge, split, defer or re-tier):

| # | Unit            | Path                    | Depth | Priority | Tier     | Status  |
| 1 | Ordering API    | src/Ordering.API/       | 1     | high     | deep     | pending |
| 2 | Basket API      | src/Basket.API/         | 1     | high     | standard | pending |
| 3 | Web app         | src/WebApp/             | 1     | medium   | standard | pending |
…

> merge 1 and 2, they share one deployment
Applied — units merged. Worklist confirmed; dispatching scouts.

Your edit is binding: the worklist is the plan of record, and nothing proceeds while it is unconfirmed. It is the only gate the scan adds.

Scouts (Phase B). One isolated sdd-scout agent per pending unit, at most three in parallel — a Claude Code project subagent or a VS Code custom agent run as a subagent, same shared body. Scouts climb a read ladder instead of reading everything: locate via outline, index or grep, read file heads (~first 60 lines) by default, and open full files only on budgeted triggers — entry points, contracts, one representative per recognized pattern, or genuine uncertainty; the report header audits the count (full reads: n/cap). Each scout analyzes exactly one unit, writes one report to .sdd-scan/reports/, in your DocLanguage, and returns at most five summary lines. A unit too large or incoherent for one honest report (heuristic: no single recognizable pattern, or clearly beyond ~150 relevant files) is not analyzed shallowly — the scout proposes child units instead, which join the worklist with a depth capped at 3. If an environment cannot delegate, the documented fallback is sequential: one unit per turn, worklist updated each time.

Synthesis (Phase C). Reports merge bottom-up — child details collapse into the pattern they share — until the root report is the big picture. The curation rules are strict: path patterns over path lists, nothing inferable in seconds, every documented command executed once (anything network-reaching, like a package restore, asks first), the why into systemPatterns.md, the facts into techContext.md.

Self-test, then the update gate. Before handing anything over, the scan composes ten navigation questions, answers them blind from its distilled result only, then verifies each against the repository and fixes what it missed. The score travels into the delta report of /sdd-architecture-update, which the scan runs exactly as if you had typed it — the snapshot is written only behind that confirmation gate, and a confirmed merge also sets last deep scan in the snapshot comment. Finally the scan asks once whether to delete the raw analysis in .sdd-scan/ (recommended: yes).

Interrupting and resuming

The files decide where the scan resumes, not the conversation:

  • no .sdd-scan/_worklist.md → inventory runs
  • worklist with pending units → scouts run, pending units only
  • all units done, or you say "distill what we have" → synthesis runs

Close the session mid-scan, come back tomorrow, type /sdd-architecture-scan — it continues from the worklist with no repeated work. That is also why every scout return updates the worklist in the same change set: a report whose worklist row did not move is not done.

Keeping the fingerprint fresh

  • The snapshot comment carries last deep scan: next to last reconciled:, and /sdd-overview reports the date plus the count of unmapped: entries.
  • Day-to-day drift stays with /sdd-architecture-update, exactly as before. But when reconciliation is not enough — structures the snapshot cannot place, snapshot paths that no longer exist, a focus area sitting under unmapped: — its delta report recommends the scan instead of guessing.
  • A rescan does not start over: /sdd-architecture-scan src/payments scopes every phase to that subtree and merges only its entries into the fingerprint.

The budget cascade — when .architecture/ appears

The fingerprint targets the architecture: snapshot alone, measured against the constitution cap on AGENTS.md. Only when staying under the cap would evict navigation facts does per-module detail move out to .architecture/<unit>.md — each map ≤ 40 lines, holding the unit's internal pattern, entry points, task playbooks, deviations and traps — while the snapshot keeps one line and a map: reference per module. No cascade needed, no folder: on small and mid-size repositories .architecture/ never exists.

What does a scan cost?

A planning rule of thumb, not a guarantee — the dominant variable is the scouts' read discipline (head-reads by default, full files only against a per-unit budget: standard 10, roots up to 20, shallow ≤ 3): roughly ~50k tokens per leaf unit (range 30–100k, shallow units far below), plus ~5–20k per synthesis node, plus the one-off inventory. The biggest price lever is the model the scouts run on — they inherit your session model, and Configuration shows how to run them cheaper (a per-session model choice or a local pin), with the navigation self-test as the quality gate. A 13–15-unit scan of a repository the size of dotnet/eShop lands in the order of 0.8–1.2M tokens. Two levers keep large repositories affordable: defer low-priority units at the worklist gate (they stay visible under unmapped:), and rescan with a focus path instead of rescanning the world. Model advice in one line: scouts are cheap-model territory, synthesis rewards a reasoning model — see Configuration.

FAQ

Huge monorepo? The worklist gate is where you defer: keep the high-churn units, mark the rest deferred. The scan records coverage: and an unmapped: list in the snapshot, so agents know to explore carefully there — and to propose a worklist entry when they do. The split rule and the depth cap of 3 keep any single scout's job graspable.

Can I stop mid-scan? Anytime. The worklist is the resume point; nothing depends on the chat session. You can also say "distill what we have" to synthesize from the units done so far and leave the rest as unmapped:.

Is .sdd-scan/ safe to delete? Yes, always — it is volatile working state and the scan offers the deletion itself after a confirmed merge. Everything curated has moved on to the snapshot, the .architecture/ maps and the Memory Bank. See Configuration for the team-resume option (committing the worklist mid-scan).

Do both tools produce the same result? Same body file, same worklist format, same report schema, same gates — the fingerprints are structurally equivalent; wording may differ. VS Code environments that cannot delegate to subagents use the sequential fallback and arrive at the same files, one unit per turn.

Can more than three scouts run in parallel? Three is a declared default protecting the permission-prompt experience and the tools' own concurrency limits — correctness never depends on it, because the worklist makes any degree of parallelism safe. An explicit request in your invocation ("run up to 6 scouts") overrides it; no configuration needed.

Clone this wiki locally