Detects drift between cited external docs (Claude Code, n8n nodes) and what our skills claim. Use before major n8n work or on /forge docs-check — doc drift, source verification, staleness.
Scanned 9/6/2026
Install to Claude Code
npx -y skills add ForgeyClap/claude-forge --skill forge-docdrift --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Forge Docdrift?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/forgeyclap-forge-docdrift)More formats (shields.io, HTML) on the badges page.
---
name: forge-docdrift
description: Detects drift between cited external docs (Claude Code, n8n nodes) and what our skills claim. Use before major n8n work or on /forge docs-check — doc drift, source verification, staleness.
---
# Forge playbook — Docdrift (external-doc claim drift detection)
**Do not duplicate existing tools — this is a NEW, narrow capability.** It does not replace `forge-scout`
(external-capability research/vetting) or `forge-audit-loop` (this project's own internal health) — it only
watches whether an external page a skill/doc CITES still backs up the claim made about it.
## Provenance (honesty)
This tool's IDEA came from researching `shanraisshan/claude-code-best-practice` (an external community
repo) — the Lead approved adopting the underlying idea ("keep external docs and our own claims about them in
sync") as one of 3 GH-research winners. **No code was copied.** `forge-bin/forge-docdrift.cjs` is a
Forge-native reimplementation built from scratch around this project's own conventions (zero-dep,
`config/orchestration/*.json` seed + `.claude/forge-research/*` state/ledger, `log-event.cjs`'s existing
`audit_finding` event type, the same injectable-fetcher hermetic-test seam every other network-touching
`forge-bin` tool uses). Provenance: **PATTERN_ADAPTED** (see the global research-recovery policy's honesty
vocabulary) — the pattern was adapted, not the implementation.
## What it does
`forge-bin/forge-docdrift.cjs check [--source <id>] [--json] [--run <run_id>]` reads
`config/orchestration/docdrift-sources.json` — a seeded list of REAL claims this project's own skills/docs
make that depend on an external, changeable page (an official Claude Code doc page, an n8n node doc page).
For each claim it fetches the real `source_url` (following redirects, timeout-bounded, zero-dependency
`node:https`/`node:http`) and searches the raw response body for every one of that claim's `check_tokens`.
Every claim is classified against its own persisted history in
`.claude/forge-research/docdrift-state.json`:
- **OK** — tokens found, claim was not drifted last known check.
- **NEW-DRIFT** — a token is missing, claim was NOT drifted before (first time this claim looks stale).
- **RECURRING** — a token is missing again, same as last known check (a standing, already-reported gap).
- **RESOLVED** — tokens found again after a prior drift (the doc caught back up, or the claim was fixed).
- **UNREACHABLE** — the fetch failed/timed out/returned non-2xx. **Never counts as drift** — the last KNOWN
drift state is left exactly as it was. A network hiccup is not proof the docs changed.
Every check appends one line to `.claude/forge-research/docdrift-ledger.jsonl` (append-only, never
truncated) and persists the updated state. With `--run <run_id>`, ONE `audit_finding` event (already a
registered `log-event.cjs` event type — no new registration needed) is logged per **NEW-DRIFT** result only
— a RECURRING/RESOLVED/OK/UNREACHABLE result never re-fires an event for a condition already on record.
## Honest limits (read before trusting a result)
- **This is a heuristic token search, not a real diff against a known-good snapshot.** A missing token can
mean the docs genuinely changed — or it can mean an unrelated redesign/paraphrase changed the wording while
the underlying behavior is unchanged. Every report says **"possible drift, verify by hand"** — never "the
docs changed" as an assertion of fact.
- **UNREACHABLE is not drift.** A network failure, timeout, or non-2xx response tells you nothing about
whether the claim still holds — it is reported honestly as unreachable, and it never overwrites the
claim's last known drift state.
- **Seeding a new claim requires reading BOTH files first**: the citing skill/doc (to state the claim
accurately) AND the live source page (to pick `check_tokens` that are genuinely present right now). Never
invent a claim or a token set without checking both.
- **Advisory only.** A DRIFT/RECURRING result never blocks a build, a doctor run, or a WP handoff — it is a
signal for a human (or a future Boss) to go verify the cited doc by hand.
## When to use
- Before major n8n work (an n8n node's documented behavior — auth options, response mode — may have moved).
- Before relying on a cited Claude Code native feature (a subagent frontmatter field like `memory`/`hooks`/
`isolation`, or a slash command like `/goal`/`/loop`) in a new skill or governance doc.
- On the owner's `/forge docs-check`.
- As one more check inside a periodic audit pass (alongside `forge-audit-loop`'s own MEMORY-INTEGRITY/
AGENT-HEALTH/FEATURE-USAGE/DOCTOR-DELTA checks — this tool covers a gap none of those four checks touch:
claims about content OUTSIDE this project).
## Adding a new claim
Edit `config/orchestration/docdrift-sources.json` — add `{id, skill, rule_id, category, check, check_tokens,
source_url, added}`. `id` must be unique; `check_tokens` must be a non-empty array of non-empty strings, each
independently searched (all must be present for the claim to read as OK); `source_url` must be `http(s)://`.
`forge-docdrift.cjs`'s own config loader (`loadSources()`) refuses a malformed entry outright (missing field,
empty `check_tokens`, non-http(s) URL, duplicate id) rather than silently skipping it.
## Skills / commands
`forge-bin/forge-docdrift.cjs` (`check` — the only command; `--source <id>` to check one claim, `--json` for
machine output, `--run <run_id>` to also log NEW-DRIFT findings as `audit_finding` events),
`config/orchestration/docdrift-sources.json` (the seeded claim list — the single source of truth for what is
checked), `.claude/forge-research/docdrift-state.json` (persisted drift memory, per-project, never a template
file), `.claude/forge-research/docdrift-ledger.jsonl` (append-only audit trail, per-project).
## Events
A real docdrift check with `--run <run_id>` logs `audit_finding` (the existing event type — never a new
registration) once per NEW-DRIFT claim, carrying the claim id, rule id, missing tokens, and source URL as
`evidence`. OK/RESOLVED/RECURRING/UNREACHABLE results are still recorded in the ledger but never generate a
duplicate event for a condition already on record.
## Fan-out & flow
**1 agent, no team.** Build Boss (or whichever Boss is doing the citing work) runs a docdrift check directly
— this is a single zero-dependency CLI call, not a multi-agent task.
## Ship-readiness (unique)
Every seeded claim's `check_tokens` were verified against the REAL live source page before being written to
`docdrift-sources.json` (never invented); a real check was actually run (not merely described) before any
report claims a verdict; every result names its literal status (OK/NEW-DRIFT/RECURRING/RESOLVED/UNREACHABLE)
— never blurred into a single "drift found: yes/no"; UNREACHABLE is reported as UNREACHABLE, never silently
treated as either OK or drift; nothing here ever blocks a build — it is advisory input for a human to verify.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!