docguard-cli 0.28.0 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.es.md +102 -0
- package/README.md +80 -32
- package/README.pt-BR.md +101 -0
- package/STANDARD.md +20 -10
- package/cli/commands/agents.mjs +149 -0
- package/cli/commands/diff.mjs +6 -15
- package/cli/commands/generate.mjs +14 -1001
- package/cli/commands/guard.mjs +136 -8
- package/cli/commands/llms.mjs +67 -5
- package/cli/commands/mcp.mjs +263 -0
- package/cli/commands/memory.mjs +115 -0
- package/cli/commands/score.mjs +76 -12
- package/cli/commands/trace.mjs +364 -1
- package/cli/commands/verify.mjs +93 -6
- package/cli/docguard.mjs +42 -5
- package/cli/findings.mjs +511 -0
- package/cli/scanners/agent-readability.mjs +202 -0
- package/cli/scanners/instruction-audit.mjs +320 -0
- package/cli/scanners/semantic-claims.mjs +7 -1
- package/cli/scanners/speckit.mjs +443 -28
- package/cli/shared-ignore.mjs +148 -16
- package/cli/shared.mjs +45 -1
- package/cli/validators/api-surface.mjs +113 -26
- package/cli/validators/architecture.mjs +66 -43
- package/cli/validators/canonical-sync.mjs +59 -28
- package/cli/validators/changelog.mjs +41 -17
- package/cli/validators/cross-reference.mjs +28 -11
- package/cli/validators/doc-quality.mjs +78 -44
- package/cli/validators/docs-coverage.mjs +90 -63
- package/cli/validators/docs-diff.mjs +63 -64
- package/cli/validators/docs-sync.mjs +48 -33
- package/cli/validators/drift.mjs +40 -34
- package/cli/validators/environment.mjs +67 -27
- package/cli/validators/freshness.mjs +12 -5
- package/cli/validators/generated-staleness.mjs +26 -10
- package/cli/validators/metadata-sync.mjs +28 -25
- package/cli/validators/metrics-consistency.mjs +89 -47
- package/cli/validators/schema-sync.mjs +37 -32
- package/cli/validators/security.mjs +7 -20
- package/cli/validators/spec-kit.mjs +3 -0
- package/cli/validators/structure.mjs +58 -23
- package/cli/validators/surface-sync.mjs +34 -15
- package/cli/validators/test-spec.mjs +87 -29
- package/cli/validators/todo-tracking.mjs +83 -74
- package/cli/validators/traceability.mjs +67 -39
- package/cli/writers/doc-generators.mjs +853 -0
- package/cli/writers/generate-io.mjs +142 -0
- package/cli/writers/sarif.mjs +129 -0
- package/commands/docguard.fix.md +56 -53
- package/commands/docguard.guard.md +53 -47
- package/commands/docguard.review.md +49 -31
- package/docs/ai-integration.md +133 -134
- package/docs/commands.md +49 -3
- package/docs/configuration.md +38 -0
- package/docs/faq.md +15 -0
- package/extensions/spec-kit-docguard/extension.yml +1 -1
- package/extensions/spec-kit-docguard/skills/docguard-fix/SKILL.md +2 -2
- package/extensions/spec-kit-docguard/skills/docguard-guard/SKILL.md +2 -2
- package/extensions/spec-kit-docguard/skills/docguard-review/SKILL.md +2 -2
- package/extensions/spec-kit-docguard/skills/docguard-score/SKILL.md +2 -2
- package/extensions/spec-kit-docguard/skills/docguard-sync/SKILL.md +2 -2
- package/package.json +2 -1
- package/schemas/docguard-config.schema.json +28 -0
- package/templates/ci/gitlab-component.yml +90 -0
- package/templates/commands/docguard.fix.md +33 -10
- package/templates/commands/docguard.guard.md +40 -26
- package/templates/commands/docguard.init.md +23 -11
- package/templates/commands/docguard.review.md +25 -8
- package/templates/commands/docguard.update.md +14 -4
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate IO — write-path helpers behind `docguard generate`: backup-then-
|
|
3
|
+
* write file IO, canonical-doc registration in .docguard.json, standards
|
|
4
|
+
* citation footers, and the surface-confidence heuristic.
|
|
5
|
+
*
|
|
6
|
+
* v0.29 split: extracted verbatim from cli/commands/generate.mjs — pure code
|
|
7
|
+
* motion, zero behavior change.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, copyFileSync } from 'node:fs';
|
|
11
|
+
import { resolve, dirname } from 'node:path';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Create a .bak backup of an existing file before --force overwrites it.
|
|
15
|
+
* Only backs up if the file exists and has content.
|
|
16
|
+
*/
|
|
17
|
+
export function backupFile(filePath) {
|
|
18
|
+
if (existsSync(filePath)) {
|
|
19
|
+
try {
|
|
20
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
21
|
+
if (content.trim().length > 0) {
|
|
22
|
+
copyFileSync(filePath, filePath + '.bak');
|
|
23
|
+
}
|
|
24
|
+
} catch { /* backup failure is non-fatal */ }
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Safe write — creates a .bak backup before overwriting existing files.
|
|
30
|
+
* Call this instead of raw writeFileSync when generating docs.
|
|
31
|
+
*/
|
|
32
|
+
export function safeWrite(filePath, content) {
|
|
33
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
34
|
+
backupFile(filePath);
|
|
35
|
+
writeFileSync(filePath, content, 'utf-8');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* B7 (field report): after generate emits canonical docs, register them in
|
|
40
|
+
* `.docguard.json` requiredFiles.canonical so `guard` doesn't immediately flag
|
|
41
|
+
* the generator's OWN output as an "orphaned" doc ("exists but not in your
|
|
42
|
+
* requiredFiles"). Only ADDS (never removes/deletes), only docs-canonical/*.md
|
|
43
|
+
* that actually exist on disk, and only when a config file already exists (init
|
|
44
|
+
* owns config creation). Idempotent — a second run with nothing new is a no-op.
|
|
45
|
+
* @returns {number} count of paths newly registered.
|
|
46
|
+
*/
|
|
47
|
+
export function registerGeneratedCanonicalDocs(projectDir, candidatePaths) {
|
|
48
|
+
const cfgPath = resolve(projectDir, '.docguard.json');
|
|
49
|
+
if (!existsSync(cfgPath)) return 0;
|
|
50
|
+
let cfg;
|
|
51
|
+
try { cfg = JSON.parse(readFileSync(cfgPath, 'utf-8')); } catch { return 0; }
|
|
52
|
+
const canon = [...new Set(candidatePaths)].filter(p =>
|
|
53
|
+
p.startsWith('docs-canonical/') && p.endsWith('.md') && existsSync(resolve(projectDir, p))
|
|
54
|
+
);
|
|
55
|
+
if (canon.length === 0) return 0;
|
|
56
|
+
if (!cfg.requiredFiles || typeof cfg.requiredFiles !== 'object') cfg.requiredFiles = {};
|
|
57
|
+
const existing = Array.isArray(cfg.requiredFiles.canonical) ? cfg.requiredFiles.canonical : [];
|
|
58
|
+
const seen = new Set(existing);
|
|
59
|
+
let added = 0;
|
|
60
|
+
for (const p of canon) if (!seen.has(p)) { existing.push(p); seen.add(p); added++; }
|
|
61
|
+
if (added === 0) return 0;
|
|
62
|
+
cfg.requiredFiles.canonical = existing;
|
|
63
|
+
try { writeFileSync(cfgPath, JSON.stringify(cfg, null, 2) + '\n', 'utf-8'); } catch { return 0; }
|
|
64
|
+
return added;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Standards citation map — each doc type maps to its governing industry standard.
|
|
69
|
+
* Inspired by RAG-grounded standards alignment (Lopez et al., AITPG, IEEE TSE 2026).
|
|
70
|
+
*/
|
|
71
|
+
const STANDARDS_CITATIONS = {
|
|
72
|
+
'ARCHITECTURE.md': {
|
|
73
|
+
standard: 'arc42 Template + C4 Model',
|
|
74
|
+
reference: 'Starke, G. & Brown, S. "arc42 — Architecture communication template." https://arc42.org | Brown, S. "The C4 Model for visualising software architecture." https://c4model.com',
|
|
75
|
+
sections: '§1 Introduction, §2 Constraints, §3 Context, §4 Solution Strategy, §5 Building Blocks, §6 Runtime, §7 Deployment, §8 Crosscutting, §9 ADRs, §10 Quality, §11 Risks, §12 Glossary',
|
|
76
|
+
},
|
|
77
|
+
'DATA-MODEL.md': {
|
|
78
|
+
standard: 'C4 Component Diagram + Entity-Relationship (Chen notation)',
|
|
79
|
+
reference: 'Brown, S. "C4 Model — Component diagrams." https://c4model.com | Chen, P. "The Entity-Relationship Model." ACM TODS 1(1), 1976',
|
|
80
|
+
sections: 'Entities, Relationships, ER Diagrams (Mermaid), Field-level definitions',
|
|
81
|
+
},
|
|
82
|
+
'TEST-SPEC.md': {
|
|
83
|
+
standard: 'ISO/IEC/IEEE 29119-3:2022 — Test Documentation',
|
|
84
|
+
reference: 'ISO/IEC/IEEE, "Software and systems engineering — Software testing — Part 3: Test documentation." International Standard, 2022',
|
|
85
|
+
sections: 'Test Categories, Coverage Rules, Test Matrix, Tool Configuration',
|
|
86
|
+
},
|
|
87
|
+
'SECURITY.md': {
|
|
88
|
+
standard: 'OWASP ASVS v4.0 + CWE Top 25',
|
|
89
|
+
reference: 'OWASP Foundation, "Application Security Verification Standard v4.0." https://owasp.org/asvs | MITRE, "CWE Top 25." https://cwe.mitre.org/top25',
|
|
90
|
+
sections: 'Authentication, Secrets Management, Access Control, Input Validation',
|
|
91
|
+
},
|
|
92
|
+
'ENVIRONMENT.md': {
|
|
93
|
+
standard: '12-Factor App Methodology',
|
|
94
|
+
reference: 'Wiggins, A. "The Twelve-Factor App." https://12factor.net',
|
|
95
|
+
sections: 'Environment Variables, Config Separation, Setup Steps, Provider Configuration',
|
|
96
|
+
},
|
|
97
|
+
'API-REFERENCE.md': {
|
|
98
|
+
standard: 'OpenAPI Specification 3.1',
|
|
99
|
+
reference: 'OpenAPI Initiative, "OpenAPI Specification v3.1.0." https://spec.openapis.org/oas/v3.1.0',
|
|
100
|
+
sections: 'Endpoints, Request/Response schemas, Authentication, Error codes',
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Append a standards citation footer to generated doc content.
|
|
106
|
+
* @param {string} content - The generated markdown content
|
|
107
|
+
* @param {string} docName - The filename (e.g., 'ARCHITECTURE.md')
|
|
108
|
+
* @returns {string} Content with citation footer appended
|
|
109
|
+
*/
|
|
110
|
+
export function appendStandardsCitation(content, docName) {
|
|
111
|
+
const citation = STANDARDS_CITATIONS[docName];
|
|
112
|
+
if (!citation) return content;
|
|
113
|
+
|
|
114
|
+
const footer = `
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Standards Reference
|
|
118
|
+
|
|
119
|
+
> **Aligned with**: ${citation.standard}
|
|
120
|
+
>
|
|
121
|
+
> **Sections covered**: ${citation.sections}
|
|
122
|
+
>
|
|
123
|
+
> **Reference**: ${citation.reference}
|
|
124
|
+
>
|
|
125
|
+
> *Standards alignment inspired by RAG-grounded generation (Lopez et al., AITPG, IEEE TSE 2026).*
|
|
126
|
+
`;
|
|
127
|
+
|
|
128
|
+
return content.trimEnd() + '\n' + footer;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* F1 (field report): web-shaped surface (HTTP endpoints, SDK deps, routes)
|
|
133
|
+
* auto-extracted from a cli/library/unknown-kind project is often pattern-
|
|
134
|
+
* matches in the project's OWN source (e.g. a scanner/linter whose code mentions
|
|
135
|
+
* express, boto3, jwt as detection strings), not real usage. We do NOT suppress
|
|
136
|
+
* it — that could hide a real surface (a false-green) — we flag it 'low'
|
|
137
|
+
* confidence so the surface is verified before being documented. Web kinds
|
|
138
|
+
* (webapp/api/service) stay 'normal'.
|
|
139
|
+
*/
|
|
140
|
+
export function surfaceConfidence(kind) {
|
|
141
|
+
return ['webapp', 'api', 'service'].includes(kind) ? 'normal' : 'low';
|
|
142
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SARIF 2.1.0 writer — `docguard guard --format sarif`.
|
|
3
|
+
*
|
|
4
|
+
* Maps guard's structured findings (stable codes, locations, suggestions) onto
|
|
5
|
+
* the OASIS SARIF schema so DocGuard results land natively in GitHub Code
|
|
6
|
+
* Scanning, PR diff annotations, and enterprise SARIF dashboards. The mapping
|
|
7
|
+
* is possible only because every validator emits findings with stable codes —
|
|
8
|
+
* codes become reportingDescriptors (rules), findings become results.
|
|
9
|
+
*
|
|
10
|
+
* Zero npm dependencies — pure Node.js built-ins.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { readFileSync } from 'node:fs';
|
|
14
|
+
import { CODES } from '../findings.mjs';
|
|
15
|
+
|
|
16
|
+
const SARIF_SCHEMA = 'https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Sarif/v2.1/os/sarif-schema-2.1.0.json';
|
|
17
|
+
const HELP_URI = 'https://github.com/raccioly/docguard#validators';
|
|
18
|
+
|
|
19
|
+
function pkgInfo() {
|
|
20
|
+
try {
|
|
21
|
+
const pkg = JSON.parse(readFileSync(new URL('../../package.json', import.meta.url), 'utf-8'));
|
|
22
|
+
return { version: pkg.version || '0.0.0', homepage: pkg.homepage || HELP_URI };
|
|
23
|
+
} catch {
|
|
24
|
+
return { version: '0.0.0', homepage: HELP_URI };
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** severity 'error' → SARIF 'error'; everything else (warn) → 'warning'. */
|
|
29
|
+
function toLevel(severity) {
|
|
30
|
+
return severity === 'error' ? 'error' : 'warning';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Split a finding location ('path' or 'path:line') into {uri, line}.
|
|
35
|
+
* A trailing :N is only a line number when N is all digits — Windows drive
|
|
36
|
+
* letters and URLs with ports never reach here (locations are repo-relative).
|
|
37
|
+
*/
|
|
38
|
+
function parseLocation(location) {
|
|
39
|
+
if (!location || typeof location !== 'string') return null;
|
|
40
|
+
const m = location.match(/^(.*?):(\d+)$/);
|
|
41
|
+
if (m) return { uri: m[1].replace(/\\/g, '/'), line: parseInt(m[2], 10) };
|
|
42
|
+
return { uri: location.replace(/\\/g, '/'), line: null };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Convert a runGuardInternal() result into a SARIF 2.1.0 log object.
|
|
47
|
+
*
|
|
48
|
+
* @param {object} guardData - the guard JSON contract ({findings, validators, ...})
|
|
49
|
+
* @param {{projectDir?: string}} [opts]
|
|
50
|
+
* @returns {object} SARIF log, ready for JSON.stringify
|
|
51
|
+
*/
|
|
52
|
+
export function toSarif(guardData, opts = {}) {
|
|
53
|
+
const { version, homepage } = pkgInfo();
|
|
54
|
+
const findings = Array.isArray(guardData.findings) ? guardData.findings : [];
|
|
55
|
+
|
|
56
|
+
// Validators that crashed (or legacy strings without findings) still need
|
|
57
|
+
// representation — a SARIF consumer must not read "no results" as "clean"
|
|
58
|
+
// when a validator errored. Synthesize one result per crash-path string on
|
|
59
|
+
// validators that emitted NO structured findings.
|
|
60
|
+
const synthetic = [];
|
|
61
|
+
for (const v of guardData.validators || []) {
|
|
62
|
+
if (v.status === 'skipped' || v.status === 'na') continue;
|
|
63
|
+
if (Array.isArray(v.findings) && v.findings.length > 0) continue;
|
|
64
|
+
for (const msg of v.errors || []) {
|
|
65
|
+
synthetic.push({ code: `DOCGUARD-${String(v.key || v.name || 'unknown').toUpperCase()}`, severity: 'error', message: msg, location: null, suggestion: null });
|
|
66
|
+
}
|
|
67
|
+
for (const msg of v.warnings || []) {
|
|
68
|
+
synthetic.push({ code: `DOCGUARD-${String(v.key || v.name || 'unknown').toUpperCase()}`, severity: 'warn', message: msg, location: null, suggestion: null });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const all = [...findings, ...synthetic];
|
|
72
|
+
|
|
73
|
+
// rules[]: one descriptor per distinct code, in first-appearance order.
|
|
74
|
+
const ruleIndexByCode = new Map();
|
|
75
|
+
const rules = [];
|
|
76
|
+
for (const f of all) {
|
|
77
|
+
if (ruleIndexByCode.has(f.code)) continue;
|
|
78
|
+
const meta = CODES[f.code];
|
|
79
|
+
const rule = { id: f.code };
|
|
80
|
+
if (meta) {
|
|
81
|
+
rule.name = meta.title;
|
|
82
|
+
rule.shortDescription = { text: meta.title };
|
|
83
|
+
rule.fullDescription = { text: meta.help };
|
|
84
|
+
}
|
|
85
|
+
rule.helpUri = HELP_URI;
|
|
86
|
+
rule.defaultConfiguration = { level: toLevel(f.severity) };
|
|
87
|
+
ruleIndexByCode.set(f.code, rules.length);
|
|
88
|
+
rules.push(rule);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const results = all.map((f) => {
|
|
92
|
+
const result = {
|
|
93
|
+
ruleId: f.code,
|
|
94
|
+
ruleIndex: ruleIndexByCode.get(f.code),
|
|
95
|
+
level: toLevel(f.severity),
|
|
96
|
+
message: { text: f.suggestion && f.suggestion.text ? `${f.message}\n→ ${f.suggestion.text}` : f.message },
|
|
97
|
+
};
|
|
98
|
+
const loc = parseLocation(f.location);
|
|
99
|
+
if (loc) {
|
|
100
|
+
const physicalLocation = { artifactLocation: { uri: loc.uri, uriBaseId: 'SRCROOT' } };
|
|
101
|
+
if (loc.line) physicalLocation.region = { startLine: loc.line };
|
|
102
|
+
result.locations = [{ physicalLocation }];
|
|
103
|
+
}
|
|
104
|
+
if (f.confidence === 'low') {
|
|
105
|
+
result.properties = { confidence: 'low', reportable: !!f.reportable };
|
|
106
|
+
}
|
|
107
|
+
return result;
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
const run = {
|
|
111
|
+
tool: {
|
|
112
|
+
driver: {
|
|
113
|
+
name: 'DocGuard',
|
|
114
|
+
informationUri: homepage,
|
|
115
|
+
version,
|
|
116
|
+
rules,
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
results,
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
if (opts.projectDir) {
|
|
123
|
+
// file:// URIs require a trailing slash on directory bases (SARIF §3.14.14).
|
|
124
|
+
const dir = String(opts.projectDir).replace(/\\/g, '/').replace(/\/$/, '');
|
|
125
|
+
run.originalUriBaseIds = { SRCROOT: { uri: `file://${dir}/` } };
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return { $schema: SARIF_SCHEMA, version: '2.1.0', runs: [run] };
|
|
129
|
+
}
|
package/commands/docguard.fix.md
CHANGED
|
@@ -1,81 +1,84 @@
|
|
|
1
1
|
---
|
|
2
|
-
description:
|
|
2
|
+
description: Find and fix all CDD documentation issues using AI-driven research
|
|
3
3
|
handoffs:
|
|
4
4
|
- label: Verify Fixes
|
|
5
5
|
agent: docguard.guard
|
|
6
6
|
prompt: Run guard to verify all fixes pass
|
|
7
|
-
- label: Check Score
|
|
7
|
+
- label: Check Score
|
|
8
8
|
agent: docguard.score
|
|
9
9
|
prompt: Show score improvement after fixes
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
#
|
|
12
|
+
# /docguard.fix — Find and Fix CDD Documentation Issues
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
You are an AI agent responsible for maintaining documentation quality using DocGuard.
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
`docguard fix --write` — e.g. removing an endpoint from `docs-canonical/API-REFERENCE.md`
|
|
18
|
-
that the OpenAPI spec confirms no longer exists (its table row + detail block are deleted).
|
|
19
|
-
- **Agent (needs an AI):** content rewrites that require judgment — e.g. replacing an
|
|
20
|
-
X-Ray prose section with CloudWatch, or writing a new endpoint's request/response block.
|
|
21
|
-
These use the research-prompt workflow below.
|
|
22
|
-
|
|
23
|
-
## Apply mechanical fixes first (fast, safe)
|
|
16
|
+
## Step 1: Mechanical fixes first (no AI judgment needed)
|
|
24
17
|
|
|
25
18
|
```bash
|
|
26
|
-
npx docguard-cli fix --write
|
|
19
|
+
npx docguard-cli fix --write
|
|
27
20
|
```
|
|
28
|
-
- Only edits docs marked `<!-- docguard:generated true -->` (use `--force` to override).
|
|
29
|
-
- Prints exactly what it removed. Re-run is a no-op if nothing changed.
|
|
30
|
-
- Run `docguard guard` afterward; whatever remains is agent work (below).
|
|
31
21
|
|
|
32
|
-
|
|
22
|
+
This deterministically applies the safe fix class: broken doc anchors, stale
|
|
23
|
+
counts bound to code collections, stale version references. Each fix is
|
|
24
|
+
provenance-checked and fail-closed — it never rewrites content whose source of
|
|
25
|
+
truth it cannot verify. Doing this first shrinks the issue list you research.
|
|
26
|
+
|
|
27
|
+
## Step 2: Assess what remains
|
|
33
28
|
|
|
34
|
-
1. **Identify what needs fixing** (each issue is tagged `mechanical` or `agent`):
|
|
35
29
|
```bash
|
|
36
30
|
npx docguard-cli diagnose
|
|
37
31
|
```
|
|
38
32
|
|
|
39
|
-
|
|
33
|
+
Parse the output — issues are categorized with AI-ready fix prompts. Every
|
|
34
|
+
finding carries a stable code; run `npx docguard-cli explain <CODE>` whenever
|
|
35
|
+
the right remediation isn't obvious from the message.
|
|
36
|
+
|
|
37
|
+
If no issues remain, report "All CDD documentation is up to date" and stop.
|
|
38
|
+
|
|
39
|
+
## Step 3: Fix each issue
|
|
40
|
+
|
|
41
|
+
| Issue Type | Action |
|
|
42
|
+
|-----------|--------|
|
|
43
|
+
| `missing-file` | Run `npx docguard-cli fix --doc <name>` to generate |
|
|
44
|
+
| `empty-doc` / `partial-doc` | Proceed to Step 4 for codebase research |
|
|
45
|
+
| `missing-config` | Create `.docguard.json` based on project type |
|
|
46
|
+
| `stale-doc` | Update `docguard:last-reviewed` date and content |
|
|
47
|
+
| `quality-issue` | Fix negation language, add missing sections |
|
|
48
|
+
| false positive | Suppress at the site: `// docguard:ignore <CODE>` (with a reason comment), and report it: `npx docguard-cli feedback` |
|
|
49
|
+
|
|
50
|
+
**Doc wrong vs code wrong:** a doc/code mismatch does not automatically mean
|
|
51
|
+
the doc is stale. Canonical docs are the spec — if the code drifted from a
|
|
52
|
+
documented decision, flag the code (or record the deviation with a
|
|
53
|
+
`// DRIFT: reason` comment + DRIFT-LOG.md entry) instead of silently rewriting
|
|
54
|
+
the doc to match the regression.
|
|
55
|
+
|
|
56
|
+
## Step 4: Write real content
|
|
57
|
+
|
|
58
|
+
For each document that needs content:
|
|
59
|
+
|
|
40
60
|
```bash
|
|
41
|
-
npx docguard-cli fix --doc
|
|
42
|
-
npx docguard-cli fix --doc security
|
|
43
|
-
npx docguard-cli fix --doc test-spec
|
|
44
|
-
npx docguard-cli fix --doc data-model
|
|
45
|
-
npx docguard-cli fix --doc environment
|
|
61
|
+
npx docguard-cli fix --doc <name>
|
|
46
62
|
```
|
|
47
63
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
5. **Include metadata header** in every canonical doc:
|
|
61
|
-
```markdown
|
|
62
|
-
<!-- docguard:version X.X.X -->
|
|
63
|
-
<!-- docguard:status active -->
|
|
64
|
-
<!-- docguard:last-reviewed YYYY-MM-DD -->
|
|
65
|
-
```
|
|
64
|
+
Where `<name>` is: `architecture`, `data-model`, `security`, `test-spec`, `environment`
|
|
65
|
+
|
|
66
|
+
Read the output carefully — it contains:
|
|
67
|
+
- **RESEARCH STEPS**: Exactly what files to read and commands to run
|
|
68
|
+
- **WRITE THE DOCUMENT**: Expected structure and content for each section
|
|
69
|
+
|
|
70
|
+
Execute the research steps, then write with REAL project content. No placeholders.
|
|
71
|
+
Never edit inside `<!-- docguard:section ... source=code -->` markers by hand —
|
|
72
|
+
those bodies are regenerated from code by `docguard sync --write`; pin them
|
|
73
|
+
(`pinned="reason"`) if a hand-maintained exception is genuinely needed.
|
|
74
|
+
|
|
75
|
+
## Step 5: Verify (iterate up to 3 times)
|
|
66
76
|
|
|
67
|
-
6. **Validate the fix** (iterate up to 3 times):
|
|
68
77
|
```bash
|
|
69
78
|
npx docguard-cli guard
|
|
79
|
+
npx docguard-cli score
|
|
70
80
|
```
|
|
71
81
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
- `tasks.md`: Phased breakdown (Phase 1, 2, 3+), Task IDs (T001+)
|
|
76
|
-
|
|
77
|
-
## Important
|
|
78
|
-
|
|
79
|
-
- Never use placeholder content — every section must reference real code
|
|
80
|
-
- Back up before overwriting — use `.bak` files or `safeWrite()`
|
|
81
|
-
- Log deviations in DRIFT-LOG.md with `// DRIFT: reason`
|
|
82
|
+
All checks should pass. If any fail, read the output and fix remaining issues.
|
|
83
|
+
Report the final CDD score, plus anything you suppressed (with reasons) or
|
|
84
|
+
reported as a false positive.
|
|
@@ -1,61 +1,67 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Run DocGuard guard validation — check
|
|
2
|
+
description: Run DocGuard guard validation — check all validators and fix any issues
|
|
3
3
|
handoffs:
|
|
4
|
-
- label: Fix
|
|
4
|
+
- label: Fix Issues
|
|
5
5
|
agent: docguard.fix
|
|
6
6
|
prompt: Fix all documentation issues found by guard
|
|
7
|
-
- label: Deep Review
|
|
8
|
-
agent: docguard.review
|
|
9
|
-
prompt: Perform semantic cross-document consistency analysis
|
|
10
7
|
- label: Check Score
|
|
11
8
|
agent: docguard.score
|
|
12
|
-
prompt: Show CDD maturity score
|
|
9
|
+
prompt: Show CDD maturity score after fixes
|
|
13
10
|
---
|
|
14
11
|
|
|
15
|
-
#
|
|
12
|
+
# /docguard.guard — Validate CDD Compliance
|
|
16
13
|
|
|
17
|
-
|
|
14
|
+
You are an AI agent enforcing Canonical-Driven Development (CDD) compliance using DocGuard.
|
|
18
15
|
|
|
19
|
-
##
|
|
16
|
+
## Step 1: Run Guard (machine-readable)
|
|
20
17
|
|
|
21
|
-
1. **Run the guard command**:
|
|
22
18
|
```bash
|
|
23
|
-
npx docguard-cli guard
|
|
19
|
+
npx docguard-cli guard --format json
|
|
24
20
|
```
|
|
25
21
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
22
|
+
Read the JSON contract — do not parse prose:
|
|
23
|
+
|
|
24
|
+
| Field | Meaning |
|
|
25
|
+
|-------|---------|
|
|
26
|
+
| `status` | `PASS` / `WARN` / `FAIL` (severity-aware; matches the exit code: 0/2/1) |
|
|
27
|
+
| `findings[]` | Structured issues: `{code, severity, confidence, message, location, suggestion}` |
|
|
28
|
+
| `nextStep` | The single suggested follow-up command (`null` on PASS) |
|
|
29
|
+
| `reportable[]` | Low-confidence findings (possible false positives) — verify before acting |
|
|
30
|
+
| `coverage` | Markdown tier map: `canonical / tracked / ignored / unclassified[]` |
|
|
31
|
+
| `semanticClaims.count` | Documented counts/limits/enums NOT yet verified against code |
|
|
32
|
+
| `validators[]` | Per-validator results, including `na` (nothing to validate ≠ pass) |
|
|
33
|
+
|
|
34
|
+
## Step 2: Understand each finding before fixing
|
|
35
|
+
|
|
36
|
+
- Every finding carries a stable code (e.g. `STR001`, `ENV003`, `XRF002`). Run
|
|
37
|
+
`npx docguard-cli explain <CODE>` for its contract, cause, and remediation.
|
|
38
|
+
- `confidence: "low"` means the scanner itself is unsure — verify against the
|
|
39
|
+
code before changing anything, and report real false positives with
|
|
40
|
+
`npx docguard-cli feedback`.
|
|
41
|
+
- A finding's `suggestion` may include a ready-to-run `command` or an inline
|
|
42
|
+
`pragma`. Prefer those over inventing your own fix.
|
|
43
|
+
|
|
44
|
+
## Step 3: Fix, suppress, or escalate
|
|
45
|
+
|
|
46
|
+
1. **Mechanical issues first**: `npx docguard-cli fix --write` applies safe,
|
|
47
|
+
provenance-checked fixes (broken anchors, stale counts/versions). Never
|
|
48
|
+
hand-edit what the tool can fix deterministically.
|
|
49
|
+
2. **Prose/content issues**: follow the `/docguard.fix` workflow (research →
|
|
50
|
+
write real content).
|
|
51
|
+
3. **Genuine false positives**: suppress at the finding site with the code —
|
|
52
|
+
`// docguard:ignore <CODE>` on (or above) the flagged line — or mark a whole
|
|
53
|
+
validator not-applicable in a doc:
|
|
54
|
+
`<!-- docguard:validator <key> n/a — reason -->`. Always include the reason.
|
|
55
|
+
Never suppress to silence a real issue.
|
|
56
|
+
4. If `semanticClaims.count > 0`, offer to run `npx docguard-cli verify --semantic`
|
|
57
|
+
and check each extracted claim against the code — a green guard asserts
|
|
58
|
+
structure, not the truth of documented numbers.
|
|
59
|
+
|
|
60
|
+
## Step 4: Report
|
|
61
|
+
|
|
62
|
+
Show the user:
|
|
63
|
+
1. `status` and pass/total, plus anything in `coverage.unclassified` (docs no
|
|
64
|
+
validator watches — suggest enrolling or ignoring them)
|
|
65
|
+
2. Each finding fixed (by code), each suppressed (with reason), each reported
|
|
66
|
+
as a false positive
|
|
67
|
+
3. Final score: `npx docguard-cli score`
|
|
@@ -1,53 +1,71 @@
|
|
|
1
1
|
---
|
|
2
|
-
description:
|
|
2
|
+
description: Review documentation quality — identify drift, coverage gaps, and improvements
|
|
3
3
|
handoffs:
|
|
4
|
-
- label: Fix Issues
|
|
4
|
+
- label: Fix Issues
|
|
5
5
|
agent: docguard.fix
|
|
6
6
|
prompt: Fix the documentation issues identified in the review
|
|
7
7
|
- label: Run Guard
|
|
8
8
|
agent: docguard.guard
|
|
9
|
-
prompt: Validate all
|
|
9
|
+
prompt: Validate all checks pass after review
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
#
|
|
12
|
+
# /docguard.review — Review Documentation vs Code
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
You are an AI agent reviewing documentation quality and detecting drift between docs and code.
|
|
15
15
|
|
|
16
|
-
##
|
|
16
|
+
## Step 1: Run Diagnostics
|
|
17
17
|
|
|
18
|
-
1. **Run the full diagnostic**:
|
|
19
18
|
```bash
|
|
20
19
|
npx docguard-cli diagnose
|
|
20
|
+
npx docguard-cli diff
|
|
21
21
|
npx docguard-cli score
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Read all output. Identify where documentation no longer matches the codebase.
|
|
25
|
+
Findings carry stable codes — `npx docguard-cli explain <CODE>` when unclear.
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
|--------------|--------------|
|
|
28
|
-
| Terminology | Same concepts named consistently across docs |
|
|
29
|
-
| Architecture ↔ Code | Components listed in ARCHITECTURE.md exist in codebase |
|
|
30
|
-
| Data Model ↔ Code | Schemas in DATA-MODEL.md match actual implementations |
|
|
31
|
-
| Test Coverage | Critical flows in TEST-SPEC.md have actual test files |
|
|
32
|
-
| Security Claims | Auth mechanisms in SECURITY.md match actual code |
|
|
33
|
-
| Cross-References | Internal doc links resolve to valid targets |
|
|
27
|
+
## Step 2: Verify Documented Claims Against Code
|
|
34
28
|
|
|
35
|
-
|
|
29
|
+
```bash
|
|
30
|
+
npx docguard-cli verify --semantic
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
This extracts every checkable claim in the canonical docs — counts, limits,
|
|
34
|
+
rate numbers, retention windows, status enums — as a task list with the nearest
|
|
35
|
+
cited code path. **You perform each verification**: read the cited code, compare
|
|
36
|
+
the value, and report every mismatch with both values. This is the highest-value
|
|
37
|
+
review step; deterministic validators cannot judge these.
|
|
38
|
+
|
|
39
|
+
## Step 3: Semantic Analysis (Beyond CLI)
|
|
40
|
+
|
|
41
|
+
For each canonical doc, verify alignment with actual code:
|
|
36
42
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
| Analysis | What to Check |
|
|
44
|
+
|----------|--------------|
|
|
45
|
+
| Architecture ↔ Code | Components in ARCHITECTURE.md exist as real modules |
|
|
46
|
+
| Data Model ↔ Code | Schemas in DATA-MODEL.md match actual implementations |
|
|
47
|
+
| Security Claims | Auth mechanisms in SECURITY.md match actual code |
|
|
48
|
+
| Test Coverage | Critical flows in TEST-SPEC.md have actual test files |
|
|
49
|
+
| Terminology | Same concepts named consistently across all docs |
|
|
44
50
|
|
|
45
|
-
4
|
|
46
|
-
- 🔴 **CRITICAL**: Security claim mismatch, missing mandatory doc, broken architecture reference
|
|
47
|
-
- 🟠 **HIGH**: Undocumented component, stale content (>5 commits behind), terminology conflict
|
|
48
|
-
- 🟡 **MEDIUM**: Missing cross-reference, minor coverage gap, readability issue
|
|
49
|
-
- 🟢 **LOW**: Minor formatting, optional section missing, style inconsistency
|
|
51
|
+
## Step 4: Update Stale Docs
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
For each stale or drifted document:
|
|
54
|
+
1. **Decide which side is wrong first.** Canonical docs are the spec — if the
|
|
55
|
+
code regressed from a documented decision, flag the code (or record a
|
|
56
|
+
`// DRIFT: reason` + DRIFT-LOG.md entry); don't rewrite the doc to match a
|
|
57
|
+
regression.
|
|
58
|
+
2. Sections inside `<!-- docguard:section ... source=code -->` markers are
|
|
59
|
+
regenerated — run `npx docguard-cli sync --write` instead of editing by hand.
|
|
60
|
+
3. For hand-maintained sections: read the relevant source, update the specific
|
|
61
|
+
section, refresh `docguard:last-reviewed` to today.
|
|
62
|
+
4. Add entry to CHANGELOG.md under [Unreleased].
|
|
63
|
+
|
|
64
|
+
## Step 5: Verify
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npx docguard-cli guard
|
|
68
|
+
npx docguard-cli score
|
|
69
|
+
```
|
|
52
70
|
|
|
53
|
-
|
|
71
|
+
Report findings, changes made, and the final score.
|