docguard-cli 0.40.4 → 0.41.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +3218 -0
  2. package/README.md +25 -16
  3. package/cli/assessment.mjs +94 -0
  4. package/cli/commands/ci.mjs +15 -5
  5. package/cli/commands/diagnose.mjs +20 -13
  6. package/cli/commands/fix.mjs +14 -45
  7. package/cli/commands/guard.mjs +53 -25
  8. package/cli/commands/hooks.mjs +51 -10
  9. package/cli/commands/init.mjs +15 -0
  10. package/cli/commands/reconcile.mjs +10 -3
  11. package/cli/commands/report.mjs +5 -1
  12. package/cli/commands/score.mjs +2 -1
  13. package/cli/commands/upgrade.mjs +4 -1
  14. package/cli/commands/verify.mjs +9 -2
  15. package/cli/commands/watch.mjs +3 -2
  16. package/cli/config.mjs +23 -0
  17. package/cli/evidence/adapters.mjs +14 -0
  18. package/cli/evidence/manifest.mjs +15 -0
  19. package/cli/evidence/python-literal.mjs +304 -0
  20. package/cli/findings.mjs +17 -3
  21. package/cli/scanners/instruction-audit.mjs +88 -11
  22. package/cli/scanners/js-ast.mjs +156 -18
  23. package/cli/scanners/reconciliation.mjs +56 -6
  24. package/cli/scanners/routes.mjs +84 -9
  25. package/cli/scanners/spec-registry.mjs +29 -0
  26. package/cli/shared-git.mjs +98 -0
  27. package/cli/shared-ignore.mjs +1 -1
  28. package/cli/shared.mjs +30 -1
  29. package/cli/validators/api-doc-smells.mjs +2 -2
  30. package/cli/validators/api-surface.mjs +4 -9
  31. package/cli/validators/diff-suspicion.mjs +3 -2
  32. package/cli/validators/docs-sync.mjs +45 -29
  33. package/cli/validators/environment.mjs +64 -6
  34. package/cli/validators/metrics-consistency.mjs +52 -11
  35. package/cli/validators/reference-existence.mjs +4 -2
  36. package/cli/validators/security.mjs +37 -12
  37. package/cli/validators/spec-registry.mjs +10 -7
  38. package/cli/validators/todo-tracking.mjs +31 -11
  39. package/cli/validators/traceability.mjs +29 -4
  40. package/cli/writers/junit.mjs +3 -3
  41. package/cli/writers/sarif.mjs +13 -9
  42. package/docs/configuration.md +12 -1
  43. package/extensions/spec-kit-docguard/README.md +3 -0
  44. package/extensions/spec-kit-docguard/commands/review.md +50 -0
  45. package/extensions/spec-kit-docguard/extension.yml +16 -4
  46. package/extensions/spec-kit-docguard/skills/docguard-fix/SKILL.md +2 -2
  47. package/extensions/spec-kit-docguard/skills/docguard-guard/SKILL.md +2 -2
  48. package/extensions/spec-kit-docguard/skills/docguard-review/SKILL.md +2 -2
  49. package/extensions/spec-kit-docguard/skills/docguard-score/SKILL.md +2 -2
  50. package/extensions/spec-kit-docguard/skills/docguard-sync/SKILL.md +2 -2
  51. package/extensions/spec-kit-docguard/templates/github-workflows/docguard-autofix.yml +1 -1
  52. package/extensions/spec-kit-docguard/templates/github-workflows/docguard-guard.yml +1 -1
  53. package/package.json +2 -1
  54. package/schemas/docguard-config.schema.json +15 -1
  55. package/schemas/docguard-evidence.schema.json +12 -0
  56. package/templates/ci/github-actions.yml +1 -1
  57. package/templates/evidence-manifest.json +16 -0
@@ -18,6 +18,7 @@ import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
18
18
  import { resolve, join, relative, basename, extname } from 'node:path';
19
19
  import { TRACE_MAP, isTraceableSource } from '../shared-trace-patterns.mjs';
20
20
  import { walkFiles as sharedWalkFiles, listCanonicalDocs } from '../shared-ignore.mjs';
21
+ /** @implements docguard.adoption-workflow-integrity#FR-006 */
21
22
  import { mkFinding, resultFromFindings } from '../findings.mjs';
22
23
  import { tokenize } from '../shared-diff.mjs';
23
24
  import { rankBySimilarity } from '../shared-ir.mjs';
@@ -32,7 +33,7 @@ import {
32
33
  requirementPatterns,
33
34
  } from '../shared-requirements.mjs';
34
35
  import { readRetirementManifest } from '../scanners/retirement-manifest.mjs';
35
- import { parseSpecId } from '../scanners/spec-registry.mjs';
36
+ import { parseSpecId, trustedSpecLifecycleIndex } from '../scanners/spec-registry.mjs';
36
37
 
37
38
  /**
38
39
  * Optional graphify interop (github.com/Graphify-Labs/graphify, MIT).
@@ -250,7 +251,9 @@ export function validateTraceability(projectDir, config) {
250
251
  passed += reqResult.passed;
251
252
  total += reqResult.total;
252
253
 
253
- return resultFromFindings(findings, { passed, total });
254
+ const result = resultFromFindings(findings, { passed, total });
255
+ result.requirementCoverage = reqResult.requirementCoverage;
256
+ return result;
254
257
  }
255
258
 
256
259
  // ──── Requirement ID Traceability ────────────────────────────────────────────
@@ -274,6 +277,7 @@ function validateRequirementTraceability(projectDir, config, projectFiles) {
274
277
  // ── Step 1: Collect requirement IDs from documentation ──
275
278
  const reqIds = collectRequirementIds(projectDir, config, patterns);
276
279
  const retiredReqIds = loadRetiredRequirementIds(projectDir);
280
+ const lifecycleIndex = trustedSpecLifecycleIndex(projectDir);
277
281
 
278
282
  // ── Step 2: Scan test files for requirement ID references ──
279
283
  const testRefs = scanTestFilesForReferences(projectDir, projectFiles, patterns);
@@ -295,9 +299,18 @@ function validateRequirementTraceability(projectDir, config, projectFiles) {
295
299
  const softThreshold = config.traceability?.irSoftThreshold ?? 0.10;
296
300
  let testCorpus = null;
297
301
 
298
- // Check each documented requirement has at least one test reference
302
+ let deferred = 0;
303
+ let lifecycleUnknown = 0;
304
+ // Planned specs are intent awaiting implementation. Only committed,
305
+ // digest-current reviewed lifecycle can defer their test linkage.
299
306
  for (const [key, location] of reqIds) {
300
307
  const reqId = location.id;
308
+ const lifecycle = location.specId ? lifecycleIndex.get(`${location.specId}\0${location.file}`) : null;
309
+ if (lifecycle?.delivery === 'planned') {
310
+ deferred++;
311
+ continue;
312
+ }
313
+ if (location.specId && !lifecycle) lifecycleUnknown++;
301
314
  total++;
302
315
  if (resolvedRefs.has(key)) {
303
316
  passed++;
@@ -326,6 +339,8 @@ function validateRequirementTraceability(projectDir, config, projectFiles) {
326
339
  }));
327
340
  }
328
341
  }
342
+ const applicableRequirements = total;
343
+ const tracedRequirements = passed;
329
344
 
330
345
  // Check for orphaned test refs (tests referencing non-existent requirements)
331
346
  for (const [reqId, refs] of testRefs) {
@@ -346,7 +361,17 @@ function validateRequirementTraceability(projectDir, config, projectFiles) {
346
361
  }
347
362
  }
348
363
 
349
- return { findings, passed, total };
364
+ return {
365
+ findings, passed, total,
366
+ requirementCoverage: {
367
+ discovered: reqIds.size,
368
+ applicable: applicableRequirements,
369
+ traced: tracedRequirements,
370
+ missing: findings.filter(finding => finding.code === 'TRC004').length,
371
+ deferred,
372
+ lifecycleUnknown,
373
+ },
374
+ };
350
375
  }
351
376
 
352
377
  /**
@@ -48,8 +48,8 @@ export function toJUnit(data) {
48
48
  const vFindings = Array.isArray(v.findings)
49
49
  ? v.findings
50
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');
51
+ const errors = vFindings.filter(f => (f.effectiveSeverity || f.severity) === 'error');
52
+ const warns = vFindings.filter(f => (f.effectiveSeverity || f.severity) !== 'error');
53
53
  const attrs = `name="${esc(v.name)}" classname="docguard.guard"`;
54
54
 
55
55
  if (v.status === 'skipped' || v.status === 'na') {
@@ -63,7 +63,7 @@ export function toJUnit(data) {
63
63
  ` <failure message="${esc(errors[0].message)}" type="${esc(errors[0].code || 'docguard')}">${esc(body)}</failure>\n` +
64
64
  ` </testcase>`
65
65
  );
66
- } else if (v.status === 'fail') {
66
+ } else if (v.status === 'fail' && vFindings.length === 0) {
67
67
  // A validator that failed WITHOUT structured error findings — the
68
68
  // crash path (guard catches the throw and records string errors only).
69
69
  // This must go red in CI, not render as a passing testcase (M1).
@@ -25,9 +25,9 @@ function pkgInfo() {
25
25
  }
26
26
  }
27
27
 
28
- /** severity 'error' → SARIF 'error'; everything else (warn) → 'warning'. */
28
+ /** Effective severity → SARIF level. */
29
29
  function toLevel(severity) {
30
- return severity === 'error' ? 'error' : 'warning';
30
+ return severity === 'error' ? 'error' : severity === 'info' ? 'note' : 'warning';
31
31
  }
32
32
 
33
33
  /**
@@ -62,10 +62,11 @@ export function toSarif(guardData, opts = {}) {
62
62
  if (v.status === 'skipped' || v.status === 'na') continue;
63
63
  if (Array.isArray(v.findings) && v.findings.length > 0) continue;
64
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 });
65
+ synthetic.push({ code: `DOCGUARD-${String(v.key || v.name || 'unknown').toUpperCase()}`, severity: 'error', effectiveSeverity: 'error', message: msg, location: null, suggestion: null });
66
66
  }
67
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 });
68
+ const effectiveSeverity = v.severity === 'high' ? 'error' : v.severity === 'low' ? 'info' : 'warn';
69
+ synthetic.push({ code: `DOCGUARD-${String(v.key || v.name || 'unknown').toUpperCase()}`, severity: 'warn', effectiveSeverity, message: msg, location: null, suggestion: null });
69
70
  }
70
71
  }
71
72
  const all = [...findings, ...synthetic];
@@ -83,7 +84,7 @@ export function toSarif(guardData, opts = {}) {
83
84
  rule.fullDescription = { text: meta.help };
84
85
  }
85
86
  rule.helpUri = HELP_URI;
86
- rule.defaultConfiguration = { level: toLevel(f.severity) };
87
+ rule.defaultConfiguration = { level: toLevel(f.effectiveSeverity || f.severity) };
87
88
  ruleIndexByCode.set(f.code, rules.length);
88
89
  rules.push(rule);
89
90
  }
@@ -92,7 +93,7 @@ export function toSarif(guardData, opts = {}) {
92
93
  const result = {
93
94
  ruleId: f.code,
94
95
  ruleIndex: ruleIndexByCode.get(f.code),
95
- level: toLevel(f.severity),
96
+ level: toLevel(f.effectiveSeverity || f.severity),
96
97
  message: { text: f.suggestion && f.suggestion.text ? `${f.message}\n→ ${f.suggestion.text}` : f.message },
97
98
  };
98
99
  const loc = parseLocation(f.location);
@@ -101,9 +102,12 @@ export function toSarif(guardData, opts = {}) {
101
102
  if (loc.line) physicalLocation.region = { startLine: loc.line };
102
103
  result.locations = [{ physicalLocation }];
103
104
  }
104
- if (f.confidence === 'low') {
105
- result.properties = { confidence: 'low', reportable: !!f.reportable };
106
- }
105
+ result.properties = {
106
+ originalSeverity: f.severity,
107
+ effectiveSeverity: f.effectiveSeverity || f.severity,
108
+ ...(f.enforcement ? { enforcement: f.enforcement } : {}),
109
+ ...(f.confidence === 'low' ? { confidence: 'low', reportable: !!f.reportable } : {}),
110
+ };
107
111
  return result;
108
112
  });
109
113
 
@@ -7,7 +7,7 @@ DocGuard is configured via `.docguard.json` in the project root. If no config fi
7
7
  ```json
8
8
  {
9
9
  "projectName": "my-project",
10
- "version": "0.5",
10
+ "version": "0.6",
11
11
  "profile": "standard",
12
12
  "projectType": "webapp",
13
13
 
@@ -57,6 +57,10 @@ DocGuard is configured via `.docguard.json` in the project root. If no config fi
57
57
 
58
58
  "docs": {
59
59
  "dirs": ["reference", "website/docs"]
60
+ },
61
+ "findingSeverity": {
62
+ "TRC004": "low",
63
+ "SEC001": "high"
60
64
  }
61
65
  }
62
66
  ```
@@ -94,6 +98,13 @@ anything from display: `"high"` promotes its warnings to blocking (CI fails),
94
98
  `"low"` demotes them (shown, but never fail the build). Valid values:
95
99
  `high | medium | low`. To silence a validator entirely, use `validators.<key>: false`.
96
100
 
101
+ `findingSeverity.<CODE>` applies the same enforcement levels to one stable
102
+ finding code and takes precedence over the validator setting. This is the
103
+ preferred control for a noisy rule because neighboring findings retain their
104
+ policy. Intrinsic errors remain blocking unless their exact code is configured.
105
+ Machine outputs preserve `severity` and add `effectiveSeverity` plus the
106
+ enforcement source so audit consumers can distinguish detection from policy.
107
+
97
108
  ## Collections — verify documented counts against code
98
109
 
99
110
  `collections` binds a documentation noun to a glob whose **file count is the
@@ -45,12 +45,15 @@ docguard score
45
45
 
46
46
  | Command | Alias | Purpose |
47
47
  |---------|-------|---------|
48
+ | `speckit.docguard.init` | `docguard.init` | Initialize CDD in a project |
48
49
  | `speckit.docguard.guard` | `docguard.guard` | Run configurable quality gate with severity triage |
49
50
  | `speckit.docguard.fix` | `docguard.fix` | AI-driven documentation repair with codebase research |
50
51
  | `speckit.docguard.review` | `docguard.review` | Cross-document semantic consistency analysis (read-only) |
51
52
  | `speckit.docguard.score` | `docguard.score` | CDD maturity score with ROI improvement roadmap |
52
53
  | `speckit.docguard.diagnose` | — | Diagnose issues + generate multi-perspective AI prompts |
53
54
  | `speckit.docguard.generate` | — | Reverse-engineer canonical docs from codebase |
55
+ | `speckit.docguard.sync` | — | Refresh code-truth sections and flag prose for review |
56
+ | `speckit.docguard.trace` | — | Generate requirements traceability matrix |
54
57
  | `speckit.docguard.brief` | — | Load current spec intent before specification |
55
58
  | `speckit.docguard.preflight` | — | Gate the generated spec before task generation |
56
59
  | `speckit.docguard.complete` | — | Plan reviewed completion and regenerate active context after verification |
@@ -0,0 +1,50 @@
1
+ ---
2
+ description: "Review documentation against code without modifying the repository"
3
+ allowed-tools: Bash, Read
4
+ handoffs:
5
+ - label: Fix Reviewed Issues
6
+ agent: docguard.fix
7
+ prompt: Fix the documentation issues confirmed by the review
8
+ - label: Run Guard
9
+ agent: docguard.guard
10
+ prompt: Validate all checks after approved fixes
11
+ ---
12
+
13
+ # DocGuard Review
14
+
15
+ Perform a read-only semantic review of canonical documentation against the
16
+ repository. Report evidence and recommendations; do not edit files.
17
+
18
+ ## User Input
19
+
20
+ ```text
21
+ $ARGUMENTS
22
+ ```
23
+
24
+ You **MUST** consider the user input before proceeding when it is not empty.
25
+
26
+ ## Execution
27
+
28
+ 1. Run the deterministic inventory and quality checks:
29
+
30
+ ```bash
31
+ npx --yes docguard-cli@latest diagnose $ARGUMENTS
32
+ npx --yes docguard-cli@latest diff $ARGUMENTS
33
+ npx --yes docguard-cli@latest score $ARGUMENTS
34
+ npx --yes docguard-cli@latest verify --evidence --format json $ARGUMENTS
35
+ npx --yes docguard-cli@latest verify --semantic $ARGUMENTS
36
+ ```
37
+
38
+ 2. Read the canonical documents and their cited code. Check architecture,
39
+ schemas, security claims, test coverage, terminology, and cross-references.
40
+ 3. For every contradiction, identify whether approved documentation or current
41
+ code owns the intended behavior. A mismatch can be a code regression.
42
+ 4. Return a severity-ranked report with exact file paths, evidence, confidence,
43
+ and a proposed next action. Keep unsupported claims explicitly unverified.
44
+
45
+ ## Constraints
46
+
47
+ - Do not modify files or treat a clean structural guard as proof that prose is
48
+ factually correct.
49
+ - Do not rewrite canonical intent to match code until ownership is resolved.
50
+ - Cap the report at 50 findings and aggregate lower-priority overflow.
@@ -3,8 +3,8 @@ schema_version: "1.0"
3
3
  extension:
4
4
  id: "docguard"
5
5
  name: "DocGuard — CDD Enforcement"
6
- version: "0.40.4"
7
- description: "Canonical-Driven Development enforcement as a true spec-kit extension. LLM-first design with automated validators, 5 AI behavior skills, spec-kit skill chaining, and workflow hooks. One pinned runtime dependency (@babel/parser); pure Node.js otherwise."
6
+ version: "0.41.0"
7
+ description: "Documentation integrity for AI-assisted repositories: lifecycle registry, drift validation, traceability, safe archival, SARIF/JUnit, MCP, GitHub Actions, and Spec Kit hooks."
8
8
  author: "Ricardo Accioly"
9
9
  repository: "https://github.com/raccioly/docguard"
10
10
  license: "MIT"
@@ -25,16 +25,20 @@ requires:
25
25
 
26
26
  provides:
27
27
  commands:
28
+ - name: "speckit.docguard.init"
29
+ file: "commands/init.md"
30
+ description: "Initialize Canonical-Driven Development in a project"
31
+
28
32
  - name: "speckit.docguard.guard"
29
33
  file: "commands/guard.md"
30
34
  description: "Run configurable quality gate with severity triage and remediation plan"
31
35
 
32
36
  - name: "speckit.docguard.fix"
33
- file: "commands/generate.md"
37
+ file: "commands/fix.md"
34
38
  description: "AI-driven documentation repair with codebase research and validation loops"
35
39
 
36
40
  - name: "speckit.docguard.review"
37
- file: "commands/diagnose.md"
41
+ file: "commands/review.md"
38
42
  description: "Cross-document semantic consistency analysis (read-only)"
39
43
 
40
44
  - name: "speckit.docguard.score"
@@ -49,6 +53,14 @@ provides:
49
53
  file: "commands/generate.md"
50
54
  description: "Reverse-engineer canonical docs from existing codebase"
51
55
 
56
+ - name: "speckit.docguard.sync"
57
+ file: "commands/sync.md"
58
+ description: "Refresh generated code-truth sections while preserving human prose"
59
+
60
+ - name: "speckit.docguard.trace"
61
+ file: "commands/trace.md"
62
+ description: "Generate the requirements traceability matrix"
63
+
52
64
  - name: "speckit.docguard.brief"
53
65
  file: "commands/brief.md"
54
66
  description: "Brief prior spec intent and lifecycle before creating a new specification"
@@ -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.40.4
9
+ version: 0.41.0
10
10
  source: extensions/spec-kit-docguard/skills/docguard-fix
11
11
  ---
12
- <!-- docguard:version: 0.40.4 -->
12
+ <!-- docguard:version: 0.41.0 -->
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.40.4
10
+ version: 0.41.0
11
11
  source: extensions/spec-kit-docguard/skills/docguard-guard
12
12
  ---
13
- <!-- docguard:version: 0.40.4 -->
13
+ <!-- docguard:version: 0.41.0 -->
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.40.4
9
+ version: 0.41.0
10
10
  source: extensions/spec-kit-docguard/skills/docguard-review
11
11
  ---
12
- <!-- docguard:version: 0.40.4 -->
12
+ <!-- docguard:version: 0.41.0 -->
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.40.4
9
+ version: 0.41.0
10
10
  source: extensions/spec-kit-docguard/skills/docguard-score
11
11
  ---
12
- <!-- docguard:version: 0.40.4 -->
12
+ <!-- docguard:version: 0.41.0 -->
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.40.4
7
+ version: 0.41.0
8
8
  source: extensions/spec-kit-docguard/skills/docguard-sync
9
9
  ---
10
- <!-- docguard:version: 0.40.4 -->
10
+ <!-- docguard:version: 0.41.0 -->
11
11
 
12
12
  # DocGuard Sync Skill
13
13
 
@@ -44,7 +44,7 @@ jobs:
44
44
  fetch-depth: 0
45
45
 
46
46
  - name: Run DocGuard fix --write + auto-commit + PR comment
47
- uses: raccioly/docguard@v0.40.4
47
+ uses: raccioly/docguard@v0.41.0
48
48
  with:
49
49
  command: fix
50
50
  auto-commit: 'true'
@@ -35,7 +35,7 @@ jobs:
35
35
  node-version: '20'
36
36
 
37
37
  - name: Install DocGuard
38
- run: npm install --global --ignore-scripts docguard-cli@0.40.4
38
+ run: npm install --global --ignore-scripts docguard-cli@0.41.0
39
39
 
40
40
  - name: Run DocGuard
41
41
  shell: bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docguard-cli",
3
- "version": "0.40.4",
3
+ "version": "0.41.0",
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": {
@@ -61,6 +61,7 @@
61
61
  "STANDARD.md",
62
62
  "PRIVACY.md",
63
63
  "PHILOSOPHY.md",
64
+ "CHANGELOG.md",
64
65
  "README.md",
65
66
  "LICENSE"
66
67
  ]
@@ -11,7 +11,7 @@
11
11
  },
12
12
  "version": {
13
13
  "type": "string",
14
- "description": "Schema version (0.1, 0.2, ... 0.5). Bumped when fields are added or behavior changes. Migrate with `docguard upgrade --apply`.",
14
+ "description": "Schema version (0.1, 0.2, ... 0.6). Bumped when fields are added or behavior changes. Migrate with `docguard upgrade --apply`.",
15
15
  "pattern": "^\\d+\\.\\d+(\\.\\d+)?$"
16
16
  },
17
17
  "projectName": {
@@ -112,6 +112,9 @@
112
112
  "generatedStaleness":{ "type": "boolean" },
113
113
  "canonicalSync": { "type": "boolean" },
114
114
  "surfaceSync": { "type": "boolean" },
115
+ "diffSuspicion": { "type": "boolean" },
116
+ "referenceExistence":{ "type": "boolean" },
117
+ "apiDocSmells": { "type": "boolean" },
115
118
  "metricsConsistency":{ "type": "boolean" }
116
119
  },
117
120
  "additionalProperties": false
@@ -124,6 +127,17 @@
124
127
  "enum": ["high", "medium", "low"]
125
128
  }
126
129
  },
130
+ "findingSeverity": {
131
+ "type": "object",
132
+ "description": "Per-finding-code enforcement overrides. Exact codes take precedence over validator severity. high = blocking error, medium = warning, low = informational. Intrinsic errors can only be demoted with an explicit code entry.",
133
+ "patternProperties": {
134
+ "^[A-Z]{3}[0-9]{3}$": {
135
+ "type": "string",
136
+ "enum": ["high", "medium", "low"]
137
+ }
138
+ },
139
+ "additionalProperties": false
140
+ },
127
141
  "draftStalenessDays": {
128
142
  "type": "integer",
129
143
  "minimum": 1,
@@ -48,6 +48,7 @@
48
48
  "oneOf": [
49
49
  { "$ref": "#/$defs/jsonSource" },
50
50
  { "$ref": "#/$defs/collectionSource" },
51
+ { "$ref": "#/$defs/pythonLiteralSource" },
51
52
  { "$ref": "#/$defs/oasdiffSource" },
52
53
  { "$ref": "#/$defs/bufSource" }
53
54
  ]
@@ -82,6 +83,17 @@
82
83
  "allowEmpty": { "type": "boolean" }
83
84
  }
84
85
  },
86
+ "pythonLiteralSource": {
87
+ "type": "object",
88
+ "additionalProperties": false,
89
+ "required": ["adapter", "path", "symbol", "allowEmpty"],
90
+ "properties": {
91
+ "adapter": { "const": "python-literal-count" },
92
+ "path": { "allOf": [{ "$ref": "#/$defs/safePath" }, { "pattern": "\\.py$" }] },
93
+ "symbol": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]{0,127}$" },
94
+ "allowEmpty": { "type": "boolean" }
95
+ }
96
+ },
85
97
  "input": {
86
98
  "type": "object",
87
99
  "additionalProperties": false,
@@ -31,7 +31,7 @@ jobs:
31
31
  node-version: '20'
32
32
 
33
33
  - name: Install DocGuard
34
- run: npm install --global --ignore-scripts docguard-cli@0.40.4
34
+ run: npm install --global --ignore-scripts docguard-cli@0.41.0
35
35
 
36
36
  - name: Run DocGuard
37
37
  shell: bash
@@ -16,6 +16,22 @@
16
16
  "pointer": "/retentionDays"
17
17
  },
18
18
  "predicate": { "kind": "equals", "valueType": "number" }
19
+ },
20
+ {
21
+ "id": "surface.python-scanners",
22
+ "applicability": { "mode": "always" },
23
+ "target": {
24
+ "document": "docs-canonical/ARCHITECTURE.md",
25
+ "heading": "Scanner registry",
26
+ "statement": "The registry contains {{value}} scanners."
27
+ },
28
+ "source": {
29
+ "adapter": "python-literal-count",
30
+ "path": "src/package/scanners.py",
31
+ "symbol": "SCANNERS",
32
+ "allowEmpty": false
33
+ },
34
+ "predicate": { "kind": "count-equals" }
19
35
  }
20
36
  ]
21
37
  }