-
Notifications
You must be signed in to change notification settings - Fork 2
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).
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.mdandCLAUDE.md— if you already have anAGENTS.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
.gitignoreentries (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.
Produced, all behind their normal gates:
- the
architecture:snapshot inAGENTS.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 anunmapped: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.
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).
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.
- The snapshot comment carries
last deep scan:next tolast reconciled:, and/sdd-overviewreports the date plus the count ofunmapped: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 underunmapped:— its delta report recommends the scan instead of guessing. - A rescan does not start over:
/sdd-architecture-scan src/paymentsscopes every phase to that subtree and merges only its entries into the fingerprint.
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.
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.
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.
Start here
Reference
Design & interop
- Interop Matrix
- Design Decisions
- Specify Method
- Committing to One Tool
- Migrating from the predecessor
- Releasing
Help