From harness-docs
Scan an existing docs/ folder, cross-reference it against the current codebase and recent git history, and update documentation that has drifted out of sync with reality. Use this skill whenever the user asks to refresh / update / review / audit their docs, check for stale documentation, sync docs with code, run doc maintenance, or "garden" the docs. Also trigger on phrases like "our docs are out of date", "make sure docs match the code", "what docs need updating after these changes", or any request to check documentation freshness. Works best on repos that follow the harness-engineering pattern (Status / Last reviewed headers) but falls back to git-based heuristics otherwise. Produces drift findings with evidence, then applies user-approved updates.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-docs:doc-gardenerThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Keep the `docs/` folder honest. This skill implements the "doc gardening" loop described in OpenAI's *Harness engineering* article: scan the knowledge base for content that no longer reflects the code, and propose precise updates with evidence.
Keep the docs/ folder honest. This skill implements the "doc gardening" loop described in OpenAI's Harness engineering article: scan the knowledge base for content that no longer reflects the code, and propose precise updates with evidence.
The output is a drift report (per-document classification with evidence from code and git) followed by targeted updates the user approves and applies.
Trigger on requests like:
Also trigger when the user mentions having run harness-docs previously and wants to keep it maintained, or when they reference the OpenAI harness engineering article's gardener concept.
Do NOT trigger for:
harness-docs for that.harness-docs territory or a direct write.Six phases. Run in order. The first four produce a drift report; Phase 5 applies approved updates; Phase 6 wraps up.
Start by running the bundled scripts/docs_lint.py — this catches deterministic issues (broken links, missing/invalid metadata, stale dates, index coverage gaps) in one shot, and produces a machine-readable manifest the rest of the workflow builds on.
python3 <skill-path>/scripts/docs_lint.py --root <repo-root> --threshold-days <N> --json
The default threshold is 60 days; pass what the user requested. The skill is bundled with this script and should invoke it directly — no need to reimplement any of its checks.
Parse the JSON output. For each file you get:
path, status, last_reviewed, owner — the doc's metadata.findings[] — each with rule, severity, line, message. These are pre-classified mechanical drift signals.On top of the script's output, extract linked code paths per doc (the script doesn't do this — it's doc-gardener-specific context):
`src/auth/service.ts`)docs/design-docs/auth.md → src/auth/)Build a manifest: one entry per doc with lint findings + related code paths + git mtime (filled in next phase).
If docs_lint.py is not runnable for some reason (no python3, permission denied), fall back to reading each doc yourself and applying the same checks manually — but this is much slower. Prefer fixing the environment over skipping the script.
For each doc in the manifest, collect evidence about whether the underlying reality has moved. Read references/git-recipes.md for the exact commands — key queries:
git log -1 --format=%cI -- <doc-path>. If this date is older than Last reviewed, the Last reviewed header is almost certainly wrong (someone bumped it without looking). If newer, the doc was touched after being reviewed — possibly fine, possibly drifted.Last reviewed: git log --since=<date> -- <path>. Count and categorize (bugfix vs feature vs refactor based on commit messages, conservatively).ls / git cat-file -e HEAD:<path>. Paths that no longer exist are hard drift signals.git log --follow --diff-filter=R -- <path> or a repo-wide rename heuristic to detect if the file was moved.src/ (or equivalent). Any that have no design doc in docs/design-docs/ mentioning them are potential orphans — the code has grown a surface the docs don't cover.git log --since=<review-threshold> --name-only --pretty=format: | sort | uniq -c | sort -rn | head -20. Files with many commits that are mentioned in docs deserve extra scrutiny.Keep the output per-doc. Don't merge signals across docs yet.
Assign each doc one of these grades, with evidence. Findings from docs_lint.py (Phase 1) and from git (Phase 2) both feed into this — a doc can earn Critical from either source.
links/broken, metadata/status-invalid, metadata/last-reviewed-malformed, code-fence/path-missing, index/missing-sibling. From code comparison: APIs/symbols referenced by the doc that no longer exist. Must fix.Last reviewed, and the changes appear to affect what the doc describes. Needs verification and probably updates. Lint may be quiet — this is exactly the kind of drift lint can't catch.freshness/stale, or references/path-missing (soft — the script only flags unambiguous paths). From metadata: no strong code-drift signal found. Refresh review recommended; may just need a date bump.metadata/status-missing or metadata/last-reviewed-missing, and no git signal pins down whether the doc is current. Surface for human triage.The staleness threshold passed to the lint script is the same one used for git-signal analysis. If the user hasn't specified, default to 60 days. Mention the default in the report so they can override.
Critical rule: evidence-bound classification. For Critical, cite the specific lint rule or the specific broken code reference. For Likely stale, cite the specific commits. Never guess.
Output a single structured report for the user to review before making any changes. Shape:
# Doc gardening report
Scope: <docs/ + AGENTS.md + ARCHITECTURE.md>
Threshold: 60 days since Last reviewed
Manifest: 23 docs scanned
## Summary
- 🔴 Critical: 2
- 🟠 Likely stale: 5
- 🟡 Possibly stale: 8
- 🟢 Fresh: 6
- ⚪ Unknown: 2
- ➕ Orphans: 3
## 🔴 Critical
### docs/design-docs/auth.md
- `Last reviewed: 2025-09-14`
- Doc references `src/auth/middleware/jwt.ts` which was removed in commit a3f21b (2026-01-08). Functionality moved to `src/auth/providers/token.ts`.
- Code example at line 63 imports `verifyToken` from `@app/auth` — this export no longer exists (replaced by `verifySession`).
- Proposed fix: update file path and import; verify the example still illustrates the intended flow.
### ...
## 🟠 Likely stale
...
## ➕ Orphans
- `src/billing/` (added 2026-02-10, 34 files, no design doc)
- `src/features/sharing/` (added 2026-01-22, no product spec)
...
## Recommended actions
1. Apply fixes for the 2 Critical docs.
2. Review and refresh the 5 Likely stale docs.
3. For Possibly stale: bulk-bump Last reviewed where you're confident, or schedule a review pass.
4. For Orphans: decide whether each warrants a design doc, product spec, or just a tech-debt entry.
Then ask: "Which of these should I apply? You can say 'all critical', 'show me the full diff for auth.md first', 'just bump the possibly-stale dates', etc."
This is the most important checkpoint in the skill. Do not proceed without user direction.
Only after the user approves. Read references/update-patterns.md for how to rewrite different doc types — the short rules:
Rationale and Consequences sections of a design doc usually stay put. The Decision and any code examples are what drifts.src/old/path.ts → src/new/path.ts, update every mention in the doc.Last reviewed: <today>, keep Status: verified unless the change is so large the doc needs re-review (then Status: draft).Status: deprecated and add a header explaining what replaced it and linking there. Don't silently remove — agents may follow old links.docs/exec-plans/tech-debt-tracker.md.tech-debt-tracker.md as documentation-coverage gaps. Creating design docs for code you don't fully understand is how bad docs get born.After each update, show the diff and confirm before moving on. For "Possibly stale" bulk date-bumps the user approves, it's fine to batch — those are metadata-only changes.
After all approved updates are applied:
scripts/docs_lint.py into CI, this is a good moment to suggest it — offer to generate a workflow file that runs python3 scripts/docs_lint.py --root . --strict on PRs touching docs/ or referenced code paths.Do not open a PR automatically. Commit and push only if the user explicitly asks.
scripts/docs_lint.py — Bundled mechanical lint script. Use this at Phase 1 and whenever the user wants a quick freshness check. Also suitable for the user's CI. Run with --json for machine-readable output. Exit codes: 0 clean, 1 warnings, 2 errors.references/staleness-signals.md — Full taxonomy of drift signals and how to detect each. Read during Phases 2–3.references/git-recipes.md — Concrete git commands for every signal this skill uses. Keep open during Phase 2.references/update-patterns.md — How to safely rewrite each doc type (design doc, architecture, index, product spec, etc.). Read during Phase 5.Last reviewed trust problem. Someone may have bumped the date without reading the doc. When a doc's own git mtime predates its Last reviewed, distrust the header and verify from code anyway.Last reviewed. Bumping the date without reviewing is exactly the anti-pattern that creates silent rot. Only bump dates after either (a) substantive review, or (b) the user explicitly approves a bulk bump with the understanding that it's a self-attested "nothing changed".Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
Applies a firm's KYC/AML rules grid to parsed onboarding records: assigns risk rating, checks required documents, outputs rule outcomes with citations, and routes for escalation.
Generates daily or weekly digests of activity from connected sources (chat, email, docs, tasks, CRM), highlighting action items, decisions, mentions, and project updates.
npx claudepluginhub keito654/harness-docs --plugin harness-docs