drift-review
Compares code against project-context.md, features.md, and project-plan.md to find drift. Use when docs may be out of sync with reality, or after a long implementation sprint.
Drift Review
Purpose
Verify that documentation and code tell the same story. In LLM-assisted projects, drift happens fast: features get added without updating features.md, architecture evolves without updating project-context.md, and plan phases get reordered without updating project-plan.md. This skill performs a systematic comparison between documented intent and implemented reality.
This is distinct from counter-review (which challenges whether the plan is good) and refactor-review (which challenges how the code is written). Drift review only asks: does the code match what the docs say?
Inputs
- The full codebase
project-context.md— stated architecture, scope, and design decisionsfeatures.md— feature list with status trackingproject-plan.md— implementation phases and deliverables
Outputs
- Standalone mode: Store findings in the artifact DB:
source artifacts/db.sh db_upsert 'drift-review' 'findings' 'standalone' "$FINDINGS_CONTENT" - Multi-model mode (called by meta-review): Store per-model findings in the artifact DB:
- Sonnet:
db_upsert 'drift-review' 'findings' 'sonnet' "$CONTENT" - Codex:
db_upsert 'drift-review' 'findings' 'codex' "$CONTENT" - Gemini:
db_upsert 'drift-review' 'findings' 'gemini' "$CONTENT"
- Sonnet:
Instructions
Fresh Findings Check
Before running a new scan, check if fresh findings already exist:
source artifacts/db.sh
AGE=$(db_age_hours 'drift-review' 'findings' 'standalone')
# For multi-model: db_age_hours 'drift-review' 'findings' 'sonnet'
If $AGE is non-empty and less than 24, report: "Found fresh drift-review findings from $AGE hours ago. Reuse them? (y/n)"
If the user says yes, read findings from DB: db_read 'drift-review' 'findings' 'standalone' (or sonnet/codex/gemini as appropriate).
If no record exists or user says no, proceed with a fresh scan.
1. Extract Documented Claims
Read all three input documents and extract concrete, verifiable claims:
From project-context.md:
- Technology stack (languages, frameworks, databases)
- Architecture pattern (monolith, microservices, serverless, etc.)
- Module/component structure
- Integration points (APIs, services, databases)
- Stated constraints and non-goals
From features.md:
- Each feature and its documented status (planned, in-progress, done)
- Feature descriptions and acceptance criteria
From project-plan.md:
- Phase deliverables and their stated completion status
- Dependencies between phases
- Deferred/cut items
Build a checklist of these claims. Each one gets verified against the code.
2. Code-to-Docs Comparison (What's documented but missing)
For each documented claim, search the codebase for evidence:
- Features marked "done" — find the implementing code. If it doesn't exist or is a stub, that's drift.
- Architecture claims — verify the actual structure matches. If project-context.md says "REST API with Express" but the code uses Fastify, that's drift.
- Stack claims — check actual dependencies against what's documented.
- Integration claims — verify the integration code exists and connects to the stated services.
Flag every discrepancy with the specific doc reference and code location (or absence).
3. Docs-to-Code Comparison (What's built but undocumented)
Scan the codebase for functionality that doesn't appear in any doc:
- Routes/endpoints not mentioned in features.md
- Modules/services not mentioned in project-context.md
- Dependencies not mentioned in the stack description
- Features that work but aren't listed anywhere
Undocumented features are drift too — they mean the docs can't be trusted as a complete picture of the system.
Code-Side Discovery (Codex)
After comparing docs to code, run a reverse check — find things in code that docs don't mention:
- Load
/codexfor invocation syntax. If Codex is unavailable, skip to step 4. - If available, dispatch a Codex worker. Key params:
--sandbox read-only,--ephemeral,--cd <project-root>, 120s timeout. Prompt:"Scan this codebase for features, endpoints, configuration options, and behaviors that are NOT documented in any .md file in the project root. List each with file:line. Focus on: API endpoints without docs, env vars without .env.example entries, CLI flags without README mention, and database tables without schema docs.". - Add any undocumented findings to the drift report as "Code-ahead" items.
- If Codex is unavailable, skip this step — the standard doc-to-code comparison still runs.
4. Status Accuracy Check
Focus specifically on the status fields in features.md and project-plan.md:
- Features marked "done" — are they actually complete? (Test by tracing the feature end-to-end through the code.)
- Features marked "in-progress" — is there any code for them, or did they stall?
- Features marked "planned" — is there already code for them? (Status should be updated.)
- Plan phases marked complete — are all deliverables actually present?
5. Produce Findings
Format each finding using this structure (store via db_upsert as shown in Outputs above):
## [SEVERITY] Finding Title
**Drift Direction**: Docs ahead of code | Code ahead of docs | Contradiction
**Doc Reference**: Which document, which section, exact quote
**Code Reference**: file/path:line (or "no corresponding code found")
**What the docs say**: Quote the relevant documentation.
**What the code does**: Describe the actual behavior or show a code snippet.
**Resolution**: Which is correct — the doc or the code? Recommend updating whichever
is wrong. If unclear, flag for human decision.
Drift directions:
- Docs ahead of code — Documentation describes something that isn't built yet (features marked done but not implemented)
- Code ahead of docs — Code exists for something not documented (undocumented features, architecture changes)
- Contradiction — Both exist but disagree (docs say X, code does Y)
Severity levels:
- CRITICAL — Feature marked "done" that doesn't work, or architectural contradiction that would mislead a new developer
- HIGH — Significant undocumented functionality or incorrect status tracking
- MEDIUM — Minor discrepancy that could cause confusion
- LOW — Cosmetic doc issue (naming inconsistency, outdated terminology)
6. Summarize
End with:
- A drift map table: document | section | drift direction | severity
- Count of findings by direction and severity
- Overall sync assessment: are the docs trustworthy, or do they need a major update pass?
- Recommendation: which documents should be updated first to restore trust
Execution Mode
- Standalone: Spawn the
review-lensagent (subagent_type: "review-lens") with this skill's lens instructions and input files. Stores findings in DB asdb_upsert 'drift-review' 'findings' 'standalone'. - Via meta-review: The
review-lensagent runs the Sonnet review, while Codex (/codex) and Gemini (/gemini) run in parallel with the same prompt. Each model stores findings in DB under labelsonnet,codex, orgemini. The meta-review skill handles synthesis.
Examples
User: Do our docs match what's actually built?
→ Triggers drift-review. Full comparison of all three input documents against the codebase.
User: I need to update features.md. What's actually done vs what it says?
→ Triggers drift-review with emphasis on the Status Accuracy Check section.
User: A new developer is joining. Can they trust our project docs?
→ Triggers drift-review. Frame findings as "here's what would mislead the new developer."
Before completing, read and follow ../references/cross-cutting-rules.md.