docguard-cli 0.32.0 → 0.33.1

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.
@@ -0,0 +1,103 @@
1
+ /**
2
+ * JUnit XML writer — `docguard guard --format junit`.
3
+ *
4
+ * SARIF covers GitHub Code Scanning; JUnit covers everything else an
5
+ * enterprise runs: GitLab CI (`artifacts:reports:junit`), Jenkins
6
+ * (`junit` step), Azure DevOps, CircleCI, Bamboo. One testcase per
7
+ * validator keeps the report readable in those UIs — a failed validator
8
+ * shows its findings (code + message + location) as the failure body.
9
+ *
10
+ * Mapping (deterministic):
11
+ * validator error findings → <failure> (red in every CI)
12
+ * validator crashed (fail, no
13
+ * structured findings) → <error> from its string errors (red)
14
+ * warn-only validator → passing testcase + findings in
15
+ * <system-out> (visible, non-gating)
16
+ * skipped / n/a → <skipped/>
17
+ *
18
+ * Zero npm dependencies — pure string assembly with strict XML escaping.
19
+ */
20
+
21
+ function esc(s) {
22
+ return String(s ?? '')
23
+ .replace(/&/g, '&amp;')
24
+ .replace(/</g, '&lt;')
25
+ .replace(/>/g, '&gt;')
26
+ .replace(/"/g, '&quot;')
27
+ .replace(/'/g, '&apos;');
28
+ }
29
+
30
+ function findingLine(f) {
31
+ const code = f.code ? `[${f.code}] ` : '';
32
+ const loc = f.location ? ` (${f.location})` : '';
33
+ return `${code}${f.message}${loc}`;
34
+ }
35
+
36
+ /**
37
+ * Build the JUnit XML document from runGuardInternal's data.
38
+ * `data.validators` entries: { name, status, findings? }; `data.findings`
39
+ * is the flat list with `validator` back-references — we group by the
40
+ * validator display name via each result's own findings when present,
41
+ * falling back to the flat list.
42
+ */
43
+ export function toJUnit(data) {
44
+ const cases = [];
45
+ let failures = 0, errorCount = 0, skipped = 0;
46
+
47
+ for (const v of data.validators || []) {
48
+ const vFindings = Array.isArray(v.findings)
49
+ ? v.findings
50
+ : (data.findings || []).filter(f => f.validator === v.key || f.validator === v.name);
51
+ const errors = vFindings.filter(f => f.severity === 'error');
52
+ const warns = vFindings.filter(f => f.severity !== 'error');
53
+ const attrs = `name="${esc(v.name)}" classname="docguard.guard"`;
54
+
55
+ if (v.status === 'skipped' || v.status === 'na') {
56
+ skipped++;
57
+ cases.push(` <testcase ${attrs}><skipped/></testcase>`);
58
+ } else if (errors.length > 0) {
59
+ failures++;
60
+ const body = errors.map(findingLine).join('\n');
61
+ cases.push(
62
+ ` <testcase ${attrs}>\n` +
63
+ ` <failure message="${esc(errors[0].message)}" type="${esc(errors[0].code || 'docguard')}">${esc(body)}</failure>\n` +
64
+ ` </testcase>`
65
+ );
66
+ } else if (v.status === 'fail') {
67
+ // A validator that failed WITHOUT structured error findings — the
68
+ // crash path (guard catches the throw and records string errors only).
69
+ // This must go red in CI, not render as a passing testcase (M1).
70
+ errorCount++;
71
+ const body = (v.errors || []).join('\n') || 'validator failed without structured findings';
72
+ cases.push(
73
+ ` <testcase ${attrs}>\n` +
74
+ ` <error message="${esc((v.errors || [])[0] || 'validator failed')}" type="docguard.crash">${esc(body)}</error>\n` +
75
+ ` </testcase>`
76
+ );
77
+ } else if (warns.length > 0) {
78
+ const body = warns.map(findingLine).join('\n');
79
+ cases.push(
80
+ ` <testcase ${attrs}>\n` +
81
+ ` <system-out>${esc(body)}</system-out>\n` +
82
+ ` </testcase>`
83
+ );
84
+ } else {
85
+ cases.push(` <testcase ${attrs}/>`);
86
+ }
87
+ }
88
+
89
+ const total = (data.validators || []).length;
90
+ const suiteAttrs =
91
+ `name="docguard guard — ${esc(data.project || 'project')}" ` +
92
+ `tests="${total}" failures="${failures}" errors="${errorCount}" skipped="${skipped}" ` +
93
+ `timestamp="${esc(data.timestamp || '')}"`;
94
+
95
+ return (
96
+ `<?xml version="1.0" encoding="UTF-8"?>\n` +
97
+ `<testsuites tests="${total}" failures="${failures}" errors="${errorCount}">\n` +
98
+ ` <testsuite ${suiteAttrs}>\n` +
99
+ cases.join('\n') + (cases.length ? '\n' : '') +
100
+ ` </testsuite>\n` +
101
+ `</testsuites>`
102
+ );
103
+ }
package/docs/commands.md CHANGED
@@ -38,6 +38,17 @@ npx docguard-cli diagnose --format prompt # Raw AI prompt (all issues combined)
38
38
  npx docguard-cli guard # Text output
39
39
  npx docguard-cli guard --format json # Structured JSON (the stable agent contract)
40
40
  npx docguard-cli guard --format sarif # SARIF 2.1.0 for GitHub Code Scanning
41
+ npx docguard-cli guard --format junit # JUnit XML for GitLab/Jenkins/Azure DevOps
42
+ npx docguard-cli guard --update-baseline # Freeze current findings (brownfield adoption)
43
+ npx docguard-cli guard --no-baseline # Ignore the committed baseline this run
44
+ ```
45
+
46
+ **Adoption baseline:** on a legacy repo, `--update-baseline` writes
47
+ `.docguard.baseline.json` (commit it). From then on guard/ci suppress those
48
+ frozen findings — visibly — and gate only new drift. Fingerprints are stable
49
+ across line-number churn and volatile counts, so the baseline doesn't rot.
50
+
51
+ ```bash
41
52
  npx docguard-cli guard --verbose # Show all check details
42
53
  npx docguard-cli guard --changed-only # Pre-commit lite mode (fast subset)
43
54
  ```
@@ -181,7 +192,7 @@ never touched without `--force`.
181
192
 
182
193
  **MCP server over stdio** — DocGuard's read-only core as native agent tools
183
194
  (`docguard_guard`, `docguard_score`, `docguard_explain`,
184
- `docguard_verify_claims`, `docguard_diagnose`).
195
+ `docguard_verify_claims`, `docguard_report`, `docguard_diagnose`).
185
196
 
186
197
  ```bash
187
198
  claude mcp add docguard -- npx docguard-cli mcp
@@ -211,15 +222,32 @@ npx docguard-cli memory --pack # .docguard/context-pack.md (session-start co
211
222
 
212
223
  ## DevOps Commands
213
224
 
225
+ ### `docguard report`
226
+
227
+ **Compliance-evidence bundle for audits** — guard verdict, CDD score, ALCOA+
228
+ data-integrity attributes, findings grouped by code, and fix history, stamped
229
+ with the git commit and a tamper-evident sha256 integrity hash. Evidence, not
230
+ a gate: always exits 0 (`guard`/`ci` fail builds).
231
+
232
+ ```bash
233
+ npx docguard-cli report # markdown to stdout
234
+ npx docguard-cli report --format json # machine bundle
235
+ npx docguard-cli report --out evidence.md # write to a file
236
+ ```
237
+
214
238
  ### `docguard ci`
215
239
 
216
- **Single command for CI/CD pipelines.** Runs guard + score internally (no subprocess).
240
+ **Single command for CI/CD pipelines.** Runs guard + score internally (no
241
+ subprocess). Read-only and machine-clean: it never scaffolds or mutates the
242
+ workspace it validates. Each run appends one line to `.docguard/history.jsonl`
243
+ so `docguard score --trend` can show the trajectory (opt out: `--no-history`).
217
244
 
218
245
  ```bash
219
246
  npx docguard-cli ci # Basic check
220
247
  npx docguard-cli ci --threshold 70 # Fail below score 70
221
248
  npx docguard-cli ci --threshold 80 --fail-on-warning # Strict mode
222
249
  npx docguard-cli ci --format json # JSON for GitHub Actions
250
+ npx docguard-cli score --trend # Score history from past ci runs
223
251
  ```
224
252
 
225
253
  ### `docguard hooks`
@@ -111,6 +111,20 @@ Conventional doc folders (`docs/`, `doc/`, `documentation/`, `guides/`,
111
111
  that set with non-standard homes — it never replaces auto-detection. To exclude
112
112
  a conventional dir, list it in `.docguardignore`.
113
113
 
114
+ ## Adoption baseline — `baseline`
115
+
116
+ When a committed `.docguard.baseline.json` exists (written by
117
+ `docguard guard --update-baseline`), guard/ci suppress the frozen findings
118
+ and gate only new drift. Set `"baseline": false` in `.docguard.json` to
119
+ ignore the file entirely (same as always passing `--no-baseline`):
120
+
121
+ ```json
122
+ { "baseline": false }
123
+ ```
124
+
125
+ Suppression is always visible in output and in the `baselineSuppressed`
126
+ JSON field — nothing is silently hidden.
127
+
114
128
  ## Muting a validator
115
129
 
116
130
  Two ways to turn a validator off, for two different intents:
package/docs/faq.md CHANGED
@@ -119,10 +119,41 @@ Exit code 0 = pass, 1 = fail. Use `--threshold` to set minimum score.
119
119
 
120
120
  Yes — DocGuard ships a template at `templates/ci/github-actions.yml`. Copy it to `.github/workflows/` or use the reusable action in `action.yml`.
121
121
 
122
+ ### Claude (or my AI agent) says DocGuard is "unknown" and wants a legitimacy check. Why?
123
+
124
+ That's the agent's default posture toward **any** third-party MCP server or
125
+ npx package — MCP servers run code with your permissions, so unknown ones get
126
+ a trust prompt. It's not a DocGuard-specific flag. What DocGuard provides so
127
+ the check can pass:
128
+
129
+ - **npm provenance** — releases are signed by GitHub Actions (Sigstore), so
130
+ the tarball is verifiably built from this repository.
131
+ - **Official MCP registry** — `io.github.raccioly/docguard` is a verified
132
+ namespace at registry.modelcontextprotocol.io.
133
+ - **Read-only annotations** — every MCP tool declares `readOnlyHint`; the
134
+ server never writes or reaches the network.
135
+ - **[PRIVACY.md](../PRIVACY.md)** — no telemetry, no data collection.
136
+
137
+ To stop the prompt on your own machines: approve with "Always allow", or
138
+ pre-trust it for a whole team via a project-scoped `.mcp.json` /
139
+ enterprise managed-settings allowlist.
140
+
122
141
  ### Does DocGuard block commits?
123
142
 
124
143
  Only if you install hooks (`docguard hooks`). Without hooks, it's advisory only.
125
144
 
145
+ ### I ran guard on our legacy repo and got dozens of findings. Now what?
146
+
147
+ Freeze them and move forward:
148
+
149
+ ```bash
150
+ npx docguard-cli guard --update-baseline # writes .docguard.baseline.json — commit it
151
+ ```
152
+
153
+ From then on guard/ci pass, suppress the frozen findings **visibly**
154
+ ("N pre-existing finding(s) suppressed"), and gate only NEW drift. Burn the
155
+ baseline down at your own pace; `--no-baseline` shows the full picture anytime.
156
+
126
157
  ---
127
158
 
128
159
  ## Technical
@@ -3,7 +3,7 @@ schema_version: "1.0"
3
3
  extension:
4
4
  id: "docguard"
5
5
  name: "DocGuard — CDD Enforcement"
6
- version: "0.32.0"
6
+ version: "0.33.1"
7
7
  description: "Canonical-Driven Development enforcement as a true spec-kit extension. LLM-first design with automated validators, 4 AI behavior skills, spec-kit skill chaining, and workflow hooks. One pinned runtime dependency (@babel/parser); pure Node.js otherwise."
8
8
  author: "Ricardo Accioly"
9
9
  repository: "https://github.com/raccioly/docguard"
@@ -6,10 +6,10 @@ description: AI-driven documentation repair with structured research workflow, t
6
6
  compatibility: Requires DocGuard CLI installed (npm i -g docguard-cli or npx docguard-cli)
7
7
  metadata:
8
8
  author: docguard
9
- version: 0.32.0
9
+ version: 0.33.1
10
10
  source: extensions/spec-kit-docguard/skills/docguard-fix
11
11
  ---
12
- <!-- docguard:version: 0.32.0 -->
12
+ <!-- docguard:version: 0.33.1 -->
13
13
 
14
14
  # DocGuard Fix Skill
15
15
 
@@ -7,10 +7,10 @@ description: Run DocGuard guard validation against Canonical-Driven Development
7
7
  compatibility: Requires DocGuard CLI installed (npm i -g docguard-cli or npx docguard-cli)
8
8
  metadata:
9
9
  author: docguard
10
- version: 0.32.0
10
+ version: 0.33.1
11
11
  source: extensions/spec-kit-docguard/skills/docguard-guard
12
12
  ---
13
- <!-- docguard:version: 0.32.0 -->
13
+ <!-- docguard:version: 0.33.1 -->
14
14
 
15
15
  # DocGuard Guard Skill
16
16
 
@@ -6,10 +6,10 @@ description: Cross-document consistency analysis and quality assessment. Perform
6
6
  compatibility: Requires DocGuard CLI installed (npm i -g docguard-cli or npx docguard-cli)
7
7
  metadata:
8
8
  author: docguard
9
- version: 0.32.0
9
+ version: 0.33.1
10
10
  source: extensions/spec-kit-docguard/skills/docguard-review
11
11
  ---
12
- <!-- docguard:version: 0.32.0 -->
12
+ <!-- docguard:version: 0.33.1 -->
13
13
 
14
14
  # DocGuard Review Skill
15
15
 
@@ -6,10 +6,10 @@ description: CDD maturity assessment with category-aware improvement roadmap. Ru
6
6
  compatibility: Requires DocGuard CLI installed (npm i -g docguard-cli or npx docguard-cli)
7
7
  metadata:
8
8
  author: docguard
9
- version: 0.32.0
9
+ version: 0.33.1
10
10
  source: extensions/spec-kit-docguard/skills/docguard-score
11
11
  ---
12
- <!-- docguard:version: 0.32.0 -->
12
+ <!-- docguard:version: 0.33.1 -->
13
13
 
14
14
  # DocGuard Score Skill
15
15
 
@@ -4,10 +4,10 @@ description: Keep canonical documentation ALWAYS UP TO DATE. Refreshes code-trut
4
4
  compatibility: Requires DocGuard CLI installed (npm i -g docguard-cli or npx docguard-cli)
5
5
  metadata:
6
6
  author: docguard
7
- version: 0.32.0
7
+ version: 0.33.1
8
8
  source: extensions/spec-kit-docguard/skills/docguard-sync
9
9
  ---
10
- <!-- docguard:version: 0.32.0 -->
10
+ <!-- docguard:version: 0.33.1 -->
11
11
 
12
12
  # DocGuard Sync Skill
13
13
 
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "docguard-cli",
3
- "version": "0.32.0",
3
+ "version": "0.33.1",
4
4
  "description": "The enforcement tool for Canonical-Driven Development (CDD). Audit, generate, and guard your project documentation.",
5
5
  "type": "module",
6
6
  "bin": {
7
- "docguard": "./cli/docguard.mjs"
7
+ "docguard": "cli/docguard.mjs"
8
8
  },
9
9
  "scripts": {
10
10
  "docguard": "node cli/docguard.mjs",
@@ -36,7 +36,7 @@
36
36
  "license": "MIT",
37
37
  "repository": {
38
38
  "type": "git",
39
- "url": "https://github.com/raccioly/docguard"
39
+ "url": "git+https://github.com/raccioly/docguard.git"
40
40
  },
41
41
  "homepage": "https://github.com/raccioly/docguard#readme",
42
42
  "mcpName": "io.github.raccioly/docguard",
@@ -57,6 +57,7 @@
57
57
  "docs/",
58
58
  "schemas/",
59
59
  "STANDARD.md",
60
+ "PRIVACY.md",
60
61
  "PHILOSOPHY.md",
61
62
  "README.md",
62
63
  "LICENSE"
@@ -29,6 +29,11 @@
29
29
  "enum": ["cli", "library", "webapp", "api", "unknown"],
30
30
  "description": "Project shape. Affects which validators run (e.g. webapp + api need env vars; cli/library can skip)."
31
31
  },
32
+ "baseline": {
33
+ "type": "boolean",
34
+ "description": "Set false to ignore a committed .docguard.baseline.json entirely (equivalent to always passing --no-baseline). Default: the baseline auto-applies when the file exists.",
35
+ "default": true
36
+ },
32
37
  "projectTypeConfig": {
33
38
  "type": "object",
34
39
  "description": "Per-type behavior knobs that override profile defaults.",