docguard-cli 0.15.3__tar.gz → 0.17.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.
- {docguard_cli-0.15.3/extensions/spec-kit-docguard → docguard_cli-0.17.0/.agent}/skills/docguard-fix/SKILL.md +2 -2
- {docguard_cli-0.15.3/extensions/spec-kit-docguard → docguard_cli-0.17.0/.agent}/skills/docguard-guard/SKILL.md +3 -3
- {docguard_cli-0.15.3/extensions/spec-kit-docguard → docguard_cli-0.17.0/.agent}/skills/docguard-review/SKILL.md +2 -2
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.agent/skills/docguard-score/SKILL.md +2 -2
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.agent/skills/docguard-sync/SKILL.md +1 -1
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/CHANGELOG.md +71 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/PKG-INFO +1 -1
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/commands/diff.mjs +32 -6
- docguard_cli-0.17.0/cli/commands/explain.mjs +286 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/commands/guard.mjs +101 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/commands/hooks.mjs +82 -13
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/commands/init.mjs +5 -1
- docguard_cli-0.17.0/cli/commands/memory.mjs +143 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/commands/score.mjs +9 -2
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/commands/trace.mjs +72 -25
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/docguard.mjs +76 -3
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/validators/environment.mjs +12 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/validators/structure.mjs +26 -4
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/commands/docguard.guard.md +2 -2
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/extensions/spec-kit-docguard/commands/guard.md +1 -1
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/extensions/spec-kit-docguard/extension.yml +2 -2
- {docguard_cli-0.15.3/.agent → docguard_cli-0.17.0/extensions/spec-kit-docguard}/skills/docguard-fix/SKILL.md +2 -2
- {docguard_cli-0.15.3/.agent → docguard_cli-0.17.0/extensions/spec-kit-docguard}/skills/docguard-guard/SKILL.md +3 -3
- {docguard_cli-0.15.3/.agent → docguard_cli-0.17.0/extensions/spec-kit-docguard}/skills/docguard-review/SKILL.md +2 -2
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/extensions/spec-kit-docguard/skills/docguard-score/SKILL.md +2 -2
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/extensions/spec-kit-docguard/skills/docguard-sync/SKILL.md +1 -1
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/extensions/spec-kit-docguard/templates/github-workflows/docguard-guard.yml +1 -1
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/package.json +1 -1
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/pyproject.toml +1 -1
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/commands/docguard.guard.md +2 -2
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/hooks.test.mjs +42 -5
- docguard_cli-0.17.0/tests/section-na-markers.test.mjs +91 -0
- docguard_cli-0.17.0/tests/trace-multilang.test.mjs +139 -0
- docguard_cli-0.17.0/tests/validator-naming.test.mjs +104 -0
- docguard_cli-0.17.0/tests/version-pin.test.mjs +91 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.agent/commands/speckit.analyze.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.agent/commands/speckit.checklist.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.agent/commands/speckit.clarify.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.agent/commands/speckit.constitution.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.agent/commands/speckit.implement.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.agent/commands/speckit.plan.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.agent/commands/speckit.specify.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.agent/commands/speckit.tasks.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.agent/commands/speckit.taskstoissues.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.agent/skills/speckit-analyze/SKILL.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.agent/skills/speckit-checklist/SKILL.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.agent/skills/speckit-clarify/SKILL.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.agent/skills/speckit-constitution/SKILL.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.agent/skills/speckit-implement/SKILL.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.agent/skills/speckit-plan/SKILL.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.agent/skills/speckit-specify/SKILL.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.agent/skills/speckit-tasks/SKILL.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.agent/skills/speckit-taskstoissues/SKILL.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.docguard.json +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.docguardignore +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.github/dependabot.yml +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.github/scripts/patch-catalog.py +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.github/workflows/ci.yml +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.github/workflows/release.yml +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.github/workflows/supply-chain.yml +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.github/workflows/sync-speckit-catalog.yml +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.gitignore +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.jules/bolt.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.jules/palette.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.jules/sentinel.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.npmignore +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.npmrc +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.specify/extensions/.cache/catalog-ebf165086500aab1-metadata.json +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.specify/extensions/.cache/catalog-ebf165086500aab1.json +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.specify/extensions/.cache/catalog-metadata.json +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.specify/extensions/.cache/catalog.json +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.specify/init-options.json +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.specify/memory/constitution.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.specify/scripts/bash/check-prerequisites.sh +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.specify/scripts/bash/common.sh +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.specify/scripts/bash/create-new-feature.sh +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.specify/scripts/bash/setup-plan.sh +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.specify/scripts/bash/update-agent-context.sh +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.specify/templates/agent-file-template.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.specify/templates/checklist-template.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.specify/templates/constitution-template.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.specify/templates/plan-template.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.specify/templates/spec-template.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/.specify/templates/tasks-template.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/AGENTS.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/CODE_OF_CONDUCT.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/COMPARISONS.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/CONTRIBUTING.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/DRIFT-LOG.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/LICENSE +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/PHILOSOPHY.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/README.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/ROADMAP.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/SECURITY.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/STANDARD.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/SUPPLY-CHAIN-AUDIT.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/SUPPORT.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/action.yml +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/commands/agents.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/commands/badge.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/commands/ci.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/commands/diagnose.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/commands/fix.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/commands/generate.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/commands/impact.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/commands/llms.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/commands/publish.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/commands/setup.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/commands/sync.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/commands/upgrade.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/commands/watch.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/ensure-skills.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/scanners/api-doc.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/scanners/cdk.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/scanners/doc-tools.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/scanners/frontend.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/scanners/iac.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/scanners/integrations.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/scanners/memory-plan.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/scanners/project-type.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/scanners/routes.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/scanners/schemas.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/scanners/speckit.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/shared-git.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/shared-ignore.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/shared-source.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/shared.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/validators/api-surface.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/validators/architecture.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/validators/changelog.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/validators/cross-reference.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/validators/doc-quality.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/validators/docs-coverage.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/validators/docs-diff.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/validators/docs-sync.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/validators/drift.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/validators/freshness.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/validators/generated-staleness.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/validators/metadata-sync.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/validators/metrics-consistency.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/validators/schema-sync.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/validators/security.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/validators/test-spec.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/validators/todo-tracking.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/validators/traceability.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/writers/api-reference.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/writers/fix-memory.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/writers/mechanical.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/cli/writers/sections.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/commands/docguard.fix.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/commands/docguard.review.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/commands/docguard.score.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/configs/fastify.json +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/configs/generic.json +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/configs/nextjs.json +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/configs/python.json +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/docguard_cli/__init__.py +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/docguard_cli/wrapper.py +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/docs/ai-integration.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/docs/commands.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/docs/configuration.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/docs/doc-sections.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/docs/faq.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/docs/installation.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/docs/profiles.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/docs/quickstart.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/docs-canonical/ARCHITECTURE.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/docs-canonical/CI-RECIPES.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/docs-canonical/DATA-MODEL.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/docs-canonical/ENVIRONMENT.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/docs-canonical/SECURITY.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/docs-canonical/TEST-SPEC.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/examples/01-express-api/README.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/examples/01-express-api/package.json +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/examples/01-express-api/server.js +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/examples/02-python-flask/README.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/examples/02-python-flask/app.py +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/examples/02-python-flask/docs-canonical/ARCHITECTURE.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/examples/02-python-flask/requirements.txt +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/examples/03-spec-kit-project/CHANGELOG.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/examples/03-spec-kit-project/README.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/examples/03-spec-kit-project/docs-canonical/ARCHITECTURE.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/examples/03-spec-kit-project/docs-canonical/TEST-SPEC.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/examples/03-spec-kit-project/package.json +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/examples/03-spec-kit-project/src/index.js +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/examples/03-spec-kit-project/tests/basic.test.js +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/examples/README.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/extensions/spec-kit-docguard/LICENSE +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/extensions/spec-kit-docguard/README.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/extensions/spec-kit-docguard/commands/diagnose.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/extensions/spec-kit-docguard/commands/fix.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/extensions/spec-kit-docguard/commands/generate.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/extensions/spec-kit-docguard/commands/init.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/extensions/spec-kit-docguard/commands/score.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/extensions/spec-kit-docguard/commands/sync.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/extensions/spec-kit-docguard/commands/trace.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/extensions/spec-kit-docguard/scripts/bash/common.sh +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/extensions/spec-kit-docguard/scripts/bash/docguard-check-docs.sh +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/extensions/spec-kit-docguard/scripts/bash/docguard-init-doc.sh +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/extensions/spec-kit-docguard/scripts/bash/docguard-suggest-fix.sh +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/extensions/spec-kit-docguard/templates/extensions.yml +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/extensions/spec-kit-docguard/templates/github-workflows/docguard-autofix.yml +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/pr_description.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/schemas/docguard-config.schema.json +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/specs/001-fix-ignore-validators/plan.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/specs/001-fix-ignore-validators/spec.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/specs/001-fix-ignore-validators/tasks.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/specs/002-fix-test-discovery/plan.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/specs/002-fix-test-discovery/spec.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/specs/002-fix-test-discovery/tasks.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/specs/003-v011-false-positives/plan.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/specs/003-v011-false-positives/spec.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/specs/003-v011-false-positives/tasks.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/ADR.md.template +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/AGENTS.md.template +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/ARCHITECTURE.md.template +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/CHANGELOG.md.template +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/CURRENT-STATE.md.template +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/DATA-MODEL.md.template +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/DEPLOYMENT.md.template +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/DRIFT-LOG.md.template +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/ENVIRONMENT.md.template +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/KNOWN-GOTCHAS.md.template +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/REQUIREMENTS.md.template +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/ROADMAP.md.template +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/RUNBOOKS.md.template +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/SECURITY.md.template +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/TEST-SPEC.md.template +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/TROUBLESHOOTING.md.template +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/VENDOR-BUGS.md.template +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/ci/github-actions.yml +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/commands/docguard.fix.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/commands/docguard.init.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/commands/docguard.review.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/templates/commands/docguard.update.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/test-draft.js +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/test-metrics.js +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/anchor-autofix.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/api-doc.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/api-surface.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/api-write.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/architecture.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/backup-failure.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/cdk-detection.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/changed-only-scoping.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/changed-only.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/changelog.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/commands.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/cross-reference.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/doc-quality.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/docguardignore.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/docs-coverage.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/docs-diff.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/docs-sync.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/drift.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/environment.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/fix-memory.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/fix-suppression.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/fixture-projects.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/freshness.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/frontend-deep.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/frontend.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/generated-staleness.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/guard-classify.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/guard-no-throw.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/i18n.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/impact.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/integrations.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/mechanical.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/memory-plan.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/metadata-sync.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/metrics-consistency.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/metrics-dedup.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/monorepo-scanning.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/multi-spec.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/patch-0.11.2.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/profile-flag.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/project-type.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/regenerate-section.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/routes-multilang.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/schema-sync.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/schemas-multilang.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/schemas.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/scoping-extended.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/sections.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/security.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/severity.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/shared-git.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/shared-source.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/stress-test.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/structure.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/sweep-nudge.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/sync-since.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/sync.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/test-spec.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/todo-tracking.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/trace-reverse.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/traceability.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/upgrade-pr.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/tests/upgrade.test.mjs +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/vscode-extension/.vscodeignore +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/vscode-extension/README.md +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.0}/vscode-extension/extension.js +0 -0
- {docguard_cli-0.15.3 → docguard_cli-0.17.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.
|
|
9
|
+
version: 0.17.0
|
|
10
10
|
source: extensions/spec-kit-docguard/skills/docguard-fix
|
|
11
11
|
---
|
|
12
|
-
<!-- docguard:version: 0.
|
|
12
|
+
<!-- docguard:version: 0.17.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.
|
|
10
|
+
version: 0.17.0
|
|
11
11
|
source: extensions/spec-kit-docguard/skills/docguard-guard
|
|
12
12
|
---
|
|
13
|
-
<!-- docguard:version: 0.
|
|
13
|
+
<!-- docguard:version: 0.17.0 -->
|
|
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
|
|
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.
|
|
9
|
+
version: 0.17.0
|
|
10
10
|
source: extensions/spec-kit-docguard/skills/docguard-review
|
|
11
11
|
---
|
|
12
|
-
<!-- docguard:version: 0.
|
|
12
|
+
<!-- docguard:version: 0.17.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.
|
|
9
|
+
version: 0.17.0
|
|
10
10
|
source: extensions/spec-kit-docguard/skills/docguard-score
|
|
11
11
|
---
|
|
12
|
-
<!-- docguard:version: 0.
|
|
12
|
+
<!-- docguard:version: 0.17.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.
|
|
7
|
+
version: 0.17.0
|
|
8
8
|
source: extensions/spec-kit-docguard/skills/docguard-sync
|
|
9
9
|
---
|
|
10
10
|
|
|
@@ -7,6 +7,77 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.17.0] - 2026-05-26
|
|
11
|
+
|
|
12
|
+
Feature release picking up the 4 deferred items from v0.16 — **reproducibility
|
|
13
|
+
(version pin), accuracy drill-down (memory --diff), self-scaffolding drift fix,
|
|
14
|
+
and naming flexibility (kebab + camel both accepted)**. **530 tests** (was 519,
|
|
15
|
+
+11). 22 validators.
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- **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.
|
|
20
|
+
- **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.
|
|
21
|
+
- **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.
|
|
22
|
+
- **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.
|
|
23
|
+
|
|
24
|
+
### Internal
|
|
25
|
+
|
|
26
|
+
- **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).**
|
|
27
|
+
- **New module**: `cli/commands/memory.mjs` (~140 lines).
|
|
28
|
+
- **Exported from `cli/commands/diff.mjs`**: `diffRoutes`, `diffEntities`, `diffEnvVars`, `diffTechStack` so `memory.mjs` can reuse them without duplicating logic.
|
|
29
|
+
- **New helpers in `cli/docguard.mjs`**: `normalizeConfig()`, `_kebabToCamel()`, `_KNOWN_VALIDATORS`.
|
|
30
|
+
- **New helpers in `cli/commands/guard.mjs`**: `_parseSemver`, `_semverCompare`, `_checkVersionPin`, `_updateVersionPin`.
|
|
31
|
+
- **Templates scrubbed** of numeric validator counts (6 files).
|
|
32
|
+
- Dry-run on a real client project: 99% memory accuracy, 3 specific env-var mismatches surfaced by `memory --diff`.
|
|
33
|
+
- No new NPM deps.
|
|
34
|
+
|
|
35
|
+
### Out of scope (deferred to v0.18)
|
|
36
|
+
|
|
37
|
+
- **F6** stale score cache — still low repro confidence; deferred until we get a reliable reproducer.
|
|
38
|
+
- **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.
|
|
39
|
+
|
|
40
|
+
## [0.16.0] - 2026-05-26
|
|
41
|
+
|
|
42
|
+
Feature release driven entirely by feedback from a real Python project running
|
|
43
|
+
DocGuard for the first time. **8 user-reported items shipped, 519 tests** (was
|
|
44
|
+
497, +22). 22 validators. The Python user's top two asks (language-aware
|
|
45
|
+
TRACE_MAP, hook-overwrite protection) are both in.
|
|
46
|
+
|
|
47
|
+
### Fixed
|
|
48
|
+
|
|
49
|
+
- **P1 — JSON+ANSI bleed in `score`/`trace`/`diff` `--format json`.** Critical CI bug. The v0.12 headless-mode fix only covered `guard` and (later) `diagnose`; three other commands leaked colored banners before the JSON body, breaking `jq` / `python -c "json.loads(...)"` pipelines. All five JSON-emitting commands now produce clean parseable output.
|
|
50
|
+
- **P4 — `docguard diff` false positive on system env vars.** Backticked mentions of `PATH`, `HOME`, `USER`, `SHELL`, etc. inside ENVIRONMENT.md prose ("the venv `PATH`") were flagged as documented-but-not-implemented user env vars. Added a `SYSTEM_ENV_VARS` denylist to both `diff` and the `Environment` validator. The 30-name list covers OS/shell/CI vars; user-app names (`DATABASE_URL`, `API_KEY`, etc.) still count as documented.
|
|
51
|
+
|
|
52
|
+
### Added
|
|
53
|
+
|
|
54
|
+
- **P2 — Language-aware `TRACE_MAP`** (top user ask). The original JS/TS-only patterns false-negatived on Python (`test_*.py`), Rust (`tests/*.rs`), Go (`*_test.go`), Java (`*Test.java`), Ruby (`*_spec.rb`), and PHP test layouts. Every `TRACE_MAP` entry — Test files, Entry points, Config files, Schemas, Env files — now matches the equivalent patterns across ecosystems. New `tests/trace-multilang.test.mjs` (16 tests) locks the cross-language matching in.
|
|
55
|
+
- **P3 — Hook overwrite protection** (2nd user ask). `docguard hooks --type pre-commit` previously clobbered user customizations on re-install. Now wraps DocGuard's content in `# BEGIN DOCGUARD MANAGED — do not edit between these markers` / `# END DOCGUARD MANAGED` markers and **splices only the managed block** on re-install, preserving everything around it. Legacy pre-v0.16 hooks (no markers) prompt the user to re-run with `--force` to upgrade. Third-party pre-existing hooks refuse to clobber without `--force`.
|
|
56
|
+
- **P5 — `--quiet` / `-q` flag.** Suppresses the banner + ensureSkills decorative line. Useful inside git hooks and CI loops where the 5-line banner becomes 30 lines of noise. Doesn't affect validator output itself.
|
|
57
|
+
- **P6 — `docguard explain <warning>` command** (user wishlist). Paste any warning text and get back: which validator emitted it, what triggered it, how to fix, a passing example, and the standard it references. Cuts source-spelunking time from 5-10 minutes to seconds. Covers all 16 validators. Also accepts a validator key directly (`docguard explain freshness`). JSON mode for tooling.
|
|
58
|
+
- **P7 — N/A markers for required doc sections.** A project that legitimately has no auth (CLI, library, internal tool) can now declare it via `<!-- docguard:section authentication n/a — CLI tool, no user accounts -->` instead of writing "Absent by design" boilerplate. The marker requires a reason (non-empty after the dash) so it can't be a silent opt-out. Doc-Sections counts the marked section as passed.
|
|
59
|
+
- **P8 — `--no-spec-kit` flag for `init`.** Default-on stays for discoverability, but minimalist library projects can now skip the `.specify/`, `.agent/`, `commands/` scaffolding entirely with `docguard init --no-spec-kit`.
|
|
60
|
+
|
|
61
|
+
### Internal
|
|
62
|
+
|
|
63
|
+
- **3 new test files**: `tests/trace-multilang.test.mjs` (16), `tests/section-na-markers.test.mjs` (5), plus expanded `tests/hooks.test.mjs` (+2 for managed-block). **Total: 497 → 519 tests (+22 new).**
|
|
64
|
+
- New top-level command: `cli/commands/explain.mjs` with a 16-validator explainer table.
|
|
65
|
+
- New helpers in `cli/commands/hooks.mjs`: `wrapManaged()`, `spliceManagedBlock()`, `BEGIN_MARKER`, `END_MARKER`.
|
|
66
|
+
- New `SYSTEM_ENV_VARS` constant exported from `cli/commands/diff.mjs` (mirrored in `cli/validators/environment.mjs`).
|
|
67
|
+
- Headless-mode flag check (`flags.quiet`) added to the main dispatcher.
|
|
68
|
+
- No new NPM deps.
|
|
69
|
+
|
|
70
|
+
### Out of scope (deferred to v0.17)
|
|
71
|
+
|
|
72
|
+
User feedback items NOT addressed in this release:
|
|
73
|
+
|
|
74
|
+
- **F6 — Score "Top improvements" cache** (low repro confidence — user cleared on the next run, may have been observer effect).
|
|
75
|
+
- **F7 — Validator count drift in tool's own scaffolding** (philosophical: counts ARE accurate per-run; the issue is that DocGuard's OWN docs mention the count and naturally drift as validators are added. Could compute at runtime; defer for now.)
|
|
76
|
+
- **F8 — Version pin in `.docguard.json`** (CDD reproducibility — record the DocGuard version that last passed). Medium effort, real value.
|
|
77
|
+
- **F10 — Memory accuracy drill-down** (`docguard memory --diff` to show which claims don't match code). Bigger feature.
|
|
78
|
+
- **N1 — Validator naming consistency** (`testSpec` JSON key / `test-spec` CLI flag / `Test-Spec` display). Breaking change; needs migration story.
|
|
79
|
+
- **N3 — `--tax` fold** (philosophical: `--tax` does add information, just not enough to feel different).
|
|
80
|
+
|
|
10
81
|
## [0.15.3] - 2026-05-26
|
|
11
82
|
|
|
12
83
|
Repo hygiene release — scrubbed a client-specific project name from public artifacts.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: docguard-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.17.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
|
|
@@ -25,8 +25,12 @@ const CODE_EXTENSIONS = new Set([
|
|
|
25
25
|
]);
|
|
26
26
|
|
|
27
27
|
export function runDiff(projectDir, config, flags) {
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
// v0.16-P1: headless mode for JSON output (matches guard/score/trace fix).
|
|
29
|
+
const isJson = flags.format === 'json';
|
|
30
|
+
if (!isJson) {
|
|
31
|
+
console.log(`${c.bold}🔍 DocGuard Diff — ${config.projectName}${c.reset}`);
|
|
32
|
+
console.log(`${c.dim} Directory: ${projectDir}${c.reset}\n`);
|
|
33
|
+
}
|
|
30
34
|
|
|
31
35
|
const results = [];
|
|
32
36
|
|
|
@@ -97,7 +101,7 @@ export function runDiff(projectDir, config, flags) {
|
|
|
97
101
|
|
|
98
102
|
// ── Diff Functions ─────────────────────────────────────────────────────────
|
|
99
103
|
|
|
100
|
-
function diffRoutes(dir, config = {}) {
|
|
104
|
+
export function diffRoutes(dir, config = {}) {
|
|
101
105
|
// Documented surface: prefer the dedicated API reference, fall back to ARCHITECTURE.md.
|
|
102
106
|
const apiRefPath = resolve(dir, 'docs-canonical/API-REFERENCE.md');
|
|
103
107
|
const archPath = resolve(dir, 'docs-canonical/ARCHITECTURE.md');
|
|
@@ -129,7 +133,7 @@ const CODE_ENTITY_NOISE = new Set([
|
|
|
129
133
|
'models', 'model', 'utils', 'helpers', 'constants', 'config', 'common', 'base',
|
|
130
134
|
]);
|
|
131
135
|
|
|
132
|
-
function diffEntities(dir, config = {}) {
|
|
136
|
+
export function diffEntities(dir, config = {}) {
|
|
133
137
|
const dataModelPath = resolve(dir, 'docs-canonical/DATA-MODEL.md');
|
|
134
138
|
if (!existsSync(dataModelPath)) return null;
|
|
135
139
|
|
|
@@ -196,7 +200,26 @@ function diffEntities(dir, config = {}) {
|
|
|
196
200
|
};
|
|
197
201
|
}
|
|
198
202
|
|
|
199
|
-
|
|
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".
|
|
208
|
+
//
|
|
209
|
+
// Conservative list — only the names that are unambiguously OS/shell vars.
|
|
210
|
+
// Application names like `DATABASE_URL`, `API_KEY` etc. still count.
|
|
211
|
+
const SYSTEM_ENV_VARS = new Set([
|
|
212
|
+
'PATH', 'HOME', 'USER', 'USERNAME', 'SHELL', 'PWD', 'OLDPWD', 'TMPDIR', 'TEMP', 'TMP',
|
|
213
|
+
'LANG', 'LC_ALL', 'LC_CTYPE', 'LC_MESSAGES', 'TZ',
|
|
214
|
+
'EDITOR', 'VISUAL', 'PAGER', 'TERM', 'COLORTERM',
|
|
215
|
+
'DISPLAY', 'SSH_AUTH_SOCK', 'SSH_CONNECTION', 'SSH_TTY',
|
|
216
|
+
'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
|
|
220
|
+
]);
|
|
221
|
+
|
|
222
|
+
export function diffEnvVars(dir, config = {}) {
|
|
200
223
|
const envDocPath = resolve(dir, 'docs-canonical/ENVIRONMENT.md');
|
|
201
224
|
if (!existsSync(envDocPath)) return null;
|
|
202
225
|
|
|
@@ -208,6 +231,9 @@ function diffEnvVars(dir, config = {}) {
|
|
|
208
231
|
const varRegex = /`([A-Z][A-Z0-9_]*[A-Z0-9])`/g;
|
|
209
232
|
let match;
|
|
210
233
|
while ((match = varRegex.exec(content)) !== null) {
|
|
234
|
+
// v0.16-P4: skip backticked system vars that appear in prose. They're
|
|
235
|
+
// never user-set application env vars; flagging them produces noise.
|
|
236
|
+
if (SYSTEM_ENV_VARS.has(match[1])) continue;
|
|
211
237
|
docVars.add(match[1]);
|
|
212
238
|
}
|
|
213
239
|
|
|
@@ -237,7 +263,7 @@ function diffEnvVars(dir, config = {}) {
|
|
|
237
263
|
};
|
|
238
264
|
}
|
|
239
265
|
|
|
240
|
-
function diffTechStack(dir, config = {}) {
|
|
266
|
+
export function diffTechStack(dir, config = {}) {
|
|
241
267
|
const archPath = resolve(dir, 'docs-canonical/ARCHITECTURE.md');
|
|
242
268
|
if (!existsSync(archPath)) return null;
|
|
243
269
|
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Explain Command — v0.16-P6.
|
|
3
|
+
*
|
|
4
|
+
* Asked for by a user who'd spent 5-10 minutes per warning spelunking
|
|
5
|
+
* through validators/*.mjs source to understand what the validator wanted.
|
|
6
|
+
* `docguard explain "<warning text>"` matches the warning back to its
|
|
7
|
+
* validator and prints:
|
|
8
|
+
* - Which validator emitted it
|
|
9
|
+
* - What pattern triggered it
|
|
10
|
+
* - A passing example
|
|
11
|
+
* - The doc / spec / standard it's checking against
|
|
12
|
+
*
|
|
13
|
+
* Also supports `docguard explain <validator-key>` to show the whole
|
|
14
|
+
* validator's purpose without needing a specific warning.
|
|
15
|
+
*
|
|
16
|
+
* Zero NPM dependencies. Pure lookup table.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { c } from '../shared.mjs';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Validator-key → human-readable explainer. Keyed by the same key DocGuard
|
|
23
|
+
* uses internally for severity overrides + lite-mode selection.
|
|
24
|
+
*
|
|
25
|
+
* Each entry has:
|
|
26
|
+
* - title: one-line summary
|
|
27
|
+
* - what: what the validator checks (declarative)
|
|
28
|
+
* - why: why it matters (motivation)
|
|
29
|
+
* - triggers: array of common warning fragments and what each means
|
|
30
|
+
* - example: a tiny passing snippet
|
|
31
|
+
* - standard: the spec/practice the validator references
|
|
32
|
+
*/
|
|
33
|
+
const EXPLAINERS = {
|
|
34
|
+
structure: {
|
|
35
|
+
title: 'Structure — required CDD files exist',
|
|
36
|
+
what: 'Verifies the canonical files declared in .docguard.json `requiredFiles.canonical` are present, plus AGENTS.md/CLAUDE.md, CHANGELOG.md, DRIFT-LOG.md.',
|
|
37
|
+
why: 'A documentation memory needs known anchor points. Missing files = broken memory.',
|
|
38
|
+
triggers: [
|
|
39
|
+
['Missing required file', 'A canonical doc declared in your config doesn\'t exist on disk. Create it or remove it from `requiredFiles.canonical`.'],
|
|
40
|
+
['Missing agent file', 'No AGENTS.md or CLAUDE.md found. Create one — even a stub establishes the agent contract.'],
|
|
41
|
+
],
|
|
42
|
+
example: 'docs-canonical/ARCHITECTURE.md, AGENTS.md, CHANGELOG.md all present',
|
|
43
|
+
standard: 'CDD STANDARD (this project\'s STANDARD.md)',
|
|
44
|
+
},
|
|
45
|
+
docsSync: {
|
|
46
|
+
title: 'Docs-Sync — code files are referenced in canonical docs',
|
|
47
|
+
what: 'Walks route/service files in your source tree. For each, checks that the file path or basename appears in any canonical doc.',
|
|
48
|
+
why: 'Code that exists but isn\'t mentioned in any doc is invisible to future contributors and AI agents.',
|
|
49
|
+
triggers: [
|
|
50
|
+
['not referenced in any canonical doc', 'A route or service file has no mention anywhere in docs-canonical/. Add a one-line reference (path or filename) to ARCHITECTURE.md or DATA-MODEL.md.'],
|
|
51
|
+
],
|
|
52
|
+
example: '`src/services/auth.ts` mentioned in ARCHITECTURE.md\'s Components table',
|
|
53
|
+
standard: 'arc42 Component Map',
|
|
54
|
+
},
|
|
55
|
+
drift: {
|
|
56
|
+
title: 'Drift-Comments — every `// DRIFT:` has a DRIFT-LOG entry',
|
|
57
|
+
what: 'Scans code for `// DRIFT: reason` comments (also # / /* / -- variants). Each must have a row in DRIFT-LOG.md.',
|
|
58
|
+
why: 'DRIFT comments document conscious deviations from canonical specs. Without log entries, the deviation is invisible.',
|
|
59
|
+
triggers: [
|
|
60
|
+
['DRIFT comment but DRIFT-LOG.md doesn\'t exist', 'Create DRIFT-LOG.md or remove the DRIFT comment.'],
|
|
61
|
+
['no matching DRIFT-LOG.md entry', 'Add a row to DRIFT-LOG.md documenting the deviation, OR remove the // DRIFT: comment if the deviation is no longer current.'],
|
|
62
|
+
],
|
|
63
|
+
example: '// DRIFT: using S3 SDK v2 here for compatibility — DRIFT-LOG.md has a row dated and explaining why',
|
|
64
|
+
standard: 'CDD principle: log every intentional deviation',
|
|
65
|
+
},
|
|
66
|
+
changelog: {
|
|
67
|
+
title: 'Changelog — Keep a Changelog format',
|
|
68
|
+
what: 'CHANGELOG.md must have a top-level `# Changelog` heading and an `## [Unreleased]` section.',
|
|
69
|
+
why: 'Standard format makes changelogs machine-readable. The Unreleased section is where new work accumulates between releases.',
|
|
70
|
+
triggers: [
|
|
71
|
+
['Missing # Changelog heading', 'Start CHANGELOG.md with `# Changelog`.'],
|
|
72
|
+
['Missing ## [Unreleased] section', 'Add `## [Unreleased]` between `# Changelog` and your first dated release.'],
|
|
73
|
+
],
|
|
74
|
+
example: '# Changelog\\n\\n## [Unreleased]\\n\\n## [1.0.0] - 2026-01-01',
|
|
75
|
+
standard: 'Keep a Changelog v1.1.0 (https://keepachangelog.com)',
|
|
76
|
+
},
|
|
77
|
+
testSpec: {
|
|
78
|
+
title: 'Test-Spec — declared tests exist',
|
|
79
|
+
what: 'Reads TEST-SPEC.md\'s test mapping (rows linking sources to test files) and verifies each referenced test file exists.',
|
|
80
|
+
why: 'A spec that claims test coverage for X but the test file is missing is a stale promise.',
|
|
81
|
+
triggers: [
|
|
82
|
+
['no service-to-test mappings', 'TEST-SPEC.md has no recognized mapping table. Add a table with `| Source | Test file | Status |` columns.'],
|
|
83
|
+
['referenced test file does not exist', 'A path in TEST-SPEC.md\'s mapping doesn\'t exist. Update the path or remove the row.'],
|
|
84
|
+
],
|
|
85
|
+
example: '| `src/auth.ts` | `tests/auth.test.ts` | ✅ |',
|
|
86
|
+
standard: 'ISO/IEC/IEEE 29119-3 (test specification)',
|
|
87
|
+
},
|
|
88
|
+
environment: {
|
|
89
|
+
title: 'Environment — env vars used in code are documented',
|
|
90
|
+
what: 'Greps `process.env.X` and `import.meta.env.X` (plus `os.environ` for Python) across source. Each name must appear in ENVIRONMENT.md or .env.example/.env.template.',
|
|
91
|
+
why: 'Undocumented env vars are runtime surprises waiting to happen.',
|
|
92
|
+
triggers: [
|
|
93
|
+
['used but not documented', 'Code reads an env var that ENVIRONMENT.md doesn\'t list. Add it to the table.'],
|
|
94
|
+
['VITE_API_URL or similar prefix', 'Naked prefixes like `VITE_` (no suffix) get filtered out — they\'re convention markers, not real var names.'],
|
|
95
|
+
],
|
|
96
|
+
example: '`DATABASE_URL` listed in ENVIRONMENT.md\'s Environment Variables table AND read via `process.env.DATABASE_URL` in code',
|
|
97
|
+
standard: '12-Factor App III. Config',
|
|
98
|
+
},
|
|
99
|
+
security: {
|
|
100
|
+
title: 'Security — secrets handling + auth presence',
|
|
101
|
+
what: 'Checks SECURITY.md for required sections, and scans code for committed secrets / unsafe patterns.',
|
|
102
|
+
why: 'OWASP ASVS baseline.',
|
|
103
|
+
triggers: [
|
|
104
|
+
['Missing "Authentication" section', 'Add `## Authentication` to SECURITY.md. If the project genuinely has no auth (CLI, library), use the v0.16-P7 N/A marker: `<!-- docguard:section authentication n/a — reason -->`.'],
|
|
105
|
+
['Possible secret', 'A pattern matching common secret formats (API keys, JWT secrets) was found in committed code. Move to env var or .env.example.'],
|
|
106
|
+
],
|
|
107
|
+
example: 'SECURITY.md has `## Authentication` describing JWT flow; no `sk_live_*` strings in code',
|
|
108
|
+
standard: 'OWASP ASVS v4.0',
|
|
109
|
+
},
|
|
110
|
+
freshness: {
|
|
111
|
+
title: 'Freshness — docs updated alongside code',
|
|
112
|
+
what: 'For each canonical doc, counts code commits since the doc\'s last commit. >10 commits = stale.',
|
|
113
|
+
why: 'Docs drift silently. This validator surfaces the drift before it becomes invisible.',
|
|
114
|
+
triggers: [
|
|
115
|
+
['code commits since last doc update', 'Run `docguard sync --write` to refresh code-truth sections, then review the prose for accuracy.'],
|
|
116
|
+
['DRIFT-LOG.md may be stale', 'DRIFT comments in code outpaced log entries. Add the entries.'],
|
|
117
|
+
],
|
|
118
|
+
example: 'ARCHITECTURE.md last committed within 10 code commits',
|
|
119
|
+
standard: 'CDD principle: docs and code commit together',
|
|
120
|
+
},
|
|
121
|
+
traceability: {
|
|
122
|
+
title: 'Traceability — every FR/SC ID has test coverage',
|
|
123
|
+
what: 'Scans specs/ for FR-### and SC-### requirement IDs. Each must appear in a test file as `@req FR-###`.',
|
|
124
|
+
why: 'Untraceable requirements drift from implementation.',
|
|
125
|
+
triggers: [
|
|
126
|
+
['has no test coverage', 'Add `// @req FR-012` (or similar) as a comment in the test that verifies the requirement.'],
|
|
127
|
+
['orphaned test reference', 'A `@req` comment references an ID that doesn\'t exist in any spec. Update the ID or remove the marker.'],
|
|
128
|
+
],
|
|
129
|
+
example: 'spec.md defines `**FR-012**: ...` and test file has `// @req FR-012` near the test that verifies it',
|
|
130
|
+
standard: 'ISO/IEC/IEEE 29148 (requirements traceability)',
|
|
131
|
+
},
|
|
132
|
+
apiSurface: {
|
|
133
|
+
title: 'API-Surface — endpoints in code match API-REFERENCE.md',
|
|
134
|
+
what: 'Compares routes scanned from code (Express, Next, FastAPI, Spring, etc.) against endpoints listed in API-REFERENCE.md and OpenAPI specs.',
|
|
135
|
+
why: 'Documented but missing endpoints are dead links. Endpoints in code that aren\'t documented are invisible.',
|
|
136
|
+
triggers: [
|
|
137
|
+
['documented but absent', 'API-REFERENCE.md lists an endpoint that scanRoutes() can\'t find. Remove or fix the doc; `fix --write` removes when marked.'],
|
|
138
|
+
['present but undocumented', 'A route exists in code but API-REFERENCE.md doesn\'t list it. Add it.'],
|
|
139
|
+
],
|
|
140
|
+
example: 'GET /api/users in src/routes/users.ts AND in API-REFERENCE.md\'s Endpoints table',
|
|
141
|
+
standard: 'OpenAPI 3.1',
|
|
142
|
+
},
|
|
143
|
+
metricsConsistency: {
|
|
144
|
+
title: 'Metrics-Consistency — quoted numbers match reality',
|
|
145
|
+
what: 'Greps canonical + root docs for "N validators" / "N checks" claims and compares against the actual runtime count.',
|
|
146
|
+
why: 'Stale numeric claims ("19 validators" when it\'s now 22) erode credibility.',
|
|
147
|
+
triggers: [
|
|
148
|
+
['says "N validators" but actual count is M', 'Run `docguard fix --write` — this is auto-fixable.'],
|
|
149
|
+
],
|
|
150
|
+
example: 'AGENTS.md says "22 validators" and `docguard guard` shows 22 active validators',
|
|
151
|
+
standard: 'CDD principle: documented metrics match reality',
|
|
152
|
+
},
|
|
153
|
+
crossReference: {
|
|
154
|
+
title: 'Cross-Reference — internal markdown links resolve',
|
|
155
|
+
what: 'Scans canonical docs for `[text](./OTHER.md#anchor)` and `#anchor` links. Verifies the target file exists and the anchor matches a heading.',
|
|
156
|
+
why: 'Broken doc-to-doc links are the most-clicked dead ends in onboarding.',
|
|
157
|
+
triggers: [
|
|
158
|
+
['broken link: target file not found', 'The file path doesn\'t exist. Fix the path or remove the link.'],
|
|
159
|
+
['broken anchor', 'Anchor doesn\'t match any heading. Hint: `(did you mean #X?)` is appended for near-misses; if marked `[auto-fixable]`, run `docguard fix --write`.'],
|
|
160
|
+
],
|
|
161
|
+
example: '`[Setup](#prerequisites)` in ENVIRONMENT.md AND `## Prerequisites` heading present',
|
|
162
|
+
standard: 'GitHub Flavored Markdown anchor rules',
|
|
163
|
+
},
|
|
164
|
+
generatedStaleness: {
|
|
165
|
+
title: 'Generated-Staleness — source=code sections match scanner output',
|
|
166
|
+
what: 'For each `<!-- docguard:section source=code -->` block, re-runs the memory plan scanner and compares against on-disk content. Also flags status: draft docs unmodified for > 14 days.',
|
|
167
|
+
why: 'Code-truth sections must reflect what the code actually says. Forgotten drafts rot.',
|
|
168
|
+
triggers: [
|
|
169
|
+
['is stale', 'A code-truth section drifted. Run `docguard sync --write` (or `docguard fix --write` since v0.14-P3 — the validator now emits a regenerate-section fix).'],
|
|
170
|
+
['status: draft for', 'A doc has been in draft for too long. Promote to `status: current` or remove. Threshold via `config.draftStalenessDays`.'],
|
|
171
|
+
],
|
|
172
|
+
example: 'All source=code sections match what the scanner would produce right now',
|
|
173
|
+
standard: 'CDD principle: code-truth sections are machine-owned',
|
|
174
|
+
},
|
|
175
|
+
todoTracking: {
|
|
176
|
+
title: 'TODO-Tracking — TODOs are tracked + skipped tests explained',
|
|
177
|
+
what: 'Finds TODO/FIXME/HACK comments in source. Each must be referenced in tracking docs (ROADMAP.md, GitHub issues, etc.). Also flags `it.skip()` / `test.skip()` without an adjacent `// REASON:` comment.',
|
|
178
|
+
why: 'TODOs in code that no one tracks are silent debt.',
|
|
179
|
+
triggers: [
|
|
180
|
+
['Skipped test without explanation', 'Add `// REASON: <why>` immediately above the skip.'],
|
|
181
|
+
['Untracked TODO', 'Reference the TODO from ROADMAP.md by file:line, OR add it to a GitHub issue and link the issue ID in the comment.'],
|
|
182
|
+
],
|
|
183
|
+
example: '// REASON: waiting on upstream fix in libfoo v2.5\\ntest.skip("foo", () => {})',
|
|
184
|
+
standard: 'Pragmatic Programmer (debt visibility)',
|
|
185
|
+
},
|
|
186
|
+
specKit: {
|
|
187
|
+
title: 'Spec-Kit — spec.md/plan.md/tasks.md have required sections',
|
|
188
|
+
what: 'For projects using Spec Kit, validates each spec/*.md against the spec-kit-template required sections.',
|
|
189
|
+
why: 'Spec Kit\'s value comes from consistent shape across specs.',
|
|
190
|
+
triggers: [
|
|
191
|
+
['Missing mandatory section', 'Add the section listed in the warning. Reference the template at .specify/templates/'],
|
|
192
|
+
],
|
|
193
|
+
example: 'plan.md has Summary, Technical Context, Constitution Check, Project Structure',
|
|
194
|
+
standard: 'GitHub Spec Kit',
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Match a warning text fragment against the explainer table. Returns the
|
|
200
|
+
* matching entry's key + the trigger entry that best matches, or null when
|
|
201
|
+
* no match is confident enough.
|
|
202
|
+
*/
|
|
203
|
+
function matchWarning(query) {
|
|
204
|
+
const q = query.toLowerCase();
|
|
205
|
+
|
|
206
|
+
// Exact validator-key lookup (e.g. `docguard explain freshness`)
|
|
207
|
+
if (EXPLAINERS[query]) return { key: query, trigger: null };
|
|
208
|
+
// Also try kebab-case (e.g. `cross-reference` → `crossReference`)
|
|
209
|
+
const camelized = query.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
210
|
+
if (EXPLAINERS[camelized]) return { key: camelized, trigger: null };
|
|
211
|
+
|
|
212
|
+
// Search trigger phrases
|
|
213
|
+
let best = null;
|
|
214
|
+
let bestScore = 0;
|
|
215
|
+
for (const [key, e] of Object.entries(EXPLAINERS)) {
|
|
216
|
+
for (const [phrase, _hint] of e.triggers) {
|
|
217
|
+
if (q.includes(phrase.toLowerCase())) {
|
|
218
|
+
const score = phrase.length; // prefer the more-specific phrase
|
|
219
|
+
if (score > bestScore) {
|
|
220
|
+
best = { key, trigger: [phrase, _hint] };
|
|
221
|
+
bestScore = score;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return best;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export function runExplain(projectDir, _config, flags) {
|
|
230
|
+
const query = (flags.args || []).join(' ').trim();
|
|
231
|
+
const isJson = flags.format === 'json';
|
|
232
|
+
|
|
233
|
+
if (!query) {
|
|
234
|
+
if (isJson) {
|
|
235
|
+
console.log(JSON.stringify({ validators: Object.keys(EXPLAINERS) }, null, 2));
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
console.log(`${c.bold}🧭 docguard explain${c.reset} ${c.dim}— usage:${c.reset}`);
|
|
239
|
+
console.log(` ${c.cyan}docguard explain <validator-key>${c.reset} e.g. docguard explain freshness`);
|
|
240
|
+
console.log(` ${c.cyan}docguard explain "<warning text>"${c.reset} e.g. docguard explain "no service-to-test mappings"`);
|
|
241
|
+
console.log(`\n${c.dim}Known validators:${c.reset}`);
|
|
242
|
+
for (const [k, e] of Object.entries(EXPLAINERS)) {
|
|
243
|
+
console.log(` ${c.cyan}${k.padEnd(22)}${c.reset} ${c.dim}${e.title}${c.reset}`);
|
|
244
|
+
}
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const match = matchWarning(query);
|
|
249
|
+
if (!match) {
|
|
250
|
+
if (isJson) {
|
|
251
|
+
console.log(JSON.stringify({ query, match: null }, null, 2));
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
console.log(`${c.yellow}No matching validator or warning found for: "${query}"${c.reset}`);
|
|
255
|
+
console.log(`${c.dim}Try: ${c.cyan}docguard explain${c.dim} (no args) to list all validators.${c.reset}`);
|
|
256
|
+
process.exit(1);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const e = EXPLAINERS[match.key];
|
|
260
|
+
if (isJson) {
|
|
261
|
+
console.log(JSON.stringify({ query, match: { key: match.key, ...e, matchedTrigger: match.trigger } }, null, 2));
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
console.log(`${c.bold}🧭 ${e.title}${c.reset}`);
|
|
266
|
+
console.log(`${c.dim} validator key: ${match.key}${c.reset}\n`);
|
|
267
|
+
|
|
268
|
+
console.log(`${c.bold}What it checks:${c.reset}\n ${e.what}\n`);
|
|
269
|
+
console.log(`${c.bold}Why:${c.reset}\n ${e.why}\n`);
|
|
270
|
+
|
|
271
|
+
if (match.trigger) {
|
|
272
|
+
console.log(`${c.bold}Your warning ("${query}") matches:${c.reset}`);
|
|
273
|
+
console.log(` ${c.yellow}${match.trigger[0]}${c.reset}`);
|
|
274
|
+
console.log(` ${match.trigger[1]}\n`);
|
|
275
|
+
} else {
|
|
276
|
+
console.log(`${c.bold}Common warnings:${c.reset}`);
|
|
277
|
+
for (const [phrase, hint] of e.triggers) {
|
|
278
|
+
console.log(` ${c.yellow}${phrase}${c.reset}`);
|
|
279
|
+
console.log(` ${c.dim}${hint}${c.reset}`);
|
|
280
|
+
}
|
|
281
|
+
console.log('');
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
console.log(`${c.bold}Passing example:${c.reset}\n ${c.dim}${e.example}${c.reset}\n`);
|
|
285
|
+
console.log(`${c.bold}Standard:${c.reset} ${c.dim}${e.standard}${c.reset}`);
|
|
286
|
+
}
|
|
@@ -11,6 +11,80 @@ 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-P1: update the docguardVersion field in .docguard.json after a
|
|
71
|
+
* successful guard run. Triggered by `docguard guard --pin`. Idempotent.
|
|
72
|
+
*/
|
|
73
|
+
function _updateVersionPin(projectDir) {
|
|
74
|
+
const cfgPath = resolvePath(projectDir, '.docguard.json');
|
|
75
|
+
if (!existsSync(cfgPath)) return { written: false, reason: '.docguard.json not found — run `docguard init` first' };
|
|
76
|
+
let raw, cfg;
|
|
77
|
+
try { raw = readFileSync(cfgPath, 'utf-8'); cfg = JSON.parse(raw); } catch (e) {
|
|
78
|
+
return { written: false, reason: `could not parse .docguard.json: ${e.message}` };
|
|
79
|
+
}
|
|
80
|
+
if (cfg.docguardVersion === CLI_VERSION) {
|
|
81
|
+
return { written: false, reason: `already pinned at v${CLI_VERSION}` };
|
|
82
|
+
}
|
|
83
|
+
const prev = cfg.docguardVersion || '(unset)';
|
|
84
|
+
cfg.docguardVersion = CLI_VERSION;
|
|
85
|
+
writeFileSync(cfgPath, JSON.stringify(cfg, null, 2) + '\n', 'utf-8');
|
|
86
|
+
return { written: true, from: prev, to: CLI_VERSION };
|
|
87
|
+
}
|
|
14
88
|
import { validateStructure, validateDocSections } from '../validators/structure.mjs';
|
|
15
89
|
import { validateDrift } from '../validators/drift.mjs';
|
|
16
90
|
import { validateChangelog } from '../validators/changelog.mjs';
|
|
@@ -364,6 +438,15 @@ export function runGuard(projectDir, config, flags) {
|
|
|
364
438
|
console.log(`\n ${c.yellow}↑ ${upgradeHint}${c.reset}`);
|
|
365
439
|
}
|
|
366
440
|
|
|
441
|
+
// v0.17-P1: version-pin nudge. When .docguard.json carries a
|
|
442
|
+
// docguardVersion field and the running CLI doesn't match, emit a
|
|
443
|
+
// one-line note. Keeps CDD reproducibility honest — "same project,
|
|
444
|
+
// same docs, different score across versions" no longer silent.
|
|
445
|
+
const pinHint = _checkVersionPin(config);
|
|
446
|
+
if (pinHint) {
|
|
447
|
+
console.log(`\n ${c.yellow}📌 ${pinHint}${c.reset}`);
|
|
448
|
+
}
|
|
449
|
+
|
|
367
450
|
// K-6 / S-2: sweep-needed nudge. Aggregates freshness warnings — if 2+
|
|
368
451
|
// canonical docs are stale (matching the "X code commits since last doc
|
|
369
452
|
// update" pattern), suggest a single `docguard sync --write` pass that
|
|
@@ -402,6 +485,24 @@ export function runGuard(projectDir, config, flags) {
|
|
|
402
485
|
|
|
403
486
|
console.log('');
|
|
404
487
|
|
|
488
|
+
// v0.17-P1: --pin updates docguardVersion in .docguard.json to the running
|
|
489
|
+
// CLI version. Only meaningful AFTER a clean (or near-clean) guard run —
|
|
490
|
+
// pinning to a version that just failed defeats the reproducibility goal.
|
|
491
|
+
// We allow pinning when status is PASS or WARN; refuse on FAIL.
|
|
492
|
+
if (flags.pin) {
|
|
493
|
+
if (data.status === 'FAIL') {
|
|
494
|
+
console.log(` ${c.red}✗ Cannot --pin after a FAIL run.${c.reset} Fix the errors first, then retry.`);
|
|
495
|
+
} else {
|
|
496
|
+
const r = _updateVersionPin(projectDir);
|
|
497
|
+
if (r.written) {
|
|
498
|
+
console.log(` ${c.green}📌 docguardVersion pinned: ${r.from} → ${r.to}${c.reset}`);
|
|
499
|
+
} else {
|
|
500
|
+
console.log(` ${c.dim}📌 ${r.reason}${c.reset}`);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
console.log('');
|
|
504
|
+
}
|
|
505
|
+
|
|
405
506
|
// v0.5: severity-aware exit codes (see runGuardInternal for the rollup).
|
|
406
507
|
if (data.effectiveErrors > 0) process.exit(1);
|
|
407
508
|
if (data.effectiveWarnings > 0) process.exit(2);
|