# Doc Drift

> Check a capability's documentation against the current codebase and report every statement that no longer holds — stale claims, decisions silently reverted in code, and documented behaviour that was never built. Reports and routes findings; never edits the notes itself. Use when the user asks whether a capability note or ADR is still accurate, wants to audit documentation against code, or suspects a note has gone stale.

- Skill: `jo-bity/doc-drift` (Agent Skill)
- Install (CLI): `npx skillmds@latest add jo-bity/doc-drift`
- Raw SKILL.md: https://api.skillmd.com/api/skills/jo-bity/doc-drift/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: Jo-bity (https://skillmd.com/u/jo-bity)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/jo-bity/doc-drift

---


> **Style:** Focus on conciseness in your output. Stay brief, but never sacrifice semantics (meaning) for conciseness.

# Doc Drift

The return edge of the documentation loop. Everything else in the loop *writes*; this skill
**verifies**, and routes what it finds back to the skill that owns the fix.

It never edits a note or a decision record. A drift report the user reads and acts on is useful; a
skill that silently rewrites documentation to match the code destroys the record of what was
intended — which is the whole point of having it.

## Configuration

`$OBSIDIAN_VAULT` is the vault root. Resolve it before reading; if unset, ask once and offer to
record it in the user's `CLAUDE.md` / `AGENTS.md`.

## Step 1 — Read the documentation

From `$OBSIDIAN_VAULT/02_Entwicklung/<Capability>/`:

1. `<Capability> — Arbeitsdokument.md` — the current-state claims
2. `ADR/` — every decision record, including amendments and statuses
3. Snapshots only when a claim's meaning is unclear without them

## Step 2 — Extract checkable claims

Turn the prose into a list of statements that code can confirm or refute. A claim is checkable when
a specific file could prove it wrong.

| Checkable | Not checkable |
|---|---|
| "`POST /kyc/cases` requires the `kyc:write` policy" | "KYC is owned by the onboarding team" |
| "State moves `PENDING → VERIFIED` only via the webhook" | "This keeps the design simple" |
| "The connector lives in `billing-service`" | "We may revisit this next quarter" |

Skip ownership, rationale and intent — they are not the code's to answer. Note how many claims you
skipped; a note that is mostly unverifiable prose is itself a finding.

## Step 3 — Verify against the code

Launch Explore agents in parallel, batched by area rather than one per claim. Each returns the
evidence — file and what it actually says — not a yes/no.

Classify every claim:

| Verdict | Meaning |
|---|---|
| **confirmed** | Code matches. Report the count only, not the list. |
| **stale** | Code says something different. The note is wrong. |
| **unbuilt** | The note describes behaviour that does not exist yet. Intent recorded as fact. |
| **reverted** | An ADR's decision is contradicted by the code — the decision was undone without a record. |
| **unverifiable** | No code could settle it. Say why. |

**Do not guess.** If an Explore agent could not find the code, the verdict is `unverifiable`, never
`stale`. A false drift report costs more trust than a missed one.

## Step 4 — Report and route

Group by verdict, worst first. One entry per finding:

```
### reverted — "Connector lives in `billing-service`"
Source:   KYC ADR-002 — Connector-Ort billing-service
Evidence: services/onboarding/connectors/KycConnector.java — the connector now sits in onboarding
Route:    adr-log (the move is a new decision, ADR-002 needs an amendment or a successor)
```

Routing rules:

- **stale** → `capability-doc`. The note is behind; replace the statement in place.
- **reverted** → `adr-log` **first**. Someone changed a decision without recording it. Capture the
  new decision and amend or supersede the old record, *then* update the note. Never just edit the
  note — that erases the fact that a decision changed.
- **unbuilt** → not drift, a gap. Move it to `Offene Punkte`, or raise a ticket with `jira-ticket`.
- **unverifiable** → leave it. Flag only if a claim that reads as fact cannot be checked at all.

## Step 5 — Close

Report: how many claims were checked, the split across verdicts, the findings in priority order, and
which skill to run next. Offer to run it.

If nothing drifted, say so in one line. That is a good result, not a thin report.

