DocGuard

Official registry Security

Deterministic doc-drift detection: guard, score, explain, verify-claims and diagnose MCP tools.

Install

Add this to your client's MCP configuration (Claude Desktop: claude_desktop_config.json; Cursor: .cursor/mcp.json; VS Code and others use the same "mcpServers" shape).

NPM package docguard-cli
Claude Code
claude mcp add docguard -- npx -y docguard-cli@0.40.5 mcp
JSON configuration (Claude Desktop, Cursor, VS Code)
{
    "mcpServers": {
        "docguard": {
            "command": "npx",
            "args": [
                "-y",
                "docguard-cli@0.40.5",
                "mcp"
            ]
        }
    }
}

Documentation

From the project's README on GitHub, refreshed weekly. Links open on GitHub.

Contents
  1. 🛡️ DocGuard
  2. Table of Contents
  3. What is DocGuard?
  4. Why DocGuard?
  5. ⚡ Quick Start
  6. 🌱 Spec Kit Integration
  7. Usage
  8. 🔍 Validators
  9. 🎚️ Reading a Finding
  10. 📄 Templates
  11. 🤖 AI Agent Support
  12. ⚡ Slash Commands
  13. 🧠 AI Skills (Enterprise)
  14. 📁 Examples
  15. 🧪 Testing
  16. 🏢 Enterprise Adoption
  17. ⚙️ CI/CD Integration
  18. ✨ What's New
  19. 📁 File Structure
  20. ⚙️ Configuration
  21. 🔬 Research Credits
  22. ⭐ Star History
  23. 🔒 Privacy & Supply Chain
  24. 📄 License

🛡️ DocGuard

English · Português (BR) · Español

The enforcement layer for Spec-Driven Development. Validate. Score. Enforce. Ship documentation that AI agents can actually use.

-green)


✨ See what DocGuard catches in 30 seconds — no install, no setup:

npx docguard-cli demo

Runs against a baked-in sample project with intentional drift and shows you the findings + a clear path to fixing them.

📚 Documentation: Installation · Existing projects · Spec Kit · CI · Languages and frameworks · Coding agents · Finding codes · Troubleshooting


Table of Contents


What is DocGuard?

DocGuard enforces Canonical-Driven Development (CDD) — a methodology where documentation is the source of truth, not an afterthought. AI writes the docs, DocGuard validates them.

Traditional DevelopmentCanonical-Driven Development
Code first, docs maybeDocs first, code conforms
Docs rot silentlyDrift is tracked and enforced
Docs are optionalDocs are required and validated
One AI agent, one contextAny agent, shared context via canonical docs

DocGuard is an official GitHub Spec Kit community extension. It validates the artifacts that Spec Kit creates, ensuring your specs stay high-quality throughout the development lifecycle.

🧭 How it works (9-page brief) (PDF) · 📖 Philosophy · 📋 CDD Standard · ⚖️ Comparisons · 🔬 Validation · 🗺️ Roadmap

Architecture
graph TD
    CLI["CLI Entry<br/>docguard.mjs"] --> Commands["Commands (27)"]
    Commands --> guard["guard"]
    Commands --> generate["generate"]
    Commands --> score["score"]
    Commands --> diagnose["diagnose"]
    Commands --> setup["setup wizard"]
    Commands --> other["diff · init · fix · trace · impact · sync · reconcile · retire · specs · ignore<br/>explain · memory · upgrade · agents · hooks · badge · ci · watch"]

    guard --> Validators["Validators (34)"]
    generate --> Scanners["Scanners (4)<br/>routes · schemas · doc-tools · speckit"]
    score --> Scoring["Weighted Scoring<br/>8 categories"]
    diagnose --> Validators
    diagnose --> AIPrompts["AI-Ready<br/>Fix Prompts"]

    Validators --> Output["Output"]
    Scanners --> Output
    Scoring --> Output
    Output --> Terminal["Terminal"]
    Output --> JSON["JSON"]
    Output --> Badge["Badge"]

    style CLI fill:#2d5016,color:#fff
    style Validators fill:#1a3a5c,color:#fff
    style Scanners fill:#1a3a5c,color:#fff
    style Output fill:#5c3a1a,color:#fff

Distribution: Node.js core (npm) · Python wrapper (PyPI) · GitHub Action (action.yml) · Spec Kit Extension (ZIP)


Why DocGuard?

DocGuard checks declared documentation facts against repository evidence and gives agents structured repair tasks. Deterministic checks cover supported facts, references, and generated sections. Human-authored requirements and architectural decisions retain their authority when implementation diverges.

A guard result describes the checks performed. The CDD grade measures structural maturity. Exact declarations in .docguard-evidence.json can verify selected statements against current local evidence; every other statement remains unverified. Coverage and unresolved claims remain visible, so teams can choose an appropriate enforcement policy.

Research motivates evaluation of this approach. A 2026 study found that repository context files did not generally improve task success and increased inference cost in its evaluated settings. It also found agents generally followed the instructions. These results support testing concise, relevant context and measuring actual task outcomes; they do not establish DocGuard's effectiveness. Evaluating AGENTS.md, revised June 2026.

The current roadmap prioritizes accurate detection, reproducible evidence, document lifecycle management, and contributor-supplied regression cases. Released plans and superseded specifications are removed from active AI context and remain recoverable from Git.


⚡ Quick Start

Package naming: this repo is raccioly/docguard; the published package is docguard-cli on both npm and PyPI; the installed command is docguard. Same project — the -cli suffix is just the registry name. The package runs no install scripts, so npm i -g docguard-cli --ignore-scripts is equivalent.

Node.js (npm)
# No install needed — run directly
npx docguard-cli diagnose

# Or install globally
npm i -g docguard-cli
docguard diagnose
Python (PyPI)
pip install docguard-cli
docguard diagnose

Note: The Python package is a thin wrapper that delegates to npx. Node.js 18+ is required on the system.

Docker (MCP server)

The MCP server ships as a container image on GHCR — no Node.js install required. Public image, so no authentication is needed to pull it:

# Run the MCP server against the current directory
docker run -i --rm -v "$PWD":/workspace ghcr.io/raccioly/docguard:latest

The entrypoint is the stdio MCP transport: stdout is the JSON-RPC channel, so don't pipe anything else into it. Mount the project you want inspected at /workspace; tools inspect it by default, and a projectDir in a tool call must be /workspace or a directory inside it (add --root <dir> after the image name to serve another mounted tree).

Pin a version rather than tracking latest in CI:

docker run -i --rm -v "$PWD":/workspace ghcr.io/raccioly/docguard:0.34.9

The server is read-only — it never writes to the mounted project.

More ways to integrate
  • pre-commit — changed-only guard on every commit:
    repos:
      - repo: https://github.com/raccioly/docguard
        rev: v0.45.1
        hooks: [{ id: docguard-guard }]   # docguard-guard-full for pre-push
  • MCP (Claude, Cursor, any MCP client) — claude mcp add docguard -- npx -y docguard-cli mcp; read-only tools to check docs (guard, score, diagnose, …) and to navigate them one bounded section at a time — the full list is in docs/ai-integration.md. Registry manifest ships in-repo (server.json, Smithery-ready).
  • GitLab CI — component staged at templates/ci/gitlab-component.yml (guard/score/ci job with a SARIF artifact).
  • Homebrew — brew install raccioly/tap/docguard. The release workflow renders the formula template in packaging/homebrew/ from the published npm tarball and pushes it to the tap.
Core Workflow
# 1. Initialize docs for your project
npx docguard-cli init

# 2. Or reverse-engineer docs from existing code
npx docguard-cli generate

# 3. AI diagnoses issues and generates fix prompts
npx docguard-cli diagnose

# 4. Validate — use as CI gate
npx docguard-cli guard

# 5. Check maturity score
npx docguard-cli score
The AI Loop
diagnose  →  AI reads prompts  →  AI fixes docs  →  guard verifies
   ↑                                                       ↓
   └───────────────── issues found? ←──────────────────────┘

diagnose is the primary command. It runs all validators, maps every failure to an AI-actionable fix prompt, and outputs a remediation plan. Your AI agent runs it, fixes the docs, and runs guard to verify.

Mechanical vs. agent fixes

DocGuard splits drift into two kinds and is explicit about which is which:

KindExampleHow it's fixed
Mechanical (deterministic)An endpoint documented in API-REFERENCE.md that the OpenAPI spec confirms is gonedocguard fix --write deletes the row + detail block itself — no AI
Agent (needs judgment)Rewriting an X-Ray prose section as CloudWatch; writing a new endpoint's request/responseRouted to an AI agent via diagnose / fix --doc prompts

docguard fix --write only touches docs marked ` (override with--force`), is idempotent, and prints exactly what changed. It never rewrites prose — that stays with the agent.

Continuous documentation workflow
guard ──▶ fix --write (mechanical, auto) ──▶ guard ──▶ diagnose (agent prompts for the rest)
  • CI / pre-commit: docguard hooks --type pre-commit --auto-fix installs a hook that applies mechanical fixes, re-stages the docs, then runs guard; anything left is surfaced as agent prompts.
  • Agent-driven: docguard diagnose --auto scaffolds missing docs and applies mechanical fixes, then emits prompts for the content rewrites that remain.
  • JSON for automation: guard/diagnose --format json include a mechanicalFixes array and tag each issue mechanical vs agent, so an agent can apply or delegate precisely.

🌱 Spec Kit Integration

DocGuard is a community extension for GitHub's Spec Kit framework. While Spec Kit focuses on creating specifications (via AI slash commands like /speckit.specify and /speckit.plan), DocGuard focuses on validating their quality.

How They Work Together
┌─────────────────┐          ┌──────────────────┐
│    Spec Kit      │          │    DocGuard       │
│                  │          │                   │
│  /speckit.specify│ ──────→  │  docguard guard   │
│  Creates specs   │          │  Validates specs  │
│  (AI-driven)     │          │  (automated)      │
└─────────────────┘          └──────────────────┘
PhaseToolWhat happens
1. Initializespecify initCreates .specify/ directory and templates
2. Write specs/speckit.specifyAI creates spec.md with FR-IDs, user stories
3. Validatedocguard guardChecks spec quality (mandatory sections, FR/SC IDs)
4. Plan/speckit.planAI creates plan.md with technical context
5. Validatedocguard guardChecks plan quality (sections, structure)
6. Tasks/speckit.tasksAI creates tasks.md with phased breakdown
7. Validatedocguard guardChecks task quality (phases, T-IDs)
8. Implement/speckit.implementAI writes code
9. Enforcedocguard guardFinal quality gate — CI/CD
What DocGuard Validates in Spec Kit Projects
  • spec.md — Mandatory sections (User Scenarios, Requirements, Success Criteria), FR-xxx IDs, SC-xxx IDs
  • plan.md — Summary, Technical Context, Project Structure sections
  • tasks.md — Phased task breakdown (Phase 1, 2, 3+), T-xxx task IDs
  • constitution.md — Detected at .specify/memory/constitution.md or project root
  • Requirement traceability — FR, SC, NFR, US, AC, UC, SYS, ARCH, MOD, T IDs
Installing as a Spec Kit Extension

docguard init does this for you: when the specify CLI (Spec Kit ≥ 0.11.2, the floor the extension declares) is on your PATH, it initializes Spec Kit for the coding agent the repository already uses, then registers the DocGuard extension shipped inside the installed package. Nothing is downloaded for the registration. If a project's registered extension is from another DocGuard release, init re-registers it when the versions differ (keeping its priority), and docguard upgrade --apply does the same. init says the workflow hooks are active only after each mandatory hook (speckit.docguard.brief before specify, speckit.docguard.preflight before tasks, speckit.docguard.guard after implement) resolves to a command file your agent can run; otherwise it names the missing one. Spec Kit registers no extension commands for its generic integration, so for generic DocGuard writes them next to Spec Kit's own commands (.agent/commands/ by default). Every failure is printed with Spec Kit's own error and the command to run by hand. Only init and upgrade --apply touch Spec Kit; other commands print a one-line hint at most.

DocGuard's own skills go where your agent reads them: .claude/skills/ for Claude Code (or the skills directory of another skills-based integration), .agent/ for the generic integration or an agent DocGuard cannot place. A commands-only integration such as Gemini gets Spec Kit's speckit.docguard.* commands and no extra copies. The command and skill files run docguard from your PATH when it is installed, and otherwise npx --yes docguard-cli@<version>, pinned to the release they shipped with; they never fetch @latest.

Suggestions DocGuard prints (Next: …, Fix: …) name a slash command only when its file exists for your agent, in its form (/speckit-docguard-guard in Claude Code, /speckit.docguard.guard for generic); otherwise they print the CLI command.

docguard init registers the copy of the extension inside the installed package. To register it yourself, use a release ZIP or a local checkout. A bare specify extension add docguard does not work on a default Spec Kit setup: DocGuard is in Spec Kit's community catalog, which Spec Kit uses for discovery only.

specify extension add docguard --from https://github.com/raccioly/docguard/releases/download/vX.Y.Z/spec-kit-docguard-vX.Y.Z.zip
specify extension add ./node_modules/docguard-cli/extensions/spec-kit-docguard --dev

See the Spec Kit guide for the hooks, the spec lifecycle registry and an end-to-end flow.

This registers the speckit.docguard.* commands listed in extension.yml (invoked as /speckit-docguard-guard and so on in skills-based agents such as Claude Code) and the workflow hooks that run them.


Usage

DocGuard ships 27 commands (the "Daily 5" + 22 situational tools, including lifecycle reconciliation, doc dependency review, requirement anchors, agent-rule resolution, the suppression listing, retirement and spec tracking, the zero-install demo, the mcp server, and the ci pipeline gate). Six additional one-shot scaffolders are accessed via docguard init --with <name>. Legacy command forms remain compatible until v1.0 and print their replacements.

The Daily 5 — what you'll reach for 95% of the time:

CommandWhat It Does
initBootstrap a project (--wizard for interactive · --with <name> for scaffolders)
guardValidate against canonical docs — 34 validators
diffShow gaps between docs and code (--since <ref> for impact mode)
syncRefresh code-truth doc sections, including the module-graph and entity-diagram mermaid diagrams drawn from code — keeps memory always up to date
scoreStructural CDD maturity score (0-100; not a guard verdict; --diff for delta between refs)

Tools (situational, but day-to-day useful):

CommandPurpose
demoZero-install showcase — runs guard against a baked-in drifting fixture (npx docguard-cli demo)
diagnoseAI orchestrator — guard → emit fix prompts in one command
fixGenerate AI fix instructions for specific docs (--doc <name> --format prompt)
fix --writeApply deterministic fixes (no AI — version bumps, counts, anchors, sections)
fix --historyAudit log of every mechanical fix applied (from .docguard/fixed.json)
generateReverse-engineer docs from existing codebase (--plan for AI scan) — includes auto-generated Mermaid ER diagrams from your detected schemas (Prisma/Drizzle/TypeORM/Sequelize/Django/Rails) in DATA-MODEL.md. --spec <area> writes an as-built Spec Kit spec for one code area: one requirement candidate per route, exported symbol, env var or entity found there (the agent writes every statement), registered as origin: as_built; guard then reports new or vanished facts (SPR007)
agentOne-shot agent task graph, or a bounded current-evidence packet for one task (--task <text>, --format json)
`explain <warning\CODE>`Paste any warning — or a finding code like SEC001 — to get the validator's docstring, fix path, and how to suppress
verify --evidenceEvaluate strict statement-to-source declarations for typed JSON values, bounded collection counts, saved oasdiff JSON, and saved Buf JSON Lines. Results distinguish scoped verification, contradiction, stale inputs, inconclusive evidence, and unsupported formats.
verify --semanticExtract documented numbers/limits/enums (retention days, rate limits, GSI/role counts, status enums) as a task list for an agent to check against code — the semantic-drift class regex/AST can't see
verify --instructionsAudit AGENTS.md/CLAUDE.md themselves for drift: duplicate rules, never-vs-always contradictions, stale file pointers, unknown commands — plus clustered rule pairs as agent judgment tasks
feedbackReview any finding or a synthetic false-positive/false-negative/unsupported fixture; verify its opposite control, reduce it deterministically, search open and closed duplicates, and optionally emit a test-only contribution. Nothing is submitted automatically.
retireFind completed or superseded planning material (--plan/--check; --fail-on-warning gates advisory candidates) and explicitly remove clean tracked documentation from active AI context. .docguard-archive.json records recovery metadata and retired requirement identities, and --retention-ref proves the source revision remains reachable. This is separate from the Spec Kit Archive extension, which consolidates feature documents.
reconcileBuild a read-only code↔spec review graph since a Git ref. Classifies mechanical facts, approved intent, decisions, unrelated changes, and unsupported evidence; --write applies only mechanical generated-section refreshes.
reviewDoc sections whose covered code changed since their last review (--accept <doc>#<id> --reason, --prune, --suggest)
anchorsEvery @implements/@req tag, the requirement it resolves to, and the symbol, statement, route or file it anchors to, with the tier that resolved it (--spec <id>, --file <path>, --format json)
ignoreEvery suppression in the project (.docguardignore entries with their # reason and expires: date, .docguard.json ignore arrays, inline pragmas, N/A markers, the baseline) with its state; --format claimspec exports the reasoned .docguardignore entries as a claimspec ignore document and reports what it left out
rulesWhich agent instruction files each harness (Codex, Claude Code, Cursor, Copilot, OpenHands) loads for a path, why, and how many bytes (--for <path>, --harness)
specsMaintain the versioned spec registry, preflight new specs, and apply evidence-gated completion transactions with bounded outcomes and active-context regeneration. Verified living specs can record later reviewed maintenance without reopening or duplicating the specification. specs require is the spec-first gate: a change to governed paths must name its spec or declare Spec-Exempt: <kind> — <reason>.
specs --check / specs --writeValidate or refresh .docguard-specs.json, the byte-stable index of immutable spec IDs, reviewed lifecycle/lineage/scope, artifact digests, task state, explicitly scoped test evidence, and archive tombstones. Refreshes preserve the reviewed block.
specs preflight [--path <spec>]Before specification, print current spec lifecycle and evidence. Before planning, check the generated draft for structural blockers and report semantic overlap as review-only evidence.
specs approve --id <spec-id>Record a person's approval of a spec in the registry, and with --delivery its planned, in_progress or implemented state. Plans by default; --write records it. Verification stays with specs complete.
mcpMCP server — exposes checking (guard, score, explain, verify, report, diagnose) and exact doc navigation (docs for a file, document outline, one section, task context) as native tools for Claude, Cursor, and any MCP client; docguard_guard returns each fact once unless called with detail: "full". Stdio: claude mcp add docguard -- npx docguard-cli mcp. Team-shared HTTP: docguard mcp --transport http --port 8585 (loopback by default; non-loopback binds require --api-key)
reportCompliance-evidence bundle for audits — combined readiness, guard verdict, structural maturity, ALCOA+ attributes, and fix history, stamped with git commit and a tamper-evident sha256 integrity hash (--format json, --out <file>). Evidence, not a gate: always exits 0
ciPipeline gate: guard + structural maturity in one command with READY/ATTENTION/BLOCKED assessment — never scaffolds or touches source; its only write is its own .docguard/history.jsonl (opt out: --no-history). --threshold <n> fails below a score, --fail-on-warning for strict mode, --format json for parsers
score --trendScore trajectory from recorded ci runs — sparkline, delta, and the last 10 runs with commit stamps
memoryPer-domain accuracy headline (endpoints / entities / env / tech)
memory --diffDrill into which specific claims don't match code
memory --packWrite .docguard/context-pack.md — compact, code-truth-stamped session-start context for AI agents
score --diffDrill into which checks pulled each category down
trace / trace --reverse <file>Requirements traceability — forward AND reverse
trace --featuresPer-feature spec-adherence scores (requirement coverage, task completion, task evidence, artifacts) — worst-first with fix hints
upgrade [--apply] [--pr]Check npm for a newer CLI (the one command that contacts a registry) + migrate .docguard.json schema; --pr opens a PR. When the installed release is over 14 days old, guard's text output, the MCP server and the context pack suggest running docguard upgrade; nothing upgrades on its own (DOCGUARD_NO_UPDATE_HINT=1 silences the note)
watchLive mode: re-run guard on file changes

init --with <name> scaffolders — picked at init time:

ScaffolderWhat It Generates
agentsAGENTS.md, CLAUDE.md, .cursor/rules/, .github/copilot-instructions.md
hooksGit pre-commit / pre-push hooks
ciGitHub Actions / pipeline YAML
badgeShields.io score badges for README
llmsllms.txt (AI-friendly summary)
publishExternal doc-site config (Mintlify) — experimental

Run them solo (docguard init --with hooks) or stacked (docguard init --with agents,hooks,badge,ci).

To declare an exact fact, copy templates/evidence-manifest.json to .docguard-evidence.json, point its literal Markdown template at one unique statement, and bind that value to a supported local source. Run docguard verify --evidence --format json before enabling the guard in CI. External compatibility declarations consume saved oasdiff or Buf output and require current SHA-256 identities for every declared repository input.

Deprecation aliases — setup · agents · hooks · badge · llms · publish · impact remain compatible until v1.0 with a yellow stderr warning. audit → guard is permanent and silent; ci is a current first-class pipeline command.

CLI Flags
FlagDescriptionCommands
--dir <path>Project directory (default: .); explicit selection suppresses ancestor-root guidanceAll
--verboseShow detailed outputAll
--quiet / -qSuppress banner — for hooks, CI loops, scriptsAll
--format jsonMachine-readable output (clean JSON, no ANSI bleed)guard, score, diff, trace, diagnose, memory, impact, explain, verify, reconcile, retire, specs, ignore
--format claimspecclaimspec v1 ignore document on stdout, validated against the vendored schema; what could not be exported goes to stderrignore
--format sarifSARIF 2.1.0 output — findings as rules/results for GitHub Code Scanning and SARIF dashboardsguard
--format junitJUnit XML output — one testcase per validator, for GitLab CI (artifacts:reports:junit), Jenkins, Azure DevOps, CircleCIguard
--update-baselineAdopt DocGuard on a legacy repo without a red day one: freeze today's findings into a committed .docguard.baseline.json; guard/ci then gate only NEW drift. Suppression is always visible ("N pre-existing finding(s) suppressed"), and --no-baseline shows the full pictureguard
--fullGenerate llms-full.txt (full doc bodies inlined) instead of the llms.txt link indexllms
--compactWith --format json: each fact once, the form the MCP guard tool returns by defaultguard
--packWrite .docguard/context-pack.md — agent session-start contextmemory
--symbolsWith --pack: add a symbol map (most central files and their exported names, within memory.symbolMap.maxBytes); opt-in: the frozen agent-context benchmark (protocol v3) found no regression and no benefit, so it is not on by defaultmemory
--syncRegenerate the agent-file family (CLAUDE.md, Copilot, Cursor, …) from AGENTS.md; hash-marked, never touches hand-written files without --forceagents
--checkCI gate for the synced agent-file family — exit 2 when a variant is staleagents
--forceOverwrite existing files (creates .bak backups)generate, agents, init
--force-redoBypass ping-pong suppression in .docguard/fixed.jsonfix --write
--profile <name>Starter / standard / enterpriseinit
--no-spec-kitSkip Spec Kit: no specify call and no .specify/; DocGuard's own agent skills still installinit
--spec-kitWith --profile starter, initialize Spec Kit too (starter skips it by default)init
--changed-only [--since <ref>]Pre-commit lite mode: the fast validators (including covered-doc dependencies) on changed files onlyguard
--timingsPer-validator wall-time profile (slowest first)guard
--show-failingShow warnings/errors even when status is PASSguard
--pinRecord running CLI version into .docguard.json (reproducibility)guard
--diffPer-category drill-downscore, memory
--check-onlyExit 1 if behind (for CI)upgrade
--applyActually run the migrationupgrade
--prOpen a PR with the migrationupgrade
--reverse <file>Reverse traceability (code → docs)trace
--no-indirectSkip the reverse-import-graph analysis (docs about modules that import a changed file)impact, diff --since
--prsOpen-PR doc-conflict analysis — two PRs impacting the same canonical doc = merge-order risk (needs the gh CLI)impact
--transport http --port --host --api-key --pathServe MCP over Streamable HTTP instead of stdio (team-shared server; loopback-only unless an api-key is set)mcp
--root <dir>Serve another directory tree: tool calls may pass a projectDir inside it (repeatable). Without it, projectDir must stay inside the served directorymcp
--historyShow fix audit logfix

When run from a nested package without --dir, DocGuard checks only that selected directory. If a bounded ancestor scan finds a .docguard.json or an npm/pnpm workspace declaration that owns the package, stderr shows an exact repository-scope rerun command. DocGuard never changes scope automatically. JSON, SARIF, and JUnit stdout remain valid; machine runs receive one typed docguard.repository-root-guidance JSON diagnostic on stderr. A local config, an explicit --dir, an unmatched workspace, or a nested Git boundary suppresses the suggestion.

Example Output
$ npx docguard-cli generate

🔮 DocGuard Generate — my-project
   Scanning codebase to generate canonical documentation...

  Detected Stack:
    language: TypeScript ^5.0
    framework: Next.js ^14.0
    database: PostgreSQL
    orm: Drizzle 0.33
    testing: Vitest
    hosting: AWS Amplify

  ✅ ARCHITECTURE.md (4 components, 6 tech)
  ✅ DATA-MODEL.md (12 entities detected)
  ✅ ENVIRONMENT.md (18 env vars detected)
  ✅ TEST-SPEC.md (45 tests, 8/10 services mapped)
  ✅ SECURITY.md (auth: NextAuth.js)
  ✅ REQUIREMENTS.md (spec-kit aligned)
  ✅ AGENTS.md
  ✅ CHANGELOG.md
  ✅ DRIFT-LOG.md

  Generated: 9  Skipped: 0

🔍 Validators

DocGuard runs 34 automated validators on every guard check. Source-facing validators are language-aware where their evidence model applies; repository and document validators operate independently of source language.

Counting note: guard prints 30 result rows, not 29. Structure emits a second check result (Doc Sections) under the same validator key, so rows are checks, not validators. The published number is the count of shipped cli/validators/*.mjs modules and is enforced by tests — don't derive it by counting output rows.

#ValidatorWhat It ChecksDefault
1StructureRequired CDD files exist; each AGENTS.md chain fits the agent's load limit (32 KiB default, per-chain allowances for existing debt)✅ On
2Doc SectionsCanonical docs have required sections (or N/A markers)✅ On
3Docs-SyncRoutes/services referenced in docs + OpenAPI cross-check✅ On
4Drift-Comments// DRIFT: comments logged in DRIFT-LOG.md (skips test files by default)✅ On
5ChangelogCHANGELOG.md has [Unreleased] section✅ On
6Test-SpecTests exist per TEST-SPEC.md rules✅ On
7EnvironmentEnv vars documented, .env.example exists✅ On
8SecurityNo hardcoded secrets in source code✅ On
9ArchitectureImports follow layer boundaries (honors config.ignore)✅ On
10FreshnessDocs not stale relative to code changes (rename-aware via git log --follow)✅ On
11TraceabilityRequirement IDs (FR, SC, NFR, US, AC, T) trace to tests✅ On
12Docs-DiffCode artifacts match documented entities✅ On
13API-SurfaceAPI-REFERENCE.md endpoints match real routes (OpenAPI cross-check)✅ On
14Metadata-SyncVersion refs consistent across docs✅ On
15Docs-CoverageCode features referenced in documentation✅ On
16Doc-QualityWriting quality (readability, passive voice, atomicity, IEEE 830)✅ On
17TODO-TrackingUntracked TODOs/FIXMEs and skipped tests (skips test files by default)✅ On
18Schema-SyncDatabase models documented in DATA-MODEL.md✅ On
19Spec-KitSpec quality validation (FR-IDs, mandatory sections, phased tasks, unique spec numbers)✅ On
20Document-LifecycleExact terminal states, advisory completion signals, incomplete coverage, and manifest/working-tree inconsistencies✅ On
21Spec-RegistryImmutable spec identities, byte-stable evidence projection, reviewed lifecycle preservation, and archive/storage consistency✅ On
22EvidenceExact declared Markdown statements match current typed JSON, bounded collections, or saved compatibility reports; unsupported and missing evidence stays visible✅ On
23Cross-ReferenceInternal markdown links + anchors resolve (with "did you mean?" hints); Obsidian wikilinks validated when the repo uses them as file links (.obsidian present or a target resolves)✅ On
24Generated-Stalenesssource=code sections match scanner output; status: draft doc age✅ On
25Canonical-SyncDocGuard's own README count claims match code-truth (DocGuard repo only — N/A elsewhere)✅ On
26Metrics-ConsistencyHardcoded numbers match actual counts, including runtime-dependency claims against package.json (the Spec Kit constitution is read too)✅ On
27Surface-SyncItem-level enumerable drift — names in doc tables/lists (commands, checks, etc.) match code-truth (opt-in via surfaceSync.surfaces; N/A unless configured)✅ On
28Diff-SuspicionChange-driven: a doc/agent-instruction file that references code changed since the ref AND shares removed domain symbols is flagged for review (arXiv 2010.01625, F1 74.7)✅ On
29Reference-ExistenceTwo-revision check: a backticked code symbol present when the doc was last updated but gone at HEAD is flagged as outdated (arXiv 2212.01479)✅ On
30API-Doc-SmellsBloated (≥300 words) / Lazy (≤6 prose words) API documentation units, keyed on signature-headed sections (F1 0.90/0.95)✅ On
31Doc-DependencyA doc section that declares covers= is reported when a covered symbol's code changes semantically since its last docguard review --accept (formatting, comments and line moves do not count); opt-in by declaration✅ On
32Path-Scoped-RulesAgent instruction files per harness (nested AGENTS.md/CLAUDE.md, Claude Code rules and skills, Cursor .mdc, Copilot .instructions.md, OpenHands skills): scope globs that match no tracked file, pointers to missing paths (including routing tables), instructions loaded for one path over the byte budget, and scopes a harness cannot read✅ On
33Doc-OwnershipWith an ownership map in .docguard.json: source directories no doc section owns, two equally specific owners, patterns that match nothing, entries naming missing docs; also lints a committed .devin/wiki.json against Devin's limits and for paths that are gone✅ On
34Suppressions.docguardignore entries whose expires: date has passed (they no longer exclude anything), whose expiry is not a calendar date, or, with suppressions.requireReason, that have no # reason✅ On
35Requirement-AnchorsWith .docguard-anchor-lock.jsonl or anchors.enabled: reviewed code→requirement links whose code or requirement changed since review (ANC001/ANC002), reviewed links whose tag is gone (ANC003), tags citing an undeclared or retired requirement (ANC007/ANC008), lock problems (ANC005/ANC009) and files read below their exact tier (ANC010). docguard anchors lists every link; anchors accept records a review✅ On

Per-validator controls (in .docguard.json):

{
  "validators": {
    "test-spec": false,                 // disable (kebab-case OR camelCase both accepted)
    "freshness": true
  },
  "severity": {
    "todoTracking": "high",             // warnings fail CI
    "freshness": "low"                  // warnings ignored for exit code
  },
  "findingSeverity": {
    "TRC004": "low",                    // only this finding becomes informational
    "SEC001": "high"                    // this exact code always blocks
  }
}

Exact findingSeverity entries take precedence over validator severity. Guard JSON, SARIF, and JUnit retain the detector's intrinsic severity and add the effective severity plus the policy source. Intrinsic errors stay blocking unless their exact stable code is explicitly configured.


🎚️ Reading a Finding

A finding used to answer one question — "how worried should you be?" — with one confidence field, which meant the field was doing three incompatible jobs at once. DocGuard now separates them. These axes are independent: a blocking error can be an escalation, and a high-confidence finding can still be one a human must judge.

FieldThe question it answersValues
severity / effectiveSeverityDoes CI block?error, warn, info
dispositionWho decides — the tool or you?act, escalate
confidenceHow sure is the detector of its observation?high, low
evidence.statusHas the reviewed corpus ever measured this code?measured, not-measured
parserTierWhich analyzer produced it?js-ast, py-ast, regex-fallback, fallback-language, mixed, not-applicable

act — DocGuard asserts a defect and names the correction. Safe to apply, including through docguard fix or an agent.

escalate — DocGuard observed a signal; the judgement is yours. Freshness FRS002 ("13 code commits since the document was reviewed") is the canonical case: the count comes from git log, so it is exact and confidence: high — and it establishes only that a review is due, never that the document is wrong. Editing a document until an escalation stops printing destroys the signal and fixes nothing. A judged-and-left escalation is a correct outcome.

evidence.status tells you what a confidence label is worth. measured quotes the reviewed precision corpus with n and a Wilson lower bound; not-measured means the label is a maintainer's prior and nothing more. Most codes are unmeasured — that does not make their findings wrong, only unverified, and docguard feedback samples them for exactly that reason.

parserTier tells you what the detector could see. js-ast and py-ast mean a syntax tree. regex-fallback means the language has one (JS/TS, Python) but it was unavailable for that file. fallback-language means DocGuard has no parser for the language at all — Go, Java, Kotlin, Ruby, Rust, PHP, C# — so routes and env reads there are matched by pattern. Either way the absence of a finding there is weak evidence, and the owning validator reports applicability: partial with a reason that names the language and the file count. Environment variables are matched by pattern in every supported language; a source language with no env patterns (Swift, Scala, …) makes the Environment check partial rather than a silent pass.

Every channel appears on every finding in guard --format json, in SARIF result.properties, and per-issue in diagnose --format json (which also emits a dispositionCounts summary). guard, diagnose, ci and report all print the act/escalate split beside the verdict; report adds a column per channel to its findings table. Run docguard explain <CODE> for one code's evidence.


📄 Templates

DocGuard ships 18 professional templates with metadata, badges, and revision history:

TemplateTypePurpose
ARCHITECTURE.mdCanonicalSystem design, components, layer boundaries
DATA-MODEL.mdCanonicalSchemas, entities, relationships
SECURITY.mdCanonicalAuth, permissions, secrets management
TEST-SPEC.mdCanonicalTest strategy, coverage requirements
ENVIRONMENT.mdCanonicalEnvironment variables, deployment config
REQUIREMENTS.mdCanonicalSpec-kit aligned FR/SC IDs, user stories
DEPLOYMENT.mdCanonicalInfrastructure, CI/CD, DNS
ADR.mdCanonicalArchitecture Decision Records
ROADMAP.mdCanonicalProject phases, feature tracking
KNOWN-GOTCHAS.mdImplementationSymptom → gotcha → fix entries
TROUBLESHOOTING.mdImplementationError diagnosis guides
RUNBOOKS.mdImplementationOperational procedures
VENDOR-BUGS.mdImplementationThird-party issue tracker
CURRENT-STATE.mdImplementationDeployment status, tech debt
AGENTS.mdAgentAI agent behavior rules
CHANGELOG.mdTrackingChange log
DRIFT-LOG.mdTrackingDeviation tracking
llms.txtGeneratedAI-friendly project summary (llmstxt.org)

🤖 AI Agent Support

One-click MCP install

  • Claude Code: claude mcp add docguard -- npx docguard-cli mcp
  • Claude Desktop: download docguard-v<version>.mcpb from the latest release and drag it into Settings → Extensions — you'll be asked which project folder to analyze. No npm, no JSON editing.
  • Anything MCP: DocGuard is a verified namespace on the official MCP registry (io.github.raccioly/docguard).

DocGuard works with every major AI coding agent. All canonical docs are plain markdown — no vendor lock-in.

AgentCompatibilityAuto-Generate Config
Claude Code✅docguard agents --agent claude
GitHub Copilot✅docguard agents --agent copilot
Cursor✅docguard agents --agent cursor
Windsurf✅docguard agents --agent windsurf
Cline✅docguard agents --agent cline
Google Gemini CLI✅docguard agents --agent gemini
Kiro (AWS)✅—
Always-on nudge hook (Claude Code)
docguard hooks --claude            # install   (remove: docguard hooks --claude --remove)

Registers a PostToolUse hook in the project's .claude/settings.json. After the agent edits a canonical doc it is nudged to run docguard guard --changed-only; after it edits a code file the docs reference, it is nudged toward docguard impact. Merge-safe (only DocGuard's own entry is ever added/removed), throttled to one nudge per file per 30 minutes, and the hook runtime can never break a session (errors are silent by contract). Explicit opt-in — init never installs it for you.


⚡ Slash Commands

DocGuard ships four slash commands (commands/ in this repository):

CommandWhat It Does
/docguard.guardRun quality validation across every validator
/docguard.reviewAnalyze doc quality and suggest improvements
/docguard.fixGenerate targeted fix prompts for specific issues
/docguard.scoreCDD maturity score with an improvement roadmap

Where they go depends on your agent. With a Spec Kit integration that uses skills (Claude Code, Codex, Cursor, Copilot), DocGuard installs its skills instead, and Spec Kit installs the speckit.docguard.* extension commands. The /docguard.* files are written to .agent/commands/ only for Spec Kit's generic integration, or when no Spec Kit integration is present. The Coding Agents reference lists the exact paths for each agent.


🧠 AI Skills (Enterprise)

Beyond slash commands, DocGuard provides 5 enterprise-grade AI skills — deep behavior protocols that tell AI agents not just what to run, but how to think, validate, and iterate. Skills are modeled after Spec Kit's skill architecture.

SkillWhat It Does
docguard-guard6-step quality gate with severity triage (CRITICAL→LOW), structured reporting, remediation
docguard-fix7-step research workflow with per-document codebase research and 3-iteration validation loops
docguard-reviewRead-only semantic cross-document analysis with 6 analysis passes and quality scoring
docguard-scoreCDD maturity assessment with ROI-based improvement roadmap and grade progression
docguard-syncRefreshes code-truth doc sections in place and flags the prose sections to review when code changes
Workflow Hooks

DocGuard integrates into the spec-kit workflow as an automated quality gate:

HookWhenBehavior
before_specifyBefore /speckit.specifyMandatory — briefs the agent on existing specs (speckit.docguard.brief)
before_tasksBefore /speckit.tasksMandatory — preflight check of the generated spec (speckit.docguard.preflight)
after_implementAfter /speckit.implementMandatory — runs DocGuard guard; then optionally records completion
after_convergeAfter /speckit.convergeOptional — records spec completion (speckit.docguard.complete)
after_tasksAfter /speckit.tasksOptional — shows CDD maturity score
Orchestration Scripts

For advanced users and CI/CD pipelines, DocGuard includes bash scripts with --json output:

ScriptPurpose
docguard-check-docs.shDiscover project docs, return JSON inventory with metadata
docguard-suggest-fix.shRun guard, parse results, output prioritized fixes
docguard-init-doc.shInitialize canonical doc with metadata header

📁 Examples

Three real-world projects to see DocGuard in action:

ExampleScenarioWhat You'll See
01-express-apiNode.js API with zero docsCold-start: generate → instant coverage
02-python-flaskPython app with drifted docsDrift detection: catch when docs lie
03-spec-kit-projectFull CDD + Spec KitGold standard: what maturity looks like

See examples/README.md for step-by-step instructions.


🧪 Testing

Test Suite
npm test    # 3,283 tests (node:test, zero test dependencies)

Covers all 27 commands, every validator, project type detection, compliance profiles, JSON/SARIF/JUnit output, the packed npm tarball, and downstream field reports replayed as regression cases. Static test-case declarations are a lower bound of that number: Metrics-Consistency flags this line if it ever falls below what the test files declare.

CI Matrix
Node.jsOSStatus
18ubuntu-latest✅
20ubuntu-latest✅
22ubuntu-latest✅
24ubuntu-latest✅
Self-Validation (Dogfooding)

DocGuard runs its own guard, score, diff, diagnose, and badge commands against itself in CI — ensuring the tool passes its own checks.


🏢 Enterprise Adoption

Everything runs local or in your CI — no SaaS, no data leaving your infra. The pieces that matter at company scale:

NeedDocGuard answer
Adopt on a legacy repo without a red pipeline on day oneguard --update-baseline freezes existing findings into a committed .docguard.baseline.json; only NEW drift gates from then on (suppression always visible)
Audit trail for compliance reviewsdocguard report — commit-stamped evidence bundle (guard verdict, findings by code, CDD score, ALCOA+ data-integrity attributes, fix history) with a tamper-evident sha256 integrity hash
Every CI system, not just GitHubguard --format sarif (GitHub Code Scanning) · --format junit (GitLab, Jenkins, Azure DevOps, CircleCI) · --format json (anything else)
Trajectory, not snapshotsdocguard ci records every run to .docguard/history.jsonl; score --trend shows the sparkline + delta
AI agents on the teamMCP server (stdio or team-shared HTTP) exposes guard, score, verify, report, doc navigation and task context as read-only tools; agents --sync keeps the whole agent-file family drift-proof
Data-integrity framing auditors knowALCOA+ scoring (FDA 21 CFR Part 11 / EMA Annex 11 vocabulary) built into score and report

⚙️ CI/CD Integration

Full recipes: see docs-canonical/CI-RECIPES.md for guard, auto-fix (commits mechanical fixes back to PRs), nightly sync, score-on-PR, and pre-commit configs.

GitHub Actions — Guard (most common)
name: DocGuard Guard
on: [pull_request, push]
permissions: { pull-requests: write }   # for the sticky PR comment (optional)
jobs:
  docguard:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }
      - uses: raccioly/docguard@v0.45.1
        with:
          command: guard

The action installs the docguard-cli version it was released with, so pinning the action pins the CLI too. Set docguard-version: latest (or an exact x.y.z) to override.

On pull requests, guard mode also gives inline PR feedback (both default on):

InputDefaultDescription
annotationstrueInline ::error/::warning annotations on the PR diff, one per guard finding (capped at 50; a final notice reports how many were elided)
pr-commenttrueSticky PR comment with the guard verdict, top findings (by code), and which canonical docs the PR's changed files impact (diff --since origin/<base>). Needs permissions: pull-requests: write; degrades to a log warning without it

Both run even when guard fails — that's when the feedback matters. Prefer native code-scanning integration? docguard guard --format sarif uploads straight to GitHub Code Scanning via github/codeql-action/upload-sarif.

GitHub Actions — Auto-Fix (commits mechanical fixes back)
name: DocGuard Auto-Fix
on: { pull_request: { types: [opened, synchronize, reopened] } }
permissions: { contents: write, pull-requests: write }
jobs:
  autofix:
    runs-on: ubuntu-latest
    if: github.event.pull_request.head.repo.full_name == github.repository
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.ref }}
          token: ${{ secrets.GITHUB_TOKEN }}
          fetch-depth: 0
      - uses: raccioly/docguard@v0.45.1
        with: { command: fix, auto-commit: 'true', comment-on-pr: 'true' }
Pre-commit Hook
npx docguard-cli hooks --type pre-commit
Workflow starters (copy directly)

Two ready-to-use templates ship with the Spec Kit extension and as standalone files:

  • extensions/spec-kit-docguard/templates/github-workflows/docguard-guard.yml — mandatory CI gate
  • extensions/spec-kit-docguard/templates/github-workflows/docguard-autofix.yml — PR auto-fix

✨ What's New

Highlights from recent releases:

  • Calibrated finding channels — disposition, evidence.status and parserTier now sit beside severity and confidence on every finding, so "does CI block", "who decides", "how sure is the detector", "has this code ever been measured" and "which analyzer saw it" stop being one overloaded field. See Reading a Finding.
  • Adoption baseline — guard --update-baseline freezes a legacy repo's existing findings into a committed .docguard.baseline.json; guard/ci then gate only NEW drift, with suppression always visible. Adopt today, burn down at your own pace.
  • docguard report — commit-stamped compliance-evidence bundle (guard verdict, findings by code, CDD score, ALCOA+ attributes, fix history) with a tamper-evident sha256 integrity hash. Also exposed as the docguard_report MCP tool.
  • Score history + score --trend — docguard ci records every run to .docguard/history.jsonl; the trend view shows the sparkline and delta over time.
  • Three machine formats for guard — --format json, --format sarif (GitHub Code Scanning), and --format junit (GitLab, Jenkins, Azure DevOps, CircleCI).
  • MCP server, stdio + team HTTP — guard, score, verify, report, doc navigation and task context as read-only agent tools: claude mcp add docguard -- npx docguard-cli mcp.
  • Agent-file family sync — agents --sync treats AGENTS.md as canonical and regenerates CLAUDE.md / .cursor/rules / Copilot / Gemini variants with drift-proof source-hash markers.
  • verify --evidence, verify --semantic, and verify --instructions — check exact local evidence declarations first, extract remaining numbers/limits/enums as agent tasks, and audit agent-instruction files for contradictions and stale pointers.
  • docguard agent — one-shot ordered task graph with pre-filled code-truth, collapsing ~10 agent round-trips into one call.
  • docguard agent --task <text> — opt-in task context from approved current specs and canonical docs, with hashed excerpts, source/test pointers, strict budgets, and honest abstention. The frozen 27-run evaluation preserved every tested behavior and cut median steps by 50% and latency by 17% versus the context pack, while using 80% more uncached input tokens.

See CHANGELOG.md for the full history.


📁 File Structure

your-project/
├── .specify/                        # Spec Kit (if using specify init)
│   ├── specs/
│   │   └── 001-feature/
│   │       ├── spec.md              # Requirements (FR-IDs, user stories)
│   │       ├── plan.md              # Implementation plan
│   │       └── tasks.md             # Task breakdown
│   ├── memory/
│   │   └── constitution.md          # Project principles
│   └── templates/
│
├── docs-canonical/                  # CDD canonical docs (the "blueprint")
│   ├── ARCHITECTURE.md              # System design, components
│   ├── DATA-MODEL.md                # Database schemas
│   ├── SECURITY.md                  # Auth, permissions, secrets
│   ├── TEST-SPEC.md                 # Required tests, coverage
│   ├── ENVIRONMENT.md               # Environment variables
│   └── REQUIREMENTS.md              # Spec-kit aligned FR/SC IDs
│
├── docs-implementation/             # Current state (optional)
│   ├── KNOWN-GOTCHAS.md
│   ├── TROUBLESHOOTING.md
│   ├── RUNBOOKS.md
│   └── CURRENT-STATE.md
│
├── AGENTS.md                        # AI agent behavior rules
├── CHANGELOG.md                     # Change tracking
├── DRIFT-LOG.md                     # Documented deviations
├── llms.txt                         # AI-friendly summary
└── .docguard.json                   # DocGuard configuration

⚙️ Configuration

Create .docguard.json in your project root (auto-generated by docguard init):

{
  "projectName": "my-project",
  "version": "0.4",
  "profile": "standard",
  "projectType": "webapp",
  "validators": {
    "structure": true,
    "docsSync": true,
    "drift": true,
    "changelog": true,
    "testSpec": true,
    "security": true,
    "environment": true,
    "docQuality": true,
    "specKit": true
  }
}

See Configuration Guide for all options.


🔬 Research Credits

DocGuard's quality evaluation and documentation generation patterns are informed by peer-reviewed research from the University of Arizona and the Joint Interoperability Test Command (JITC), U.S. Department of Defense:

Lead researcher: Martin Manuel Lopez · ORCID 0009-0002-7652-2385

See CONTRIBUTING.md for full citations.

What the labels measure. DocGuard borrows TRACE's HIGH/MEDIUM/LOW vocabulary as deterministic strata (a validator's check pass-ratio). Detector precision is the quantity DocGuard actually measures: on a labelled, deliberately balanced benchmark corpus, published with sample sizes and Wilson 95% bounds in benchmarks/baseline.json (contract: schemas/docguard-benchmark-baseline.schema.json). Every number there carries a caveat explaining that benchmark precision on a balanced corpus differs from the base rate of stale claims in your repository. See VALIDATION.md.


⭐ Star History


🔒 Privacy & Supply Chain

DocGuard is local-first: no telemetry, no analytics, no phone-home — the full (short) policy is in PRIVACY.md. npm releases are published with provenance attestation, so you can verify each tarball was built by GitHub Actions from this repository.

📄 License

MIT — Free to use, modify, and distribute.


Made with ❤️ by Ricardo Accioly

Frequently asked questions

What is DocGuard?

Deterministic doc-drift detection: guard, score, explain, verify-claims and diagnose MCP tools.

How do I install DocGuard?

It runs on your machine. In Claude Code: claude mcp add docguard -- npx -y docguard-cli@0.40.5 mcp. For other clients, paste the JSON configuration from this page into their MCP settings.

Does DocGuard need an API key?

Its registry entry lists no required key or secret. Some features may still need an account with the service it connects to.

Is DocGuard open source?

Yes. Its code is on GitHub under the MIT license.

Who maintains DocGuard?

It is published by raccioly. AI.tn lists it but does not maintain or endorse it.

From the official MCP Registry. Listing is not an endorsement: review a server's code and permissions before giving it access to your data.