Skill: survey
The pipeline's anchor on architecture. It produces docs/architecture-map.md — the single source of "what the system is" that specify (constraints), design (matches against it), data-model, and implement all read instead of re-discovering the code. It runs in one of two modes, auto-detected:
- Brownfield (the repo has source) → scan it once and persist the current architecture.
- Greenfield (empty / near-empty repo) → run a short, level-adaptive foundation session: pick the stack / structure / data approach / conventions with the user (defaults-heavy), fix them as the foundation + foundational ADRs, and emit a scaffold
tasks.json that scaffold turns into a real skeleton. Greenfield detail → ./references/foundation.md.
Repo-level utility (one map serves every feature). The scan is delegated to explorer; question phrasing → ../_shared/ask-style.md; depth → ../_shared/size-matrix.md.
Map prose follows artifact_language (carry the language in the explorer's dispatch prompt) — frontmatter keys like test_cmd / reflects_commit stay machine-form, module/file names stay as-is → ../_shared/artifact-language.md.
Owner
Architect / Tech Lead — they own the architecture (brownfield: confirm it reflects reality; greenfield: decide the foundation).
Inputs
- (Optional) a path/scope hint (default: repo root).
- (Read, never overwrite) an authored architecture doc if present (
docs/architecture.md, ARCHITECTURE.md, root CLAUDE.md, ADRs) — a strong input the map reconciles with, never clobbers.
- (Optional, greenfield)
docs/idea-brief.md — the intent G3 would otherwise ask for; present → confirmed, not re-asked.
Protocol
- Ensure the settings file (first thing, after this skill's own gate). If
.claude/sdd.local.md is absent, create it now from the canonical template — documented defaults + the self-documenting body — and patch .gitignore; if it exists, read it and never overwrite. The one procedure lives in ../_shared/settings-file.md. Creating is unconditional; changing values is only ever offered by config. Say one line: «.claude/sdd.local.md created with documented defaults — /sdd:config to tune it». Then detect mode + freshness (incremental re-survey on stale). If docs/architecture-map.md exists and is fresh (its reflects_commit ≈ current HEAD) → «map is fresh (reflects <commit>). Reuse or refresh?»; STOP on reuse. If it exists but is stale, prefer the incremental re-survey: git diff --name-only <reflects_commit>..HEAD, group the changed paths by top-level module, and dispatch the step-3 explorer scoped only to the changed subfolders; update just the touched map rows/sections (module inventory, conventions, frontend, machine keys) and re-stamp updated_at + reflects_commit. Fall back to the full re-scan only when the diff spans more than half the modules in the inventory (or reflects_commit no longer resolves) — say which mode ran in the handoff. No map at all → decide the mode: brownfield if the repo has source (modules/packages beyond config), else greenfield (empty or only scaffolding like a bare go.mod / package.json).
Brownfield path (existing code)
- Read authored docs first. Any hand-maintained architecture doc / root
CLAUDE.md / ADRs → authoritative input; reconcile with it, never overwrite.
- Scan via explorer. Dispatch the
explorer agent — subagent_type: "sdd:explorer" (haiku/low, clean-isolated per ../_shared/agent-roster.md): «Report (a) language + frameworks + versions, (b) top-level module layout + per-module layers, (c) layering / wiring conventions, (d) datastores + access, (e) inter-module comms, (f) cross-cutting conventions (errors, IDs, tests, migrations) with one cited example each, (g) 2–3 representative features as precedents, (h) if a frontend exists — the component library / design system, design tokens (colors/spacing/typography), styling approach (Tailwind / CSS-modules / styled-components / …), shared UI primitives, and a representative screen/component as the UI precedent to reuse.» Large repo → fan out per subtree. (Fallback subagent_type: "Explore".) Item (h) is the reuse invariant's source: the §Frontend / UI foundation section it fills is what design / tasks / implement later compose against instead of reinventing — new UI work reuses these components / tokens / the single styling approach, and review flags from-scratch UI that duplicates them. An incomplete inventory here silently licenses a second design system downstream.
- Synthesize + stamp + validate + write. Fill
./templates/architecture-map.md (C4 of what exists, module inventory, cited conventions, datastores, the Frontend / UI foundation if a frontend exists, precedent guide, constraints) with real file:line anchors. Fill the machine-readable frontmatter keys (language, build_cmd, test_cmd, lint_cmd, migration_tool, frontend) from the explorer's findings — a key with no evidence stays "" (unknown), never a guess; implement's command-detection cascade reads test_cmd/lint_cmd from here. Record updated_at + reflects_commit: <short HEAD>. Validate the C4 Mermaid per ../_shared/mermaid-check.md (render-parse with mmdc if available, else the structural lint; fix before committing). Then the structural self-check (per ../_shared/self-check.md) — re-read the map from disk and verify: (1) every machine key holds an explorer-backed value or the explicit ""; (2) every convention line cites a file that exists; (3) the C4 validated; (4) reflects_commit = current short HEAD. Write + commit survey: architecture map (reflects <commit>). Then emit the stage-handoff block per ../_shared/handoff.md — What I did + Review (docs/architecture-map.md) + Run next (/clear, then /sdd:specify <slug>). (The greenfield path emits its own handoff in G6 — forward to /sdd:scaffold.)
G2. Calibrate to the person. One opening AskUserQuestion to gauge how the user wants to engage — «pick good defaults, I'll confirm» / «walk me through each choice with explanations» / «let me choose each piece, keep it terse». This sets the dialogue's depth + phrasing (junior → defaults + glossed explanations per ../_shared/ask-style.md; senior → terser, more control). Not a product brief.
G3. Intent (short). What the project is + the kind of capabilities it'll have (e.g. «HTTP API» / «CLI» / «web app»). Enough to choose an architecture — deliberately NOT the feature briefing (that's specify, per feature). Read docs/idea-brief.md first if it exists (interview writes it): its raw-idea and problem sections already answer this, so restate the intent back in one line for confirmation and move on. Only what the brief leaves open becomes a question — 1–3 of them, never a re-ask of something already on disk.
G4. Pick the foundation, defaults-heavy. At the calibrated depth, choose: stack (language/framework/datastore), architectural style (e.g. hexagonal modules), folder/module structure, data/persistence approach (migration tool, ID strategy), core conventions (errors, tests, CI). Recommend a coherent default set; the user confirms or adjusts. Choice menus + defaults → ./references/foundation.md.
G5. Fix the foundation. Write docs/architecture-map.md as the established foundation (mark mode: greenfield-bootstrap; the C4 is the target baseline) + spawn foundational ADRs in docs/adr/ for the irreversible picks (stack, module style, persistence). Fill the machine-readable frontmatter keys from the chosen foundation (language, build_cmd, test_cmd, lint_cmd, migration_tool, frontend) — here they encode the decided toolchain; anything not yet decided stays "". Record reflects_commit. Validate the C4 Mermaid per ../_shared/mermaid-check.md before committing, and run the same step-4 structural self-check.
G6. Emit the scaffold plan + hand off. Write a scaffold tasks.json (the skeleton: folder/module structure, a baseline module, the test harness, migration tooling, CI, a CLAUDE.md/rules doc) per the contract in ./references/foundation.md. Each task's DoD anchors on the skeleton smoke test — «the project builds + boots + the empty test suite runs + the migration tool runs» (canonical in ../scaffold/SKILL.md). Commit survey: greenfield foundation + scaffold plan. Then emit the stage-handoff block per ../_shared/handoff.md — What I did + Review (docs/architecture-map.md, docs/adr/, docs/features/_scaffold/tasks.json) + Run next: /clear, then /sdd:scaffold (it materializes the skeleton; the per-feature flow starts afterwards with /sdd:specify <slug>).
Definition of Done
docs/architecture-map.md exists with updated_at + reflects_commit; an authored doc (if any) was reconciled, never overwritten.
- Brownfield: C4 of what exists + module inventory + cited conventions + precedent guide, real anchors (no placeholders).
- Greenfield: foundation fixed (stack/structure/data/conventions) at the user's calibrated level + foundational ADRs + a scaffold
tasks.json whose tasks carry the skeleton smoke-test DoD, ready for /sdd:scaffold.
- The step-4 structural self-check passed (
../_shared/self-check.md): machine keys explorer-backed or explicitly "", convention citations resolve, C4 validated, reflects_commit current; its result is reported in the handoff.
Anti-patterns
- Re-scanning the repo in every downstream skill — the point is to scan once; others read the map (drift detection is the only re-read, of real domain files).
- Overwriting a hand-maintained
docs/architecture.md — survey writes its own map and reconciles.
- A map with no
reflects_commit — it silently rots; nobody knows it's stale.
- Greenfield: a full product brief. The foundation session picks the architecture, not the features — the idea/briefing is
specify's job, per feature. Keep it to intent + foundation choices.
- Greenfield: ignoring the person's level. A junior gets defaults + plain-language explanations; a senior gets control + terseness. One calibration question sets this — don't fire a senior-level wall of choices at a first-timer.
- Placeholders / guessed layout — cited or
UNKNOWN; a fictional map is worse than none.
References & template
1---2name: survey3description: Use to establish the repo's architecture map the rest of the pipeline reads. Two modes: on an EXISTING codebase it scans once and persists what's there; on an EMPTY/greenfield repo it runs a short, level-adaptive foundation session — picks the stack / folder structure / data approach / conventions WITH you (defaults-heavy), fixes them as the foundation + foundational ADRs, and emits a scaffold tasks.json that the scaffold skill materializes into a real skeleton. Triggers on "survey the codebase", "map the architecture", "set up a new project", "bootstrap the foundation", "/sdd:survey", "вивчи кодову базу", "карта архітектури", "новий проєкт", "заклади фундамент". Output: docs/architecture-map.md (+ adr/ + scaffold tasks.json on greenfield). Records reflects_commit for staleness; reads, never overwrites, an authored architecture doc.4---56# Skill: survey78The pipeline's anchor on architecture. It produces `docs/architecture-map.md` — the single source of "what the system is" that `specify` (constraints), `design` (matches against it), `data-model`, and `implement` all read instead of re-discovering the code. It runs in one of **two modes**, auto-detected:910- **Brownfield** (the repo has source) → scan it once and persist the **current** architecture.11- **Greenfield** (empty / near-empty repo) → run a short, **level-adaptive foundation session**: pick the stack / structure / data approach / conventions *with* the user (defaults-heavy), fix them as the **foundation** + foundational ADRs, and emit a **scaffold `tasks.json`** that [`scaffold`](../scaffold/SKILL.md) turns into a real skeleton. Greenfield detail → [`./references/foundation.md`](./references/foundation.md).1213Repo-level utility (one map serves every feature). The scan is delegated to [`explorer`](../../agents/explorer.md); question phrasing → [`../_shared/ask-style.md`](../_shared/ask-style.md); depth → [`../_shared/size-matrix.md`](../_shared/size-matrix.md).1415Map prose follows `artifact_language` (carry the language in the explorer's dispatch prompt) — frontmatter keys like `test_cmd` / `reflects_commit` stay machine-form, module/file names stay as-is → [`../_shared/artifact-language.md`](../_shared/artifact-language.md).1617## Owner1819Architect / Tech Lead — they own the architecture (brownfield: confirm it reflects reality; greenfield: decide the foundation).2021## Inputs2223- (Optional) a path/scope hint (default: repo root).24- (Read, never overwrite) an authored architecture doc if present (`docs/architecture.md`, `ARCHITECTURE.md`, root `CLAUDE.md`, ADRs) — a strong input the map reconciles with, never clobbers.25- (Optional, greenfield) `docs/idea-brief.md` — the intent G3 would otherwise ask for; present → confirmed, not re-asked.2627## Protocol28291. **Ensure the settings file (first thing, after this skill's own gate).** If `.claude/sdd.local.md` is absent, create it now from the canonical template — documented defaults + the self-documenting body — and patch `.gitignore`; if it exists, read it and never overwrite. The one procedure lives in [`../_shared/settings-file.md`](../_shared/settings-file.md). Creating is unconditional; **changing values is only ever offered by [`config`](../config/SKILL.md)**. Say one line: «`.claude/sdd.local.md` created with documented defaults — `/sdd:config` to tune it». **Then detect mode + freshness (incremental re-survey on stale).** If `docs/architecture-map.md` exists and is fresh (its `reflects_commit` ≈ current HEAD) → «map is fresh (reflects `<commit>`). Reuse or refresh?»; STOP on reuse. If it exists but is **stale**, prefer the **incremental re-survey**: `git diff --name-only <reflects_commit>..HEAD`, group the changed paths by top-level module, and dispatch the step-3 explorer **scoped only to the changed subfolders**; update just the touched map rows/sections (module inventory, conventions, frontend, machine keys) and re-stamp `updated_at` + `reflects_commit`. Fall back to the **full re-scan only when the diff spans more than half the modules** in the inventory (or `reflects_commit` no longer resolves) — say which mode ran in the handoff. No map at all → decide the mode: **brownfield** if the repo has source (modules/packages beyond config), else **greenfield** (empty or only scaffolding like a bare `go.mod` / `package.json`).3031### Brownfield path (existing code)32332. **Read authored docs first.** Any hand-maintained architecture doc / root `CLAUDE.md` / ADRs → authoritative input; reconcile with it, never overwrite.343. **Scan via explorer.** Dispatch the [`explorer`](../../agents/explorer.md) agent — `subagent_type: "sdd:explorer"` (`haiku`/`low`, clean-isolated per [`../_shared/agent-roster.md`](../_shared/agent-roster.md)): «Report (a) language + frameworks + versions, (b) top-level module layout + per-module layers, (c) layering / wiring conventions, (d) datastores + access, (e) inter-module comms, (f) cross-cutting conventions (errors, IDs, tests, migrations) with one cited example each, (g) 2–3 representative features as precedents, (h) **if a frontend exists** — the component library / design system, design tokens (colors/spacing/typography), styling approach (Tailwind / CSS-modules / styled-components / …), shared UI primitives, and a representative screen/component as the UI precedent to reuse.» Large repo → fan out per subtree. (Fallback `subagent_type: "Explore"`.) Item (h) is the **reuse invariant's source**: the §Frontend / UI foundation section it fills is what `design` / `tasks` / `implement` later **compose against instead of reinventing** — new UI work reuses these components / tokens / the single styling approach, and `review` flags from-scratch UI that duplicates them. An incomplete inventory here silently licenses a second design system downstream.354. **Synthesize + stamp + validate + write.** Fill [`./templates/architecture-map.md`](./templates/architecture-map.md) (C4 of what exists, module inventory, cited conventions, datastores, **the Frontend / UI foundation if a frontend exists**, precedent guide, constraints) with real `file:line` anchors. **Fill the machine-readable frontmatter keys** (`language`, `build_cmd`, `test_cmd`, `lint_cmd`, `migration_tool`, `frontend`) from the explorer's findings — a key with no evidence stays `""` (unknown), **never a guess**; `implement`'s command-detection cascade reads `test_cmd`/`lint_cmd` from here. Record `updated_at` + `reflects_commit: <short HEAD>`. **Validate the C4 Mermaid per [`../_shared/mermaid-check.md`](../_shared/mermaid-check.md)** (render-parse with `mmdc` if available, else the structural lint; fix before committing). Then the **structural self-check** (per [`../_shared/self-check.md`](../_shared/self-check.md)) — re-read the map from disk and verify: (1) every machine key holds an explorer-backed value or the explicit `""`; (2) every convention line cites a file that exists; (3) the C4 validated; (4) `reflects_commit` = current short HEAD. Write + commit `survey: architecture map (reflects <commit>)`. Then **emit the stage-handoff block** per [`../_shared/handoff.md`](../_shared/handoff.md) — *What I did* + *Review* (`docs/architecture-map.md`) + *Run next* (`/clear`, then `/sdd:specify <slug>`). (The greenfield path emits its own handoff in G6 — forward to `/sdd:scaffold`.)3637### Greenfield path (empty repo) → [`./references/foundation.md`](./references/foundation.md)3839G2. **Calibrate to the person.** One opening `AskUserQuestion` to gauge how the user wants to engage — «pick good defaults, I'll confirm» / «walk me through each choice with explanations» / «let me choose each piece, keep it terse». This sets the dialogue's depth + phrasing (junior → defaults + glossed explanations per [`../_shared/ask-style.md`](../_shared/ask-style.md); senior → terser, more control). Not a product brief.40G3. **Intent (short).** What the project is + the kind of capabilities it'll have (e.g. «HTTP API» / «CLI» / «web app»). Enough to choose an architecture — deliberately NOT the feature briefing (that's `specify`, per feature). **Read `docs/idea-brief.md` first if it exists** ([`interview`](../interview/SKILL.md) writes it): its raw-idea and problem sections already answer this, so restate the intent back in one line for confirmation and move on. Only what the brief leaves open becomes a question — 1–3 of them, never a re-ask of something already on disk.41G4. **Pick the foundation, defaults-heavy.** At the calibrated depth, choose: stack (language/framework/datastore), architectural style (e.g. hexagonal modules), folder/module structure, data/persistence approach (migration tool, ID strategy), core conventions (errors, tests, CI). Recommend a coherent default set; the user confirms or adjusts. Choice menus + defaults → [`./references/foundation.md`](./references/foundation.md).42G5. **Fix the foundation.** Write `docs/architecture-map.md` as the **established foundation** (mark `mode: greenfield-bootstrap`; the C4 is the *target* baseline) + spawn **foundational ADRs** in `docs/adr/` for the irreversible picks (stack, module style, persistence). **Fill the machine-readable frontmatter keys** from the chosen foundation (`language`, `build_cmd`, `test_cmd`, `lint_cmd`, `migration_tool`, `frontend`) — here they encode the *decided* toolchain; anything not yet decided stays `""`. Record `reflects_commit`. **Validate the C4 Mermaid per [`../_shared/mermaid-check.md`](../_shared/mermaid-check.md)** before committing, and run the same step-4 structural self-check.43G6. **Emit the scaffold plan + hand off.** Write a scaffold `tasks.json` (the skeleton: folder/module structure, a baseline module, the test harness, migration tooling, CI, a `CLAUDE.md`/rules doc) per the contract in [`./references/foundation.md`](./references/foundation.md). Each task's DoD anchors on the **skeleton smoke test** — «the project builds + boots + the empty test suite runs + the migration tool runs» (canonical in [`../scaffold/SKILL.md`](../scaffold/SKILL.md)). Commit `survey: greenfield foundation + scaffold plan`. Then **emit the stage-handoff block** per [`../_shared/handoff.md`](../_shared/handoff.md) — *What I did* + *Review* (`docs/architecture-map.md`, `docs/adr/`, `docs/features/_scaffold/tasks.json`) + *Run next*: `/clear`, then `/sdd:scaffold` (it materializes the skeleton; the per-feature flow starts afterwards with `/sdd:specify <slug>`).4445## Definition of Done4647- `docs/architecture-map.md` exists with `updated_at` + `reflects_commit`; an authored doc (if any) was reconciled, never overwritten.48- **Brownfield:** C4 of what exists + module inventory + cited conventions + precedent guide, real anchors (no placeholders).49- **Greenfield:** foundation fixed (stack/structure/data/conventions) at the user's calibrated level + foundational ADRs + a scaffold `tasks.json` whose tasks carry the skeleton smoke-test DoD, ready for `/sdd:scaffold`.50- The step-4 **structural self-check** passed ([`../_shared/self-check.md`](../_shared/self-check.md)): machine keys explorer-backed or explicitly `""`, convention citations resolve, C4 validated, `reflects_commit` current; its result is reported in the handoff.5152## Anti-patterns5354- **Re-scanning the repo in every downstream skill** — the point is to scan once; others read the map (drift detection is the only re-read, of real domain files).55- **Overwriting a hand-maintained `docs/architecture.md`** — survey writes its own map and reconciles.56- **A map with no `reflects_commit`** — it silently rots; nobody knows it's stale.57- **Greenfield: a full product brief.** The foundation session picks the *architecture*, not the features — the idea/briefing is `specify`'s job, per feature. Keep it to intent + foundation choices.58- **Greenfield: ignoring the person's level.** A junior gets defaults + plain-language explanations; a senior gets control + terseness. One calibration question sets this — don't fire a senior-level wall of choices at a first-timer.59- **Placeholders / guessed layout** — cited or `UNKNOWN`; a fictional map is worse than none.6061## References & template6263- [`./references/foundation.md`](./references/foundation.md) — greenfield: the calibration question, level-adaptive depth, the stack/structure/convention choice menus + defaults, foundational-ADR list, and the scaffold `tasks.json` contract.64- [`./templates/architecture-map.md`](./templates/architecture-map.md) — output scaffold (same file for current OR foundation; a `mode:` marker distinguishes).65- [`../_shared/agent-roster.md`](../_shared/agent-roster.md) — the explorer contract.