| name | project-blueprint |
| description | Discover the architectural slices, conventions, and patterns of a codebase by examining its structure, then output a written BLUEPRINT.md per project under docs/architecture (plus a SYSTEM_MAP.md for monorepos) that captures what the project actually does. Discovery means finding repeated structural patterns (slices) from folder shapes and naming conventions, not applying architectural theory. Detects monorepos with sub-projects, internal dimensions like voice/text verticals, and slice variants. Human-in-the-loop by design — pauses to ask about singletons vs templates, canonical reference selection, slice naming, and pre-write confirmation. Use whenever the user wants to map a codebase, onboard onto a project, document architecture, understand "how does this team add X", build a slice catalog, or generate a reference document for new contributors. |
Project Blueprint
Map a codebase by discovering its slices — repeated structural patterns that show up when a dev adds new work of the same kind. Output a written reference that captures what the project actually does, not what it should do.
This skill is descriptive, not prescriptive. It documents reality.
Core principles
- Discovery over theory. Find patterns by reading structure, not by applying DDD/Hexagonal/Clean checklists.
- Human-in-the-loop. Pause and ask whenever judgment is needed. Don't invent names. Don't classify ambiguous things.
- Blueprint is the only persistent artifact. Audits and PR reviews are ephemeral outputs of running the blueprint against code — they don't get committed.
- Evidence over assertions. Every claim points to a real path/file/line. If you can't point to evidence, mark with ⚠️ or move to open questions.
- Respect conscious decisions. A choice documented in
CLAUDE.md or a decision spec is not an anti-pattern. Only undocumented divergences are.
What this skill produces
| Situation | Output files |
|---|
| Single project | docs/architecture/BLUEPRINT.md |
| Monorepo with N projects | docs/architecture/SYSTEM_MAP.md + docs/architecture/<project>/BLUEPRINT.md per project |
Optional cross-cutting findings (UNIVERSAL_NOTES.md) are NOT generated by default — they're emitted to chat when the user explicitly asks for a universal sweep.
Workflow
Step 1 — Detect monorepo vs single project
Find every manifest file at top-level through depth 3:
find . -maxdepth 3 -type f \( \
-name '*.csproj' -o -name '*.sln' \
-o -name 'package.json' \
-o -name 'pyproject.toml' -o -name 'requirements.txt' -o -name 'setup.py' -o -name 'Pipfile' \
-o -name 'go.mod' \
-o -name 'Cargo.toml' \
-o -name 'pom.xml' -o -name 'build.gradle' -o -name 'build.gradle.kts' \
-o -name 'composer.json' -o -name 'Gemfile' -o -name 'mix.exs' \
\) -not -path '*/node_modules/*' -not -path '*/.venv/*'
Group manifests by directory. Each top-level or depth-2 directory with a manifest is a sub-project candidate. Ignore dependency, build, cache, generated, and vendor folders.
⏸ Stop-and-ask checkpoint 1:
"Detected these N projects: [list]. Is this correct? Anything missing or wrongly included?"
Wait for confirmation. Don't proceed if uncertain.
Step 2 — Per project, Phase A: Stack and layers
For each confirmed project, read:
- Manifest file → language, framework version, key dependencies
README.md, CLAUDE.md, docs/architecture* → declared conventions, prohibited libraries, migration notes
.csproj references / package.json workspaces / go.mod modules → inter-module dependency graph
Map the layer structure if visible:
- For .NET:
Api → Application → Domain ← Infrastructure / Persistence
- For Node/Python/Go: equivalent if it exists; otherwise note "flat structure"
Step 3 — Per project, Phase B: Vocabulary detection
Walk the directory tree (depth 3-4, excluding bin/obj/node_modules/.venv/dist/target/__pycache__).
For each building block, check if it's instantiated:
| Building block | How to detect |
|---|
| Entity / Aggregate | Domain folder with classes carrying id + invariants |
| Value object | Small immutable types with equality by value |
| Repository | I*Repository ports + implementations |
| Domain service | Service classes in Domain |
| Application service / Use case | Orchestrator classes (services, use cases, command handlers) |
| Domain event | Event types + publish points |
| Driver adapter | HTTP controllers, CLI handlers, WebSocket, queue consumers |
| Driven adapter | DB, HTTP clients, message producers |
| Port (interface) | I* in Domain (or Application — note as asymmetry if so) |
| Options / Config class | Typed config bound from IConfiguration / settings |
Reference references/patterns.md for the architectural pattern signatures (DDD, Hexagonal, Clean, Layered, CQRS, etc.) when needed to label what you found.
Step 4 — Per project, Phase C: Slice discovery
A slice is a repeated folder/file shape — the structural template a dev follows when adding new work of the same kind.
Detection method:
- List directories at depth 2-3 from project root
- For each, capture its child filenames
- Cluster directories whose child filenames match the same regex/pattern
- Clusters with N ≥ 2 instances → candidate slices
- Clusters with N = 1 → singleton candidates (require human classification)
For each candidate slice with N ≥ 2:
- Shape: regex of filenames that define membership
- Instances: full list of paths, tagged by dimension if applicable (see Step 5)
- Canonical reference: pick using the heuristic below
- Co-created files: what else gets added in the same commit (DI registration, test mirror, controller endpoint, options class)
- Constraints: imports allowed/forbidden, naming, framework choices observed in the canonical
- Variants: instances deviating from the canonical shape; describe HOW they differ
- Status:
active (preferred for new work) / frozen (legacy, do not extend) / deprecated (will be removed)
Canonical selection heuristic (priority order):
- Exercises the full shape non-trivially (no empty files)
- Has accompanying tests
- Recently modified (≤ 6 months)
- No findings against it in audit history
- Descriptive name
- Non-trivial Response/output
If two instances tie on the heuristic, use two-tier canonical: Primary (start here, simpler) + Advanced (richer example).
⏸ Stop-and-ask checkpoint 2 (if needed):
"Slice X has these two equally-strong canonicals: A and B. Which is Primary, which is Advanced? Or are they co-canonical?"
Step 5 — Detect dimensions (within a single project)
Look for folder/namespace patterns separating internal verticals:
- Channel-based: e.g.
Voice* vs Whatsapp* markers in a project with multiple input channels
- Tenant-based: e.g.
Internal* vs External* markers
- Module-based: explicitly named bounded contexts
If found, tag every slice instance with its dimension (voice | text | channel-agnostic | etc.).
⏸ Stop-and-ask checkpoint 3:
"Detected dimension X with markers [...]. Confirm or correct the dimension labels."
Step 6 — Classify N=1 candidates
Collect everything found with N=1 into a list. For each, ask one question:
⏸ Stop-and-ask checkpoint 4 (group all N=1 in one batch):
"Found N N=1 candidates. For each, classify:"
• [path/name]: singleton (unique role, never replicated) | template (first of its kind, more coming) | smell (should have been split into multiple)?
Wait for batch answer before proceeding.
Step 7 — Cross-cutting conventions and asymmetries
Capture rules that span the project but aren't slices:
- Mappers — where they live by boundary
- Serialization — JSON case, BSON, etc.
- Validation — framework and registration
- Error model — envelope shape, code conventions
- Dependency direction — confirmed from manifest graph
- Logging / tracing — single source, conventions
Document known asymmetries explicitly — historic placements, naming exceptions, migration in flight. A reader needs to know "this is weird but intentional" so they don't try to "fix" it.
Step 8 — (Monorepo only) Build the SYSTEM_MAP
After per-project blueprints exist, build the system map covering:
- Project inventory with role of each
- Cross-project calls (caller → callee → protocol → contract)
- Cross-language boundaries explicit, with rules
- Same-language boundaries if any
- Shared external dependencies (databases, SaaS, queues)
For each cross-project boundary, note:
- Who owns the contract
- What kind of change needs coordination
- Mitigations in place
Step 9 — Pre-write summary
Before writing any file, present:
Summary
- Projects: [list]
- Slices per project: [count]
- N=1 classified as: [singletons | templates | smells]
- Dimensions: [if any]
- Files to be written: [list of paths]
⏸ Stop-and-ask checkpoint 5:
"Proceed to write the files above? Or adjust first?"
Step 10 — Write the files
Only after confirmation. Use assets/blueprint-template.md and assets/system-map-template.md as structure.
After writing, present each file path and offer: "Want me to commit these, or are you reviewing first?" Don't commit without explicit go-ahead.
Stop-and-ask checkpoints summary
| # | Checkpoint | When |
|---|
| 1 | Project list | After Step 1 (always) |
| 2 | Canonical tie-breakers | During Step 4 (only if ambiguous) |
| 3 | Dimension labels | After Step 5 (only if dimensions detected) |
| 4 | N=1 classification | After Step 6 (always, batched) |
| 5 | Pre-write | Before Step 10 (always) |
Optional asks during the run when something genuinely ambiguous appears:
- Slice naming when the shape is clear but the name isn't obvious
- Variant classification (deliberate variant vs accidental divergence)
- Status of a slice (active / frozen / deprecated) when CLAUDE.md doesn't say
What the agent observes vs what the human decides
The agent observes (factual, no asking):
- Folder shapes and their repetition counts
- Imports between modules
- File sizes, method counts
- Default values in source
- Existence of tests/DI registrations
- Matches against architectural pattern signatures
Human decides (always ask):
- Singleton vs template vs smell for N=1
- Slice names when not obvious
- Primary vs advanced canonical when tied
- Whether a variant is deliberate
- Status (active/frozen/deprecated) when undocumented
This separation matters: if the agent guesses on the human's decisions, the blueprint becomes opinion-laden. If the human supplies the judgment, the blueprint stays grounded.
What this skill does NOT do
- Generate anti-pattern audits as persistent files (use
pr-antipattern-review for diffs, or run a universal sweep ephemerally if asked)
- Recommend refactors
- Compare PRs against the blueprint (use
pr-antipattern-review)
- Make architectural decisions for the team
See also
references/slice-discovery.md — detailed heuristics for finding slices
references/patterns.md — architectural pattern signatures (DDD, Hexagonal, Clean, etc.)
references/universal-checks.md — project-independent observations (emitted on demand only)
assets/blueprint-template.md — output template per project
assets/system-map-template.md — output template for monorepos