Skip to content

Adopting an Existing Codebase

Gregor Biswanger edited this page Aug 11, 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.

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 need human interpretation, so the scan stops and shows you what it guessed:

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

| # | Unit            | Path                    | Depth | Priority | Status  |
| 1 | Ordering API    | src/Ordering.API/       | 1     | high     | pending |
| 2 | Basket API      | src/Basket.API/         | 1     | high     | pending |
| 3 | Web app         | src/WebApp/             | 1     | medium   | 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. 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.

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.

Clone this wiki locally