| name | doctor |
| description | Per-project invariant checker. Runs automated checks derived from the project's architecture.md Non-Negotiables (§12). Must complete in < 5 seconds. Invoked automatically by /ship-it before format/lint/test/build. Generalizes /bb3-doctor to work for any ADF project. |
doctor — Per-Project Invariant Checker
You are verifying that the current code does not violate any project-level invariants. This is a FAST check (< 5 seconds) that runs BEFORE format/lint/test/build because invariant violations are architectural — they indicate you're building the wrong thing, not that you made a typo.
Step 1 — Identify the active project
Determine which project's invariants to check:
- Check
git status --porcelain to see which files are modified.
- Match modified files against project paths in
docs/program-plan.csv or the module registry in CLAUDE.md.
- If files match multiple projects, run checks for ALL matching projects.
- If no project match is found, check if BB-3/Segmenter/SI-Billing non-negotiables from CLAUDE.md apply (backward compatibility).
Step 2 — Load invariants
For each matched project:
- If
docs/projects/<project>/architecture.md exists and has §12 (Non-Negotiables) → load those.
- If the project is BB-3, Segmenter, or SI-Billing → use the existing non-negotiables from CLAUDE.md (these predate the ADF directory structure).
- Each invariant must have an enforcement method: grep pattern, file check, or dependency check.
Step 3 — Execute checks
Run ALL checks in parallel using the Grep tool. For each invariant:
- Define the pattern to search for (the violation)
- Define the paths to search in
- Define exclusions (test files, documented exceptions)
- Expected result: ZERO matches (or specific count if documented)
Standard check types:
Forbidden pattern in paths:
Pattern: <regex that should NOT appear>
Paths: <source directories>
Exclude: <test files, documented exceptions>
Expected: 0 matches
Required file exists:
File: <path>
Must contain: <string or pattern>
Dependency check:
File: <package.json path>
Forbidden in dependencies: <package names>
No violations of coding rule:
Pattern: <e.g., parseFloat|toFixed in fee paths>
Paths: <relevant source files>
Expected: 0 matches
Step 4 — Report
Output format:
## doctor report — <project name>
C1 (<invariant name>): [OK] clean | [FAIL] <file:line> — <violation>
C2 (<invariant name>): [OK] clean | [FAIL] <file:line> — <violation>
...
Verdict: CLEAN | DIRTY
Behavior
- CLEAN: return to caller (usually
/ship-it). Exit quietly.
- DIRTY: STOP. Report all violations with file:line. Do NOT proceed. The caller must not continue.
Module-Specific Checks (BB-3, Segmenter, SI Billing)
When BB-3, Segmenter, or SI Billing files are touched, run the C1–C9 checks defined in CLAUDE.md non-negotiables sections. These are the same checks that used to be in the now-removed /bb3-doctor — they live here as first-class checks alongside any project-specific invariants from architecture.md §12.
Rules
- Must complete in < 5 seconds total. If a check takes > 1 second, narrow its path scope.
- Never block on non-existent projects — if a project directory doesn't exist yet, skip its checks with
[OK] (project not initialized).
- Report ALL violations, not just the first one. The developer needs the full picture.
- Do NOT fix violations. Only report them. The developer (or ship-it) decides how to fix.
- Do NOT run tests or build. That's the next step in the pipeline.