Repository navigation
[Extension]: Update DocGuard — CDD Enforcement (v0.29.0) #3325
Description
Extension ID
docguard
Extension Name
DocGuard — CDD Enforcement
Version
0.29.0
Description
Canonical-Driven Development enforcement. Validates, scores, and traces project documentation with automated checks, AI-driven workflows, and spec-kit hooks. One pinned runtime dependency; pure Node.js otherwise.
Author
raccioly
Repository URL
https://github.com/raccioly/docguard
Download URL
https://github.com/raccioly/docguard/releases/download/v0.29.0/spec-kit-docguard-v0.29.0.zip
License
MIT
Homepage (optional)
https://www.npmjs.com/package/docguard-cli
Documentation URL (optional)
https://github.com/raccioly/docguard/blob/main/extensions/spec-kit-docguard/README.md
Changelog URL (optional)
https://github.com/raccioly/docguard/blob/main/CHANGELOG.md
Required Spec Kit Version
=0.1.0
Required Tools (optional)
- node (>=18.0.0) - required
- npx - required
- specify - optional (auto-initializes the SDD workflow during docguard init)Number of Commands
6
Number of Hooks (optional)
3
Tags
documentation, validation, quality, cdd, traceability, ai-agents, enforcement, spec-kit
Key Features
- 19-validator quality gate with severity triage and a remediation plan
- AI-driven documentation repair with codebase research and validation loops
- Cross-document semantic consistency analysis (read-only review)
- CDD maturity score with an ROI-based improvement roadmap
- Reverse-engineers canonical docs from an existing codebase
- spec-kit workflow hooks (after_implement, before_tasks, after_tasks)
Testing Checklist
- Extension installs successfully via download URL
- All commands execute without errors
- Documentation is complete and accurate
- No security vulnerabilities identified
- Tested on at least one real project
Submission Requirements
- Valid
extension.ymlmanifest included - README.md with installation and usage instructions
- LICENSE file included
- GitHub release created with version tag
- All command files exist and are properly formatted
- Extension ID follows naming conventions (lowercase-with-hyphens)
Testing Details
Tested on: Linux + macOS with the spec-kit CLI.
Install:
specify extension add docguard --from https://github.com/raccioly/docguard/releases/download/v0.29.0/spec-kit-docguard-v0.29.0.zipScenarios verified:
- Extension installs from the release ZIP without manifest validation errors.
- All six
speckit.docguard.*commands resolve and run. - The three workflow hooks register against spec-kit's lifecycle.
Example Usage
bash
# Install the extension
specify extension add docguard --from https://github.com/raccioly/docguard/releases/download/v0.29.0/spec-kit-docguard-v0.29.0.zip
# Run the documentation quality gate
/speckit.docguard.guardProposed Catalog Entry
json
{
"docguard": {
"name": "DocGuard \u2014 CDD Enforcement",
"id": "docguard",
"description": "Canonical-Driven Development enforcement. Validates, scores, and traces project documentation with automated checks, AI-driven workflows, and spec-kit hooks. One pinned runtime dependency; pure Node.js otherwise.",
"author": "raccioly",
"version": "0.29.0",
"download_url": "https://github.com/raccioly/docguard/releases/download/v0.29.0/spec-kit-docguard-v0.29.0.zip",
"repository": "https://github.com/raccioly/docguard",
"homepage": "https://www.npmjs.com/package/docguard-cli",
"documentation": "https://github.com/raccioly/docguard/blob/main/extensions/spec-kit-docguard/README.md",
"changelog": "https://github.com/raccioly/docguard/blob/main/CHANGELOG.md",
"license": "MIT",
"requires": {
"speckit_version": ">=0.1.0",
"tools": [
{
"name": "node",
"version": ">=18.0.0",
"required": true
}
]
},
"provides": {
"commands": 6,
"hooks": 3
},
"tags": [
"documentation",
"validation",
"quality",
"cdd",
"traceability",
"ai-agents",
"enforcement",
"spec-kit"
],
"verified": false,
"downloads": 0,
"stars": 0
}
}Additional Context
This is an update to an existing catalog entry (docguard) for a new release — please bump the version and download URL on the current entry rather than adding a duplicate.
Release notes (v0.29.0):
Closes both gaps from LLM field report #6 (a downstream adopter reported guard
A+ / "Accurate: 100%" while a watched doc stated a wrong count — the one
false-negative a documentation-integrity tool must not have). Diagnosis held up:
the literal cause was a domain noun missing from a hardcoded vocabulary, and an
ALCOA pillar named "Accurate" that was computed from structure/markers, not facts.
The fix is precision-first (the tool's existing philosophy), not the report's
recall-maximizing "validate every claim in every doc" — which prior field reports
already showed floods false positives.
Added — AI integration surface
The detection core is the moat; this batch makes the output consumable by
everything that isn't a human reading a terminal (the gap vs. Swimm/Mintlify/
Context7 identified in the platform review).
docguard mcp— Model Context Protocol server over stdio (JSON-RPC 2.0,
zero dependencies,node:readline). Five tools:docguard_guard,
docguard_score,docguard_explain,docguard_verify_claims,
docguard_diagnose— DocGuard's read-only core as native agent tools for
Claude, Cursor, and any MCP client (claude mcp add docguard -- npx docguard-cli mcp). Config loads per call; a malformed.docguard.json
becomes anisErrortool result instead of killing the session (loadConfig's
process.exit is defused by pre-parsing); stdout is the pure transport
(registered in both the headless gate and READ_ONLY_COMMANDS, so no banner
and no scaffolding side effects).- Action: inline PR annotations + sticky doc-impact comment —
guardruns
now annotate each finding on the PR diff (annotationsinput, default on,
capped at 50) and maintain a single sticky PR comment (pr-comment, default
on) with the guard verdict, top findings, and the canonical docs impacted by
the PR's changed files (diff --since origin/<base>). Purely additive steps
gated onalways()(feedback must appear exactly when guard fails); degrade
gracefully on fork tokens, shallow clones, and missing permissions; existing
outputs and exit codes untouched. - SARIF 2.1.0 output —
docguard guard --format sarifmaps the structured
findings 1:1 onto SARIF (codes → rules with title/help from the registry,
locations → physicalLocation/region, low-confidence → property bags,
validator crashes → synthesizedDOCGUARD-<KEY>results, exit codes
unchanged). Drops straight into GitHub Code Scanning and enterprise SARIF
dashboards.sarifjoinsjsonin the machine-format gate, so stdout is the
pure artifact — no banner. docguard llms --full— generatesllms-full.txt(the Mintlify-style
full-content companion to thellms.txtindex): every canonical + optional
doc inlined under one fetch, per-doc 400-line cap with truncation notes.docguard memory --pack— writes.docguard/context-pack.md, a compact
(<200 lines) code-truth-stamped session-start context for AI agents: guard
status, scanner-derived surface counts (modules/endpoints/entities/env
vars/tests), canonical-doc index with last-reviewed dates, the Rules/Workflow
sections of AGENTS.md verbatim, and known-drift summary. Everything derived
from scanners — regenerable, hallucination-free.docguard agents --sync/--check— AGENTS.md becomes the CANONICAL
source for the whole agent-file family (CLAUDE.md, GEMINI settings,
.github/copilot-instructions.md,.cursor/rules/,.clinerules,
.windsurfrules). Generated variants carry a source-hash marker;--sync
regenerates marked/missing variants (never touches unmarked hand-written
files without--force);--checkis the CI gate (exit 2 on stale). Kills
the hand-duplicated-agent-file drift class entirely.- Agent Readability score axis —
docguard scorenow measures how well AI
consumers can read the repo (display-only, like ALCOA+ — the gating grade is
untouched): agent entry file presence, entry-file token budget, section
addressability (quotable-alone + unique headings), structured-content
density, machine-marker presence, llms.txt, and entry-file link integrity.
Deterministic, zero-LLM. Dogfooded: found real defects in DocGuard's own
docs (duplicate headings, an unmarked doc) on first run.
Added
- Auto-detected documentation homes — clearly-named doc folders (
docs/,
doc/,documentation/,guides/,guide/,handbook/,manual/,wiki/,
plusdocs-canonical/,docs-implementation/,extensions/, and Docusaurus
website/docs/) are now claim-scanned and counted as "tracked" without being
enrolled inrequiredFiles.canonical. A folder literally nameddocumentation/
is unambiguously a doc home DocGuard governs; this stays distinct from the
arbitrary-subdir walk the wu-whatsappinbox scoping fix removed (a number buried
insecurity/wolf-archive/is still never scanned).config.docs.dirsEXTENDS
the set with non-standard homes (it never replaces auto-detection); use
.docguardignoreto exclude a conventional dir. The doc-home set is now a single
source of truth (resolveDocDirs) shared by the claim scanner and the coverage
map, so "tracked" provably means "actually scanned." New optionaldocs.dirskey
in the schema. - Project collections —
config.collectionsmaps a documentation noun (e.g.
extractors) to a glob whose matching-file count is the source of truth.
Metrics-Consistency now flags a documented count that disagrees ("16 extractors"
in prose vs 19 files on disk) deterministically, inguard, with no LLM —
catching the exact class that bit the adopter. A declared collection is the
opt-in binding, so it does not need thedocguard-on-the-line subject bind the
built-in checks/validators counts use; reserved nouns (checks/validators/tests)
keep their built-in meaning; an unresolved glob (0 matches) is skipped, never
asserting a false "0". ComplementssurfaceSync(WHICH members drift) with a
count check (HOW MANY). New optional key indocguard-config.schema.json. - Coverage line in
guard— every run now reports how many Markdown files are
canonical / tracked / ignored / outside any tier, turning silent non-coverage
(the "I forgot to enroll this doc" trap) into a visible count. Calm by default:
the count shows every run; the file list is one--verboseaway (loud-by-default
would just train users to ignore it). Also exposed on theguard --format json
contract ascoverage. - Unverified-claims notice in
guard— the deterministic semantic-claim
extractor (previously only reachable viaverify --semantic) now runs inguard
and reports how many documented counts/limits/enums remain unverified against
code, so a green run states plainly that structure is sound, not that the
numbers still match. Exposed assemanticClaimson the JSON contract.
Changed
- ALCOA+ "Accurate" no longer overclaims. It gains a third, honest state —
unverified(cyan 🔍) — shown when structure passes but documented factual
claims haven't been checked against code. Previously it read ✅ "100%" purely
from drift markers + prose quality, which is how an adopter saw "Accurate: 100%"
over a doc that stated the wrong number.unverifiedcounts as not-met for the
ALCOA compliance percentage (so it stops overclaiming) but renders neutrally, not
as a failure. Display-only: the gating CDD maturity grade (score/ci
threshold) is unchanged. - Extended the semantic claim-extractor vocabulary with the common
pluggable-architecture nouns (extractors,plugins,detectors,scanners,
commands,rules,hooks,handlers,agents,skills, …). The missing
extractorswas the literal root cause of the field report.
Internal hardening (project-review batch)
- ONE walker, ONE anchored glob compiler. Sixteen private recursive
directory walkers (13 validators + guard coverage + diff + generate) and three
divergent glob→regex implementations are consolidated into
shared-ignore.mjs:walkFiles(dir, cb, {ignoreDirs, keepDot, onError})and
compileGlob()(superset:**/,**,*,?,{a,b}). Per-validator
IGNORE_DIRS sets stay local by design — they carry intentional variance
(drift excludescli/because DocGuard's own regexes containDRIFT:;
docs-sync excludes__tests__), and the load-bearing dot-entry exceptions are
preserved viakeepDot(security must scan.env; traceability keeps
.env*,.gitignore,.github/). The ignore-sideglobToRegexkeeps its
documented unanchored semantics — different contract, own bug history. - Partial-walk counts are now fail-safe.
countGlobFilesreturns −1 when
the walk was incomplete (permission-denied subtree), so a collection count
can never silently under-count and "correct" a right doc number to a wrong
one. Callers treat ≤0 as "don't assert". - Findings migration COMPLETE — all 24 validators. Every validator now
emits structured findings with stable,explain-able, inline-suppressible
codes; the legacy hand-built errors/warnings strings are gone from the
validator layer (resultFromFindingsderives them from the same array, so
messages are byte-identical and counts/exit codes are unchanged). The CODES
registry grew from 8 (SEC only) to 91 across 21 prefixes: STR, CHG, MET,
FRS (freshness, via a new guard adapter — its array contract is preserved),
ENV, TSP, DRF, DSY, DDF, DCV, MDS, TRC, TDO, SCH, ARC, CSY, SPK (implemented
in scanners/speckit.mjs behind the validator shim), XRF, GST, SSY, plus full
first-time migrations of API (api-surface) and DQ (doc-quality), which turned
out to be fully legacy rather than partial.confidence: 'low'is set only
where the pre-existing message already hedged (TSP003, API003, API004's
code-scan variant). Guard's rich rendering ([CODE]tags,→ suggestion
lines, low-confidence markers,docguard feedbackreporting) now covers the
entire validator surface. - Docs truth pass: SURFACE-AUDIT.md gets a "historical snapshot — findings
resolved" banner (its v0.18.1 counts were being read as current); STANDARD.md
§8 no longer embeds a validator table (it had drifted 16 validators behind —
points at the machine-governed README list instead); README leads with a
compact "Why DocGuard?" and moves "What's New" below CI/CD; ROADMAP Phase 4.5
updated through v0.28; CONTRIBUTING gains the surface rule (a new
user-facing command must retire one or justify growth) and the findings
rule (new validators must emit findings); pyproject.toml no longer claims
"zero dependencies" (now: "no Python dependencies, requires Node 18+"). - Hygiene: removed tracked scratch files (
test-draft.js,
test-metrics.js,pr_description.md) and a deadIGNORE_DIRSset in
freshness.mjs. generate.mjssplit (1530 → 559 lines). The generate command now has
three coherent modules:cli/writers/generate-io.mjs(backup/safe-write/
doc-registration/citation helpers, 142 lines) and
cli/writers/doc-generators.mjs(the 7 document builders, 853 lines), with
command flow + stack detection + project scanning staying in
cli/commands/generate.mjs. Pure code motion — bodies byte-identical,
verified by the full suite plusgenerate/generate --plansmoke runs.- CI flake fix (watch spawn tests). The two
docguard watchtests polled
with a fixed 2-second cap — a hair-trigger race against CLI startup that
intermittently failed on slow runners and passed on re-run. Replaced with a
15-secondwaitFordeadline; assertions unchanged (a genuinely broken watch
still fails, just not a slow-booting one).
Remediation policy (suggest vs. auto-update)
DocGuard detects divergence, not which side is right — a doc claim that no
longer matches code can mean the doc is stale OR the code regressed and the doc is
the correct intent (the CDD premise: canonical docs are the spec). So:
- Auto-fix only the provably-mechanical class — a number bound to a code
collection (collections), where the true value is known and the code is
definitionally the source. These emit afixobject applied only via an
explicitdocguard fix --write, withactualSourceprovenance, fail-closed,
and reversible via git. Never silent. - Everything semantic/prose is SUGGEST-only — surfaced as a finding (and via
verify --semanticfor agent judgment), never auto-rewritten. DocGuard's
deterministic core can't author correct prose and must not assume code is always
the source of truth. Enrichment/rewriting is an agent task the human approves —
not a validator silently editing docs.
Activity
raccioly commentedon Jul 5, 2026
cclosing it.. added a new one