--- name: doc-syncer description: Detect stale documentation by cross-referencing git history against the project's actual doc layout. Auto-discovers root docs, docs/**, and .claude/{tasks,audits,memory}/. Stack-aware deploy-doc gating (DEPLOY.md only when non-trivial). Enforces README presence. Audit, report, patch. Supports full audit and automatic (silent) mode. tools: Read, Write, Edit, Bash, Grep, Glob model: sonnet --- # DOC SYNCER ## GOAL Keep documentation in sync with code. Detect drift, report it, patch what can be patched automatically. Auto-discover what doc the project has and what it actually needs based on stack and deploy complexity. Never invent content -- only reflect what changed in code. ## REQUEST $ARGUMENTS --- ## MODE DETECTION Parse `$ARGUMENTS`: - **AUTO MODE** — `$ARGUMENTS` starts with `auto-mode scope:` Jump to AUTO MODE section. - **FULL AUDIT** — anything else (empty, file list, description) Run the full audit workflow. --- ## FULL AUDIT ### STEP 1 — DISCOVER PROJECT DOC LAYOUT Auto-detect what doc files actually exist. No fixed list. ```bash # Standard root doc files (only those that exist) for f in README.md CLAUDE.md INSTALL.md CONFIGURE.md USAGE.md \ DEPLOY.md CONTRIBUTING.md CHANGELOG.md SECURITY.md \ CODE_OF_CONDUCT.md ARCHITECTURE.md ROADMAP.md LICENSE; do [ -f "$f" ] && echo "$f" done # docs/ tree find docs -name '*.md' 2>/dev/null # .claude/ project-state docs find .claude/tasks .claude/audits .claude/memory \ -name '*.md' 2>/dev/null ``` Store as `DOC_FILES` (existing) and `DOC_MISSING` (canonical names absent — at minimum: README.md). ### STEP 2 — STACK & DEPLOY ANALYSIS Detect project stack and deploy complexity. Drives later decisions about which docs are needed. **Stack signals (read manifest, identify framework):** | Signal file | Stack | |-------------|-------| | `package.json` — read `dependencies` | Node/JS — React, Next.js, Astro, Vue, Svelte, Express, NestJS, etc. | | `requirements.txt` / `pyproject.toml` / `Pipfile` | Python — Django, FastAPI, Flask, Streamlit | | `Cargo.toml` | Rust — Axum, Actix, Tauri | | `go.mod` | Go | | `Gemfile` | Ruby/Rails | | `composer.json` | PHP — Symfony, Laravel | | `pubspec.yaml` | Dart/Flutter | | `*.csproj` / `*.sln` | .NET | **Deploy signals — classify trivial vs non-trivial:** | Signal | Complexity | |--------|-----------| | `Dockerfile`, `docker-compose.yml`, `compose.yaml` | NON_TRIVIAL | | `fly.toml`, `render.yaml`, `railway.toml`, `vercel.json`, `netlify.toml` | NON_TRIVIAL | | `.github/workflows/deploy*.yml`, `.gitlab-ci.yml` w/ deploy stage | NON_TRIVIAL | | `kubernetes/`, `helm/`, `k8s/`, manifests w/ `kind: Deployment` | NON_TRIVIAL | | `terraform/`, `pulumi/`, `serverless.yml`, SAM `template.yaml` | NON_TRIVIAL | | `Makefile` w/ multi-step deploy target | NON_TRIVIAL | | Multiple env-specific configs (`.env.production`, `.env.staging`) | NON_TRIVIAL | | FTP / SFTP push script, single `scp`, plain static upload | TRIVIAL | | Astro/Next static export pushed to GitHub Pages w/ default action | TRIVIAL | | No deploy artifact (lib, internal tool, CLI binary release only) | NONE | Store as `STACK` and `DEPLOY_COMPLEXITY` (`NONE` / `TRIVIAL` / `NON_TRIVIAL`). Record evidence (which file triggered classification) for the report. ### STEP 3 — DETECT DRIFT PER DOC For each file in `DOC_FILES`: 1. Get last modification date: ```bash git log -1 --format=%aI -- ``` 2. Get commits touching the codebase since that date. Adapt globs to detected `STACK`: ```bash git log --oneline --since="" \ --diff-filter=AMRD -- \ 'Dockerfile' 'docker-compose.yml' 'Makefile' \ '*.toml' '*.json' '*.yaml' '*.yml' '*.env.example' ``` 3. For each commit, extract changes: ```bash git show --stat --name-only git diff ~1.. --unified=3 ``` Look for: new/renamed/deleted functions, new config keys, new CLI flags, changed endpoints, breaking changes, dep adds/removes/upgrades, new features, removed features. 4. Cross-reference each change against doc content. 5. **Feature delta detection:** - New entry points / routes / commands / skills / modules in code, no doc section → `[ADDED]`. - Doc references functions / files / endpoints / features absent from code → `[REMOVED]`. - Use `git diff --stat` between last doc edit and HEAD to identify added (`A`) / deleted (`D`) files. ### STEP 4 — ANALYSIS PER DOC TYPE Apply doc-specific checks. Skip docs not in `DOC_FILES` (handled by STEP 5/6 if creation needed). **README.md** — *must exist; see STEP 5 if absent* - Title + one-line description present? - Quick-start commands match package manifest? - Feature list covers current functionality? - **Added:** new skills/commands/endpoints/modules in code, missing from feature list → AUTO if name obvious, HUMAN if wording needs judgment. - **Removed:** entries referencing code/files/endpoints absent → AUTO for removal, HUMAN if deprecated. - Examples match current API/signatures? - Prerequisites: versions/tools accurate? - Cross-links present and pointing to existing files (`INSTALL.md`, `CONFIGURE.md`, `USAGE.md`, `DEPLOY.md`, `CONTRIBUTING.md`, `CHANGELOG.md`)? Dead link → AUTO removal. Missing link to existing doc → AUTO addition. **CLAUDE.md** - Norms match current project patterns? - Stack description matches detected `STACK`? - Build/test/lint commands runnable? - Folder tree matches actual structure? - Decisions in `.claude/memory/decisions.md` reflected when architectural (framework choice, security stance, API versioning)? **INSTALL.md** - Env vars referenced exist in `.env.example`? - Install steps match current dep manager + versions? - OS/runtime prerequisites accurate? **CONFIGURE.md** - Config-file format matches current code? - Each documented option still present in code? - New options added to code reflected here? **USAGE.md** - CLI flags / commands match current implementation? - API endpoints match current routes (versioned per `/api/v1/...` rule)? - Code examples match current signatures? **DEPLOY.md** - Steps match detected deploy artifacts (Dockerfile, fly.toml, workflows, etc.)? - Production env vars listed and match `.env.example`? - Rollback procedure present (non-trivial deploy)? - If `DEPLOY_COMPLEXITY == TRIVIAL` → file is overkill, propose inlining content into README "Deploy" section. HUMAN. **CONTRIBUTING.md** - Branch workflow accurate? - Test commands correct? - Code style rules still enforced (lint config, formatter)? **CHANGELOG.md** - Latest code changes have entries? Always HUMAN. - Entry format consistent with existing style? **docs/**/*.md** - Technical accuracy: code references match reality? - Internal links point to existing files/sections? **.claude/tasks/TODO.md** - Tasks still relevant given current code state? - Completed subtasks ticked? - Tasks for code that no longer exists → flag for cleanup. HUMAN. **.claude/audits/*.md** - Audit reports (SEO, harden, validate, BUGS-FOUND, etc.) reference paths/files that still exist? - Findings still applicable, or already resolved by later commits? Flag resolved findings → HUMAN (user decides whether to archive). **.claude/memory/decisions.md / learnings.md / blockers.md** - Decisions referencing files/modules → those still exist? - Resolved blockers marked `resolved`? - Decisions contradicting current code → surface for user reconciliation. HUMAN. **.claude/memory/journal.md / evals.md** - Append-only logs — never edit. Skip drift checks. **Inline comments (JSDoc, docstrings, rustdoc, godoc)** - Only check files changed since last doc update. - `@param` / `@return` types match actual function signatures? - Description still accurate after the change? ### STEP 5 — README BOOTSTRAP CHECK If `README.md ∉ DOC_FILES`: README is mandatory. Propose creation using typical GitHub layout — include only sections relevant to detected `STACK` and `DEPLOY_COMPLEXITY`. Use real project data (manifest name, description, install/run commands). No placeholders. Proposed template (HUMAN approval required): ```markdown # ## Features - - ## Quick Start \`\`\`bash \`\`\` ## Documentation - [Install](INSTALL.md) - [Configure](CONFIGURE.md) - [Usage](USAGE.md) - [Deploy](DEPLOY.md) - [Contributing](CONTRIBUTING.md) - [Changelog](CHANGELOG.md) ## License ``` Tag overall as HUMAN — user validates before write. ### STEP 6 — DEPLOY.md GATE | State | Action | |-------|--------| | `DEPLOY_COMPLEXITY == NONE` | Skip. Don't propose DEPLOY.md. | | `DEPLOY_COMPLEXITY == TRIVIAL` AND no DEPLOY.md | Skip. Suggest one-paragraph "Deploy" section in README. HUMAN. | | `DEPLOY_COMPLEXITY == TRIVIAL` AND DEPLOY.md exists | Suggest deletion or inlining into README. HUMAN. | | `DEPLOY_COMPLEXITY == NON_TRIVIAL` AND no DEPLOY.md | Propose creation. HUMAN. Template based on detected artifacts (Docker → image build + run + env; fly.toml → `fly deploy` + secrets; workflows → branch trigger + manual approval; k8s → kubectl apply + namespace + rollout). | | `DEPLOY_COMPLEXITY == NON_TRIVIAL` AND DEPLOY.md exists | Apply standard drift detection (STEP 3-4). | ### STEP 7 — REPORT ``` DOC SYNC REPORT =============== PROJECT STACK : DEPLOY : DOCS PRESENT : DOCS MISSING : ## Last updated: () 1. [AUTO]
Commit: Fix: 2. [HUMAN]
Commit: Reason: --- (repeat for each doc with drift) ## CREATE PROPOSALS - [HUMAN] README.md — bootstrap (template above) - [HUMAN] DEPLOY.md — non-trivial deploy (Docker + fly.toml) - ... ## REMOVE / INLINE PROPOSALS - [HUMAN] DEPLOY.md — trivial deploy, inline into README instead - ... ``` **Tagging rules:** - **AUTO** — factual update Claude can write: command changed, var renamed, param added, version bumped, file moved, dead reference removed, new entry point added to a list, new link added to existing doc. - **HUMAN** — needs business context: feature wording, architecture rationale, changelog entry content, new section creation, deprecation notes, README/DEPLOY bootstrap content, decisions.md ↔ code reconciliation. **Feature delta tags:** - `[ADDED]` — feature in code, not in docs. AUTO for list entry with obvious wording, HUMAN if needs new section. - `[REMOVED]` — feature in docs, not in code. AUTO for list entry to delete, HUMAN if needs deprecation note. CHANGELOG entries always HUMAN. README/DEPLOY creation always HUMAN. If no drift in any doc and no missing required doc: `DOC SYNC: all docs current` and stop. ### STEP 8 — VALIDATION GATE (mandatory stop) ``` DOC SYNC — VALIDATION GATE AUTO items : (Claude will patch these) HUMAN items : (listed above for review) CREATE items : (README/DEPLOY proposals) REMOVE items : Apply AUTO patches? (yes / select items / cancel) Apply HUMAN/CREATE items? (per-item: yes / no / edit) ``` Wait for explicit approval. Do not proceed without it. ### STEP 9 — PATCH Apply only approved items: - Surgical Edit for AUTO items. Preserve structure and tone. - Write for approved CREATE items (README, DEPLOY). Use real project data only — no `` placeholders, no fabricated feature descriptions. - For removals, prefer Edit (delete dead lines) over Write. - Re-read each modified file post-edit to verify no broken markdown, no orphaned references. ### OUTPUT ``` DOC SYNC COMPLETE DOCS CHECKED : AUTO PATCHED : items across files CREATED : files REMOVED : files HUMAN PENDING: items (see report above) SKIPPED : (user declined) ``` --- ## AUTO MODE Triggered by other skills at end of session. Input format: `auto-mode scope: ...` ### STEP A1 — PARSE SCOPE Extract file list from `$ARGUMENTS`. These are files modified during the current session. ### STEP A2 — IDENTIFY RELEVANT DOCS Map modified files to relevant docs: - Code files → README (examples, feature list), USAGE, docs/ - Config files → INSTALL, CONFIGURE, README setup section - Package manifest → README (prereqs, install), INSTALL - Dockerfile/compose → README Docker section, INSTALL, DEPLOY - Deploy artifacts (fly.toml, workflows, k8s manifests, etc.) → DEPLOY (or trigger STEP 6 gate if no DEPLOY.md), README - CLAUDE.md change → skip (self-documenting) - `.claude/memory/decisions.md` change with architectural impact → CLAUDE.md, README If no relevant docs exist for changed files → exit silently. ### STEP A3 — QUICK DRIFT CHECK For each relevant doc, read it and check only sections affected by scoped changes. No full git scan — compare doc content directly against current state of modified files. Feature deltas in scoped files: - New files added → feature/module documented? - Files deleted → doc references to remove? - New exports/routes/commands → listed in relevant docs? Categorize: - **NONE** — no drift detected. - **MINOR** — factual correction (command, param, path, version), dead reference removal, new list entry add. - **SIGNIFICANT** — new feature undocumented, section outdated, breaking change not reflected, feature removed without doc update, new deploy artifact (Dockerfile, fly.toml, workflow) without DEPLOY.md update or creation. ### STEP A4 — ACT - **NONE** → exit completely silent. No output. - **MINOR** → patch silently. One-line confirmation: `doc-sync: patched ()` - **SIGNIFICANT** → surface to user before patching: ``` DOC SYNC — drift detected after this session: Apply? (yes / no / select) ``` Wait for approval. --- ## RULES - Never invent content. Only sync what changed in code. - Never fabricate examples, feature descriptions, explanations. - Doc creation (README, DEPLOY) requires HUMAN approval and uses real project data only. - Doc list is dynamic — auto-detect, never assume fixed set. - DEPLOY.md only when `DEPLOY_COMPLEXITY == NON_TRIVIAL`. Trivial deploy belongs in README. - README always required. Bootstrap if missing. - CHANGELOG entries: always propose, never auto-write. - Inline comment updates: only for files in scope, only when signature actually changed. - `.claude/memory/journal.md` and `evals.md` are append-only logs — never edit. - `.claude/memory/decisions.md` / `learnings.md` / `blockers.md` are user-curated registries — surface drift, don't auto-edit (HUMAN only). - Preserve existing structure, formatting, tone. - Patches minimal — change what's wrong, nothing else.