EXISTING CODE HAS BEHAVIOR. BEHAVIOR WITHOUT DOCUMENTATION IS A GAP. GAPS MUST BE VISIBLE.
Core principle: Brownfield code already has behavior. The audit makes that behavior visible as claims, then checks if documentation supports them.
When to invoke
- Adopting DDD on an existing codebase (brownfield)
- Assessing documentation debt in legacy code
- Producing a coverage report for grandfathered code
- When
ddd-bookinitialization finds existing code without DDD coverage - When preparing a migration plan from non-DDD to DDD-governed development
When NOT to use
- Greenfield projects with no existing code — use
ddd-bookto initialize instead - Code already under DDD governance — use
ddd-verifyfor conformance checking - A single change's compliance — use
ddd-verify
What it does
Step 1: Scan the codebase
- Read
project-context.yaml(create viaddd-bookif it doesn't exist) - Identify all source directories and their structure
- Count total symbols (functions, classes, modules, components)
- Classify each source directory by architecture layer (domain, application, infrastructure, UI)
- Identify entry points, public APIs, and boundary crossings
Step 2: Extract behavioral claims from code
For each significant code construct, infer what behavioral claim it implements. See references/audit-phases.md for the extraction patterns table.
Each extracted claim starts with status: unknown and empty sources — to be matched in Step 3.
Step 3: Match claims to existing documentation
For each extracted claim, search for supporting evidence:
- Check existing ADRs,
CONTEXT.md, README, wiki - Check code comments and JSDoc/docstrings
- Check test names and descriptions
For each match: update claim with source reference, set status: known-and-supported or unsupported or unknown.
Step 4: Flag gaps and contradictions
Produce an audit report — see references/audit-phases.md for the full report schema. Key sections:
- Coverage: percentage of claims with evidence
- Gaps: claims with no documentation, ranked by severity
- Contradictions: code behavior vs documented behavior
- Legacy debt: grandfathered vs documented symbols
Step 5: Produce draft Book
From the audit results: create book.yaml, knowledge-map.yaml, claims.yaml, trace-matrix.yaml, and exceptions for all unknown and unsupported claims.
Step 6: Prioritize remediation
See references/audit-phases.md for the full prioritization table:
| Priority | Criteria |
|---|---|
| P0 | Critical security/data integrity gaps, code-doc contradictions |
| P1 | High-severity gaps in core domain logic, missing ADRs |
| P2 | Medium-severity gaps, missing docs for internal utilities |
| P3 | Low-severity gaps in non-consequential code |
Examples
Rationalization table
| Excuse | Reality |
|---|---|
| "Most of this code is simple, I'll skip it" | Simple code can have behavioral claims (validation rules, state transitions). Skipping creates invisible gaps. Audit everything significant. |
| "I don't need to check ADRs, the code is the source of truth" | In DDD, documentation is the source of truth. Code that contradicts ADRs is a P0 contradiction, not a design decision. |
| "The audit is too slow, I'll just do the important files" | Partial audits create false confidence. Unaudited code has unknown gaps. Either audit all or explicitly mark as grandfathered. |
| "I'll mark everything as grandfathered" | Grandfathered code is exempt from DDD scope, but modifications to it trigger DDD scope. Marking everything grandfathered defeats the purpose. |
| "No contradictions means the code is correct" | No contradictions means you didn't check hard enough. Compare state machines in code against ADRs, test behavior against documented contracts. |
Incremental adoption
- Phase 1: Fix all P0 gaps. Create evidence or exceptions for critical claims.
- Phase 2: New changes in audited areas are DDD-governed. Grandfathered code stays exempt.
- Phase 3: As changes touch grandfathered code, bring it into DDD scope (per §17.3).
- Phase 4: Periodically re-audit to track coverage growth and debt reduction.
Self-improvement
- Did the audit miss any significant constructs? If so, the symbol classification criteria are too narrow — expand them.
- Are contradictions clustering in a specific module? If so, that module has documentation debt — prioritize it for remediation.
- Is coverage growing over time? If not, new code is being added without DDD scope — enforce the grandfathering boundary.
Spec reference
- SPEC.md §17.3 (Incremental adoption), §17.4 (Monorepo scoping), §18.1 (Success metrics), §14 (Exceptions)