Audita un proyecto EXISTENTE (con código + docs) y produce un mapa navegable (PROJECT-MAP.md + MODULES-MATRIX.md + TECH-DEBT.md + STARTER-KIT-PLAN.md). Detecta stack, topología, módulos, capabilities, conventions. NO ejecuta /pm-bootstrap (greenfield). Use cuando Chris dice: '/project-audit', 'auditá el proyecto', 'mapeá esto', 'qué tenemos acá', 'analiza el repo', 'adopta este código al método Luana', 'baseline del proyecto'.
76
96%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Cuándo se usa: Chris clona/abre un proyecto existente (legacy o externo) y quiere que Claude entienda el proyecto antes de tocar nada, para evitar reinventar componentes que ya existen. Cuándo NO se usa: proyecto greenfield (vacío) — usar
/project-bootstrapen su lugar.
| Input | Default | Notas |
|---|---|---|
<project-root> | $(git rev-parse --show-toplevel) (o cwd si no es git) | Path del proyecto a auditar |
<stack-hint> | auto-detect | Opcional: python+fastapi / node+nextjs / rust+actix / etc. |
<depth> | standard | shallow (solo estructura) / standard (+ módulos) / deep (+ tech-debt) |
ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
cd $ROOT
# Detection layers (order matters — first match wins)
[ -f pyproject.toml ] && echo "Python (uv/poetry/pip)"
[ -f Pipfile ] && echo "Python (pipenv)"
[ -f package.json ] && echo "Node/TypeScript"
[ -f pnpm-workspace.yaml ] && echo " → pnpm workspace"
[ -f yarn.lock ] && echo " → yarn"
[ -f Cargo.toml ] && echo "Rust"
[ -f go.mod ] && echo "Go"
[ -f composer.json ] && echo "PHP"
[ -f Gemfile ] && echo "Ruby"
[ -f mix.exs ] && echo "Elixir"
# Framework hints (BE)
grep -l "fastapi" pyproject.toml requirements*.txt 2>/dev/null && echo " framework: FastAPI"
grep -l "django" pyproject.toml requirements*.txt 2>/dev/null && echo " framework: Django"
grep -l "flask" pyproject.toml requirements*.txt 2>/dev/null && echo " framework: Flask"
grep -l "next" package.json 2>/dev/null && echo " framework: Next.js"
grep -l "vite" package.json 2>/dev/null && echo " framework: Vite"
grep -l "react" package.json 2>/dev/null && echo " framework: React"
# Auth provider
grep -rl "clerk" package.json pyproject.toml 2>/dev/null && echo " auth: Clerk"
grep -rl "auth0" package.json pyproject.toml 2>/dev/null && echo " auth: Auth0"
grep -rl "supabase" package.json pyproject.toml 2>/dev/null && echo " auth: Supabase"
# DB
grep -rl "sqlalchemy" pyproject.toml 2>/dev/null && echo " orm: SQLAlchemy"
grep -rl "prisma" package.json 2>/dev/null && echo " orm: Prisma"
grep -rl "drizzle" package.json 2>/dev/null && echo " orm: Drizzle"# DDD pattern detection
[ -d backend/src/modules ] || [ -d src/modules ] && echo "BE topology: DDD modular"
[ -d backend/src/domains ] && echo "BE topology: DDD domains"
[ -d src/domain ] && [ -d src/infrastructure ] && echo "BE topology: hexagonal"
# FSD pattern detection
[ -d frontend/src/features ] && echo "FE topology: FSD"
[ -d frontend/src/app ] && echo "FE topology: Next.js App Router"
[ -d frontend/src/pages ] && echo "FE topology: Next.js Pages (legacy)"
# Monorepo vs single
[ -f pnpm-workspace.yaml ] || [ -f turbo.json ] || [ -f nx.json ] && echo "Layout: monorepo"
# Tests location
find . -type d -name tests -not -path '*/node_modules/*' -not -path '*/.venv/*' 2>/dev/null | head -5
find . -type d -name __tests__ -not -path '*/node_modules/*' 2>/dev/null | head -5
find . -type d -name e2e -not -path '*/node_modules/*' 2>/dev/null | head -3
# Docker / runtime
[ -f docker-compose.yml ] && echo "Runtime: docker-compose"
[ -f docker-compose.dev.yml ] && echo "Runtime: docker-compose.dev"
[ -d k8s ] || [ -d kubernetes ] && echo "Deploy: kubernetes"
[ -d terraform ] && echo "Infra: terraform"Para cada módulo BE detectado:
for m in backend/src/modules/*/; do
MODULE=$(basename "$m")
echo "## Module: $MODULE"
[ -d "$m/domain" ] && find "$m/domain" -name "*.py" | head -10
[ -d "$m/api" ] && find "$m/api" -name "*.py" | head -10
[ -d "$m/application" ] && find "$m/application" -name "*.py" | head -10
[ -d "$m/infrastructure" ] && find "$m/infrastructure" -name "*.py" | head -10
donePara cada feature FE detectada:
for f in frontend/src/features/*/; do
FEATURE=$(basename "$f")
echo "## Feature: $FEATURE"
find "$f" -type f \( -name "*.tsx" -o -name "*.ts" \) | head -15
done# Standard Luana location
[ -d docs/product/capabilities ] && find docs/product/capabilities -name "*.yaml" -o -name "*.md" | head -30
# Common alternatives
[ -d docs/capabilities ] && find docs/capabilities -type f | head -20
[ -d docs/features ] && find docs/features -type f | head -20
[ -d CAPABILITIES.md ] && cat CAPABILITIES.md | head -50Si NO existen → inferir desde routes/endpoints + nombres de módulos (Phase 5).
# FastAPI routes
grep -rn "@router\.(get\|post\|put\|delete\|patch)" backend/src/ 2>/dev/null | head -30
# Next.js routes
find frontend/src/app -name "page.tsx" -o -name "route.ts" 2>/dev/null | head -30
# Django URLs
grep -rn "path(" backend/*/urls.py 2>/dev/null | head -20| Convention | Probe |
|---|---|
| Tenant isolation | grep -rn "tenant_id" backend/src/ | wc -l (cuanto más alto, más probable que esté presente) |
| Soft deletes | grep -rn "deleted_at" backend/src/ | wc -l |
| Async SQLA 2.0 | grep -rn "select(.*).where" backend/src/ | wc -l vs grep -rn "session.query" backend/src/ | wc -l |
| Pydantic v2 | grep -rn "model_config = ConfigDict" backend/src/ | wc -l |
| Server Components | grep -rn "\"use client\"" frontend/src/ | wc -l (cuanto MENOR, más SC-first) |
| React Query | grep -rl "useQuery|useMutation" frontend/src/ | wc -l |
| RHF + Zod | grep -rl "useForm|zodResolver" frontend/src/ | wc -l |
| Conventional Commits | git log --oneline -50 | grep -E "^[a-f0-9]+ (feat|fix|chore|docs|test)" | wc -l |
Ejecutar (suaves, capturar output):
# Python
[ -f pyproject.toml ] && ruff check . --statistics 2>&1 | tail -20
[ -f pyproject.toml ] && python -m pytest --collect-only -q 2>&1 | tail -5
# Node
[ -f package.json ] && npx tsc --noEmit 2>&1 | tail -5
[ -f package.json ] && npx eslint src/ 2>&1 | tail -5
# Coverage actual si reportes existen
[ -f coverage/coverage-final.json ] && echo "FE coverage report exists"
[ -f .coverage ] && echo "BE coverage data exists"# Missing tenant_id (BE)
grep -rn "select(" backend/src/ 2>/dev/null | grep -v "tenant_id" | wc -l
# Hard deletes
grep -rn "session.delete\|repo.delete\b" backend/src/ 2>/dev/null
# Framework imports in domain layer (DDD violation)
grep -rn "from fastapi\|from sqlalchemy" backend/src/modules/*/domain/ 2>/dev/null
# any types (TS)
grep -rn ": any\b" frontend/src/ 2>/dev/null | wc -l
# console.log in production code
grep -rn "console\.log" frontend/src/ 2>/dev/null | grep -v test | wc -l
# TODO/HACK/FIXME count
grep -rn "TODO\|HACK\|FIXME\|XXX" backend/src/ frontend/src/ 2>/dev/null | wc -ldocs/PROJECT-MAP.mdVista navegable única. Schema:
# PROJECT-MAP.md
> Auto-gen via `python scripts/generate_project_map.py`. NO editar manual.
> Source: código + docs/product/capabilities/ + docs/product/modules/ + git log
> Last regen: {ISO date}
## Overview
- **Project:** {name auto-detected from package.json/pyproject.toml/folder name}
- **Stack:** {detected — ej "FastAPI async + Next.js 16 + Clerk + Postgres + Qdrant"}
- **Topology:** {DDD modular / FSD / monorepo / etc.}
- **Phase:** {bootstrap | development | maintenance | sunset}
- **Last touched:** {git log -1 timestamp}
- **Method version:** Luana method v0.1
## Architecture snapshot
[ASCII diagram inline OR link a docs/architecture/project-overview.md][project]/ ├── backend/src/modules/{m1,m2,m3}/ ├── frontend/src/{app,features,components}/ ├── docs/{product,architecture,process}/ ├── scripts/ └── .claude/
## Modules
| Module | Path | Capa | Capabilities | Endpoints | Tests coverage | Status |
|---|---|---|---|---|---|---|
| {m1} | backend/src/modules/{m1} | core | {cap1, cap2} | 5 | 82% | live |
| {m2} | backend/src/modules/{m2} | crm | {cap3} | 3 | 45% | planned |
## Frontend features
| Feature | Path | Components | Hooks | Tests | Status |
|---|---|---|---|---|---|
| {f1} | frontend/src/features/{f1} | 8 | 4 | 12 | live |
## Capabilities ledger
| Module | Capability | Status | Date introduced | Story |
|---|---|---|---|---|
| {m1} | {cap-x} | live | 2026-03-15 | {story-id} |
## Active stories
[Auto-gen from docs/product/stories/*/checkpoint.md state ∈ {refining, refined, ready, developing, developed, reviewing}]
| Story | State | Phase | Last touched |
|---|---|---|---|
## Recent merges (last 30 days)
[Auto-gen from docs/archive/{year}/stories/]
| Story | Merged | Outcome |
|---|---|---|
## Conventions snapshot
- Tenant isolation: ✅ pattern detected ({N} queries filter `tenant_id`) | ⚠️ missing in {paths} | ❌ no pattern
- DDD layering: ✅ {N}/{N} modules pass boundary check | ⚠️ {N} violations en {paths}
- FSD boundaries: ✅ {N}/{N} features pass | ⚠️ {N} violations
- Tests coverage: BE {X}%, FE {Y}%
- Async SQLA 2.0: ✅ {N} async / ⚠️ {M} legacy sync
- Spanish neutro UI: {detected? sí/no/N/A}
- Conventional Commits: {detected? %}
## Tech-debt outstanding
[Pointer to docs/TECH-DEBT.md]
- {N} TODO/HACK/FIXME markers
- {N} `any` types (TS)
- {N} console.log in production code
- {N} potential missing tenant_id filtersdocs/MODULES-MATRIX.md (opt-in detail)Tabla extendida si depth=deep: por módulo include entities (@dataclass(frozen=True)), services (*Service), repos (*Repository), DTOs (BaseModel), tests count, dependencies cross-module.
docs/TECH-DEBT.md + docs/STARTER-KIT-PLAN.mdTECH-DEBT.md:
# TECH-DEBT.md
> Findings auto-gen via /project-audit deep mode. Re-run quarterly.
> Severity scale: CRITICAL / HIGH / MEDIUM / LOW.
## CRITICAL
- [ ] Missing tenant_id filter en N queries: {paths}
- [ ] Hard deletes detectados (no soft delete): {paths}
- [ ] Framework imports en domain layer (DDD violation): {paths}
## HIGH
- [ ] `any` types en {N} archivos TS: {paths}
- [ ] Migrations no-idempotentes (op.create_table sin IF NOT EXISTS): {paths}
- [ ] Mocks de paths obsoletos: {paths}
## MEDIUM
- [ ] TODO/HACK/FIXME outstanding ({N} markers)
- [ ] Tests coverage BE {X}% < threshold 43%
- [ ] Tests coverage FE {Y}% < threshold 20%
## LOW
- [ ] {N} console.log en production code
- [ ] {N} eslint-disable sin justificaciónSTARTER-KIT-PLAN.md:
# STARTER-KIT-PLAN.md — Adopción incremental del método Luana
> ¿Qué pieces del método ya tiene el proyecto? ¿Qué falta?
> Generado por /project-audit. Re-run cuando agregás piezas.
## Métodos ya presentes
- ✅ DDD layering (backend/src/modules/{m}/{domain,infrastructure,application,api})
- ✅ FSD-Lite (frontend/src/{app,features,components,lib})
- ⚠️ Story-folder schema parcial (existe `docs/stories/` con format custom — migrar a docs/product/stories/{id}/01-spec.md etc.)
- ❌ Worktree protocol — no usado
- ❌ Auditor flow — no implementado
- ❌ Quality gates pre-commit hook — no instalado
- ❌ Skills .claude/ — no presentes
## Plan adopción incremental
### Quick wins (1 día)
1. Instalar `.claude/` skeleton (skills + rules + agents + hooks)
2. Instalar `docs/specs/templates/` (story-folder schema)
3. Instalar pre-commit hook básico (voseo + ruff + format)
### Mediano plazo (1 semana)
4. Migrar stories existentes a schema canónico (01-spec.md + 06-tickets.yaml + checkpoint.md)
5. Crear `docs/product/checkpoint.md` global
6. Crear `docs/PROJECT-MAP.md` auto-gen
7. Setup worktrees + scripts/git/ workflow
### Largo plazo (2-4 semanas)
8. Refactor tech-debt CRITICAL → ver TECH-DEBT.md
9. Setup auditor agents + workflow
10. CI/CD wip/* light gates + main full gates
## Comandos rápidos
```bash
# Adopt pre-commit hook
ln -sf $(pwd)/scripts/git-hooks/pre-commit .git/hooks/pre-commit
# Generate first PROJECT-MAP
python scripts/generate_project_map.py
# Bootstrap primer outcome
/pm### Phase 12 — Adversarial validation (spawn context-validator)
Antes de cerrar, spawn `context-validator` Haiku para que adversarialmente:
- Re-grep duplicate scan con synonym keywords
- Spot-check 3 claims random del PROJECT-MAP
- Marcar gaps con severidad
Si flag `blocking` → STOP, reportar findings al user. Si `partial` → seguir + citar gaps en STARTER-KIT-PLAN.
## Output finaldocs/ ├── PROJECT-MAP.md (Phase 9 — vista navegable principal) ├── MODULES-MATRIX.md (Phase 10 — opt-in si depth=deep) ├── TECH-DEBT.md (Phase 11 — opt-in si depth=deep) └── STARTER-KIT-PLAN.md (Phase 11 — recomendaciones adopción método)
Y el último mensaje al user:✅ Project audit complete.
Project: {name} Stack: {stack-detected} Topology: {topology} Modules: {N} Capabilities: {M} Active stories: {K} Tech-debt severity: {CRITICAL:N HIGH:M MEDIUM:K LOW:J}
Artifacts:
Next steps:
## Cost guardrails
- Phase 1-3: Haiku 4.5 sufficient (~5k tokens)
- Phase 4-6: Sonnet (~10-15k tokens depending on project size)
- Phase 7-9: Opus si proyecto complejo (~20-30k tokens)
- Phase 10-12: Opus + Haiku validator (~10k extra)
Total proyecto mediano: ~30-50k tokens consumo. Big project: ~80-120k. Si excede 150k → split into multiple invocations (drill-down por módulo).
## Anti-patterns
- ❌ Asumir paths Luana (`{brand}/backend/`) — siempre detectar topología real
- ❌ Sobreescribir docs existentes — preservar contenido user + agregar referencias en PROJECT-MAP
- ❌ Generar TECH-DEBT.md sin spot-check (auto-detect tiene false positives — validar muestra antes de marcar CRITICAL)
- ❌ Recomendar adopción big-bang — el plan SIEMPRE es incremental (quick wins → medio → largo)
- ❌ Skip Phase 12 (adversarial validation) — protege contra hallucinations en PROJECT-MAP
## Referencias
- `.claude/skills/project-bootstrap/SKILL.md` — el complemento (greenfield)
- `.claude/skills/pm/SKILL.md` — destino post-audit
- `scripts/generate_project_map.py` — regenerador idempotente
- `docs/specs/templates/` — schemas que aplicarías al adoptcaa08df
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.