# Project Blueprint

> 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.

- Skill: `carlitose/project-blueprint` (Agent Skill, multi-file: 7 files)
- Install (CLI): `npx skillmds@latest add carlitose/project-blueprint`
- Raw SKILL.md: https://api.skillmd.com/api/skills/carlitose/project-blueprint/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Product & Planning
- Author: carlitose (https://skillmd.com/u/carlitose)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/carlitose/project-blueprint

---


# 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

1. **Discovery over theory**. Find patterns by reading structure, not by applying DDD/Hexagonal/Clean checklists.
2. **Human-in-the-loop**. Pause and ask whenever judgment is needed. Don't invent names. Don't classify ambiguous things.
3. **Blueprint is the only persistent artifact**. Audits and PR reviews are ephemeral outputs of running the blueprint against code — they don't get committed.
4. **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.
5. **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:

```bash
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**:

1. List directories at depth 2-3 from project root
2. For each, capture its child filenames
3. Cluster directories whose child filenames match the same regex/pattern
4. Clusters with **N ≥ 2** instances → candidate slices
5. 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):
1. Exercises the full shape non-trivially (no empty files)
2. Has accompanying tests
3. Recently modified (≤ 6 months)
4. No findings against it in audit history
5. Descriptive name
6. 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

