Triggers: /project-audit, audit project, review claude config, sdd diagnostic, project health check
Read-only diagnostic of Claude/SDD config. Flow:
/project-audit → audit-report.md → /project-fix → /project-audit (verify). The
report IS the spec /project-fix implements. Kernel: discovery → evaluation →
report (stable; rules evolve). Save report at [project_root]/.claude/audit-report.md.
Sibling reference files — REPORT_TEMPLATE.md (output format), SCORING.md
(100-point distribution + interpretation), PHASE_A_SCRIPT.md (discovery script + schema).
Dimension classes
| Class | Dimensions | Score impact |
|---|---|---|
| Scored | D1, D2, D3, D4, D6, D8 | 95-pt score |
| Informational | D9, D10, D11, D12, D13, D14 | None |
D5 and D7 were removed. Informational dimensions never affect score unless stated.
Compatibility policy — global-config exemptions
IS_GLOBAL_CONFIG=1 → the methodology repo is not a consumer of its own
deployment. Skip table:
| Dim. | Check | Skip when global-config |
|---|---|---|
| D1 | Stack / package.json |
Skip |
| D1 | ## Architecture section |
Skip (in README) |
| D1 | Skills registry | Skip ALWAYS (Principle 2 — harness auto-discovers) |
| D1 | ai-context/ path refs |
Skip |
| D2 | Memory (ai-context/) |
Skip dim; N/A in score |
| D4a | Registry vs disk | Skip |
Rationale: ai-context/ is deployed BY this repo INTO consumer projects via
/project-setup — auditing the methodology repo for it is a category error.
Scoring: D2 → N/A; denominator becomes 70 (95 base − 25). Final = round(actual/70*100).
Process
Read real files. Never assume. Run dimensions systematically.
Phase A — Discovery
Run PHASE_A_SCRIPT.md once; capture key=value outputs; run the post-script
"Legacy commands/ detection". Max 3 Bash calls total per audit run.
Phase B — Per-dimension evaluation
Apply each dimension. Findings carry severity (CRITICAL/HIGH/MEDIUM/LOW/INFO) and optional FIX_MANIFEST entries.
Dimension 1 — CLAUDE.md
Project type detection: IS_GLOBAL_CONFIG=1 → global-config. Accept root
CLAUDE.md as equivalent to .claude/CLAUDE.md. Note Project Type in report.
| Check | Severity |
|---|---|
Exists .claude/CLAUDE.md (or root for global-config) |
CRITICAL |
| Not empty (>50 lines) | CRITICAL |
Has Stack section (## Tech Stack or ## Stack) |
CRITICAL |
| Stack has ≥ 3 technologies with explicit versions | CRITICAL |
Stack matches package.json / pyproject.toml |
HIGH |
Has ## Architecture section |
HIGH |
| Has Skills registry | HIGH |
| Has Unbreakable Rules section | MEDIUM |
| Has Plan Mode section | LOW |
Mentions SDD (/sdd-*) |
HIGH |
References to ai-context/ paths are correct |
MEDIUM |
Stack severity is CRITICAL per ADR-004 (every tech-reference skill routes on it). Exemptions under IS_GLOBAL_CONFIG=1: see "Compatibility policy".
Stack comparison: extract top 5–10 deps from package.json/equivalent,
compare with CLAUDE.md. Report discrepancies as declared X.Y, actual A.B.
Template path verification: locate ## Documentation Conventions section,
extract paths matching docs/templates/*.md, verify each exists. Each missing
→ MEDIUM + required_actions.medium type: create_file. Skip entirely if no
such pattern found.
Dimension 2 — Memory (ai-context/)
Skip entirely when IS_GLOBAL_CONFIG=1 — emit INFO "D2 skipped — global-config repos do not use ai-context/". D2 → N/A (25 pts excluded from denominator). See Compatibility policy.
For standard projects:
| File | Min lines | Note |
|---|---|---|
ai-context/stack.md |
> 30 | |
ai-context/architecture.md |
> 40 | |
ai-context/conventions.md |
> 30 | |
ai-context/known-issues.md |
> 10 | may be brief for new projects |
ai-context/changelog-ai.md |
> 5 | at least one entry |
Location may be ai-context/ or docs/ai-context/. Check both.
Content checks (per existing file):
stack.md: top-5 dependency versions matchpackage.json.architecture.md: directories named exist on disk.conventions.md: documented conventions appear in 2–3 sample real files.known-issues.md: real content vs.[To confirm]/[Empty]stubs.changelog-ai.md: at least one## YYYY-MM-DDentry.
Placeholder phrase detection — scan content for (case-insensitive in
brackets, case-sensitive for plain TODO): [To be filled], [empty],
[TBD], [placeholder], [To confirm], [Empty], plain uppercase TODO.
Each match → HIGH "[filename] appears to contain unfilled placeholder content". Treat the file as functionally empty even if line count passes.
Add to required_actions.high with type: update_file.
stack.md version count — count lines matching x.y, x.y.z, or vX.
< 3 → MEDIUM "stack.md lists fewer than 3 technologies with concrete versions — minimum is 3". Skip when stack.md absent or already placeholder.
User documentation freshness (for ai-context/scenarios.md and
ai-context/quick-reference.md):
- Absent → LOW
"[filename] missing — create via /project-onboard or manually". - Present → search first 10 lines for
^> Last verified: (\d{4}-\d{2}-\d{2})$. Missing/malformed → LOW. > 90 days old → LOW with age. All findings LOW, no D2 score deduction.
Dimension 3 — SDD Orchestrator
3a. Global SDD skills — 8 phase skills must exist in ~/.claude/skills/:
sdd-explore, sdd-propose, sdd-spec, sdd-design, sdd-tasks, sdd-apply,
sdd-verify, sdd-archive. Any missing → CRITICAL.
3b. Engram availability — call mem_context. Reachable → INFO log.
Unreachable → HIGH "Engram not reachable — SDD artifacts will not persist".
3c. CLAUDE.md mentions SDD — contains any /sdd-* → HIGH if absent;
section explaining SDD flow → LOW if absent.
3d. Orphaned changes — mem_search(query: "sdd/", project: "{project}"),
filter for state artifacts with last_updated > 14 days ago and no
archive-report. List them.
3e. Hook script existence — for each settings file present
(settings.json, .claude/settings.json, settings.local.json), locate
hooks key and extract script paths. Each missing on disk → HIGH +
required_actions.high type: create_file. Skip when no hooks key.
3f. Active changes conflict detection:
- Search engram for active changes (no
archive-report). Retrieve eachdesign.md. - Locate
## File Change Matrixtable. ExtractFilecolumn. Normalize: lowercase + strip leading./. - Skip if fewer than 2 active changes have a
design.md. - Intersect path sets. Each overlap → MEDIUM
"Concurrent file modification conflict: [path] is targeted by both [change-A] and [change-B]". Add toviolations[],rule: "D3-active-changes-conflict".
Normalization only handles lowercase + leading ./. Other format
inconsistencies are not caught.
Dimension 4 — Skills quality
4a. Registry vs disk (bidirectional): each skill in CLAUDE.md exists on disk; each skill on disk appears in CLAUDE.md. Report mismatches both ways.
Skip 4a when IS_GLOBAL_CONFIG=1 (no manual registry exists; Principle 2).
Emit INFO "D4a skipped — harness auto-discovery, not a manual registry".
4b and 4c still apply.
4b. Minimum content — for each skill file:
- < 30 lines → probable stub.
- Format-aware structural check (see
docs/format-types.md):- Parse YAML frontmatter, extract
format:. Absent → treat asprocedural. - Unknown value → INFO, treat as
procedural.
- Parse YAML frontmatter, extract
| Resolved format | Required sections | Finding if absent (MEDIUM) |
|---|---|---|
procedural |
## Process |
"procedural skill [name] missing ## Process section" |
reference |
At least one of ## Patterns/## Critical Patterns AND one of ## Examples/## Code Examples |
"reference skill [name] missing (## Patterns or ## Critical Patterns) or (## Examples or ## Code Examples)" |
anti-pattern |
## Anti-patterns OR ## Critical Patterns |
"anti-pattern skill [name] missing ## Anti-patterns or ## Critical Patterns section" |
Missing **Triggers** or ## Rules → MEDIUM for all formats. Missing
## Process is NOT a finding for reference/anti-pattern.
Each finding → required_actions.medium,
type: skill_quality_action,
action_type: add_missing_section,
target: [skill path],
missing_sections: ["[heading]"].
4c. Relevant tech skills coverage (scored 0–10 pts):
Stack → skill mapping: React 18+ → react-19, Next.js 14+ → nextjs-15,
TypeScript → typescript, Zustand → zustand-5, Tailwind → tailwind-4,
Zod → zod-4, Playwright → playwright, Prisma → prisma,
React Native / Expo → react-native, Go → go-testing.
Coverage rule (tech-skill locality policy): a skill counts as "covered"
if it exists EITHER in the project's local .claude/skills/<name>/ OR in the
global ~/.claude/skills/<name>/. Tech skills are expected to live locally;
only meta/orchestrator skills are expected globally. Penalizing a project
for not having zod-4 globally when it has it locally is a category error.
| Coverage of applicable skills | Points |
|---|---|
| 100% covered OR no applicable | 10 |
| ≥ 75% | 8 |
| 50–74% | 5 |
| 25–49% | 2 |
| < 25% | 0 |
"Applicable" = project uses the tech AND a matching skill exists locally or globally. D4 max: 20 pts (4a+4b = 10; 4c = 10).
Dimension 6 — Cross-reference integrity
Everything referenced in the Claude configuration must exist on disk.
| Source | Target |
|---|---|
## Documentation in CLAUDE.md |
.claude/docs/ |
| Templates section in CLAUDE.md | .claude/templates/ |
| Paths inside skills | /lib/, /domain/, pages/api/, etc. |
ai-context/architecture.md dirs |
Project filesystem |
| Skills referenced in commands | The skill file |
Each broken reference: source file, approximate line, missing path.
Dimension 8 — Testing & verification
8a. Test runner configured or detectable → HIGH if missing. Documented
testing strategy in ai-context/ → MEDIUM if missing.
8b. For each archive-report in engram, verify a verify-report exists and references tool execution results. Missing → HIGH.
8c. For each active change with tasks, verify the task plan includes
verification criteria. For each with design, verify the design defines test
approach.
Dimension 9 — Project skills quality (informational)
Skip when $LOCAL_SKILLS_DIR does not exist — emit "No [value] directory found — Dimension 9 skipped". No deduction.
Global-config circular detection: when auditing the global-config repo,
every subdir under skills/ has a matching counterpart in ~/.claude/skills/
(same files via install.sh). Disposition keep for all — expected.
D9-2 Duplicate — for each subdir under $LOCAL_SKILLS_DIR:
~/.claude/skills/<name>/ exists → disposition move-to-global (if differs)
or delete (if identical). Global catalog unreadable → INFO, disposition
keep.
D9-3 Structural completeness — apply D4b format-aware check. Missing
required section OR missing SKILL.md → disposition update, action
add_missing_section.
D9-4 Language compliance — D4e heuristic on body text outside fenced
code. Non-English prose → disposition update, action
flag_language_violation, severity INFO (no deduction).
D9-5 Stack relevance — technology references in trigger line and title.
If absent from both ai-context/stack.md AND package.json/pyproject.toml
→ disposition update, action flag_irrelevant, severity INFO. No stack
source → emit "Stack relevance check skipped — no stack source found".
Dimension 10 — Feature docs coverage (informational)
Skip when no features detected.
Config-driven — if project config.yaml has feature_docs: key, read
convention (skill|markdown|mixed), paths, and feature_detection.
Heuristic fallback — sources, in order:
- Non-SDD skills in
$LOCAL_SKILLS_DIR(names not starting withsdd-,project-,memory-,skill-). *.mdfiles indocs/features/ordocs/modules/.- Subdirs of
src/features/,src/modules/,app/with aREADME.md.
Exclude always: shared, utils, common, lib, types, hooks,
components. Empty after exclusions → emit "No feature directories detected — Dimension 10 skipped".
Per-feature checks:
- D10-a Coverage: PASS if doc exists per convention; FAIL otherwise.
- D10-b Structure: SKILL.md → PASS if frontmatter +
**Triggers**+## Process+## Rules. Other.md→ PASS if H1 + ≥1 H2. - D10-c Freshness: extract paths
/src/[^\s]+,/lib/[^\s]+,/app/[^\s]+. Each missing → flag stale. - D10-d Registry alignment: SKILL.md in
.claude/skills/not in CLAUDE.md registry → INFO (not a warning).
D10 findings MUST NOT appear in required_actions or skill_quality_actions.
Dimension 11 — Internal coherence (informational)
Read/Glob/Grep only — no Bash. Skip when neither $LOCAL_SKILLS_DIR nor root
CLAUDE.md exists.
D11-a Count consistency — extract claims via
CLAIM_PATTERN = /(\d+)\s+(Dimensions?|Steps?|Rules?|Phases?|Checks?|Sub-checks?)/i
from headings and blockquote lines. Count matching body sections. Mismatch →
INFO. Do NOT match inside code blocks.
D11-b Numbering continuity — patterns:
/^#{2,3}\s+.*Step\s+(\d+)/im, Dimension\s+(\d+), Phase\s+(\d+),
/^#{2,4}\s+.*D(\d+)/m. Sort numbers, detect gaps and duplicates. ≥ 2
members required. Severity INFO.
D11-c Frontmatter-body alignment — if description has a numeric claim,
verify via D11-a logic. Mismatch → INFO.
All D11 findings → violations[], severity info, rule names
D11-count-consistency, D11-numbering-continuity,
D11-frontmatter-body. Never in required_actions.
Dimension 12 — ADR coverage (informational)
Activation: CLAUDE.md contains string docs/adr/. If absent → emit INFO,
skip.
D12-1: ADR_README_EXISTS=0 → HIGH "CLAUDE.md references docs/adr/ but docs/adr/README.md is missing" + required_actions.high
type: create_file.
D12-2: Glob docs/adr/NNN-*.md. No matches → INFO "docs/adr/ contains no ADR files yet". Each ADR: search ## Status heading or frontmatter
status: field. Neither → MEDIUM "ADR file [filename] is missing a valid status field" + required_actions.medium type: update_file. Valid:
accepted, deprecated, superseded; custom allowed, do not validate value.
Dimension 13 — Spec coverage (informational)
Activation: Engram reachable AND mem_search(query: "sdd/") returns spec
artifacts.
D13-1: For each spec.md, extract path-like references (contain /, no
spaces, not in URLs or fenced code). Check existence at
[project_root]/[path]. Missing → INFO "Spec artifact references a path that no longer exists: [path]". Add to violations[],
rule: "D13-stale-path-reference", severity: "info",
file: "engram spec artifact". INFO findings NOT in required_actions.
Dimension 14 — Budget compliance (informational)
Runs on every audit.
- Read the active CLAUDE.md; count characters. Resolve its path the same way
D1 does:
.claude/CLAUDE.mdwhen present, else rootCLAUDE.md(root is the canonical location only underIS_GLOBAL_CONFIG=1). Neither present → INFO"No CLAUDE.md found — budget check skipped"and stop. - Global-config (install.sh + sync.sh exist) → 20,000 char budget; otherwise → 5,000.
- Over budget → INFO
"CLAUDE.md is [N] chars ([N-budget] over [budget] budget). Consider extracting content to skills (ADR-041)". - Within → INFO
"CLAUDE.md budget OK: [N]/[budget] chars".
Findings go in ## Budget Compliance section. No score impact.
Report
Save at [project_root]/.claude/audit-report.md using the exact structure in
REPORT_TEMPLATE.md. Scoring distribution and interpretation live in
SCORING.md.
Rules
- Always read real files. Never assume content.
- Run in a subagent with read tools. Never in main context.
- Always save the report at
.claude/audit-report.mdbefore presenting. - The FIX_MANIFEST is valid YAML. Verify the block parses.
- Never modify anything. 100% read-only.
- If a file cannot be read, report
❌with the exact error. Do not assume absence. - When finished:
"Report saved in .claude/audit-report.md. To implement: /project-fix". - All shell discovery in Phase A. Max 3 Bash calls per run. No per-dimension
ls/grep/wc -l/find. - Compatibility behavior is explicit, not implicit in a dimension.