feat(docs): add doc-reference drift gate#318
Merged
Merged
Conversation
A multi-agent sweep of all 126 repo docs (24 agents, adversarially verified) found references to scripts, tasks, files, and models that changed but whose docs never followed. Fixes span 8 root causes: - MCP scoping: drop the deleted update-ai-tools.sh; document the per-project .mcp.json model + /configure:mcp (README, CLAUDE.md, package-registries.md, .chezmoidata.toml, cleanup-mcp-servers.sh). - Secret scanning: detect-secrets -> gitleaks; .secrets.baseline was removed in #169 (CLAUDE.md, scripts/README.md, project-overview.md). - .chezmoidata split: registries moved to .chezmoidata/*.toml; repoint completions + uv_tools refs (shell-completions.md, homebrew-mise-migration-analysis.md, project-overview.md). - Blueprint externalized to blueprint-plugin: note the in-repo skills/commands no longer exist (exact_dot_claude/docs/blueprint-development/*). - Dangling sub-doc links: remove exact_dot_claude/commands|skills/CLAUDE.md bullets (CLAUDE.md). - nvim AI plugin swap: CodeCompanion -> claudecode.nvim/opencode.nvim (docs/components.md, neovim-configuration/SKILL.md). - mise task rename: test:docker -> docker (testing.md). - Stale paths/versions: blueprint v3.2.0 -> v3.3.0, drop nonexistent work-orders/, ai_docs/, and private_i3/ rows (blueprint/README.md, private_dot_config/CLAUDE.md). Also folds in pre-existing README markdownlint fixes (blank lines before code fences; claude /plugin install -> claude plugin install). ADRs left untouched as immutable point-in-time records. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lrwvogo4vM5kfpyrjoaPad
A deterministic guardrail for the mechanical slice of doc drift that PR #317 just fixed by hand: docs referencing scripts/paths/links that no longer exist. Complements the periodic LLM sweep, which owns the semantic "is this prose still true?" tail — the mechanical check owns "does X exist?". - scripts/check-doc-references.py: precision-first checker. Flags relative markdown links that don't resolve, and inline-code path tokens anchored to a real top-level repo entry (incl. `./name` root scripts). chezmoi-aware (resolves rendered names against executable_/dot_/*.tmpl sources), skips slash commands, domains, placeholders, ~/ paths, and fenced code. Structured KEY=VALUE/STATUS output; advisory by default, `--strict` exits 1. - .doc-reference-allow: scopes out immutable ADRs and the exact_dot_claude/ global tree (references external plugins / other projects, not this repo). - Pre-commit: advisory hook (always exits 0, verbose nudge) — never blocks. - mise: `lint:docs` (strict, for CI) + advisory step folded into `lint`. - scripts/tests/test-check-doc-references.sh: pins the flag/clean contract and asserts the live tree is STATUS=OK. Verified: catches update-ai-tools.sh / dead full paths / broken links; passes chezmoi-managed scripts, slash commands, domains. Live tree clean (0 dangling). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lrwvogo4vM5kfpyrjoaPad
laurigates
added a commit
that referenced
this pull request
Jul 12, 2026
## Summary The queued follow-up from the doc-drift work. ADR 0015 replaced detect-secrets with **gitleaks** (#169) and deleted `.secrets.baseline`, but the detect-secrets integration lingered across the repo — recipes, tasks, hooks, and permission grants all pointing at the now-missing baseline. This excises it and routes every secret scan through gitleaks (already installed via `mise` `aqua:gitleaks`). ## Removed - `scripts/audit-secrets-baseline.py`, `scripts/audit-secrets-selective.py` — baseline-audit tools for the deleted `.secrets.baseline` - `scripts/README.md` — was *entirely* the detect-secrets audit manual (no inbound links; preserved in git history) ## Rewired detect-secrets → gitleaks Using the `dir` subcommand (gitleaks **v8.18+ dropped `detect`**): | Site | Change | |---|---| | `justfile` | `secrets` recipe + `doctor` optional-tools list | | `mise` config | `security:audit` step, `security:scan` task, commented enter-hook | | `nixos/home/development.nix` | pre-commit hook → gitleaks v8.30.1 | | `.github/claude-tools-config.json`, `exact_dot_claude/modify_settings.json` | permission grants → narrow `gitleaks dir` / `gitleaks` | | `.github/labeler.yml` | security-label glob `.secrets.baseline` → `.gitleaks.toml` | | `docs/mise-migration-guide.md` | task descriptions | ## Bonus fix `CLAUDE.md` used `gitleaks detect --source .` (from #317) — but `detect` was removed in gitleaks 8.18+. Corrected to `gitleaks dir .` (verified against the installed 8.30.1). ## Left as-is (deliberate) - **ADR 0012 / 0015** — immutable point-in-time records; they document the detect-secrets→gitleaks decision historically. - **`exact_dot_claude/docs/prds/daily-catchup.PRD.md`** — external-facing PRD for an unrelated feature. ## Guardrail earned its keep The #318 doc-reference gate flagged a **latent bug from #318 itself** mid-change: `scripts/CLAUDE.md` referenced `tests/…` (resolves to top-level `tests/`) instead of `scripts/tests/…`. Fixed here. ## Validation - `mise run lint:docs` → `STATUS=OK` (0 dangling) - `git rev-parse` sanity: `gitleaks dir .` runs clean on the tree (no leaks); `just --list` parses; `modify_settings.json` overlay yields valid JSON - Regression test + pre-commit (incl. gitleaks) → all pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The guardrail follow-up to #317. A deterministic gate for the mechanical slice of doc drift — docs referencing scripts/paths/links that no longer exist — so the class #317 fixed by hand can't silently return.
Stacked on #317 (base =
docs/fix-stale-references): it needs the fixed docs to pass. Merge #317 first, then this. (If #317 is squash-merged and its branch deleted, retarget this PR's base tomainbefore that merge to avoid the auto-close trap — GitHub doesn't retarget stacked children.)Why not
surface?Researched the
surfacetool you linked +/configure:surface. It anchors prose claims to code-symbol logic fingerprints (flipped operator, droppedawait) in Rust/TS/Python/Go. This is a dotfiles repo — almost no code symbols to anchor to — and every one of #317's 19 findings was a dead reference or superseded prose, none logic drift. Surface would've caught zero of them. Right tool, wrong repo. Built the reference-existence checker yourclaude-pluginsrepo'scheck-plugin-readme-currency.shpattern already points at instead.What it does
scripts/check-doc-references.py./nameroot scripts). chezmoi-aware (resolves rendered names againstexecutable_/dot_/*.tmplsources). Skips slash commands, domains, placeholders,~/, fenced code. StructuredKEY=VALUE/STATUS=output.verbosenudge. Never blocks a commit (judgment calls shouldn't hard-gate).mise run lint:docs--strict, exit 1) — the enforcing variant for CI; also folded advisory intomise run lint..doc-reference-allowexact_dot_claude/global tree (references external plugins / other projects, not this repo).scripts/tests/test-check-doc-references.shSTATUS=OK.Design split (why mechanical + semantic, not one tool)
Validation
DANGLING_COUNT=0,STATUS=OK../update-ai-tools.sh, dead full paths, broken links; passes chezmoi-managed scripts, slash commands, domains, valid links.🤖 Generated with Claude Code