DocDrift is a background watcher that parses your working tree with tree-sitter, matches exported symbols against your README, guides and .env.example — then lets an open-source agent crew draft the documentation PR. Runs on your laptop. Costs nothing. Asks for zero API keys.
extractor: 24 symbols · 2ms
matcher: 6 stale doc targets
validators: 2/2 gates passed
drafting patch …
docs: sync setup guide with config.ts
3 files · +12 −7 · reviewed by validators
0+
languages parsed
TS · JS · Python (WASM grammars)
0
validation gates
code grounding + docs apply check
0
cloud calls required
runs on your laptop, fully offline
$0
to run, forever
open weights + open harness
numbers the demo below actually runs on — not marketing
Documentation decay is measured, not mythical — empirical studies flag READMEs that reference code elements deleted many revisions ago. DocDrift exists so fixing it stops being your job.
You ship. Docs rot.
A signature changes, an env var gets renamed, an endpoint moves to /v2 — and the README quietly becomes fiction. Nobody updates docs in the same commit, and nobody should have to.
Linters can't read markdown.
Your compiler validates code against code — but nothing validates code against prose. A TypeScript interface and the markdown table describing it live in two worlds no tool compares.
So let the sloth work.
DocDrift watches in the background and does the boring part for you: it detects the drift, grounds every claim in the actual AST, and drafts the doc PR. You review. That's it.
“Detecting Outdated Code Element References in Software Documentation” (ICSME 2023) can only flag references whose occurrences drop to zero — a changed default like
PORT 3000 → 8080sails straight past it. DocDrift compares values and shapes, not just string existence. read the paper ↗
A Mastra workflow wires the crew into one typed graph. Every step reports status, timing and notes — the same trace you see live in the demo below.
A commit drifts the docs
A pre-push hook, a GitHub Action, or a manual run hands the engine the changed tree. Nothing daemonizes in the dark — every run is explicit and inspectable.
tree-sitter reads the real AST
Grammar WASMs (TS / JS / Python) extract exported functions, classes, interfaces, routes and config keys with line-precise evidence. If a grammar fails on exotic syntax, a structural fallback extractor takes over and the miss is logged to the failure ledger.
Markdown becomes structured targets
README tables, setup guides, ARCHITECTURE.md sections and .env.example lines are parsed into typed targets with their own line evidence — the docs side gets the same rigor as the code side.
Symbols meet their doc targets
A folding matcher aligns camelCase, snake_case and prose mentions, tolerating renames via similarity scoring. Unmatched symbols and orphaned doc rows both survive as drift candidates.
Gemma drafts the findings
An open-weight Gemma model (local via Ollama, or the free Gemini API tier) reasons over code vs docs and emits findings plus a Markdown patch. No provider? A deterministic comparator produces the same artifact — the pipeline never stalls.
Every claim must be grounded
LLMs hallucinate — the traceability literature documents 'phantom links' extensively. Gate 1 re-checks each finding against the extracted symbols and drops anything the AST cannot prove, before a patch is ever built.
The patch must apply cleanly
Gate 2 applies the proposed edits to a snapshot of your docs, re-parses the result and confirms the tables stay well-formed and the symbol is genuinely documented now. Broken edits are repaired once, then flagged — never silently merged.
Humanized PR, robot-fast
A tone pass rewrites the PR title and body so the diff reads like a colleague wrote it — plain verbs, honest scope, no LLM-isms. Falls back to clean templates offline.
You get a reviewable PR
A unified diff against your docs, a ready PR description, and a full step trace with timings. One click copies the patch; wire the provided GitHub Action to automate the rest.
Every layer is inspectable: the parser, the workflow graph, the model and the validators. No SDK phones home; no feature requires a subscription.
AST, not vibes
WASM grammars parse TS, JS and Python for exported functions, classes, interfaces, routes and config keys. A structural fallback extractor keeps the engine alive when syntax gets exotic.
Agent orchestration
Typed steps, zod schemas, a committed workflow graph — an open-source harness powering production agents.
Open weights inside
Local inference on your machine, or a free API tier. Swap any compatible model with one env var.
Two validation gates
A code-side subagent drops claims the AST can't prove; a docs-side subagent refuses patches that don't apply cleanly. Hallucinations die before the diff.
PR-ready output
Unified diff against your docs, humanized PR title and body, copy button. Review, merge, move on.
Plugs into your flow
Pre-push hook, GitHub Action, CLI or the demo on this page. AST failures land in a queryable health ledger.
Real engine, real workflow — this runs the actual Mastra pipeline against fixtures (or your own paste). Pick a scenario, run it, copy the patch.
doc-drift workflow
deterministic engine · structural parsing when available
Pick a scenario and hit Run drift analysis. The stepper shows the live step trace; findings and the patch appear as the validators clear them.
nothing leaves this machine — text is parsed, never executed
A documentation watcher needs your entire working tree in context. That's exactly the payload you should never paste into a browser tab — so the whole stack runs where the repo lives.
Your code never leaves the machine
The default path runs local inference on localhost — the AST, your README and the patch all stay on your disk. The deterministic engine doesn't even open a socket. Traceability research (2025) shows LLM link-detection is useful but imperfect; doing it locally means the only thing at risk of a mistake is a markdown table, not your IP.
Set it up once, pay nothing ever
Every component is free under an open-source license. The optional hosted API path uses a free tier with a key — no credit card, no trial clock. There is no paid plan to outgrow.
Swap the brain, keep the body
The synthesizer is a provider chain, not a vendor: point at any local model, set an API key for the hosted open model, or run with neither and the deterministic comparator steps in. Changing how your agent behaves is a config edit, not a migration.
provider resolution chain — live status
GET /api/healthlocal model
open weights on localhost
not configured — skipped
hosted api · free tier
hosted open model, key from provider dashboard
not configured — skipped
deterministic engine
always-on comparator — what powers this demo
always available
querying engine …
let the docschill.
You review documentation PRs now. That’s the whole job. The sloth handles the rest — slowly, reliably, and entirely on your machine.