docguard-cli 0.16.0__tar.gz → 0.17.1__tar.gz

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 (308) hide show
  1. {docguard_cli-0.16.0/extensions/spec-kit-docguard → docguard_cli-0.17.1/.agent}/skills/docguard-fix/SKILL.md +2 -2
  2. {docguard_cli-0.16.0/extensions/spec-kit-docguard → docguard_cli-0.17.1/.agent}/skills/docguard-guard/SKILL.md +3 -3
  3. {docguard_cli-0.16.0/extensions/spec-kit-docguard → docguard_cli-0.17.1/.agent}/skills/docguard-review/SKILL.md +2 -2
  4. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.agent/skills/docguard-score/SKILL.md +2 -2
  5. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.agent/skills/docguard-sync/SKILL.md +1 -1
  6. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/CHANGELOG.md +62 -0
  7. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/PKG-INFO +1 -1
  8. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/commands/diff.mjs +23 -15
  9. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/commands/guard.mjs +147 -0
  10. docguard_cli-0.17.1/cli/commands/memory.mjs +143 -0
  11. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/docguard.mjs +57 -1
  12. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/validators/environment.mjs +6 -4
  13. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/commands/docguard.guard.md +2 -2
  14. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/extensions/spec-kit-docguard/commands/guard.md +1 -1
  15. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/extensions/spec-kit-docguard/extension.yml +2 -2
  16. {docguard_cli-0.16.0/.agent → docguard_cli-0.17.1/extensions/spec-kit-docguard}/skills/docguard-fix/SKILL.md +2 -2
  17. {docguard_cli-0.16.0/.agent → docguard_cli-0.17.1/extensions/spec-kit-docguard}/skills/docguard-guard/SKILL.md +3 -3
  18. {docguard_cli-0.16.0/.agent → docguard_cli-0.17.1/extensions/spec-kit-docguard}/skills/docguard-review/SKILL.md +2 -2
  19. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/extensions/spec-kit-docguard/skills/docguard-score/SKILL.md +2 -2
  20. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/extensions/spec-kit-docguard/skills/docguard-sync/SKILL.md +1 -1
  21. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/extensions/spec-kit-docguard/templates/github-workflows/docguard-guard.yml +1 -1
  22. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/package.json +1 -1
  23. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/pyproject.toml +1 -1
  24. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/commands/docguard.guard.md +2 -2
  25. docguard_cli-0.17.1/tests/b7-node-env-symmetry.test.mjs +97 -0
  26. docguard_cli-0.17.1/tests/validator-naming.test.mjs +104 -0
  27. docguard_cli-0.17.1/tests/version-pin.test.mjs +91 -0
  28. docguard_cli-0.17.1/tests/whats-new.test.mjs +65 -0
  29. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.agent/commands/speckit.analyze.md +0 -0
  30. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.agent/commands/speckit.checklist.md +0 -0
  31. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.agent/commands/speckit.clarify.md +0 -0
  32. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.agent/commands/speckit.constitution.md +0 -0
  33. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.agent/commands/speckit.implement.md +0 -0
  34. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.agent/commands/speckit.plan.md +0 -0
  35. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.agent/commands/speckit.specify.md +0 -0
  36. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.agent/commands/speckit.tasks.md +0 -0
  37. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.agent/commands/speckit.taskstoissues.md +0 -0
  38. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.agent/skills/speckit-analyze/SKILL.md +0 -0
  39. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.agent/skills/speckit-checklist/SKILL.md +0 -0
  40. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.agent/skills/speckit-clarify/SKILL.md +0 -0
  41. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.agent/skills/speckit-constitution/SKILL.md +0 -0
  42. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.agent/skills/speckit-implement/SKILL.md +0 -0
  43. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.agent/skills/speckit-plan/SKILL.md +0 -0
  44. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.agent/skills/speckit-specify/SKILL.md +0 -0
  45. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.agent/skills/speckit-tasks/SKILL.md +0 -0
  46. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.agent/skills/speckit-taskstoissues/SKILL.md +0 -0
  47. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.docguard.json +0 -0
  48. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.docguardignore +0 -0
  49. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  50. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  51. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.github/dependabot.yml +0 -0
  52. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.github/scripts/patch-catalog.py +0 -0
  53. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.github/workflows/ci.yml +0 -0
  54. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.github/workflows/release.yml +0 -0
  55. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.github/workflows/supply-chain.yml +0 -0
  56. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.github/workflows/sync-speckit-catalog.yml +0 -0
  57. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.gitignore +0 -0
  58. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.jules/bolt.md +0 -0
  59. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.jules/palette.md +0 -0
  60. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.jules/sentinel.md +0 -0
  61. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.npmignore +0 -0
  62. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.npmrc +0 -0
  63. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.specify/extensions/.cache/catalog-ebf165086500aab1-metadata.json +0 -0
  64. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.specify/extensions/.cache/catalog-ebf165086500aab1.json +0 -0
  65. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.specify/extensions/.cache/catalog-metadata.json +0 -0
  66. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.specify/extensions/.cache/catalog.json +0 -0
  67. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.specify/init-options.json +0 -0
  68. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.specify/memory/constitution.md +0 -0
  69. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.specify/scripts/bash/check-prerequisites.sh +0 -0
  70. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.specify/scripts/bash/common.sh +0 -0
  71. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.specify/scripts/bash/create-new-feature.sh +0 -0
  72. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.specify/scripts/bash/setup-plan.sh +0 -0
  73. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.specify/scripts/bash/update-agent-context.sh +0 -0
  74. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.specify/templates/agent-file-template.md +0 -0
  75. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.specify/templates/checklist-template.md +0 -0
  76. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.specify/templates/constitution-template.md +0 -0
  77. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.specify/templates/plan-template.md +0 -0
  78. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.specify/templates/spec-template.md +0 -0
  79. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/.specify/templates/tasks-template.md +0 -0
  80. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/AGENTS.md +0 -0
  81. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/CODE_OF_CONDUCT.md +0 -0
  82. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/COMPARISONS.md +0 -0
  83. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/CONTRIBUTING.md +0 -0
  84. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/DRIFT-LOG.md +0 -0
  85. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/LICENSE +0 -0
  86. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/PHILOSOPHY.md +0 -0
  87. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/README.md +0 -0
  88. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/ROADMAP.md +0 -0
  89. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/SECURITY.md +0 -0
  90. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/STANDARD.md +0 -0
  91. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/SUPPLY-CHAIN-AUDIT.md +0 -0
  92. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/SUPPORT.md +0 -0
  93. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/action.yml +0 -0
  94. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/commands/agents.mjs +0 -0
  95. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/commands/badge.mjs +0 -0
  96. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/commands/ci.mjs +0 -0
  97. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/commands/diagnose.mjs +0 -0
  98. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/commands/explain.mjs +0 -0
  99. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/commands/fix.mjs +0 -0
  100. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/commands/generate.mjs +0 -0
  101. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/commands/hooks.mjs +0 -0
  102. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/commands/impact.mjs +0 -0
  103. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/commands/init.mjs +0 -0
  104. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/commands/llms.mjs +0 -0
  105. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/commands/publish.mjs +0 -0
  106. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/commands/score.mjs +0 -0
  107. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/commands/setup.mjs +0 -0
  108. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/commands/sync.mjs +0 -0
  109. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/commands/trace.mjs +0 -0
  110. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/commands/upgrade.mjs +0 -0
  111. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/commands/watch.mjs +0 -0
  112. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/ensure-skills.mjs +0 -0
  113. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/scanners/api-doc.mjs +0 -0
  114. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/scanners/cdk.mjs +0 -0
  115. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/scanners/doc-tools.mjs +0 -0
  116. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/scanners/frontend.mjs +0 -0
  117. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/scanners/iac.mjs +0 -0
  118. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/scanners/integrations.mjs +0 -0
  119. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/scanners/memory-plan.mjs +0 -0
  120. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/scanners/project-type.mjs +0 -0
  121. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/scanners/routes.mjs +0 -0
  122. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/scanners/schemas.mjs +0 -0
  123. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/scanners/speckit.mjs +0 -0
  124. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/shared-git.mjs +0 -0
  125. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/shared-ignore.mjs +0 -0
  126. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/shared-source.mjs +0 -0
  127. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/shared.mjs +0 -0
  128. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/validators/api-surface.mjs +0 -0
  129. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/validators/architecture.mjs +0 -0
  130. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/validators/changelog.mjs +0 -0
  131. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/validators/cross-reference.mjs +0 -0
  132. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/validators/doc-quality.mjs +0 -0
  133. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/validators/docs-coverage.mjs +0 -0
  134. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/validators/docs-diff.mjs +0 -0
  135. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/validators/docs-sync.mjs +0 -0
  136. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/validators/drift.mjs +0 -0
  137. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/validators/freshness.mjs +0 -0
  138. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/validators/generated-staleness.mjs +0 -0
  139. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/validators/metadata-sync.mjs +0 -0
  140. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/validators/metrics-consistency.mjs +0 -0
  141. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/validators/schema-sync.mjs +0 -0
  142. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/validators/security.mjs +0 -0
  143. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/validators/structure.mjs +0 -0
  144. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/validators/test-spec.mjs +0 -0
  145. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/validators/todo-tracking.mjs +0 -0
  146. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/validators/traceability.mjs +0 -0
  147. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/writers/api-reference.mjs +0 -0
  148. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/writers/fix-memory.mjs +0 -0
  149. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/writers/mechanical.mjs +0 -0
  150. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/cli/writers/sections.mjs +0 -0
  151. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/commands/docguard.fix.md +0 -0
  152. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/commands/docguard.review.md +0 -0
  153. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/commands/docguard.score.md +0 -0
  154. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/configs/fastify.json +0 -0
  155. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/configs/generic.json +0 -0
  156. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/configs/nextjs.json +0 -0
  157. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/configs/python.json +0 -0
  158. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/docguard_cli/__init__.py +0 -0
  159. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/docguard_cli/wrapper.py +0 -0
  160. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/docs/ai-integration.md +0 -0
  161. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/docs/commands.md +0 -0
  162. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/docs/configuration.md +0 -0
  163. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/docs/doc-sections.md +0 -0
  164. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/docs/faq.md +0 -0
  165. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/docs/installation.md +0 -0
  166. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/docs/profiles.md +0 -0
  167. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/docs/quickstart.md +0 -0
  168. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/docs-canonical/ARCHITECTURE.md +0 -0
  169. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/docs-canonical/CI-RECIPES.md +0 -0
  170. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/docs-canonical/DATA-MODEL.md +0 -0
  171. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/docs-canonical/ENVIRONMENT.md +0 -0
  172. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/docs-canonical/SECURITY.md +0 -0
  173. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/docs-canonical/TEST-SPEC.md +0 -0
  174. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/examples/01-express-api/README.md +0 -0
  175. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/examples/01-express-api/package.json +0 -0
  176. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/examples/01-express-api/server.js +0 -0
  177. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/examples/02-python-flask/README.md +0 -0
  178. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/examples/02-python-flask/app.py +0 -0
  179. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/examples/02-python-flask/docs-canonical/ARCHITECTURE.md +0 -0
  180. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/examples/02-python-flask/requirements.txt +0 -0
  181. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/examples/03-spec-kit-project/CHANGELOG.md +0 -0
  182. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/examples/03-spec-kit-project/README.md +0 -0
  183. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/examples/03-spec-kit-project/docs-canonical/ARCHITECTURE.md +0 -0
  184. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/examples/03-spec-kit-project/docs-canonical/TEST-SPEC.md +0 -0
  185. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/examples/03-spec-kit-project/package.json +0 -0
  186. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/examples/03-spec-kit-project/src/index.js +0 -0
  187. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/examples/03-spec-kit-project/tests/basic.test.js +0 -0
  188. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/examples/README.md +0 -0
  189. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/extensions/spec-kit-docguard/LICENSE +0 -0
  190. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/extensions/spec-kit-docguard/README.md +0 -0
  191. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/extensions/spec-kit-docguard/commands/diagnose.md +0 -0
  192. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/extensions/spec-kit-docguard/commands/fix.md +0 -0
  193. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/extensions/spec-kit-docguard/commands/generate.md +0 -0
  194. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/extensions/spec-kit-docguard/commands/init.md +0 -0
  195. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/extensions/spec-kit-docguard/commands/score.md +0 -0
  196. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/extensions/spec-kit-docguard/commands/sync.md +0 -0
  197. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/extensions/spec-kit-docguard/commands/trace.md +0 -0
  198. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/extensions/spec-kit-docguard/scripts/bash/common.sh +0 -0
  199. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/extensions/spec-kit-docguard/scripts/bash/docguard-check-docs.sh +0 -0
  200. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/extensions/spec-kit-docguard/scripts/bash/docguard-init-doc.sh +0 -0
  201. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/extensions/spec-kit-docguard/scripts/bash/docguard-suggest-fix.sh +0 -0
  202. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/extensions/spec-kit-docguard/templates/extensions.yml +0 -0
  203. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/extensions/spec-kit-docguard/templates/github-workflows/docguard-autofix.yml +0 -0
  204. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/pr_description.md +0 -0
  205. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/schemas/docguard-config.schema.json +0 -0
  206. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/specs/001-fix-ignore-validators/plan.md +0 -0
  207. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/specs/001-fix-ignore-validators/spec.md +0 -0
  208. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/specs/001-fix-ignore-validators/tasks.md +0 -0
  209. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/specs/002-fix-test-discovery/plan.md +0 -0
  210. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/specs/002-fix-test-discovery/spec.md +0 -0
  211. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/specs/002-fix-test-discovery/tasks.md +0 -0
  212. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/specs/003-v011-false-positives/plan.md +0 -0
  213. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/specs/003-v011-false-positives/spec.md +0 -0
  214. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/specs/003-v011-false-positives/tasks.md +0 -0
  215. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/ADR.md.template +0 -0
  216. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/AGENTS.md.template +0 -0
  217. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/ARCHITECTURE.md.template +0 -0
  218. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/CHANGELOG.md.template +0 -0
  219. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/CURRENT-STATE.md.template +0 -0
  220. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/DATA-MODEL.md.template +0 -0
  221. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/DEPLOYMENT.md.template +0 -0
  222. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/DRIFT-LOG.md.template +0 -0
  223. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/ENVIRONMENT.md.template +0 -0
  224. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/KNOWN-GOTCHAS.md.template +0 -0
  225. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/REQUIREMENTS.md.template +0 -0
  226. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/ROADMAP.md.template +0 -0
  227. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/RUNBOOKS.md.template +0 -0
  228. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/SECURITY.md.template +0 -0
  229. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/TEST-SPEC.md.template +0 -0
  230. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/TROUBLESHOOTING.md.template +0 -0
  231. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/VENDOR-BUGS.md.template +0 -0
  232. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/ci/github-actions.yml +0 -0
  233. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/commands/docguard.fix.md +0 -0
  234. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/commands/docguard.init.md +0 -0
  235. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/commands/docguard.review.md +0 -0
  236. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/templates/commands/docguard.update.md +0 -0
  237. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/test-draft.js +0 -0
  238. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/test-metrics.js +0 -0
  239. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/anchor-autofix.test.mjs +0 -0
  240. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/api-doc.test.mjs +0 -0
  241. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/api-surface.test.mjs +0 -0
  242. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/api-write.test.mjs +0 -0
  243. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/architecture.test.mjs +0 -0
  244. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/backup-failure.test.mjs +0 -0
  245. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/cdk-detection.test.mjs +0 -0
  246. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/changed-only-scoping.test.mjs +0 -0
  247. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/changed-only.test.mjs +0 -0
  248. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/changelog.test.mjs +0 -0
  249. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/commands.test.mjs +0 -0
  250. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/cross-reference.test.mjs +0 -0
  251. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/doc-quality.test.mjs +0 -0
  252. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/docguardignore.test.mjs +0 -0
  253. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/docs-coverage.test.mjs +0 -0
  254. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/docs-diff.test.mjs +0 -0
  255. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/docs-sync.test.mjs +0 -0
  256. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/drift.test.mjs +0 -0
  257. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/environment.test.mjs +0 -0
  258. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/fix-memory.test.mjs +0 -0
  259. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/fix-suppression.test.mjs +0 -0
  260. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/fixture-projects.test.mjs +0 -0
  261. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/freshness.test.mjs +0 -0
  262. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/frontend-deep.test.mjs +0 -0
  263. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/frontend.test.mjs +0 -0
  264. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/generated-staleness.test.mjs +0 -0
  265. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/guard-classify.test.mjs +0 -0
  266. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/guard-no-throw.test.mjs +0 -0
  267. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/hooks.test.mjs +0 -0
  268. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/i18n.test.mjs +0 -0
  269. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/impact.test.mjs +0 -0
  270. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/integrations.test.mjs +0 -0
  271. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/mechanical.test.mjs +0 -0
  272. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/memory-plan.test.mjs +0 -0
  273. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/metadata-sync.test.mjs +0 -0
  274. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/metrics-consistency.test.mjs +0 -0
  275. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/metrics-dedup.test.mjs +0 -0
  276. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/monorepo-scanning.test.mjs +0 -0
  277. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/multi-spec.test.mjs +0 -0
  278. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/patch-0.11.2.test.mjs +0 -0
  279. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/profile-flag.test.mjs +0 -0
  280. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/project-type.test.mjs +0 -0
  281. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/regenerate-section.test.mjs +0 -0
  282. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/routes-multilang.test.mjs +0 -0
  283. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/schema-sync.test.mjs +0 -0
  284. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/schemas-multilang.test.mjs +0 -0
  285. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/schemas.test.mjs +0 -0
  286. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/scoping-extended.test.mjs +0 -0
  287. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/section-na-markers.test.mjs +0 -0
  288. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/sections.test.mjs +0 -0
  289. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/security.test.mjs +0 -0
  290. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/severity.test.mjs +0 -0
  291. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/shared-git.test.mjs +0 -0
  292. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/shared-source.test.mjs +0 -0
  293. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/stress-test.test.mjs +0 -0
  294. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/structure.test.mjs +0 -0
  295. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/sweep-nudge.test.mjs +0 -0
  296. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/sync-since.test.mjs +0 -0
  297. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/sync.test.mjs +0 -0
  298. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/test-spec.test.mjs +0 -0
  299. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/todo-tracking.test.mjs +0 -0
  300. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/trace-multilang.test.mjs +0 -0
  301. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/trace-reverse.test.mjs +0 -0
  302. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/traceability.test.mjs +0 -0
  303. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/upgrade-pr.test.mjs +0 -0
  304. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/tests/upgrade.test.mjs +0 -0
  305. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/vscode-extension/.vscodeignore +0 -0
  306. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/vscode-extension/README.md +0 -0
  307. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/vscode-extension/extension.js +0 -0
  308. {docguard_cli-0.16.0 → docguard_cli-0.17.1}/vscode-extension/package.json +0 -0
@@ -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.16.0
9
+ version: 0.17.1
10
10
  source: extensions/spec-kit-docguard/skills/docguard-fix
11
11
  ---
12
- <!-- docguard:version: 0.16.0 -->
12
+ <!-- docguard:version: 0.17.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.16.0
10
+ version: 0.17.1
11
11
  source: extensions/spec-kit-docguard/skills/docguard-guard
12
12
  ---
13
- <!-- docguard:version: 0.16.0 -->
13
+ <!-- docguard:version: 0.17.1 -->
14
14
 
15
15
  # DocGuard Guard Skill
16
16
 
@@ -139,7 +139,7 @@ For each finding, provide a **specific, actionable fix** — not "fix the issue"
139
139
 
140
140
  Based on the triage results:
141
141
 
142
- - **If all PASS**: "All 22 validators passed. Project is CDD-compliant. Ready to commit."
142
+ - **If all PASS**: "All validators passed. Project is CDD-compliant. Ready to commit."
143
143
  - **If only MEDIUM/LOW warnings**: "Non-blocking warnings found. Safe to commit, but consider running `/docguard.fix` for automated remediation."
144
144
  - **If HIGH or CRITICAL failures**: "Blocking issues found. Fix these before committing. Suggest running `/docguard.fix --doc [most impactful doc]` next."
145
145
 
@@ -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.16.0
9
+ version: 0.17.1
10
10
  source: extensions/spec-kit-docguard/skills/docguard-review
11
11
  ---
12
- <!-- docguard:version: 0.16.0 -->
12
+ <!-- docguard:version: 0.17.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.16.0
9
+ version: 0.17.1
10
10
  source: extensions/spec-kit-docguard/skills/docguard-score
11
11
  ---
12
- <!-- docguard:version: 0.16.0 -->
12
+ <!-- docguard:version: 0.17.1 -->
13
13
 
14
14
  # DocGuard Score Skill
15
15
 
@@ -4,7 +4,7 @@ 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.16.0
7
+ version: 0.17.1
8
8
  source: extensions/spec-kit-docguard/skills/docguard-sync
9
9
  ---
10
10
 
@@ -7,6 +7,68 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.17.1] - 2026-05-26
11
+
12
+ Patch responding to a client-project feedback round: 1 real bug (B-7) and
13
+ a discoverability improvement that helps users on older versions find the
14
+ features they're asking for. **537 tests** (was 530, +7). 22 validators.
15
+
16
+ ### Fixed
17
+
18
+ - **B-7: `diff` and `guard.Environment` disagreed on env-var coverage.** My v0.16-P4 `SYSTEM_ENV_VARS` denylist was over-broad: `NODE_ENV`, `CI`, `GITHUB_TOKEN`, `GITHUB_REF`, `GITHUB_SHA` are legitimately app env vars (apps read `process.env.NODE_ENV` for production/dev branching, `process.env.CI` to detect CI runs, etc.). The denylist stripped them from the doc side of `diff` only, so a project that documented `NODE_ENV` in BOTH `ENVIRONMENT.md` AND `.env.example` would correctly pass the `Environment` validator but `diff` would falsely flag it as "in code but not documented". Trimmed the denylist to truly-system-only vars (PATH, HOME, SHELL, TERM, etc. — the names no sane app would treat as runtime config). Reported by the client project running v0.16.0; their env-var accuracy went 79/82 → 80/82 with the bogus `NODE_ENV` flag gone. New `tests/b7-node-env-symmetry.test.mjs` locks in the symmetry.
19
+
20
+ ### Added
21
+
22
+ - **What's-new highlights on the guard footer.** When `.docguard.json` carries a `docguardVersion` pin and the running CLI is newer, the guard footer now prints a short "New since v<pin>" list of headline features from intermediate releases. Top 5 inline, "N more in CHANGELOG.md" pointer when there's more. Closes the recurring pattern of users asking for features that shipped one or two releases ago — `sync --since`, `docguard impact`, `docguard explain`, `memory --diff`, `--quiet`, and Cross-Reference anchor hints all appear in the table.
23
+
24
+ ### Note to readers asking about S-1, S-11, S-12
25
+
26
+ These three features are **already shipped** as of the listed releases. The v0.17.1 what's-new nudge surfaces them inline for any project still pinned to v0.12 or earlier. Quick recap:
27
+
28
+ - **S-1: `docguard sync --since <ref>`** — shipped in **v0.13.0** as L-1. Refreshes only canonical doc sections touched by code changes in the diff range. Run `docguard sync --write --since main` on a feature branch to skip unrelated doc churn.
29
+ - **S-11: `docguard impact --since <ref>`** — shipped in **v0.13.1**. Post-commit "changed files → affected canonical doc sections" map. Run `docguard impact --since HEAD~1` after a commit; JSON mode for CI bots.
30
+ - **S-12: Anchor "did you mean...?" hints** — shipped in **v0.13.1** + extended in **v0.14.1** so high-confidence matches (edit distance ≤ 2, single close candidate) are now `[auto-fixable]` via `docguard fix --write`.
31
+
32
+ Upgrade with `docguard upgrade --apply` or `npm i -g docguard-cli@latest` to pick them up.
33
+
34
+ ### Internal
35
+
36
+ - **2 new test files**: `tests/b7-node-env-symmetry.test.mjs` (4 — diff/validator symmetry), `tests/whats-new.test.mjs` (3 — highlights surface). **Total: 530 → 537 tests (+7 new).**
37
+ - **`SYSTEM_ENV_VARS`** trimmed in both `cli/commands/diff.mjs` and `cli/validators/environment.mjs` (single source of truth would be better; deferred).
38
+ - **New highlight table** `_RELEASE_HIGHLIGHTS` in `cli/commands/guard.mjs` — add an entry per release going forward.
39
+ - **Dry-run on the client project**: env accuracy 80/82, the 2 remaining mismatches are genuine doc-only drift (not bugs in our tool). Full guard still 672/672 PASS.
40
+ - No new NPM deps.
41
+
42
+ ## [0.17.0] - 2026-05-26
43
+
44
+ Feature release picking up the 4 deferred items from v0.16 — **reproducibility
45
+ (version pin), accuracy drill-down (memory --diff), self-scaffolding drift fix,
46
+ and naming flexibility (kebab + camel both accepted)**. **530 tests** (was 519,
47
+ +11). 22 validators.
48
+
49
+ ### Added
50
+
51
+ - **P1: Version pin in `.docguard.json` (F8).** CDD reproducibility. Add `docguardVersion: "0.17.0"` to your config and `docguard guard` will nudge if the running CLI differs (newer or older). New `docguard guard --pin` action records the running CLI version after a passing run — opt-in, never automatic, refuses on FAIL status so you don't pin a broken state. Closes the "same project, different score across versions" surprise reported by a Python user.
52
+ - **P2: `docguard memory --diff` (F10).** The memory-accuracy headline (e.g. "Accuracy: 83%") no longer requires source-spelunking to explain. New `docguard memory` shows per-domain accuracy (Endpoints / Entities / Env vars / Tech stack); add `--diff` for the drill-down listing *which* claims don't match code in each domain. JSON mode for tooling. Reuses the existing diff helpers — no new scanning logic.
53
+ - **P3: Drift-proofed validator-count language in templates (F7).** Templates in `commands/`, `extensions/spec-kit-docguard/commands/`, `extensions/spec-kit-docguard/skills/`, and CI workflow examples no longer bake in "N validators" — replaced with "all validators" or "the full validator suite". User's own docs that legitimately quote a count are still validated by Metrics-Consistency; only DocGuard's own scaffolding (which would drift on every new validator) is detached from the number.
54
+ - **P4: Validator naming consistency (additive, N1).** `.docguard.json` now accepts both kebab-case (`"test-spec": false`) and camelCase (`testSpec: false`) for both `validators` and `severity` maps. Normalized to camelCase internally before merge. Pre-existing configs keep working unchanged; new configs can use whichever style matches their team's convention. No breaking change.
55
+
56
+ ### Internal
57
+
58
+ - **2 new test files**: `tests/version-pin.test.mjs` (6 — nudge behavior + `--pin` action), `tests/validator-naming.test.mjs` (5 — both casings accepted). **Total: 519 → 530 tests (+11 new).**
59
+ - **New module**: `cli/commands/memory.mjs` (~140 lines).
60
+ - **Exported from `cli/commands/diff.mjs`**: `diffRoutes`, `diffEntities`, `diffEnvVars`, `diffTechStack` so `memory.mjs` can reuse them without duplicating logic.
61
+ - **New helpers in `cli/docguard.mjs`**: `normalizeConfig()`, `_kebabToCamel()`, `_KNOWN_VALIDATORS`.
62
+ - **New helpers in `cli/commands/guard.mjs`**: `_parseSemver`, `_semverCompare`, `_checkVersionPin`, `_updateVersionPin`.
63
+ - **Templates scrubbed** of numeric validator counts (6 files).
64
+ - Dry-run on a real client project: 99% memory accuracy, 3 specific env-var mismatches surfaced by `memory --diff`.
65
+ - No new NPM deps.
66
+
67
+ ### Out of scope (deferred to v0.18)
68
+
69
+ - **F6** stale score cache — still low repro confidence; deferred until we get a reliable reproducer.
70
+ - **Bigger items**: deeper Generated-Staleness optimization (still ~26% of guard time on large repos), `upgrade --pr` battle-test against a real GitHub remote, cross-process plan cache.
71
+
10
72
  ## [0.16.0] - 2026-05-26
11
73
 
12
74
  Feature release driven entirely by feedback from a real Python project running
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: docguard-cli
3
- Version: 0.16.0
3
+ Version: 0.17.1
4
4
  Summary: The enforcement tool for Canonical-Driven Development (CDD). Audit, generate, and guard your project documentation. Zero dependencies.
5
5
  Project-URL: Homepage, https://github.com/raccioly/docguard
6
6
  Project-URL: Documentation, https://github.com/raccioly/docguard#readme
@@ -101,7 +101,7 @@ export function runDiff(projectDir, config, flags) {
101
101
 
102
102
  // ── Diff Functions ─────────────────────────────────────────────────────────
103
103
 
104
- function diffRoutes(dir, config = {}) {
104
+ export function diffRoutes(dir, config = {}) {
105
105
  // Documented surface: prefer the dedicated API reference, fall back to ARCHITECTURE.md.
106
106
  const apiRefPath = resolve(dir, 'docs-canonical/API-REFERENCE.md');
107
107
  const archPath = resolve(dir, 'docs-canonical/ARCHITECTURE.md');
@@ -133,7 +133,7 @@ const CODE_ENTITY_NOISE = new Set([
133
133
  'models', 'model', 'utils', 'helpers', 'constants', 'config', 'common', 'base',
134
134
  ]);
135
135
 
136
- function diffEntities(dir, config = {}) {
136
+ export function diffEntities(dir, config = {}) {
137
137
  const dataModelPath = resolve(dir, 'docs-canonical/DATA-MODEL.md');
138
138
  if (!existsSync(dataModelPath)) return null;
139
139
 
@@ -200,26 +200,34 @@ function diffEntities(dir, config = {}) {
200
200
  };
201
201
  }
202
202
 
203
- // v0.16-P4: common system environment variables that get backticked in
204
- // prose ("the venv `PATH`", "your `HOME` directory") but are NEVER user-set
205
- // application env vars. Excluding them from the docVars set kills the
206
- // false-positive class reported by the Python user where `PATH` was flagged
207
- // as "documented-but-not-implemented".
203
+ // v0.16-P4 (revised in v0.17.1): conservative denylist of system env vars
204
+ // that appear in prose ("the venv `PATH`") but are never user-set app env
205
+ // vars. v0.17.1-B7: trimmed to TRULY-system-only after wu feedback
206
+ // NODE_ENV / CI / GITHUB_* are legitimately app env vars when read via
207
+ // process.env. Including them caused diff to falsely flag `NODE_ENV` as
208
+ // "in code but not docs" even when ENVIRONMENT.md documented it.
208
209
  //
209
- // Conservative list only the names that are unambiguously OS/shell vars.
210
- // Application names like `DATABASE_URL`, `API_KEY` etc. still count.
210
+ // Rule of thumb for inclusion: would a sane Node/Python/Go app ever
211
+ // `process.env.X` this name and treat it as app config? If yes → NOT a
212
+ // system var. PATH/HOME/SHELL/TERM never satisfy that bar.
211
213
  const SYSTEM_ENV_VARS = new Set([
212
- 'PATH', 'HOME', 'USER', 'USERNAME', 'SHELL', 'PWD', 'OLDPWD', 'TMPDIR', 'TEMP', 'TMP',
214
+ // POSIX shell / OS
215
+ 'PATH', 'HOME', 'USER', 'USERNAME', 'SHELL', 'PWD', 'OLDPWD',
216
+ 'TMPDIR', 'TEMP', 'TMP',
217
+ // Locale
213
218
  'LANG', 'LC_ALL', 'LC_CTYPE', 'LC_MESSAGES', 'TZ',
219
+ // Terminal / interactive
214
220
  'EDITOR', 'VISUAL', 'PAGER', 'TERM', 'COLORTERM',
221
+ // SSH / Display
215
222
  'DISPLAY', 'SSH_AUTH_SOCK', 'SSH_CONNECTION', 'SSH_TTY',
223
+ // XDG base directory spec
216
224
  'XDG_CONFIG_HOME', 'XDG_DATA_HOME', 'XDG_CACHE_HOME', 'XDG_RUNTIME_DIR',
217
- // CI/build platform vars (set by the platform, not by the app)
218
- 'CI', 'GITHUB_TOKEN', 'GITHUB_ACTIONS', 'GITHUB_REF', 'GITHUB_SHA',
219
- 'NODE_ENV', // could be app-set but more often platform-set; conservative skip
225
+ // NOTE: NODE_ENV / CI / GITHUB_* used to be here. Removed in v0.17.1
226
+ // because apps DO read them as app config (e.g. NODE_ENV=production
227
+ // gates branching in nearly every Node.js app).
220
228
  ]);
221
229
 
222
- function diffEnvVars(dir, config = {}) {
230
+ export function diffEnvVars(dir, config = {}) {
223
231
  const envDocPath = resolve(dir, 'docs-canonical/ENVIRONMENT.md');
224
232
  if (!existsSync(envDocPath)) return null;
225
233
 
@@ -263,7 +271,7 @@ function diffEnvVars(dir, config = {}) {
263
271
  };
264
272
  }
265
273
 
266
- function diffTechStack(dir, config = {}) {
274
+ export function diffTechStack(dir, config = {}) {
267
275
  const archPath = resolve(dir, 'docs-canonical/ARCHITECTURE.md');
268
276
  if (!existsSync(archPath)) return null;
269
277
 
@@ -11,6 +11,114 @@ import { c, resolveSeverity } from '../shared.mjs';
11
11
  import { detectAgentMode, isSpecKitInitialized } from '../ensure-skills.mjs';
12
12
  import { checkUpgradeStatus } from './upgrade.mjs';
13
13
  import { changedFilesSince, isGitRepo } from '../shared-git.mjs';
14
+ import { readFileSync, writeFileSync, existsSync } from 'node:fs';
15
+ import { resolve as resolvePath } from 'node:path';
16
+ import { fileURLToPath as fp } from 'node:url';
17
+ import { dirname as dn } from 'node:path';
18
+
19
+ // v0.17-P1: CLI version for version-pin checks (F8). Reproducibility for CDD —
20
+ // users can pin the docguard version their config was last validated against.
21
+ const _PKG = JSON.parse(readFileSync(resolvePath(dn(fp(import.meta.url)), '..', '..', 'package.json'), 'utf-8'));
22
+ const CLI_VERSION = _PKG.version;
23
+
24
+ /**
25
+ * v0.17-P1: parse a semver-ish version string into a comparable tuple.
26
+ * Tolerates trailing pre-release tags (`0.16.0-rc.1`). Returns null on garbage.
27
+ */
28
+ function _parseSemver(v) {
29
+ if (!v || typeof v !== 'string') return null;
30
+ const m = v.match(/^(\d+)\.(\d+)\.(\d+)/);
31
+ if (!m) return null;
32
+ return [Number(m[1]), Number(m[2]), Number(m[3])];
33
+ }
34
+
35
+ /**
36
+ * v0.17-P1: returns +1 if a > b, 0 if equal, -1 if a < b. Unparseable
37
+ * input sorts as equal (silent — never blocks a guard run).
38
+ */
39
+ function _semverCompare(a, b) {
40
+ const pa = _parseSemver(a);
41
+ const pb = _parseSemver(b);
42
+ if (!pa || !pb) return 0;
43
+ for (let i = 0; i < 3; i++) {
44
+ if (pa[i] > pb[i]) return 1;
45
+ if (pa[i] < pb[i]) return -1;
46
+ }
47
+ return 0;
48
+ }
49
+
50
+ /**
51
+ * v0.17-P1: emit a "you're running a newer CLI than the config was pinned
52
+ * against" nudge. Cheap, file-local check. Returns the nudge text or null.
53
+ */
54
+ function _checkVersionPin(config) {
55
+ const pinned = config.docguardVersion;
56
+ if (!pinned) return null;
57
+ const cmp = _semverCompare(CLI_VERSION, pinned);
58
+ if (cmp > 0) {
59
+ return `Running CLI v${CLI_VERSION} but config pins v${pinned}. ` +
60
+ `New validators/rules may have appeared. Run \`docguard guard --pin\` to update the pin once you've reviewed any new findings.`;
61
+ }
62
+ if (cmp < 0) {
63
+ return `Running CLI v${CLI_VERSION} but config pins v${pinned} (newer). ` +
64
+ `Older CLI may be missing checks the config expects. Upgrade with \`npm i -g docguard-cli@latest\`.`;
65
+ }
66
+ return null;
67
+ }
68
+
69
+ /**
70
+ * v0.17.1: small in-code highlight reel surfaced when a project's pinned
71
+ * version is behind the running CLI. The biggest recurring user pattern is
72
+ * "I asked for feature X" → "X shipped two releases ago". This eliminates
73
+ * the need to grep the CHANGELOG. Keep entries short and command-oriented.
74
+ *
75
+ * Add to this table on every release. Format: [introducedIn, oneLineFeature].
76
+ */
77
+ const _RELEASE_HIGHLIGHTS = [
78
+ ['0.13.0', '`docguard sync --since <ref>` — surgical refresh of code-truth doc sections'],
79
+ ['0.13.1', '`docguard impact --since <ref>` — changed files → affected canonical docs map'],
80
+ ['0.13.1', '`Cross-Reference` validator + "did you mean #X?" hints for broken anchors'],
81
+ ['0.14.1', '`docguard fix --write` auto-fixes high-confidence anchor matches'],
82
+ ['0.15.0', '`docguard guard --timings` — per-validator wall-time profile'],
83
+ ['0.15.0', '`.docguard.json` JSON Schema for VS Code autocomplete'],
84
+ ['0.16.0', '`docguard explain "<warning>"` — paste any warning, get the validator help'],
85
+ ['0.16.0', '`docguard guard --quiet` — suppress banner in hooks/CI'],
86
+ ['0.16.0', '`docguard init --no-spec-kit` — opt out of Spec Kit scaffolding'],
87
+ ['0.16.0', 'Language-aware test patterns (Python `test_*.py`, Rust `tests/*.rs`, Go `*_test.go`, ...)'],
88
+ ['0.17.0', '`docguard memory --diff` — drill into accuracy mismatches (which claim ≠ code)'],
89
+ ['0.17.0', '`docguard guard --pin` — record running CLI version into .docguard.json'],
90
+ ];
91
+
92
+ function _whatsNewSince(pinnedVersion) {
93
+ if (!pinnedVersion) return [];
94
+ const out = [];
95
+ for (const [introducedIn, feature] of _RELEASE_HIGHLIGHTS) {
96
+ if (_semverCompare(introducedIn, pinnedVersion) > 0) {
97
+ out.push(`v${introducedIn}: ${feature}`);
98
+ }
99
+ }
100
+ return out;
101
+ }
102
+
103
+ /**
104
+ * v0.17-P1: update the docguardVersion field in .docguard.json after a
105
+ * successful guard run. Triggered by `docguard guard --pin`. Idempotent.
106
+ */
107
+ function _updateVersionPin(projectDir) {
108
+ const cfgPath = resolvePath(projectDir, '.docguard.json');
109
+ if (!existsSync(cfgPath)) return { written: false, reason: '.docguard.json not found — run `docguard init` first' };
110
+ let raw, cfg;
111
+ try { raw = readFileSync(cfgPath, 'utf-8'); cfg = JSON.parse(raw); } catch (e) {
112
+ return { written: false, reason: `could not parse .docguard.json: ${e.message}` };
113
+ }
114
+ if (cfg.docguardVersion === CLI_VERSION) {
115
+ return { written: false, reason: `already pinned at v${CLI_VERSION}` };
116
+ }
117
+ const prev = cfg.docguardVersion || '(unset)';
118
+ cfg.docguardVersion = CLI_VERSION;
119
+ writeFileSync(cfgPath, JSON.stringify(cfg, null, 2) + '\n', 'utf-8');
120
+ return { written: true, from: prev, to: CLI_VERSION };
121
+ }
14
122
  import { validateStructure, validateDocSections } from '../validators/structure.mjs';
15
123
  import { validateDrift } from '../validators/drift.mjs';
16
124
  import { validateChangelog } from '../validators/changelog.mjs';
@@ -364,6 +472,27 @@ export function runGuard(projectDir, config, flags) {
364
472
  console.log(`\n ${c.yellow}↑ ${upgradeHint}${c.reset}`);
365
473
  }
366
474
 
475
+ // v0.17-P1: version-pin nudge. When .docguard.json carries a
476
+ // docguardVersion field and the running CLI doesn't match, emit a
477
+ // one-line note. Keeps CDD reproducibility honest — "same project,
478
+ // same docs, different score across versions" no longer silent.
479
+ const pinHint = _checkVersionPin(config);
480
+ if (pinHint) {
481
+ console.log(`\n ${c.yellow}📌 ${pinHint}${c.reset}`);
482
+ // v0.17.1: surface features added since the pinned version so users
483
+ // who pinned at v0.12 and just upgraded actually KNOW about sync,
484
+ // impact, explain, memory --diff, etc. The biggest user complaint
485
+ // pattern is "I asked for X but X already shipped two releases ago."
486
+ const whatsNew = _whatsNewSince(config.docguardVersion);
487
+ if (whatsNew.length > 0) {
488
+ console.log(` ${c.dim}New since v${config.docguardVersion}:${c.reset}`);
489
+ for (const item of whatsNew.slice(0, 5)) {
490
+ console.log(` ${c.dim}• ${item}${c.reset}`);
491
+ }
492
+ if (whatsNew.length > 5) console.log(` ${c.dim}... ${whatsNew.length - 5} more in CHANGELOG.md${c.reset}`);
493
+ }
494
+ }
495
+
367
496
  // K-6 / S-2: sweep-needed nudge. Aggregates freshness warnings — if 2+
368
497
  // canonical docs are stale (matching the "X code commits since last doc
369
498
  // update" pattern), suggest a single `docguard sync --write` pass that
@@ -402,6 +531,24 @@ export function runGuard(projectDir, config, flags) {
402
531
 
403
532
  console.log('');
404
533
 
534
+ // v0.17-P1: --pin updates docguardVersion in .docguard.json to the running
535
+ // CLI version. Only meaningful AFTER a clean (or near-clean) guard run —
536
+ // pinning to a version that just failed defeats the reproducibility goal.
537
+ // We allow pinning when status is PASS or WARN; refuse on FAIL.
538
+ if (flags.pin) {
539
+ if (data.status === 'FAIL') {
540
+ console.log(` ${c.red}✗ Cannot --pin after a FAIL run.${c.reset} Fix the errors first, then retry.`);
541
+ } else {
542
+ const r = _updateVersionPin(projectDir);
543
+ if (r.written) {
544
+ console.log(` ${c.green}📌 docguardVersion pinned: ${r.from} → ${r.to}${c.reset}`);
545
+ } else {
546
+ console.log(` ${c.dim}📌 ${r.reason}${c.reset}`);
547
+ }
548
+ }
549
+ console.log('');
550
+ }
551
+
405
552
  // v0.5: severity-aware exit codes (see runGuardInternal for the rollup).
406
553
  if (data.effectiveErrors > 0) process.exit(1);
407
554
  if (data.effectiveWarnings > 0) process.exit(2);
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Memory Command — v0.17-P2.
3
+ *
4
+ * `docguard memory` shows the documentation-memory accuracy headline that
5
+ * already appears in `docguard score`, but adds a `--diff` mode that drills
6
+ * into WHICH claims don't match code. Reported by a Python user:
7
+ *
8
+ * "Memory accuracy 83% with no drill-down. The headline number was the
9
+ * only signal — there's no `docguard memory --diff` to show which doc
10
+ * claim doesn't match the code."
11
+ *
12
+ * The numbers are the same ones `score` shows; this command's value is
13
+ * making them inspectable per-domain.
14
+ *
15
+ * Domains drilled into:
16
+ * - Endpoints: API-REFERENCE.md vs scanned routes
17
+ * - Entities: DATA-MODEL.md vs scanned schemas
18
+ * - Env vars: ENVIRONMENT.md vs process.env / import.meta.env usage
19
+ * - Tech: ARCHITECTURE.md vs detected stack
20
+ *
21
+ * Zero NPM dependencies. Pure orchestration of existing diff helpers.
22
+ */
23
+
24
+ import { c } from '../shared.mjs';
25
+ import { diffRoutes, diffEntities, diffEnvVars, diffTechStack } from './diff.mjs';
26
+
27
+ /**
28
+ * Compute an accuracy score for a single domain. Returns:
29
+ * { matched, total, accuracy: 0..100, onlyInDocs, onlyInCode }
30
+ * `null` when the domain isn't applicable (e.g. no API-REFERENCE.md).
31
+ */
32
+ function _domainAccuracy(d) {
33
+ if (!d) return null;
34
+ const matched = (d.matched || []).length;
35
+ const onlyDocs = (d.onlyInDocs || []).length;
36
+ const onlyCode = (d.onlyInCode || []).length;
37
+ const total = matched + onlyDocs + onlyCode;
38
+ if (total === 0) return null;
39
+ return {
40
+ title: d.title,
41
+ icon: d.icon,
42
+ matched,
43
+ onlyInDocs: d.onlyInDocs || [],
44
+ onlyInCode: d.onlyInCode || [],
45
+ total,
46
+ accuracy: Math.round((matched / total) * 100),
47
+ };
48
+ }
49
+
50
+ export function runMemory(projectDir, config, flags) {
51
+ const isJson = flags.format === 'json';
52
+ const wantsDiff = flags.diff || (flags.args || []).includes('--diff');
53
+
54
+ const domains = {
55
+ endpoints: _domainAccuracy(diffRoutes(projectDir, config)),
56
+ entities: _domainAccuracy(diffEntities(projectDir, config)),
57
+ envVars: _domainAccuracy(diffEnvVars(projectDir, config)),
58
+ techStack: _domainAccuracy(diffTechStack(projectDir, config)),
59
+ };
60
+
61
+ // Roll up across applicable domains.
62
+ let totalMatched = 0;
63
+ let totalChecks = 0;
64
+ for (const d of Object.values(domains)) {
65
+ if (!d) continue;
66
+ totalMatched += d.matched;
67
+ totalChecks += d.total;
68
+ }
69
+ const overallAccuracy = totalChecks > 0
70
+ ? Math.round((totalMatched / totalChecks) * 100)
71
+ : 0;
72
+
73
+ if (isJson) {
74
+ console.log(JSON.stringify({
75
+ project: config.projectName,
76
+ accuracy: overallAccuracy,
77
+ domains,
78
+ totals: { matched: totalMatched, checks: totalChecks },
79
+ timestamp: new Date().toISOString(),
80
+ }, null, 2));
81
+ return;
82
+ }
83
+
84
+ // ── Text output ──
85
+ console.log(`${c.bold}🧠 DocGuard Memory${c.reset} ${c.dim}— ${config.projectName}${c.reset}\n`);
86
+
87
+ const accColor = overallAccuracy >= 90 ? c.green : overallAccuracy >= 70 ? c.yellow : c.red;
88
+ console.log(` ${c.bold}Accuracy:${c.reset} ${accColor}${overallAccuracy}%${c.reset} ${c.dim}(${totalMatched}/${totalChecks} doc claims match code)${c.reset}\n`);
89
+
90
+ if (totalChecks === 0) {
91
+ console.log(` ${c.dim}No applicable domains found — add canonical docs (API-REFERENCE.md, DATA-MODEL.md, ENVIRONMENT.md) and rerun.${c.reset}`);
92
+ return;
93
+ }
94
+
95
+ // Per-domain breakdown
96
+ console.log(` ${c.bold}By domain:${c.reset}`);
97
+ for (const [name, d] of Object.entries(domains)) {
98
+ if (!d) continue;
99
+ const domainColor = d.accuracy >= 90 ? c.green : d.accuracy >= 70 ? c.yellow : c.red;
100
+ console.log(` ${d.icon} ${c.cyan}${d.title.padEnd(22)}${c.reset} ${domainColor}${String(d.accuracy).padStart(3)}%${c.reset} ${c.dim}${d.matched}/${d.total} matched${c.reset}`);
101
+ }
102
+
103
+ if (!wantsDiff) {
104
+ if (overallAccuracy < 100) {
105
+ console.log(`\n ${c.dim}Run ${c.cyan}docguard memory --diff${c.dim} to see WHICH claims don't match.${c.reset}`);
106
+ }
107
+ return;
108
+ }
109
+
110
+ // --diff mode: detail per domain
111
+ console.log(`\n ${c.bold}── Drill-down ──${c.reset}`);
112
+ let anyShown = false;
113
+ for (const [_, d] of Object.entries(domains)) {
114
+ if (!d) continue;
115
+ if (d.onlyInDocs.length === 0 && d.onlyInCode.length === 0) continue;
116
+ anyShown = true;
117
+ console.log(`\n ${d.icon} ${c.bold}${d.title}${c.reset} ${c.dim}(${d.accuracy}%)${c.reset}`);
118
+
119
+ if (d.onlyInDocs.length > 0) {
120
+ console.log(` ${c.red}✗ In docs but missing from code${c.reset} ${c.dim}(${d.onlyInDocs.length}):${c.reset}`);
121
+ for (const item of d.onlyInDocs.slice(0, 10)) {
122
+ console.log(` ${c.red}-${c.reset} ${item}`);
123
+ }
124
+ if (d.onlyInDocs.length > 10) console.log(` ${c.dim}... ${d.onlyInDocs.length - 10} more${c.reset}`);
125
+ }
126
+
127
+ if (d.onlyInCode.length > 0) {
128
+ console.log(` ${c.yellow}⚠ In code but missing from docs${c.reset} ${c.dim}(${d.onlyInCode.length}):${c.reset}`);
129
+ for (const item of d.onlyInCode.slice(0, 10)) {
130
+ console.log(` ${c.yellow}+${c.reset} ${item}`);
131
+ }
132
+ if (d.onlyInCode.length > 10) console.log(` ${c.dim}... ${d.onlyInCode.length - 10} more${c.reset}`);
133
+ }
134
+ }
135
+
136
+ if (!anyShown) {
137
+ console.log(`\n ${c.green}✅ All claims match — nothing to drill into.${c.reset}`);
138
+ } else {
139
+ console.log(`\n ${c.dim}Fix options:${c.reset}`);
140
+ console.log(` ${c.dim}• Removed-from-code items: ${c.cyan}docguard fix --write${c.dim} (deletes documented-but-absent endpoints)${c.reset}`);
141
+ console.log(` ${c.dim}• Missing-from-docs items: ${c.cyan}/docguard.fix --doc <name>${c.dim} (AI fills in the gap)${c.reset}`);
142
+ }
143
+ }
@@ -43,6 +43,7 @@ import { runSetup } from './commands/setup.mjs';
43
43
  import { runUpgrade } from './commands/upgrade.mjs';
44
44
  import { runImpact } from './commands/impact.mjs';
45
45
  import { runExplain } from './commands/explain.mjs';
46
+ import { runMemory } from './commands/memory.mjs';
46
47
  import { ensureSkills } from './ensure-skills.mjs';
47
48
 
48
49
  // ── Shared constants (imported to break circular dependencies) ──────────
@@ -121,7 +122,10 @@ export function loadConfig(projectDir) {
121
122
  ? deepMerge(defaults, profilePreset)
122
123
  : defaults;
123
124
 
124
- const merged = deepMerge(withProfile, userConfig);
125
+ // v0.17-P4: normalize validator/severity keys before merging so the
126
+ // user can write either kebab-case (`test-spec`) or camelCase (`testSpec`)
127
+ // and the internal lookups (always camelCase) still hit.
128
+ const merged = deepMerge(withProfile, normalizeConfig(userConfig));
125
129
  merged.profile = profileName;
126
130
 
127
131
  // Auto-detect project type if not set
@@ -210,6 +214,46 @@ function getProjectTypeDefaults(type) {
210
214
  return defaults[type] || defaults.unknown;
211
215
  }
212
216
 
217
+ /**
218
+ * v0.17-P4: normalize validator-key naming so users can write either
219
+ * `validators: { "test-spec": true }` (kebab-case, matches CLI display)
220
+ * or `validators: { testSpec: true }` (camelCase, matches JSON internals)
221
+ * in `.docguard.json`. We normalize the WHOLE config tree's known validator
222
+ * keys to camelCase before merging. Same treatment applied to `severity`.
223
+ *
224
+ * Non-validator keys are left alone. Unknown keys (forward-compat) are
225
+ * normalized blindly: kebab-case→camelCase always.
226
+ */
227
+ const _KNOWN_VALIDATORS = [
228
+ 'structure', 'docsSync', 'drift', 'changelog', 'testSpec', 'environment',
229
+ 'security', 'architecture', 'freshness', 'traceability', 'docsDiff',
230
+ 'apiSurface', 'metadataSync', 'docsCoverage', 'docQuality', 'todoTracking',
231
+ 'schemaSync', 'specKit', 'crossReference', 'generatedStaleness',
232
+ 'metricsConsistency',
233
+ ];
234
+
235
+ function _kebabToCamel(k) {
236
+ return k.replace(/-([a-z])/g, (_, ch) => ch.toUpperCase());
237
+ }
238
+
239
+ function _normalizeValidatorKeys(map) {
240
+ if (!map || typeof map !== 'object' || Array.isArray(map)) return map;
241
+ const out = {};
242
+ for (const [k, v] of Object.entries(map)) {
243
+ const normalized = k.includes('-') ? _kebabToCamel(k) : k;
244
+ out[normalized] = v;
245
+ }
246
+ return out;
247
+ }
248
+
249
+ function normalizeConfig(cfg) {
250
+ if (!cfg || typeof cfg !== 'object') return cfg;
251
+ const out = { ...cfg };
252
+ if (out.validators) out.validators = _normalizeValidatorKeys(out.validators);
253
+ if (out.severity) out.severity = _normalizeValidatorKeys(out.severity);
254
+ return out;
255
+ }
256
+
213
257
  function deepMerge(target, source) {
214
258
  const result = { ...target };
215
259
  for (const key of Object.keys(source)) {
@@ -406,6 +450,15 @@ async function main() {
406
450
  // Default stays on (discoverability), but lets minimalist library
407
451
  // projects skip the .specify/.agent/commands scaffolding.
408
452
  flags.noSpecKit = true;
453
+ } else if (args[i] === '--pin') {
454
+ // v0.17-P1: `docguard guard --pin` records the running CLI version
455
+ // into .docguard.json (`docguardVersion` field) after a successful run.
456
+ // Different from `--pr` (used by upgrade) — this is for guard.
457
+ flags.pin = true;
458
+ } else if (args[i] === '--diff') {
459
+ // v0.17-P2: `docguard memory --diff` drills into accuracy mismatches.
460
+ // Distinct from the `diff` command itself (which is a top-level cmd).
461
+ flags.diff = true;
409
462
  } else if (!args[i].startsWith('--') && i > 0) {
410
463
  // Positional args go into flags.args for commands that take them (e.g.
411
464
  // `docguard trace --reverse <path>`). Skip the command itself (i === 0).
@@ -544,6 +597,9 @@ async function main() {
544
597
  case 'help-warning':
545
598
  runExplain(projectDir, config, flags);
546
599
  break;
600
+ case 'memory':
601
+ runMemory(projectDir, config, flags);
602
+ break;
547
603
  default:
548
604
  console.error(`${c.red}Unknown command: ${command}${c.reset}`);
549
605
  console.log(`Run ${c.cyan}docguard --help${c.reset} for usage.`);
@@ -45,16 +45,18 @@ export function validateEnvironment(projectDir, config) {
45
45
  // tokens like `VITE_` (the convention prefix) from being treated as a real
46
46
  // variable name.
47
47
  const varRe = /`([A-Z][A-Z0-9_]*[A-Z0-9])`/g;
48
- // v0.16-P4: skip backticked SYSTEM env vars (PATH, HOME, USER, etc.).
49
- // They appear in ENVIRONMENT.md prose ("the venv `PATH`") but aren't
50
- // user-set application vars. Mirrors the same skip in diff.mjs.
48
+ // v0.16-P4 (revised in v0.17.1-B7): skip backticked SYSTEM env vars
49
+ // (PATH, HOME, USER, etc.) that appear in ENVIRONMENT.md prose. Trimmed
50
+ // to TRULY-system-only after wu feedback NODE_ENV / CI / GITHUB_* were
51
+ // causing asymmetric flagging between diff and this validator. Apps
52
+ // legitimately treat NODE_ENV as app config; keep the list to vars that
53
+ // no sane application would read as runtime config.
51
54
  const SYSTEM = new Set([
52
55
  'PATH','HOME','USER','USERNAME','SHELL','PWD','OLDPWD','TMPDIR','TEMP','TMP',
53
56
  'LANG','LC_ALL','LC_CTYPE','LC_MESSAGES','TZ',
54
57
  'EDITOR','VISUAL','PAGER','TERM','COLORTERM',
55
58
  'DISPLAY','SSH_AUTH_SOCK','SSH_CONNECTION','SSH_TTY',
56
59
  'XDG_CONFIG_HOME','XDG_DATA_HOME','XDG_CACHE_HOME','XDG_RUNTIME_DIR',
57
- 'CI','GITHUB_TOKEN','GITHUB_ACTIONS','GITHUB_REF','GITHUB_SHA','NODE_ENV',
58
60
  ]);
59
61
  let m;
60
62
  while ((m = varRe.exec(content)) !== null) {