docguard-cli 0.13.0__tar.gz → 0.14.0__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 (295) hide show
  1. {docguard_cli-0.13.0/extensions/spec-kit-docguard → docguard_cli-0.14.0/.agent}/skills/docguard-fix/SKILL.md +2 -2
  2. {docguard_cli-0.13.0/extensions/spec-kit-docguard → docguard_cli-0.14.0/.agent}/skills/docguard-guard/SKILL.md +2 -2
  3. {docguard_cli-0.13.0/extensions/spec-kit-docguard → docguard_cli-0.14.0/.agent}/skills/docguard-review/SKILL.md +2 -2
  4. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.agent/skills/docguard-score/SKILL.md +2 -2
  5. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.agent/skills/docguard-sync/SKILL.md +1 -1
  6. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/CHANGELOG.md +84 -0
  7. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/PKG-INFO +1 -1
  8. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/commands/fix.mjs +9 -3
  9. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/commands/guard.mjs +34 -5
  10. docguard_cli-0.14.0/cli/commands/impact.mjs +169 -0
  11. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/commands/upgrade.mjs +76 -2
  12. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/docguard.mjs +13 -0
  13. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/shared-source.mjs +10 -0
  14. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/validators/api-surface.mjs +16 -0
  15. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/validators/cross-reference.mjs +101 -7
  16. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/validators/freshness.mjs +41 -5
  17. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/validators/generated-staleness.mjs +71 -3
  18. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/validators/structure.mjs +25 -15
  19. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/writers/fix-memory.mjs +49 -1
  20. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/writers/mechanical.mjs +75 -0
  21. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/extensions/spec-kit-docguard/extension.yml +1 -1
  22. {docguard_cli-0.13.0/.agent → docguard_cli-0.14.0/extensions/spec-kit-docguard}/skills/docguard-fix/SKILL.md +2 -2
  23. {docguard_cli-0.13.0/.agent → docguard_cli-0.14.0/extensions/spec-kit-docguard}/skills/docguard-guard/SKILL.md +2 -2
  24. {docguard_cli-0.13.0/.agent → docguard_cli-0.14.0/extensions/spec-kit-docguard}/skills/docguard-review/SKILL.md +2 -2
  25. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/extensions/spec-kit-docguard/skills/docguard-score/SKILL.md +2 -2
  26. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/extensions/spec-kit-docguard/skills/docguard-sync/SKILL.md +1 -1
  27. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/package.json +1 -1
  28. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/pyproject.toml +1 -1
  29. docguard_cli-0.14.0/tests/changed-only-scoping.test.mjs +118 -0
  30. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/cross-reference.test.mjs +58 -0
  31. docguard_cli-0.14.0/tests/fix-suppression.test.mjs +129 -0
  32. docguard_cli-0.14.0/tests/fixture-projects.test.mjs +201 -0
  33. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/generated-staleness.test.mjs +48 -1
  34. docguard_cli-0.14.0/tests/guard-no-throw.test.mjs +119 -0
  35. docguard_cli-0.14.0/tests/impact.test.mjs +125 -0
  36. docguard_cli-0.14.0/tests/profile-flag.test.mjs +68 -0
  37. docguard_cli-0.14.0/tests/regenerate-section.test.mjs +134 -0
  38. docguard_cli-0.14.0/tests/upgrade-pr.test.mjs +79 -0
  39. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.agent/commands/speckit.analyze.md +0 -0
  40. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.agent/commands/speckit.checklist.md +0 -0
  41. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.agent/commands/speckit.clarify.md +0 -0
  42. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.agent/commands/speckit.constitution.md +0 -0
  43. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.agent/commands/speckit.implement.md +0 -0
  44. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.agent/commands/speckit.plan.md +0 -0
  45. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.agent/commands/speckit.specify.md +0 -0
  46. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.agent/commands/speckit.tasks.md +0 -0
  47. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.agent/commands/speckit.taskstoissues.md +0 -0
  48. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.agent/skills/speckit-analyze/SKILL.md +0 -0
  49. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.agent/skills/speckit-checklist/SKILL.md +0 -0
  50. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.agent/skills/speckit-clarify/SKILL.md +0 -0
  51. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.agent/skills/speckit-constitution/SKILL.md +0 -0
  52. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.agent/skills/speckit-implement/SKILL.md +0 -0
  53. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.agent/skills/speckit-plan/SKILL.md +0 -0
  54. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.agent/skills/speckit-specify/SKILL.md +0 -0
  55. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.agent/skills/speckit-tasks/SKILL.md +0 -0
  56. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.agent/skills/speckit-taskstoissues/SKILL.md +0 -0
  57. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.docguard.json +0 -0
  58. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.docguardignore +0 -0
  59. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  60. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  61. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.github/dependabot.yml +0 -0
  62. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.github/scripts/patch-catalog.py +0 -0
  63. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.github/workflows/ci.yml +0 -0
  64. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.github/workflows/release.yml +0 -0
  65. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.github/workflows/supply-chain.yml +0 -0
  66. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.github/workflows/sync-speckit-catalog.yml +0 -0
  67. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.gitignore +0 -0
  68. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.jules/bolt.md +0 -0
  69. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.jules/palette.md +0 -0
  70. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.jules/sentinel.md +0 -0
  71. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.npmignore +0 -0
  72. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.npmrc +0 -0
  73. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.specify/extensions/.cache/catalog-ebf165086500aab1-metadata.json +0 -0
  74. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.specify/extensions/.cache/catalog-ebf165086500aab1.json +0 -0
  75. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.specify/extensions/.cache/catalog-metadata.json +0 -0
  76. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.specify/extensions/.cache/catalog.json +0 -0
  77. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.specify/init-options.json +0 -0
  78. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.specify/memory/constitution.md +0 -0
  79. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.specify/scripts/bash/check-prerequisites.sh +0 -0
  80. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.specify/scripts/bash/common.sh +0 -0
  81. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.specify/scripts/bash/create-new-feature.sh +0 -0
  82. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.specify/scripts/bash/setup-plan.sh +0 -0
  83. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.specify/scripts/bash/update-agent-context.sh +0 -0
  84. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.specify/templates/agent-file-template.md +0 -0
  85. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.specify/templates/checklist-template.md +0 -0
  86. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.specify/templates/constitution-template.md +0 -0
  87. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.specify/templates/plan-template.md +0 -0
  88. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.specify/templates/spec-template.md +0 -0
  89. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/.specify/templates/tasks-template.md +0 -0
  90. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/AGENTS.md +0 -0
  91. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/CODE_OF_CONDUCT.md +0 -0
  92. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/COMPARISONS.md +0 -0
  93. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/CONTRIBUTING.md +0 -0
  94. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/DRIFT-LOG.md +0 -0
  95. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/LICENSE +0 -0
  96. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/PHILOSOPHY.md +0 -0
  97. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/README.md +0 -0
  98. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/ROADMAP.md +0 -0
  99. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/SECURITY.md +0 -0
  100. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/STANDARD.md +0 -0
  101. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/SUPPLY-CHAIN-AUDIT.md +0 -0
  102. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/SUPPORT.md +0 -0
  103. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/action.yml +0 -0
  104. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/commands/agents.mjs +0 -0
  105. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/commands/badge.mjs +0 -0
  106. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/commands/ci.mjs +0 -0
  107. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/commands/diagnose.mjs +0 -0
  108. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/commands/diff.mjs +0 -0
  109. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/commands/generate.mjs +0 -0
  110. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/commands/hooks.mjs +0 -0
  111. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/commands/init.mjs +0 -0
  112. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/commands/llms.mjs +0 -0
  113. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/commands/publish.mjs +0 -0
  114. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/commands/score.mjs +0 -0
  115. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/commands/setup.mjs +0 -0
  116. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/commands/sync.mjs +0 -0
  117. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/commands/trace.mjs +0 -0
  118. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/commands/watch.mjs +0 -0
  119. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/ensure-skills.mjs +0 -0
  120. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/scanners/api-doc.mjs +0 -0
  121. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/scanners/cdk.mjs +0 -0
  122. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/scanners/doc-tools.mjs +0 -0
  123. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/scanners/frontend.mjs +0 -0
  124. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/scanners/iac.mjs +0 -0
  125. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/scanners/integrations.mjs +0 -0
  126. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/scanners/memory-plan.mjs +0 -0
  127. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/scanners/project-type.mjs +0 -0
  128. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/scanners/routes.mjs +0 -0
  129. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/scanners/schemas.mjs +0 -0
  130. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/scanners/speckit.mjs +0 -0
  131. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/shared-git.mjs +0 -0
  132. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/shared-ignore.mjs +0 -0
  133. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/shared.mjs +0 -0
  134. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/validators/architecture.mjs +0 -0
  135. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/validators/changelog.mjs +0 -0
  136. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/validators/doc-quality.mjs +0 -0
  137. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/validators/docs-coverage.mjs +0 -0
  138. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/validators/docs-diff.mjs +0 -0
  139. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/validators/docs-sync.mjs +0 -0
  140. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/validators/drift.mjs +0 -0
  141. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/validators/environment.mjs +0 -0
  142. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/validators/metadata-sync.mjs +0 -0
  143. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/validators/metrics-consistency.mjs +0 -0
  144. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/validators/schema-sync.mjs +0 -0
  145. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/validators/security.mjs +0 -0
  146. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/validators/test-spec.mjs +0 -0
  147. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/validators/todo-tracking.mjs +0 -0
  148. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/validators/traceability.mjs +0 -0
  149. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/writers/api-reference.mjs +0 -0
  150. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/cli/writers/sections.mjs +0 -0
  151. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/commands/docguard.fix.md +0 -0
  152. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/commands/docguard.guard.md +0 -0
  153. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/commands/docguard.review.md +0 -0
  154. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/commands/docguard.score.md +0 -0
  155. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/configs/fastify.json +0 -0
  156. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/configs/generic.json +0 -0
  157. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/configs/nextjs.json +0 -0
  158. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/configs/python.json +0 -0
  159. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/docguard_cli/__init__.py +0 -0
  160. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/docguard_cli/wrapper.py +0 -0
  161. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/docs/ai-integration.md +0 -0
  162. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/docs/commands.md +0 -0
  163. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/docs/configuration.md +0 -0
  164. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/docs/doc-sections.md +0 -0
  165. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/docs/faq.md +0 -0
  166. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/docs/installation.md +0 -0
  167. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/docs/profiles.md +0 -0
  168. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/docs/quickstart.md +0 -0
  169. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/docs-canonical/ARCHITECTURE.md +0 -0
  170. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/docs-canonical/CI-RECIPES.md +0 -0
  171. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/docs-canonical/DATA-MODEL.md +0 -0
  172. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/docs-canonical/ENVIRONMENT.md +0 -0
  173. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/docs-canonical/SECURITY.md +0 -0
  174. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/docs-canonical/TEST-SPEC.md +0 -0
  175. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/examples/01-express-api/README.md +0 -0
  176. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/examples/01-express-api/package.json +0 -0
  177. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/examples/01-express-api/server.js +0 -0
  178. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/examples/02-python-flask/README.md +0 -0
  179. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/examples/02-python-flask/app.py +0 -0
  180. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/examples/02-python-flask/docs-canonical/ARCHITECTURE.md +0 -0
  181. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/examples/02-python-flask/requirements.txt +0 -0
  182. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/examples/03-spec-kit-project/CHANGELOG.md +0 -0
  183. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/examples/03-spec-kit-project/README.md +0 -0
  184. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/examples/03-spec-kit-project/docs-canonical/ARCHITECTURE.md +0 -0
  185. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/examples/03-spec-kit-project/docs-canonical/TEST-SPEC.md +0 -0
  186. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/examples/03-spec-kit-project/package.json +0 -0
  187. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/examples/03-spec-kit-project/src/index.js +0 -0
  188. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/examples/03-spec-kit-project/tests/basic.test.js +0 -0
  189. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/examples/README.md +0 -0
  190. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/extensions/spec-kit-docguard/LICENSE +0 -0
  191. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/extensions/spec-kit-docguard/README.md +0 -0
  192. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/extensions/spec-kit-docguard/commands/diagnose.md +0 -0
  193. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/extensions/spec-kit-docguard/commands/fix.md +0 -0
  194. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/extensions/spec-kit-docguard/commands/generate.md +0 -0
  195. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/extensions/spec-kit-docguard/commands/guard.md +0 -0
  196. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/extensions/spec-kit-docguard/commands/init.md +0 -0
  197. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/extensions/spec-kit-docguard/commands/score.md +0 -0
  198. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/extensions/spec-kit-docguard/commands/sync.md +0 -0
  199. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/extensions/spec-kit-docguard/commands/trace.md +0 -0
  200. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/extensions/spec-kit-docguard/scripts/bash/common.sh +0 -0
  201. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/extensions/spec-kit-docguard/scripts/bash/docguard-check-docs.sh +0 -0
  202. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/extensions/spec-kit-docguard/scripts/bash/docguard-init-doc.sh +0 -0
  203. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/extensions/spec-kit-docguard/scripts/bash/docguard-suggest-fix.sh +0 -0
  204. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/extensions/spec-kit-docguard/templates/extensions.yml +0 -0
  205. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/extensions/spec-kit-docguard/templates/github-workflows/docguard-autofix.yml +0 -0
  206. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/extensions/spec-kit-docguard/templates/github-workflows/docguard-guard.yml +0 -0
  207. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/pr_description.md +0 -0
  208. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/specs/001-fix-ignore-validators/plan.md +0 -0
  209. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/specs/001-fix-ignore-validators/spec.md +0 -0
  210. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/specs/001-fix-ignore-validators/tasks.md +0 -0
  211. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/specs/002-fix-test-discovery/plan.md +0 -0
  212. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/specs/002-fix-test-discovery/spec.md +0 -0
  213. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/specs/002-fix-test-discovery/tasks.md +0 -0
  214. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/specs/003-v011-false-positives/plan.md +0 -0
  215. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/specs/003-v011-false-positives/spec.md +0 -0
  216. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/specs/003-v011-false-positives/tasks.md +0 -0
  217. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/ADR.md.template +0 -0
  218. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/AGENTS.md.template +0 -0
  219. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/ARCHITECTURE.md.template +0 -0
  220. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/CHANGELOG.md.template +0 -0
  221. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/CURRENT-STATE.md.template +0 -0
  222. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/DATA-MODEL.md.template +0 -0
  223. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/DEPLOYMENT.md.template +0 -0
  224. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/DRIFT-LOG.md.template +0 -0
  225. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/ENVIRONMENT.md.template +0 -0
  226. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/KNOWN-GOTCHAS.md.template +0 -0
  227. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/REQUIREMENTS.md.template +0 -0
  228. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/ROADMAP.md.template +0 -0
  229. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/RUNBOOKS.md.template +0 -0
  230. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/SECURITY.md.template +0 -0
  231. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/TEST-SPEC.md.template +0 -0
  232. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/TROUBLESHOOTING.md.template +0 -0
  233. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/VENDOR-BUGS.md.template +0 -0
  234. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/ci/github-actions.yml +0 -0
  235. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/commands/docguard.fix.md +0 -0
  236. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/commands/docguard.guard.md +0 -0
  237. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/commands/docguard.init.md +0 -0
  238. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/commands/docguard.review.md +0 -0
  239. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/templates/commands/docguard.update.md +0 -0
  240. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/test-draft.js +0 -0
  241. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/test-metrics.js +0 -0
  242. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/api-doc.test.mjs +0 -0
  243. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/api-surface.test.mjs +0 -0
  244. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/api-write.test.mjs +0 -0
  245. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/architecture.test.mjs +0 -0
  246. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/backup-failure.test.mjs +0 -0
  247. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/cdk-detection.test.mjs +0 -0
  248. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/changed-only.test.mjs +0 -0
  249. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/changelog.test.mjs +0 -0
  250. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/commands.test.mjs +0 -0
  251. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/doc-quality.test.mjs +0 -0
  252. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/docguardignore.test.mjs +0 -0
  253. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/docs-coverage.test.mjs +0 -0
  254. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/docs-diff.test.mjs +0 -0
  255. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/docs-sync.test.mjs +0 -0
  256. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/drift.test.mjs +0 -0
  257. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/environment.test.mjs +0 -0
  258. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/fix-memory.test.mjs +0 -0
  259. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/freshness.test.mjs +0 -0
  260. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/frontend-deep.test.mjs +0 -0
  261. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/frontend.test.mjs +0 -0
  262. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/guard-classify.test.mjs +0 -0
  263. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/hooks.test.mjs +0 -0
  264. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/i18n.test.mjs +0 -0
  265. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/integrations.test.mjs +0 -0
  266. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/mechanical.test.mjs +0 -0
  267. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/memory-plan.test.mjs +0 -0
  268. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/metadata-sync.test.mjs +0 -0
  269. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/metrics-consistency.test.mjs +0 -0
  270. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/monorepo-scanning.test.mjs +0 -0
  271. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/multi-spec.test.mjs +0 -0
  272. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/patch-0.11.2.test.mjs +0 -0
  273. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/project-type.test.mjs +0 -0
  274. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/routes-multilang.test.mjs +0 -0
  275. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/schema-sync.test.mjs +0 -0
  276. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/schemas-multilang.test.mjs +0 -0
  277. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/schemas.test.mjs +0 -0
  278. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/sections.test.mjs +0 -0
  279. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/security.test.mjs +0 -0
  280. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/severity.test.mjs +0 -0
  281. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/shared-git.test.mjs +0 -0
  282. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/shared-source.test.mjs +0 -0
  283. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/structure.test.mjs +0 -0
  284. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/sweep-nudge.test.mjs +0 -0
  285. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/sync-since.test.mjs +0 -0
  286. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/sync.test.mjs +0 -0
  287. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/test-spec.test.mjs +0 -0
  288. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/todo-tracking.test.mjs +0 -0
  289. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/trace-reverse.test.mjs +0 -0
  290. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/traceability.test.mjs +0 -0
  291. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/tests/upgrade.test.mjs +0 -0
  292. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/vscode-extension/.vscodeignore +0 -0
  293. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/vscode-extension/README.md +0 -0
  294. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/vscode-extension/extension.js +0 -0
  295. {docguard_cli-0.13.0 → docguard_cli-0.14.0}/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.13.0
9
+ version: 0.14.0
10
10
  source: extensions/spec-kit-docguard/skills/docguard-fix
11
11
  ---
12
- <!-- docguard:version: 0.13.0 -->
12
+ <!-- docguard:version: 0.14.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.13.0
10
+ version: 0.14.0
11
11
  source: extensions/spec-kit-docguard/skills/docguard-guard
12
12
  ---
13
- <!-- docguard:version: 0.13.0 -->
13
+ <!-- docguard:version: 0.14.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.13.0
9
+ version: 0.14.0
10
10
  source: extensions/spec-kit-docguard/skills/docguard-review
11
11
  ---
12
- <!-- docguard:version: 0.13.0 -->
12
+ <!-- docguard:version: 0.14.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.13.0
9
+ version: 0.14.0
10
10
  source: extensions/spec-kit-docguard/skills/docguard-score
11
11
  ---
12
- <!-- docguard:version: 0.13.0 -->
12
+ <!-- docguard:version: 0.14.0 -->
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.13.0
7
+ version: 0.14.0
8
8
  source: extensions/spec-kit-docguard/skills/docguard-sync
9
9
  ---
10
10
 
@@ -7,6 +7,90 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.14.0] - 2026-05-26
11
+
12
+ Feature release closing the v0.13 backlog (4 features) + 2 quality investments
13
+ (multi-fixture harness, `--timings` profiler). **481 tests** (was 448, +33).
14
+ 22 validators. Headline wins: pre-commit lite went from 2s → **78ms** on
15
+ wu-whatsappinbox, and Generated-Doc Staleness now CLOSES THE LOOP by emitting
16
+ structured fixes that `fix --write` consumes.
17
+
18
+ ### Added
19
+
20
+ - **P1: Fix-history ping-pong suppression** (completes M-2). `fix --write` now skips fixes that have been applied >= N times before (default 2) — catches the "user keeps reverting, bot keeps re-applying" loop. Override with the new `--force-redo` flag. `applyCount` and `firstAppliedAt` added to each `.docguard/fixed.json` entry for an accurate audit trail.
21
+ - **P2: Environment + API-Surface honor `config.changedFiles`** (extends N-1). When `--changed-only` is set:
22
+ - `grepEnvUsage` scans only the listed files instead of the whole source tree.
23
+ - `validateApiSurface` returns N/A when no route/spec/controller files are in the changed set.
24
+ - **Result on wu-whatsappinbox: `--changed-only --since HEAD~3` runs in 78ms — a 25× speedup from v0.13.**
25
+ - **P3: Generated-Doc Staleness emits structured fixes**. M-1 (v0.13) only warned; now it ALSO produces a `fixes[]` array with new `regenerate-section` fix type that `fix --write` consumes mechanically. **Closes the loop: detect drift → fix without AI.** The applier rewrites only the named section's body, leaves surrounding prose alone, and is idempotent.
26
+ - **P4: `docguard upgrade --apply --pr`** for team-wide schema rollouts. Creates a branch, applies the migration, commits as "chore(docguard): migrate schema X → Y", pushes, opens a PR via `gh` CLI. Pre-flight checks `gh` is installed; clear error if not. Useful when `.docguard.json` is branch-protected.
27
+ - **Q1: Multi-fixture test harness** — `tests/fixture-projects.test.mjs`. Runs full guard against 5 real-world project shapes (Next.js webapp, Vite frontend, Express backend, Python CLI, Rust lib). Cross-cutting "no validator throws a developer error" assertion across every fixture. The harness that would have caught B-5 (v0.13.0 Freshness crash) before release.
28
+ - **Q2: `docguard guard --timings`** — per-validator wall-time profile, sorted slowest-first, with `data.validators[].durationMs` in JSON output. Honest delivery on the "perf pass" item: instead of speculative refactoring, ship the measurement tool. Real finding on wu: Generated-Staleness is **33% of total validator time** (~400ms) — targeted v0.15 optimization candidate.
29
+
30
+ ### Changed
31
+
32
+ - **`docguard fix --write` records `applyCount`** in `.docguard/fixed.json`. Re-applying the same fix bumps the counter; suppression engages at count >= 2.
33
+ - **`docguard fix --history`** display unchanged but now reads richer entries (applyCount, firstAppliedAt).
34
+ - **`docguard guard --format json`** includes `durationMs` per validator.
35
+
36
+ ### Internal
37
+
38
+ - **5 new test files**: `tests/fix-suppression.test.mjs` (9), `tests/changed-only-scoping.test.mjs` (6), `tests/regenerate-section.test.mjs` (6), `tests/upgrade-pr.test.mjs` (3), `tests/fixture-projects.test.mjs` (6), `tests/profile-flag.test.mjs` (3). **Total: 448 → 481 tests (+33 new).**
39
+ - New mechanical fix type: `regenerate-section`. APPLIERS registry now lists 5 types.
40
+ - `cli/writers/mechanical.mjs` got a top-level lazy-loaded `_shouldSuppress` and `_sectionsModule` to support the new applier without circular deps.
41
+ - `cli/commands/upgrade.mjs` got `openUpgradePR()` — gates on `gh` CLI availability.
42
+ - `cli/commands/guard.mjs` per-validator timing via `performance.now()`.
43
+ - Dry-run on wu-whatsappinbox: **674/674 PASS in 1.48s** (full guard), **78ms** for `--changed-only --since HEAD~3` (P2 scoping in action), Generated-Staleness identified as biggest perf hog at 33% of validator time (v0.15 target).
44
+ - No new NPM deps.
45
+
46
+ ### Out of scope (deferred to v0.15)
47
+
48
+ - **Generated-Staleness optimization**: 33% of validator time is the obvious target. Likely fix: memoize `buildMemoryPlan` across `--write` flows so it's not re-computed by the validator AND the writer.
49
+ - **Shared tree walk**: the original Q2 ambition. Now that we have `--timings`, future PRs can MEASURE the gain instead of speculating.
50
+ - **Cross-validator config.changedFiles**: only Docs-Sync, Environment, API-Surface opt in so far. Could extend to Drift-Comments, TODO-Tracking, Generated-Staleness for further `--changed-only` wins.
51
+ - **`upgrade --pr` polish**: dry-run on a real GitHub repo with a real bot identity. The flag is wired and gated, but the actual end-to-end PR creation hasn't been battle-tested in the wild.
52
+
53
+ ## [0.13.1] - 2026-05-26
54
+
55
+ Patch + small feature release responding to the wu-whatsappinbox v0.12/v0.13
56
+ feedback. Fixes 2 bugs (B-5, B-6), ships 3 new features (S-7, S-11, S-12),
57
+ and adds a cross-cutting "no validator throws" safety net. **22 validators,
58
+ 448 tests (was 434, +14 new).** New `docguard impact` command.
59
+
60
+ ### Fixed
61
+
62
+ - **B-5: Freshness validator crashed with `getLastCommitDate is not defined`.** A wu-whatsappinbox install of v0.13.0 produced this ReferenceError despite all the imports being correct in source — we couldn't reproduce locally, but the user's report was clear. Fix: defensive dynamic import in `freshness.mjs` that falls back to the pre-v0.13 inline implementation if `../shared-git.mjs` ever fails to load. Worst-case behavior is now "rename detection silently disabled" instead of "validator crashes with useless message". Also added an inline fallback for the same defensive layering. Reported by wu-whatsappinbox.
63
+ - **B-6: Cross-Reference didn't URL-decode link target paths.** A markdown link like `[name](../WU%20Documentation/foo.md)` (where the directory has a space) was looked up with `existsSync('../WU%20Documentation/foo.md')` literally — the filesystem stores the decoded form. Now: `resolveTarget` tries BOTH the literal path (for paths that legitimately contain `%`) and the URL-decoded form. **Effect on wu-whatsappinbox: Cross-Reference went from 28/28 to 101/101 checks — 73 previously-broken refs now resolve correctly.** Reported by wu-whatsappinbox.
64
+ - **Cross-cutting safety net**: new `tests/guard-no-throw.test.mjs` runs guard against a fixture repo and asserts no validator leaks a ReferenceError / TypeError / "is not defined" / "is not a function" / "Cannot read properties of undefined" pattern into user-facing output. Found a *second* lurking bug while writing the test: Structure validator threw `Cannot read properties of undefined (reading 'some')` when `config.requiredFiles.agentFile` was missing — fixed with defensive array-or-string coercion + skip-when-missing for `changelog` too. This safety net runs in CI, catching the entire class of developer-error-leaks before release.
65
+
66
+ ### Added
67
+
68
+ - **S-12: Cross-Reference suggests the closest anchor on near-miss.** When the validator flags a broken anchor, it now appends `(did you mean #athena-setup-aws-only?)` when a heading in the target doc is a close match. Two-pass matcher: (1) substring containment with ≥4-char minimum and ≥50% overlap to avoid spurious matches, (2) Levenshtein edit distance within a `max(3, len/5)` budget. **Three of the five wu user-fixes in v0.12.0 were "heading renamed, link not updated" — now deterministic-fixable from the warning text.** Reported by wu-whatsappinbox.
69
+ - **S-7: Draft-staleness check in Generated-Doc Staleness validator.** A `docguard:generated` doc with `status: draft` (either YAML frontmatter or `<!-- status: draft -->` inline marker) that hasn't been modified in `> draftStalenessDays` days (default 14) now warns. Catches forgotten skeletons that stall before the AI fills them in. Threshold configurable via `config.draftStalenessDays`. Validator returns N/A only when there's NOTHING to check (no source=code sections AND no draft docs). Reported by wu-whatsappinbox.
70
+ - **S-11: New `docguard impact` command.** After a commit (or before a PR), runs `git diff --name-only --since=<ref>` and shows which canonical doc sections reference any of the changed code files. Three match strategies (direct path / basename / backticked module name — same as L-2 trace --reverse). Highlights orphaned files (code that changed but no doc references it) so reviewers know what's undocumented. JSON mode emits `{ since, changedFiles, ignoredFiles, affectedDocs }` for CI bots. Designed as a post-commit hook companion to K-1's auto-fix Action. Reported by wu-whatsappinbox.
71
+
72
+ ### Internal
73
+
74
+ - **+3 new test files**: `tests/guard-no-throw.test.mjs` (2 — cross-cutting safety), `tests/impact.test.mjs` (5 — S-11), plus 5 new test cases in `cross-reference.test.mjs` (S-12 + B-6) and `generated-staleness.test.mjs` (S-7). **Total: 434 → 448 tests (+14 new).**
75
+ - **New module**: `cli/commands/impact.mjs` (~140 lines).
76
+ - **Hardened**: `cli/validators/freshness.mjs` (defensive shared-git import), `cli/validators/structure.mjs` (defensive config-shape handling), `cli/validators/cross-reference.mjs` (URL-decode + anchor suggestion).
77
+ - **Dry-run on wu-whatsappinbox before push** (read-only): 670/674 PASS in 1.8s with all 22 validators. Cross-Reference jumped from 28/28 to **101/101 checks** — B-6 fix unlocked 73 previously-broken refs.
78
+ - No new NPM deps.
79
+
80
+ ### Note on wu's v0.12 feedback
81
+
82
+ Several "still open" suggestions from the wu-whatsappinbox v0.12 feedback were already shipped:
83
+
84
+ - **S-2 (sweep-needed nudge)** → shipped in v0.12.0 as K-6.
85
+ - **S-3 (trace --reverse)** → shipped in v0.13.0 as L-2.
86
+ - **S-4 (`git log --follow`)** → shipped in v0.13.0 as L-3.
87
+ - **S-5 (.docguardignore at init)** → shipped in v0.12.0 as K-3.
88
+ - **S-6 (per-validator severity)** → shipped in v0.12.0 as K-4.
89
+ - **S-9 (pre-commit lite)** → shipped in v0.12.0 as K-5.
90
+ - **S-10 (`.docguard/fixed.json`)** → shipped in v0.13.0 as M-2.
91
+
92
+ Upgrade with `docguard upgrade --apply` (or `npm i -g docguard-cli@latest`) to get all of these. **The wu report header said v0.12.0 but the B-5 error pattern indicates an in-flight v0.13.0 install** — either way, this patch makes both versions resilient to the regression.
93
+
10
94
  ## [0.13.0] - 2026-05-26
11
95
 
12
96
  Feature release — full backlog cleanup. **Phase L** (sync intelligence: 3 features), **Phase M** (bigger validators: 2 features), **Phase N** (polish: 2 fixes), and a new `shared-git.mjs` module that gives every git-touching validator rename-aware history. **22 validators total** (was 21). 434 tests, +34 from v0.12.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: docguard-cli
3
- Version: 0.13.0
3
+ Version: 0.14.0
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
@@ -272,13 +272,16 @@ IMPORTANT: A new contributor should be able to follow this doc and have the proj
272
272
  * insert-changelog-unreleased (Changelog).
273
273
  * @returns {{ applied: object[], skipped: object[], total: number }}
274
274
  */
275
- export function applyAllMechanicalFixes(projectDir, config, { force = false } = {}) {
275
+ export function applyAllMechanicalFixes(projectDir, config, opts = {}) {
276
+ const { force = false, forceRedo = false } = opts;
276
277
  const guardData = runGuardInternal(projectDir, config);
277
278
  const fixes = [];
278
279
  for (const v of guardData.validators) {
279
280
  if (Array.isArray(v.fixes)) fixes.push(...v.fixes);
280
281
  }
281
- const { applied, skipped } = applyMechanicalFixes(projectDir, fixes, { force });
282
+ // v0.14-P1: forwarding forceRedo so users with `--force-redo` can override
283
+ // ping-pong suppression for a specific fix they actually want re-applied.
284
+ const { applied, skipped } = applyMechanicalFixes(projectDir, fixes, { force, forceRedo });
282
285
  return { applied, skipped, total: fixes.length };
283
286
  }
284
287
 
@@ -333,7 +336,10 @@ function runHistoryMode(projectDir, flags) {
333
336
 
334
337
  function runWriteMode(projectDir, config, flags) {
335
338
  const isJson = flags.format === 'json';
336
- const { applied, skipped, total } = applyAllMechanicalFixes(projectDir, config, { force: flags.force });
339
+ const { applied, skipped, total } = applyAllMechanicalFixes(projectDir, config, {
340
+ force: flags.force,
341
+ forceRedo: flags.forceRedo, // v0.14-P1: bypass ping-pong suppression
342
+ });
337
343
 
338
344
  if (isJson) {
339
345
  console.log(JSON.stringify({
@@ -109,27 +109,36 @@ export function runGuardInternal(projectDir, config) {
109
109
  // Metrics-Consistency runs post-loop (needs guard results)
110
110
  ];
111
111
 
112
+ // v0.14-Q2: per-validator timing. Cheap (one `performance.now()` pair per
113
+ // validator) and the data is what we'd need to optimize anything later.
114
+ // Exposed via --profile in the public guard.
112
115
  for (const { key, name, fn } of validatorMap) {
113
116
  if (validators[key] === false) {
114
- results.push({ name, key, status: 'skipped', quality: null, errors: [], warnings: [], passed: 0, total: 0 });
117
+ results.push({ name, key, status: 'skipped', quality: null, errors: [], warnings: [], passed: 0, total: 0, durationMs: 0 });
115
118
  continue;
116
119
  }
117
120
 
121
+ const start = performance.now();
118
122
  try {
119
123
  const result = fn();
120
- results.push({ ...result, name, key, ...classifyResult(result) });
124
+ const durationMs = Math.round((performance.now() - start) * 100) / 100;
125
+ results.push({ ...result, name, key, durationMs, ...classifyResult(result) });
121
126
  } catch (err) {
122
- results.push({ name, key, status: 'fail', quality: 'LOW', errors: [err.message], warnings: [], passed: 0, total: 1 });
127
+ const durationMs = Math.round((performance.now() - start) * 100) / 100;
128
+ results.push({ name, key, status: 'fail', quality: 'LOW', errors: [err.message], warnings: [], passed: 0, total: 1, durationMs });
123
129
  }
124
130
  }
125
131
 
126
132
  // ── Metrics-Consistency runs AFTER all other validators (needs their results) ──
127
133
  if (validators.metricsConsistency !== false) {
134
+ const start = performance.now();
128
135
  try {
129
136
  const result = validateMetricsConsistency(projectDir, config, results);
130
- results.push({ ...result, name: 'Metrics-Consistency', key: 'metricsConsistency', ...classifyResult(result) });
137
+ const durationMs = Math.round((performance.now() - start) * 100) / 100;
138
+ results.push({ ...result, name: 'Metrics-Consistency', key: 'metricsConsistency', durationMs, ...classifyResult(result) });
131
139
  } catch (err) {
132
- results.push({ name: 'Metrics-Consistency', key: 'metricsConsistency', status: 'fail', quality: 'LOW', errors: [err.message], warnings: [], passed: 0, total: 1 });
140
+ const durationMs = Math.round((performance.now() - start) * 100) / 100;
141
+ results.push({ name: 'Metrics-Consistency', key: 'metricsConsistency', status: 'fail', quality: 'LOW', errors: [err.message], warnings: [], passed: 0, total: 1, durationMs });
133
142
  }
134
143
  }
135
144
 
@@ -326,6 +335,26 @@ export function runGuard(projectDir, config, flags) {
326
335
  const badgeUrl = `https://img.shields.io/badge/CDD_Guard-${data.passed}%2F${data.total}_passed-${bColor}`;
327
336
  console.log(`\n ${c.dim}📎 Badge: ![CDD Guard](${badgeUrl})${c.reset}`);
328
337
 
338
+ // v0.14-Q2: --timings prints per-validator timing, sorted slowest-first.
339
+ // Designed for self-diagnosis on slow repos: shows exactly which validator
340
+ // to optimize first. Cheap to opt into; off by default to keep output clean.
341
+ // (Originally proposed as `--profile` but that flag is taken by `init`.)
342
+ if (flags.timings) {
343
+ console.log(`\n ${c.bold}⏱ Profile${c.reset} ${c.dim}(per-validator wall time, slowest first)${c.reset}`);
344
+ const timed = data.validators
345
+ .filter(v => typeof v.durationMs === 'number' && v.status !== 'skipped')
346
+ .sort((a, b) => b.durationMs - a.durationMs);
347
+ const total = timed.reduce((sum, v) => sum + v.durationMs, 0);
348
+ for (const v of timed.slice(0, 10)) {
349
+ const pct = total > 0 ? Math.round((v.durationMs / total) * 100) : 0;
350
+ const bar = '▇'.repeat(Math.max(1, Math.round(pct / 5)));
351
+ console.log(` ${v.durationMs.toFixed(1).padStart(7)}ms ${pct.toString().padStart(2)}% ${bar.padEnd(20)} ${v.name}`);
352
+ }
353
+ if (timed.length > 10) console.log(` ${c.dim}... ${timed.length - 10} faster validators omitted${c.reset}`);
354
+ console.log(` ${c.dim}─────────${c.reset}`);
355
+ console.log(` ${c.bold}${total.toFixed(1).padStart(7)}ms${c.reset} ${c.dim}total validator time${c.reset}`);
356
+ }
357
+
329
358
  // Schema upgrade nudge — fires when the project's .docguard.json schema is
330
359
  // behind the CLI's CURRENT_SCHEMA_VERSION. Cheap, file-local check; no
331
360
  // network access. Suppressed in JSON output to keep machine consumers clean.
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Impact Command — S-11
3
+ *
4
+ * After a commit (or before opening a PR), shows which canonical doc
5
+ * sections reference any file that changed since `--since` (default HEAD~1).
6
+ * Combines the L-2 reverse-trace logic with the changed-files diff so you
7
+ * get "you should re-read these doc sections" in one command.
8
+ *
9
+ * Use cases:
10
+ * - Post-commit hook: `docguard impact --since HEAD~1` runs after each
11
+ * commit and reminds the developer which docs to update.
12
+ * - PR prep: `docguard impact --since main` shows the doc surface area
13
+ * touched by the whole branch.
14
+ *
15
+ * JSON mode emits a structured `{ changedFiles, affectedDocs }` payload
16
+ * for CI integrations and PR-comment bots.
17
+ *
18
+ * @req SC-S11-001 — impact reports per-file → doc mappings
19
+ * @req SC-S11-002 — files with no doc references are listed as "no impact"
20
+ * @req SC-S11-003 — --format json emits parseable structured output
21
+ * @req SC-S11-004 — non-code files (.md, .json, etc.) are skipped from impact analysis
22
+ */
23
+
24
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
25
+ import { resolve, basename } from 'node:path';
26
+
27
+ import { c } from '../shared.mjs';
28
+ import { changedFilesSince, isGitRepo } from '../shared-git.mjs';
29
+
30
+ /**
31
+ * File extensions we consider "code" for the purposes of impact analysis.
32
+ * Match the set used by other validators (Docs-Sync, Freshness).
33
+ */
34
+ const CODE_EXTENSIONS = /\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|kt|rb|php|cs|swift)$/;
35
+
36
+ function escapeRegex(s) {
37
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
38
+ }
39
+
40
+ /**
41
+ * Find canonical doc references for a single file. Reuses the same three
42
+ * match strategies as trace --reverse for consistency: direct path,
43
+ * basename, backticked module name.
44
+ */
45
+ function findReferences(file, docs) {
46
+ const refs = [];
47
+ const normalized = file.replace(/^\.\//, '');
48
+ const base = basename(normalized);
49
+ const stem = base.replace(/\.[^.]+$/, '');
50
+ const stemRe = new RegExp(`\`${escapeRegex(stem)}\``);
51
+ for (const [docName, lines] of docs) {
52
+ for (let i = 0; i < lines.length; i++) {
53
+ const line = lines[i];
54
+ let kind = null;
55
+ if (line.includes(normalized)) kind = 'path';
56
+ else if (line.includes(base)) kind = 'basename';
57
+ else if (stemRe.test(line)) kind = 'module';
58
+ if (kind) {
59
+ refs.push({ doc: docName, line: i + 1, kind });
60
+ }
61
+ }
62
+ }
63
+ return refs;
64
+ }
65
+
66
+ export function runImpact(projectDir, _config, flags) {
67
+ const isJson = flags.format === 'json';
68
+ const since = flags.since || 'HEAD~1';
69
+
70
+ if (!isGitRepo(projectDir)) {
71
+ if (isJson) {
72
+ console.log(JSON.stringify({ since, error: 'not a git repository', changedFiles: [], affectedDocs: [] }, null, 2));
73
+ } else {
74
+ console.error(`${c.red}Not a git repository — impact requires git history.${c.reset}`);
75
+ }
76
+ process.exit(1);
77
+ }
78
+
79
+ const changed = changedFilesSince(projectDir, since);
80
+ // Filter to code files only — markdown/json/yaml changes don't have "doc
81
+ // impact" in the same sense; they ARE the docs (or config).
82
+ const codeChanged = changed.filter(f => CODE_EXTENSIONS.test(f));
83
+
84
+ // Index canonical docs once
85
+ const docsDir = resolve(projectDir, 'docs-canonical');
86
+ const docsIndex = new Map(); // docName → lines[]
87
+ if (existsSync(docsDir)) {
88
+ try {
89
+ for (const f of readdirSync(docsDir)) {
90
+ if (!f.endsWith('.md')) continue;
91
+ try {
92
+ const content = readFileSync(resolve(docsDir, f), 'utf-8');
93
+ docsIndex.set(f, content.split('\n'));
94
+ } catch { /* skip unreadable */ }
95
+ }
96
+ } catch { /* skip if dir unreadable */ }
97
+ }
98
+
99
+ // Compute per-file references
100
+ const fileImpact = []; // { file, references: [{doc, line, kind}] }
101
+ for (const f of codeChanged) {
102
+ fileImpact.push({ file: f, references: findReferences(f, docsIndex) });
103
+ }
104
+
105
+ // Roll up: which docs are affected, with all source files
106
+ const docMap = new Map(); // doc → Set<file>
107
+ for (const { file, references } of fileImpact) {
108
+ for (const r of references) {
109
+ if (!docMap.has(r.doc)) docMap.set(r.doc, new Set());
110
+ docMap.get(r.doc).add(file);
111
+ }
112
+ }
113
+ const affectedDocs = Array.from(docMap.entries()).map(([doc, files]) => ({
114
+ doc,
115
+ files: Array.from(files),
116
+ }));
117
+
118
+ // ── JSON output ──
119
+ if (isJson) {
120
+ console.log(JSON.stringify({
121
+ since,
122
+ changedFiles: codeChanged,
123
+ ignoredFiles: changed.filter(f => !CODE_EXTENSIONS.test(f)),
124
+ affectedDocs,
125
+ timestamp: new Date().toISOString(),
126
+ }, null, 2));
127
+ return;
128
+ }
129
+
130
+ // ── Text output ──
131
+ console.log(`${c.bold}📊 DocGuard Impact${c.reset} ${c.dim}(since ${since})${c.reset}\n`);
132
+
133
+ if (changed.length === 0) {
134
+ console.log(` ${c.green}✅ No file changes since ${since}.${c.reset}`);
135
+ return;
136
+ }
137
+ if (codeChanged.length === 0) {
138
+ console.log(` ${c.dim}No code files changed (${changed.length} non-code files: ${changed.slice(0, 3).join(', ')}${changed.length > 3 ? '…' : ''}).${c.reset}`);
139
+ return;
140
+ }
141
+
142
+ console.log(` ${c.cyan}${codeChanged.length}${c.reset} code file(s) changed.\n`);
143
+
144
+ if (affectedDocs.length === 0) {
145
+ console.log(` ${c.yellow}⚠ No canonical docs reference any of the changed files.${c.reset}`);
146
+ console.log(` ${c.dim}This often means the changed code is undocumented. Consider:${c.reset}`);
147
+ console.log(` ${c.dim} - Running ${c.cyan}docguard generate --plan${c.dim} to add doc skeletons${c.reset}`);
148
+ console.log(` ${c.dim} - Reviewing whether the change belongs in an existing doc${c.reset}`);
149
+ return;
150
+ }
151
+
152
+ console.log(` ${c.green}${affectedDocs.length}${c.reset} canonical doc(s) reference the changed files:\n`);
153
+ for (const { doc, files } of affectedDocs) {
154
+ console.log(` ${c.cyan}${doc}${c.reset} ${c.dim}(${files.length} file${files.length > 1 ? 's' : ''})${c.reset}`);
155
+ for (const f of files.slice(0, 5)) {
156
+ console.log(` ${c.dim}via${c.reset} ${f}`);
157
+ }
158
+ if (files.length > 5) console.log(` ${c.dim}... ${files.length - 5} more${c.reset}`);
159
+ }
160
+
161
+ // List code files with NO doc references — these may need new docs
162
+ const orphaned = fileImpact.filter(fi => fi.references.length === 0).map(fi => fi.file);
163
+ if (orphaned.length > 0) {
164
+ console.log(`\n ${c.yellow}${orphaned.length} changed file(s) have NO canonical doc reference:${c.reset}`);
165
+ for (const f of orphaned.slice(0, 5)) console.log(` ${c.dim}• ${f}${c.reset}`);
166
+ if (orphaned.length > 5) console.log(` ${c.dim}... ${orphaned.length - 5} more${c.reset}`);
167
+ console.log(` ${c.dim}These may be undocumented — review whether they belong in an existing doc.${c.reset}`);
168
+ }
169
+ }
@@ -124,6 +124,65 @@ function applyCliUpgrade() {
124
124
  return r;
125
125
  }
126
126
 
127
+ /**
128
+ * v0.14-P4: open a PR with the schema migration. Used when the team wants
129
+ * a reviewable change instead of an in-place edit. Requires `gh` CLI on
130
+ * PATH. Returns { ok: bool, prUrl?: string, error?: string }.
131
+ */
132
+ function openUpgradePR(projectDir, migratedConfig, fromVersion, toVersion) {
133
+ // Pre-flight: gh must be installed
134
+ const which = spawnSync('which', ['gh'], { encoding: 'utf-8' });
135
+ if (which.status !== 0) {
136
+ return { ok: false, error: 'gh CLI not found. Install: https://cli.github.com' };
137
+ }
138
+
139
+ const branch = `docguard/upgrade-schema-${toVersion}-${Date.now().toString(36)}`;
140
+ // Branch off current HEAD
141
+ let r = spawnSync('git', ['checkout', '-b', branch], { cwd: projectDir, encoding: 'utf-8' });
142
+ if (r.status !== 0) return { ok: false, error: `git checkout failed: ${r.stderr || r.stdout}` };
143
+
144
+ // Write the migrated config
145
+ try {
146
+ writeFileSync(
147
+ resolve(projectDir, '.docguard.json'),
148
+ JSON.stringify(migratedConfig, null, 2) + '\n',
149
+ 'utf-8'
150
+ );
151
+ } catch (e) {
152
+ return { ok: false, error: `write .docguard.json failed: ${e.message}` };
153
+ }
154
+
155
+ // Commit
156
+ r = spawnSync('git', ['add', '.docguard.json'], { cwd: projectDir, encoding: 'utf-8' });
157
+ if (r.status !== 0) return { ok: false, error: `git add failed: ${r.stderr}` };
158
+
159
+ const commitMsg = `chore(docguard): migrate .docguard.json schema ${fromVersion} → ${toVersion}\n\nAutomated migration via \`docguard upgrade --apply --pr\`.`;
160
+ r = spawnSync('git', ['commit', '-m', commitMsg], { cwd: projectDir, encoding: 'utf-8' });
161
+ if (r.status !== 0) return { ok: false, error: `git commit failed: ${r.stderr || r.stdout}` };
162
+
163
+ // Push
164
+ r = spawnSync('git', ['push', '-u', 'origin', branch], { cwd: projectDir, encoding: 'utf-8' });
165
+ if (r.status !== 0) return { ok: false, error: `git push failed: ${r.stderr || r.stdout}` };
166
+
167
+ // Open PR
168
+ const prBody =
169
+ `Automated schema migration from \`${fromVersion}\` → \`${toVersion}\`.\n\n` +
170
+ `This PR was opened by \`docguard upgrade --apply --pr\`. It updates the\n` +
171
+ `\`.docguard.json\` schema version and any additive fields the new schema\n` +
172
+ `introduces (e.g. \`severity: {}\` for v0.5).\n\n` +
173
+ `Review and merge to keep your team's DocGuard config in sync.\n\n` +
174
+ `> 🤖 Generated by [DocGuard](https://github.com/raccioly/docguard)`;
175
+ r = spawnSync('gh', [
176
+ 'pr', 'create',
177
+ '--title', `chore(docguard): migrate schema ${fromVersion} → ${toVersion}`,
178
+ '--body', prBody,
179
+ ], { cwd: projectDir, encoding: 'utf-8' });
180
+ if (r.status !== 0) return { ok: false, error: `gh pr create failed: ${r.stderr || r.stdout}` };
181
+
182
+ const prUrl = (r.stdout || '').trim().split('\n').pop();
183
+ return { ok: true, prUrl };
184
+ }
185
+
127
186
  export async function runUpgrade(projectDir, _config, flags) {
128
187
  const checkOnly = flags.checkOnly || flags['check-only'];
129
188
  const apply = flags.apply;
@@ -222,8 +281,23 @@ export async function runUpgrade(projectDir, _config, flags) {
222
281
  const cfg = JSON.parse(readFileSync(cfgPath, 'utf-8'));
223
282
  const { changed, newConfig } = migrateSchema(cfg, projectSchema);
224
283
  if (changed) {
225
- writeFileSync(cfgPath, JSON.stringify(newConfig, null, 2) + '\n', 'utf-8');
226
- console.log(` ${c.green}✓ Schema migrated ${projectSchema} ${newConfig.version}.${c.reset}`);
284
+ // v0.14-P4: --pr opens a PR for review instead of in-place editing.
285
+ // Useful when the team wants a reviewable diff or has branch-protected
286
+ // .docguard.json. Falls back to in-place if pre-flight fails.
287
+ if (flags.pr) {
288
+ console.log(` ${c.dim}Opening PR with migrated config...${c.reset}`);
289
+ const pr = openUpgradePR(projectDir, newConfig, projectSchema, newConfig.version);
290
+ if (pr.ok) {
291
+ console.log(` ${c.green}✓ Schema migration PR opened:${c.reset} ${c.cyan}${pr.prUrl}${c.reset}`);
292
+ } else {
293
+ console.error(` ${c.red}✗ PR creation failed:${c.reset} ${pr.error}`);
294
+ console.log(` ${c.dim}Tip: run without --pr to apply in place, or fix the underlying issue.${c.reset}`);
295
+ process.exit(1);
296
+ }
297
+ } else {
298
+ writeFileSync(cfgPath, JSON.stringify(newConfig, null, 2) + '\n', 'utf-8');
299
+ console.log(` ${c.green}✓ Schema migrated ${projectSchema} → ${newConfig.version}.${c.reset}`);
300
+ }
227
301
  } else {
228
302
  console.log(` ${c.dim}Schema migration was a no-op (no recipe registered yet for ${projectSchema} → ${CURRENT_SCHEMA_VERSION}).${c.reset}`);
229
303
  }
@@ -41,6 +41,7 @@ import { runTrace } from './commands/trace.mjs';
41
41
  import { runLlms } from './commands/llms.mjs';
42
42
  import { runSetup } from './commands/setup.mjs';
43
43
  import { runUpgrade } from './commands/upgrade.mjs';
44
+ import { runImpact } from './commands/impact.mjs';
44
45
  import { ensureSkills } from './ensure-skills.mjs';
45
46
 
46
47
  // ── Shared constants (imported to break circular dependencies) ──────────
@@ -385,6 +386,15 @@ async function main() {
385
386
  flags.reverse = true;
386
387
  } else if (args[i] === '--history') {
387
388
  flags.history = true;
389
+ } else if (args[i] === '--force-redo') {
390
+ flags.forceRedo = true;
391
+ } else if (args[i] === '--pr') {
392
+ flags.pr = true;
393
+ } else if (args[i] === '--timings' || args[i] === '--show-timings') {
394
+ // v0.14-Q2: per-validator timing display. Renamed from `--profile` to
395
+ // avoid collision with `docguard init --profile <name>`. `--show-timings`
396
+ // is the long form for users who prefer explicit verbs.
397
+ flags.timings = true;
388
398
  } else if (!args[i].startsWith('--') && i > 0) {
389
399
  // Positional args go into flags.args for commands that take them (e.g.
390
400
  // `docguard trace --reverse <path>`). Skip the command itself (i === 0).
@@ -514,6 +524,9 @@ async function main() {
514
524
  case 'update':
515
525
  await runUpgrade(projectDir, config, flags);
516
526
  break;
527
+ case 'impact':
528
+ runImpact(projectDir, config, flags);
529
+ break;
517
530
  default:
518
531
  console.error(`${c.red}Unknown command: ${command}${c.reset}`);
519
532
  console.log(`Run ${c.cyan}docguard --help${c.reset} for usage.`);
@@ -254,6 +254,16 @@ export function grepEnvUsage(projectDir, config = {}) {
254
254
  }
255
255
  };
256
256
 
257
+ // v0.14-P2: when config.changedFiles is populated (by --changed-only),
258
+ // restrict the scan to ONLY those paths. Skips the recursive tree walk
259
+ // entirely — turns "scan 5000 files" into "scan 3 files" in pre-commit mode.
260
+ if (Array.isArray(config.changedFiles) && config.changedFiles.length > 0) {
261
+ for (const rel of config.changedFiles) {
262
+ visit(resolve(projectDir, rel));
263
+ }
264
+ return names;
265
+ }
266
+
257
267
  for (const root of roots) walk(root);
258
268
  return names;
259
269
  }
@@ -192,6 +192,22 @@ export function validateApiSurface(projectDir, config) {
192
192
  const warnings = [];
193
193
  const fixes = [];
194
194
 
195
+ // v0.14-P2: when --changed-only scoping is active and NONE of the changed
196
+ // files look like route/spec/controller files, this validator has nothing
197
+ // to add — return N/A so the lite-mode total reflects only what was actually
198
+ // checked. Route patterns mirror the SECTION_FILE_MATCHERS in sync.mjs.
199
+ if (Array.isArray(config.changedFiles)) {
200
+ const ROUTE_RE = /(^|\/)(routes|controllers|handlers|app\/api)\/|openapi|swagger/i;
201
+ const anyRouteFile = config.changedFiles.some(f => ROUTE_RE.test(f));
202
+ if (!anyRouteFile) {
203
+ return {
204
+ errors, warnings, passed: 0, total: 0, fixes,
205
+ applicable: false,
206
+ note: 'no route/spec files in changed set',
207
+ };
208
+ }
209
+ }
210
+
195
211
  const drift = computeApiSurfaceDrift(projectDir, config);
196
212
 
197
213
  // ── Multi-spec divergence (independent of the API-REFERENCE doc) ──