diff --git a/agents/doc-syncer.md b/agents/doc-syncer.md index 9c674f3..3c2b1c8 100644 --- a/agents/doc-syncer.md +++ b/agents/doc-syncer.md @@ -1,6 +1,6 @@ --- name: doc-syncer -description: Detect stale documentation by cross-referencing git history against doc files. Audit, report, and patch. Supports full audit and automatic (silent) mode. +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 --- @@ -9,8 +9,10 @@ model: sonnet ## GOAL Keep documentation in sync with code. Detect drift, report it, -and patch what can be patched automatically. Never invent content --- only reflect what actually changed in code. +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 @@ -19,135 +21,265 @@ $ARGUMENTS ## MODE DETECTION -Parse `$ARGUMENTS` to determine mode: +Parse `$ARGUMENTS`: - **AUTO MODE** — `$ARGUMENTS` starts with `auto-mode scope:` - Jump directly to AUTO MODE section below. + Jump to AUTO MODE section. - **FULL AUDIT** — anything else (empty, file list, description) - Run the full audit workflow below. + Run the full audit workflow. --- ## FULL AUDIT -### STEP 1 — DISCOVER DOCS +### STEP 1 — DISCOVER PROJECT DOC LAYOUT -Find all documentation files in the project: +Auto-detect what doc files actually exist. No fixed list. ```bash -# Standard doc files at root -ls README.md CLAUDE.md INSTALL.md CONFIGURE.md USAGE.md \ - CONTRIBUTING.md CHANGELOG.md 2>/dev/null +# 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 directory -find docs -name '*.md' 2>/dev/null | head -50 +# 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 the list as `DOC_FILES`. -If no docs found at all, report and stop. +Store as `DOC_FILES` (existing) and `DOC_MISSING` (canonical names +absent — at minimum: README.md). -### STEP 2 — DETECT DRIFT PER DOC +### 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 its last modification date: +1. Get last modification date: ```bash git log -1 --format=%aI -- ``` -2. Get all commits touching the codebase since that date: +2. Get commits touching the codebase since that date. Adapt globs + to detected `STACK`: ```bash git log --oneline --since="" \ - --diff-filter=AMRD -- '*.py' '*.ts' '*.js' '*.tsx' \ - '*.jsx' '*.rs' '*.go' '*.java' '*.c' '*.cpp' '*.h' \ - '*.toml' '*.json' '*.yaml' '*.yml' '*.env.example' \ + --diff-filter=AMRD -- \ 'Dockerfile' 'docker-compose.yml' 'Makefile' \ - 'package.json' 'Cargo.toml' 'pyproject.toml' + '*.toml' '*.json' '*.yaml' '*.yml' '*.env.example' ``` - Adapt glob list to the project's actual stack. -3. For each commit, extract what changed: +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, - dependency adds/removes/upgrades, - **new features added**, **features removed or deprecated**. + dep adds/removes/upgrades, new features, removed features. -4. Cross-reference each change against the doc's content. - Read the doc file and check if the change is reflected. +4. Cross-reference each change against doc content. -5. **Feature delta detection** — compare what the code provides - vs what the docs describe: - - Scan for new entry points, routes, commands, skills, or - modules that have no corresponding doc section → ADDED. - - Scan docs for references to functions, files, endpoints, - or features that no longer exist in the codebase → REMOVED. +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 files added (`A`) or deleted (`D`). + identify added (`A`) / deleted (`D`) files. -### STEP 3 — ANALYSIS PER DOC TYPE +### STEP 4 — ANALYSIS PER DOC TYPE -Apply doc-specific checks: +Apply doc-specific checks. Skip docs not in `DOC_FILES` (handled +by STEP 5/6 if creation needed). -**README.md** -- Install steps: do commands still match package manifest and CLAUDE.md? -- Feature list: does it cover current functionality? - - **Added features:** new skills, commands, endpoints, or modules - present in code but missing from the feature list → tag AUTO - if name/description is obvious, HUMAN if wording needs judgment. - - **Removed features:** entries in the feature list that reference - code, files, or endpoints that no longer exist → tag AUTO for - removal, HUMAN if the feature was deprecated (needs migration note). -- Examples: do code snippets match current API/signatures? -- Prerequisites: are versions and tools still accurate? -- Docker section: present if Docker is used, absent if not? +**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: do coding conventions match current project patterns? -- Stack description: still accurate? -- Commands (build/test/lint): still runnable? -- Folder tree: matches actual structure? -- New patterns worth documenting? +- 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 / CONFIGURE.md** -- Environment variables: do all referenced vars exist in .env.example? -- Install steps: match current dependency manager and versions? -- Configuration steps: reference current config file format? +**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 and commands: match current implementation? -- API endpoints: match current routes? -- Code examples: match current signatures? +- 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: still accurate? -- Test commands: still correct? -- Code style rules: still enforced? +- Branch workflow accurate? +- Test commands correct? +- Code style rules still enforced (lint config, formatter)? **CHANGELOG.md** -- Latest code changes: do they have corresponding entries? -- Entry format: consistent with existing style? +- Latest code changes have entries? Always HUMAN. +- Entry format consistent with existing style? **docs/**/*.md** -- Technical accuracy: do references to code match reality? -- Links: do internal links point to existing files/sections? +- 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 that changed since last doc update. -- `@param` / `@return` types: match actual function signatures? -- Description: still accurate after the change? +- Only check files changed since last doc update. +- `@param` / `@return` types match actual function signatures? +- Description still accurate after the change? -### STEP 4 — REPORT +### STEP 5 — README BOOTSTRAP CHECK -Present a structured report: +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: () @@ -161,53 +293,64 @@ Last updated: () --- (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: +**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. -- **HUMAN** — needs business context or judgment: feature - description wording, architecture rationale, changelog entry - content, new section creation, deprecation notices. + 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 exists in code but not in docs. - AUTO if it's a list entry (add name + one-line description). - HUMAN if it needs a new section or paragraph. -- **[REMOVED]** — feature documented but no longer in code. - AUTO if it's a list entry to delete. - HUMAN if it needs a deprecation note or migration guidance. +**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 are always tagged HUMAN — version bump and -release notes are human decisions. +CHANGELOG entries always HUMAN. README/DEPLOY creation always +HUMAN. -If no drift detected in any doc: print +If no drift in any doc and no missing required doc: `DOC SYNC: all docs current` and stop. -### STEP 5 — VALIDATION GATE (mandatory stop) +### STEP 8 — VALIDATION GATE (mandatory stop) ``` DOC SYNC — VALIDATION GATE -AUTO items : (Claude will patch these) -HUMAN items: (listed above for your review) +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 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 6 — PATCH +### STEP 9 — PATCH -Apply only approved AUTO items: -- Surgical edits only. Preserve existing structure and tone. -- For each edit, use the Edit tool with minimal old_string/new_string. -- Do not rewrite surrounding prose. Do not reformat. -- If a doc section doesn't exist yet for a change, propose creating - it but do NOT auto-write. Tag as HUMAN and surface to user. - -After patching, re-read each modified file to verify no broken -markdown, no orphaned references. +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 @@ -215,6 +358,8 @@ markdown, no orphaned references. DOC SYNC COMPLETE DOCS CHECKED : AUTO PATCHED : items across files +CREATED : files +REMOVED : files HUMAN PENDING: items (see report above) SKIPPED : (user declined) ``` @@ -228,43 +373,48 @@ Input format: `auto-mode scope: ...` ### STEP A1 — PARSE SCOPE -Extract the file list from `$ARGUMENTS`. -These are files modified during the current session. +Extract file list from `$ARGUMENTS`. These are files modified +during the current session. ### STEP A2 — IDENTIFY RELEVANT DOCS -For each modified file, determine which docs might reference it: +Map modified files to relevant docs: - Code files → README (examples, feature list), USAGE, docs/ -- Config files → INSTALL, CONFIGURE, README (setup section) -- Package manifest → README (prerequisites, install), INSTALL -- Dockerfile/compose → README (Docker section), INSTALL -- CLAUDE.md changes → skip (CLAUDE.md is self-documenting) +- 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 the changed files → exit silently. +If no relevant docs exist for changed files → exit silently. ### STEP A3 — QUICK DRIFT CHECK -For each relevant doc, read it and check only the sections that -could be affected by the scoped changes. No full git scan — -compare the doc content directly against the current state of -the modified files. +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. -Also check for feature deltas in the scoped files: -- New files added → is the feature/module documented? -- Files deleted → are there doc references to remove? -- New exports, routes, commands → listed in relevant docs? +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 findings: -- **NONE** — no drift detected +Categorize: +- **NONE** — no drift detected. - **MINOR** — factual correction (command, param, path, version), - dead reference to remove, new list entry to add + dead reference removal, new list entry add. - **SIGNIFICANT** — new feature undocumented, section outdated, - breaking change not reflected, feature removed without doc update + 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 at all. -- **MINOR** → patch silently. Print one-line confirmation: +- **NONE** → exit completely silent. No output. +- **MINOR** → patch silently. One-line confirmation: `doc-sync: patched ()` - **SIGNIFICANT** → surface to user before patching: ``` @@ -278,11 +428,20 @@ Categorize findings: ## RULES - Never invent content. Only sync what changed in code. -- Never fabricate examples, feature descriptions, or explanations. -- If a doc section doesn't exist yet, propose creating it but - don't auto-write (tag HUMAN). +- 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. -- Preserve existing doc structure, formatting, and tone. -- Keep patches minimal — change what's wrong, nothing else. +- `.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. diff --git a/skills/doc/SKILL.md b/skills/doc/SKILL.md index 3280559..f12e118 100644 --- a/skills/doc/SKILL.md +++ b/skills/doc/SKILL.md @@ -1,15 +1,21 @@ --- name: doc description: | - Full documentation audit and sync. Detects stale docs by cross-referencing - git history against README, CLAUDE.md, INSTALL.md, CONFIGURE.md, USAGE.md, - CONTRIBUTING.md, CHANGELOG.md, docs/**/*.md, and inline comments (JSDoc, - docstrings, rustdoc, godoc). Reports drift with commit refs, proposes fixes, - patches approved items. Detects added features missing from docs and removed - features still documented (feature delta detection). + Full documentation audit and sync. Auto-detects what doc files the project + actually has — root docs (README, CLAUDE.md, INSTALL.md, CONFIGURE.md, + USAGE.md, DEPLOY.md, CONTRIBUTING.md, CHANGELOG.md), docs/**/*.md, project-state + files in .claude/{tasks,audits,memory}/, and inline comments (JSDoc, docstrings, + rustdoc, godoc). Stack-aware: detects framework + deploy complexity, proposes + DEPLOY.md only when non-trivial (Docker, fly.toml, k8s, multi-stage CI), skips + for trivial deploys (FTP push, single scp, plain static). Enforces README + presence with typical GitHub layout (title, quick start, links to existing + sub-docs). Cross-references git history for drift; detects added features + missing from docs and removed features still documented (feature delta + detection). Reports drift with commit refs, proposes fixes, patches approved + items. Trigger: "doc", "sync docs", "audit docs", "update readme", "check documentation", "are docs up to date", "documentation drift", "stale docs", "new feature not documented", - "removed feature still in docs". + "removed feature still in docs", "create README", "should I have a DEPLOY doc". Replaces the old /readme skill with broader scope. argument-hint: [leave empty for full audit, or list specific files/docs to check] disable-model-invocation: false