testguard-cli 0.19.0__tar.gz → 0.20.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 (539) hide show
  1. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.jules/README.md +13 -0
  2. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.pre-commit-hooks.yaml +1 -1
  3. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/CHANGELOG.md +15 -0
  4. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/PKG-INFO +3 -3
  5. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/README.md +2 -2
  6. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/action.yml +1 -1
  7. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/guides/ci/github-actions.md +6 -6
  8. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/guides/ci/gitlab.md +1 -1
  9. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/guides/ci/pre-commit.md +1 -1
  10. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/guides/monorepo.md +2 -2
  11. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/guides/writing-claims.md +17 -0
  12. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/i18n/es/README.md +2 -2
  13. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/i18n/pt-BR/README.md +2 -2
  14. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/i18n/zh-CN/README.md +2 -2
  15. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/installation.md +5 -5
  16. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/testguard-explained.html +1 -1
  17. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/testguard-explained.pdf +0 -0
  18. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/package-lock.json +2 -2
  19. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/package.json +1 -1
  20. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/packaging/gitlab/testguard.gitlab-ci.yml +2 -2
  21. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/packaging/homebrew/testguard.rb +2 -2
  22. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/pyproject.toml +1 -1
  23. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/GATE-SEMANTICS.md +18 -0
  24. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/origins.test.mjs +57 -0
  25. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/lib/origins.mjs +19 -0
  26. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/schemas/claims.schema.json +1 -15
  27. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/schemas/common.schema.json +16 -0
  28. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/schemas/evidence.schema.json +1 -14
  29. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/testguard.claims.json +66 -0
  30. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.agents/skills/testguard/SKILL.md +0 -0
  31. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.docguard.json +0 -0
  32. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.docguardignore +0 -0
  33. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.gitattributes +0 -0
  34. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  35. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  36. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/ISSUE_TEMPLATE/documentation.md +0 -0
  37. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  38. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  39. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/dependabot.yml +0 -0
  40. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/scripts/approve-held-runs.sh +0 -0
  41. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/scripts/benchmark-node-direct.mjs +0 -0
  42. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/scripts/benchmark-node-runner.mjs +0 -0
  43. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/scripts/build-one-pager.mjs +0 -0
  44. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/scripts/check-cost-budget.mjs +0 -0
  45. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/scripts/check-node-fixture.mjs +0 -0
  46. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/scripts/check-python-fixture.mjs +0 -0
  47. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/scripts/install-smoke.mjs +0 -0
  48. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/scripts/jules-policy.mjs +0 -0
  49. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/scripts/jules-triage.mjs +0 -0
  50. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/scripts/publish-homebrew-tap.sh +0 -0
  51. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/scripts/sync-release-version.mjs +0 -0
  52. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/workflows/auto-merge.yml +0 -0
  53. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/workflows/ci.yml +0 -0
  54. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/workflows/jules-triage.yml +0 -0
  55. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/workflows/release.yml +0 -0
  56. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/workflows/scheduled-release.yml +0 -0
  57. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.github/workflows/supply-chain.yml +0 -0
  58. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.gitignore +0 -0
  59. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.jules/RULES.md +0 -0
  60. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.jules/preflight.mjs +0 -0
  61. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.jules/routines/docs-drift.md +0 -0
  62. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.jules/routines/runner-scout.md +0 -0
  63. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.jules/routines/scaffold-hunt.md +0 -0
  64. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.jules/setup.sh +0 -0
  65. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.npmignore +0 -0
  66. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.npmrc +0 -0
  67. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/.pre-commit-config.yaml +0 -0
  68. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/AGENTS.md +0 -0
  69. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/CLAUDE.md +0 -0
  70. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/CODE_OF_CONDUCT.md +0 -0
  71. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/CONTRIBUTING.md +0 -0
  72. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/DRIFT-LOG.md +0 -0
  73. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/LICENSE +0 -0
  74. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/PRIVACY.md +0 -0
  75. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/SECURITY.md +0 -0
  76. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/SUPPORT.md +0 -0
  77. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/bench/README.md +0 -0
  78. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/cli/testguard.mjs +0 -0
  79. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/README.md +0 -0
  80. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/concepts/how-it-works.md +0 -0
  81. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/faq.md +0 -0
  82. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/glossary.md +0 -0
  83. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/guides/ai-agents.md +0 -0
  84. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/guides/existing-projects.md +0 -0
  85. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/guides/new-projects.md +0 -0
  86. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/guides/performance.md +0 -0
  87. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/guides/python.md +0 -0
  88. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/guides/replay.md +0 -0
  89. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/i18n/es/quickstart.md +0 -0
  90. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/i18n/pt-BR/quickstart.md +0 -0
  91. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/i18n/zh-CN/quickstart.md +0 -0
  92. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/quickstart.md +0 -0
  93. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/reference/artifacts.md +0 -0
  94. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/reference/cli.md +0 -0
  95. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/reference/configuration.md +0 -0
  96. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/reference/languages-and-runners.md +0 -0
  97. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/reference/mcp.md +0 -0
  98. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/reference/verdicts.md +0 -0
  99. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/troubleshooting.md +0 -0
  100. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs/upgrade.md +0 -0
  101. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs-canonical/ARCHITECTURE.md +0 -0
  102. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs-canonical/DATA-MODEL.md +0 -0
  103. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs-canonical/ENVIRONMENT.md +0 -0
  104. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs-canonical/PRIOR-ART.md +0 -0
  105. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs-canonical/REQUIREMENTS.md +0 -0
  106. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs-canonical/SECURITY.md +0 -0
  107. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/docs-canonical/TEST-SPEC.md +0 -0
  108. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer/.gitignore +0 -0
  109. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer/README.md +0 -0
  110. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer/expected.json +0 -0
  111. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer/package.json +0 -0
  112. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer/src/export.mjs +0 -0
  113. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer/src/redact.mjs +0 -0
  114. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer/test/export-mocked.test.mjs +0 -0
  115. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer/test/flaky.test.mjs +0 -0
  116. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer/test/redact.test.mjs +0 -0
  117. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer/testguard.claims.json +0 -0
  118. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer/vitest.config.mjs +0 -0
  119. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-jest/.gitignore +0 -0
  120. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-jest/README.md +0 -0
  121. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-jest/expected.json +0 -0
  122. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-jest/jest.config.js +0 -0
  123. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-jest/package.json +0 -0
  124. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-jest/src/export.js +0 -0
  125. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-jest/src/redact.js +0 -0
  126. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-jest/test/export-mocked.test.js +0 -0
  127. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-jest/test/flaky.test.js +0 -0
  128. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-jest/test/redact.test.js +0 -0
  129. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-jest/testguard.claims.json +0 -0
  130. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-node/.gitignore +0 -0
  131. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-node/README.md +0 -0
  132. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-node/expected.json +0 -0
  133. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-node/package.json +0 -0
  134. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-node/src/policy.mjs +0 -0
  135. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-node/src/unused.mjs +0 -0
  136. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-node/test/flaky.test.mjs +0 -0
  137. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-node/test/mixed.test.mjs +0 -0
  138. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-node/test/policy.test.mjs +0 -0
  139. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-node/testguard.claims.json +0 -0
  140. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-playwright/.gitignore +0 -0
  141. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-playwright/README.md +0 -0
  142. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-playwright/e2e/flaky.spec.mjs +0 -0
  143. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-playwright/e2e/toggle.spec.mjs +0 -0
  144. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-playwright/expected.json +0 -0
  145. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-playwright/package-lock.json +0 -0
  146. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-playwright/package.json +0 -0
  147. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-playwright/playwright.config.mjs +0 -0
  148. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-playwright/src/toggle.mjs +0 -0
  149. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-playwright/test/toggle.test.mjs +0 -0
  150. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-playwright/testguard.claims.json +0 -0
  151. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-playwright/vitest.config.mjs +0 -0
  152. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-python/.gitignore +0 -0
  153. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-python/README.md +0 -0
  154. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-python/demo/__init__.py +0 -0
  155. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-python/demo/export.py +0 -0
  156. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-python/demo/orphan.py +0 -0
  157. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-python/demo/pipeline.py +0 -0
  158. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-python/demo/redact.py +0 -0
  159. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-python/expected.json +0 -0
  160. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-python/testguard.claims.json +0 -0
  161. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-python/tests/test_export_mocked.py +0 -0
  162. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-python/tests/test_flaky.py +0 -0
  163. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-python/tests/test_patched.py +0 -0
  164. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/fixtures/known-answer-python/tests/test_redact.py +0 -0
  165. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/README.md +0 -0
  166. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/annotations.test.mjs +0 -0
  167. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/authoring-input.test.mjs +0 -0
  168. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/draft-append.test.mjs +0 -0
  169. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/annotations.json +0 -0
  170. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/authoring-input.json +0 -0
  171. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/baseline.json +0 -0
  172. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/brief.json +0 -0
  173. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/calibration-websec.json +0 -0
  174. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/calibration.json +0 -0
  175. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/claims-methods.json +0 -0
  176. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/claims.json +0 -0
  177. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/evidence-disturbed-run.json +0 -0
  178. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/evidence-negative-control.json +0 -0
  179. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/evidence-persistence-signal.json +0 -0
  180. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/evidence-provisional.json +0 -0
  181. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/evidence-python.json +0 -0
  182. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/evidence-resources.json +0 -0
  183. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/evidence-scan-method.json +0 -0
  184. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/evidence.json +0 -0
  185. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/gate.json +0 -0
  186. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/ignore.json +0 -0
  187. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/replay.json +0 -0
  188. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/status-baseline.json +0 -0
  189. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/status-resource-cost.json +0 -0
  190. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/examples/status.json +0 -0
  191. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/baseline.bad-fingerprint-key.json +0 -0
  192. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/baseline.zero-count.json +0 -0
  193. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/brief.text-without-heading.json +0 -0
  194. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/brief.unknown-verdict-key.json +0 -0
  195. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/calibration.backoff-cell-not-wilson.json +0 -0
  196. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/calibration.breakdown-does-not-sum-to-n.json +0 -0
  197. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/calibration.ci-not-wilson.json +0 -0
  198. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/calibration.compound-key-arity-mismatch.json +0 -0
  199. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/calibration.fallback-without-basis.json +0 -0
  200. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/calibration.p-not-positives-over-n.json +0 -0
  201. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/calibration.p-outside-ci.json +0 -0
  202. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/calibration.positives-exceed-n.json +0 -0
  203. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/claims.absolute-path.json +0 -0
  204. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/claims.duplicate-fault-id.json +0 -0
  205. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/claims.fault-injection-without-a-substitution.json +0 -0
  206. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/claims.method-detail-on-a-specified-method.json +0 -0
  207. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/claims.missing-provenance.json +0 -0
  208. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/claims.noop-fault.json +0 -0
  209. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/claims.occurrence-exceeds-hits.json +0 -0
  210. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/claims.parent-traversal.json +0 -0
  211. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.annotated-signal-without-reason.json +0 -0
  212. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.attribute-signal-not-a-defender.json +0 -0
  213. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.attribute-signal-without-attributes.json +0 -0
  214. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.byrunner-file-not-resolved.json +0 -0
  215. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.contention-without-runners.json +0 -0
  216. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.discovered-defender-mocks-subject.json +0 -0
  217. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.fault-injection-without-its-evidence.json +0 -0
  218. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.flaky-defender-without-flakiness.json +0 -0
  219. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.ignored-dirty-on-snapshot.json +0 -0
  220. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.killed-by-non-assertion.json +0 -0
  221. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.killed-on-red-baseline.json +0 -0
  222. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.killed-without-n-runs.json +0 -0
  223. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.method-detail-on-an-injecting-run.json +0 -0
  224. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.negative-control-not-reached-but-survived.json +0 -0
  225. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.negative-control-reached-on-a-kill.json +0 -0
  226. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.persistence-signal-not-a-defender.json +0 -0
  227. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.persistence-signal-on-a-non-survivor.json +0 -0
  228. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.persistence-signal-without-reason.json +0 -0
  229. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.probe-error-without-message.json +0 -0
  230. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.provisional-flag-on-confirmed-run.json +0 -0
  231. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.rank-extra-property.json +0 -0
  232. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.resource-accounting.json +0 -0
  233. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.restore-skipped-in-place.json +0 -0
  234. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.serial-worker-conflict.json +0 -0
  235. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.single-run-without-provisional.json +0 -0
  236. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.target-not-imported-but-killed.json +0 -0
  237. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.undeclared-killers-without-reason.json +0 -0
  238. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.unknown-verdict.json +0 -0
  239. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.unverifiable-without-reason.json +0 -0
  240. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/evidence.wrong-fingerprint.json +0 -0
  241. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/gate.counts-disagree.json +0 -0
  242. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/gate.exit-zero-with-uncovered.json +0 -0
  243. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/gate.ignore-cover-without-pattern.json +0 -0
  244. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/ignore.claim-pattern-not-an-identifier.json +0 -0
  245. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/ignore.fault-pattern-without-fault-id.json +0 -0
  246. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/ignore.fingerprint-kind.json +0 -0
  247. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/ignore.missing-reason.json +0 -0
  248. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/ignore.short-reason.json +0 -0
  249. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/replay.blind-with-a-failing-run.json +0 -0
  250. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/replay.duplicate-patch-id.json +0 -0
  251. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/replay.nocover-when-no-test-file-remained.json +0 -0
  252. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/status.baseline-and-run.json +0 -0
  253. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/status.baseline-frozen-and-restamped.json +0 -0
  254. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/status.claim-without-file.json +0 -0
  255. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/status.clean-with-new-findings.json +0 -0
  256. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/status.invalid-anchor-hidden.json +0 -0
  257. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/status.partial-scope-counts-disagree.json +0 -0
  258. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/status.resource-accounting.json +0 -0
  259. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/status.surface-counts-disagree.json +0 -0
  260. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/status.unclaimed-hidden-behind-unproven.json +0 -0
  261. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/invalid/status.write-test-without-target.json +0 -0
  262. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/origin-policy.test.mjs +0 -0
  263. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/origin-summaries.test.mjs +0 -0
  264. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/conformance/schemas.test.mjs +0 -0
  265. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/lib/authoring-input.mjs +0 -0
  266. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/lib/fingerprint.mjs +0 -0
  267. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/lib/validate.mjs +0 -0
  268. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/lib/wilson.mjs +0 -0
  269. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/schemas/annotations.schema.json +0 -0
  270. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/schemas/authoring-input.schema.json +0 -0
  271. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/schemas/baseline.schema.json +0 -0
  272. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/schemas/brief.schema.json +0 -0
  273. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/schemas/calibration.schema.json +0 -0
  274. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/schemas/concerns.schema.json +0 -0
  275. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/schemas/gate.schema.json +0 -0
  276. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/schemas/ignore.schema.json +0 -0
  277. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/schemas/replay.schema.json +0 -0
  278. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/schemas/status.schema.json +0 -0
  279. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/spec/schemas/sweep.schema.json +0 -0
  280. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/admit/admit.mjs +0 -0
  281. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/baseline/baseline.mjs +0 -0
  282. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/brief/brief.mjs +0 -0
  283. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/claims/anchors.mjs +0 -0
  284. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/claims/annotation-placement.mjs +0 -0
  285. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/claims/annotations.mjs +0 -0
  286. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/claims/load.mjs +0 -0
  287. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/claims/removed.mjs +0 -0
  288. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/cli.mjs +0 -0
  289. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/command-budget.mjs +0 -0
  290. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/commands/admit.mjs +0 -0
  291. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/commands/annotations.mjs +0 -0
  292. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/commands/baseline.mjs +0 -0
  293. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/commands/brief.mjs +0 -0
  294. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/commands/claims.mjs +0 -0
  295. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/commands/concerns.mjs +0 -0
  296. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/commands/gate.mjs +0 -0
  297. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/commands/init.mjs +0 -0
  298. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/commands/mcp.mjs +0 -0
  299. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/commands/probe.mjs +0 -0
  300. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/commands/replay.mjs +0 -0
  301. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/commands/runner-options.mjs +0 -0
  302. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/commands/scaffold.mjs +0 -0
  303. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/commands/status.mjs +0 -0
  304. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/commands/sweep.mjs +0 -0
  305. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/evidence/writer.mjs +0 -0
  306. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/gate/changed.mjs +0 -0
  307. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/git.mjs +0 -0
  308. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/init/init.mjs +0 -0
  309. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/init/templates/SKILL.md +0 -0
  310. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/mcp/server.mjs +0 -0
  311. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/mcp/tools.mjs +0 -0
  312. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/attribution.mjs +0 -0
  313. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/classify.mjs +0 -0
  314. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/contention.mjs +0 -0
  315. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/cost.mjs +0 -0
  316. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/discover.mjs +0 -0
  317. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/imports.mjs +0 -0
  318. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/independence.mjs +0 -0
  319. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/inject.mjs +0 -0
  320. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/mocks.mjs +0 -0
  321. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/origin-policy.mjs +0 -0
  322. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/policy-freshness.mjs +0 -0
  323. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/probe.mjs +0 -0
  324. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/progress.mjs +0 -0
  325. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/pyimports.mjs +0 -0
  326. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/rank.mjs +0 -0
  327. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/runners/discovery.mjs +0 -0
  328. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/runners/index.mjs +0 -0
  329. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/runners/jest.mjs +0 -0
  330. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/runners/lifecycle.mjs +0 -0
  331. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/runners/node/direct.mjs +0 -0
  332. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/runners/node/entry.mjs +0 -0
  333. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/runners/node/report.mjs +0 -0
  334. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/runners/node/runner.mjs +0 -0
  335. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/runners/node-test.mjs +0 -0
  336. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/runners/playwright.mjs +0 -0
  337. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/runners/python/_testguard_pytest_plugin.py +0 -0
  338. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/runners/python/_testguard_report.py +0 -0
  339. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/runners/python/_testguard_unittest_main.py +0 -0
  340. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/runners/python.mjs +0 -0
  341. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/runners/shared.mjs +0 -0
  342. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/runners/vitest.mjs +0 -0
  343. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/universe.mjs +0 -0
  344. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/probe/worktree.mjs +0 -0
  345. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/render.mjs +0 -0
  346. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/replay/label.mjs +0 -0
  347. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/replay/replay.mjs +0 -0
  348. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/scaffold/admission.mjs +0 -0
  349. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/scaffold/append.mjs +0 -0
  350. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/scaffold/apply-append.mjs +0 -0
  351. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/scaffold/fix-input.mjs +0 -0
  352. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/scaffold/fix-paths.mjs +0 -0
  353. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/scaffold/intent.mjs +0 -0
  354. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/scaffold/open-append.mjs +0 -0
  355. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/scaffold/plan-append.mjs +0 -0
  356. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/scaffold/plan-intent-input.mjs +0 -0
  357. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/scaffold/prepare-append.mjs +0 -0
  358. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/scaffold/producers.mjs +0 -0
  359. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/scaffold/producers.python.mjs +0 -0
  360. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/scaffold/request.mjs +0 -0
  361. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/scaffold/scaffold.mjs +0 -0
  362. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/status/status.mjs +0 -0
  363. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/status/surface.mjs +0 -0
  364. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/supply/concerns.mjs +0 -0
  365. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/supply/feedback.mjs +0 -0
  366. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/supply/persistence.mjs +0 -0
  367. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/supply/savepath.mjs +0 -0
  368. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/supply/select.mjs +0 -0
  369. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/sweep/pool.mjs +0 -0
  370. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/sweep/sweep.mjs +0 -0
  371. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/util/glob.mjs +0 -0
  372. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/src/util/hash.mjs +0 -0
  373. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/action.test.mjs +0 -0
  374. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/admit-decision.test.mjs +0 -0
  375. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/admit.test.mjs +0 -0
  376. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/anchor-admission.test.mjs +0 -0
  377. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/annotation-advisory-limits.test.mjs +0 -0
  378. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/annotation-advisory.test.mjs +0 -0
  379. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/annotation-apply.test.mjs +0 -0
  380. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/annotation-cli.test.mjs +0 -0
  381. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/annotation-id-bounds.test.mjs +0 -0
  382. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/annotation-placement.test.mjs +0 -0
  383. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/annotations.test.mjs +0 -0
  384. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/attribution.test.mjs +0 -0
  385. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/baseline.test.mjs +0 -0
  386. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/brief.test.mjs +0 -0
  387. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/calibration.test.mjs +0 -0
  388. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/ci-evidence-helper.github.test.mjs +0 -0
  389. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/ci-evidence-helper.gitlab.test.mjs +0 -0
  390. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/claim-options.test.mjs +0 -0
  391. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/claim-selection.test.mjs +0 -0
  392. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/claims-anchors.test.mjs +0 -0
  393. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/claims-since.test.mjs +0 -0
  394. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/classify.test.mjs +0 -0
  395. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/cli-surface.test.mjs +0 -0
  396. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/cli-unexpected-error.test.mjs +0 -0
  397. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/command-budget-write-boundaries.test.mjs +0 -0
  398. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/command-budget.test.mjs +0 -0
  399. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/contention.test.mjs +0 -0
  400. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/cost.test.mjs +0 -0
  401. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/discover.test.mjs +0 -0
  402. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/discovery-config.test.mjs +0 -0
  403. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/docs.test.mjs +0 -0
  404. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/draft-admission.test.mjs +0 -0
  405. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/draft-append-apply.test.mjs +0 -0
  406. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/draft-append-cli.test.mjs +0 -0
  407. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/draft-append-open.test.mjs +0 -0
  408. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/draft-append-plan.test.mjs +0 -0
  409. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/draft-append-prepare.test.mjs +0 -0
  410. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/draft-append.test.mjs +0 -0
  411. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/evidence-persistence-signal.test.mjs +0 -0
  412. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/fault-defender-orchestration.test.mjs +0 -0
  413. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/fault-defenders.test.mjs +0 -0
  414. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/fix-input.test.mjs +0 -0
  415. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/fix-inventory.test.mjs +0 -0
  416. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/fix-nested.test.mjs +0 -0
  417. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/fix-paths.test.mjs +0 -0
  418. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/fix-projects.test.mjs +0 -0
  419. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/fixture-git.test.mjs +0 -0
  420. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/gate-coverage.test.mjs +0 -0
  421. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/gate-ref.test.mjs +0 -0
  422. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/gate.test.mjs +0 -0
  423. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/gitlab-template.test.mjs +0 -0
  424. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/glob.test.mjs +0 -0
  425. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/helpers/gate-project.mjs +0 -0
  426. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/helpers/git.mjs +0 -0
  427. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/helpers/probe-assertions.mjs +0 -0
  428. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/helpers/release-project.mjs +0 -0
  429. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/helpers/yaml.mjs +0 -0
  430. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/imports.test.mjs +0 -0
  431. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/independence.test.mjs +0 -0
  432. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/init-hook-replace.test.mjs +0 -0
  433. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/init-ignores.test.mjs +0 -0
  434. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/init-preflight.test.mjs +0 -0
  435. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/init.test.mjs +0 -0
  436. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/inject.test.mjs +0 -0
  437. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/intent-authoring.test.mjs +0 -0
  438. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/intent-document.test.mjs +0 -0
  439. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/intent-input-cli.test.mjs +0 -0
  440. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/intent-input-plan.test.mjs +0 -0
  441. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/intent-input-request.test.mjs +0 -0
  442. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/intent-project.test.mjs +0 -0
  443. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/jules-policy.test.mjs +0 -0
  444. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/label.test.mjs +0 -0
  445. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/mcp-next.test.mjs +0 -0
  446. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/mcp-protocol.test.mjs +0 -0
  447. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/mcp.test.mjs +0 -0
  448. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/mocks.test.mjs +0 -0
  449. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/native-universe-hash.test.mjs +0 -0
  450. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/native-universe.test.mjs +0 -0
  451. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/negative-control-capabilities.test.mjs +0 -0
  452. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/negative-control.test.mjs +0 -0
  453. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/one-pager.test.mjs +0 -0
  454. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/origin-policy-admission.test.mjs +0 -0
  455. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/origin-policy-cli.test.mjs +0 -0
  456. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/origin-policy-projections.test.mjs +0 -0
  457. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/origin-policy-request.test.mjs +0 -0
  458. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/origin-policy.test.mjs +0 -0
  459. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/origin-reporting.test.mjs +0 -0
  460. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/origin-summary.test.mjs +0 -0
  461. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/policy-freshness.test.mjs +0 -0
  462. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/probe-control.test.mjs +0 -0
  463. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/probe-dirty-admission.test.mjs +0 -0
  464. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/probe-dirty-paths.test.mjs +0 -0
  465. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/probe-error-boundary.test.mjs +0 -0
  466. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/probe-error.test.mjs +0 -0
  467. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/probe-isolation.test.mjs +0 -0
  468. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/probe-native-manifest.test.mjs +0 -0
  469. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/probe-persistence-signal.test.mjs +0 -0
  470. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/probe-preconditions.test.mjs +0 -0
  471. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/probe-records.test.mjs +0 -0
  472. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/probe-runner-identity.test.mjs +0 -0
  473. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/probe.fixture.test.mjs +0 -0
  474. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/probe.jest.test.mjs +0 -0
  475. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/probe.node.test.mjs +0 -0
  476. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/probe.playwright.test.mjs +0 -0
  477. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/probe.python.test.mjs +0 -0
  478. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/progress.test.mjs +0 -0
  479. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/pyimports.test.mjs +0 -0
  480. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/python-interpreter.test.mjs +0 -0
  481. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/python-option-commands.test.mjs +0 -0
  482. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/python-wrapper.test.mjs +0 -0
  483. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/rank-aliases.test.mjs +0 -0
  484. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/release-approval.test.mjs +0 -0
  485. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/release-sync.test.mjs +0 -0
  486. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/release-tap.test.mjs +0 -0
  487. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/release-version.test.mjs +0 -0
  488. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/replay-mixed-runners.test.mjs +0 -0
  489. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/replay-no-test-file-left.test.mjs +0 -0
  490. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/replay-python-defenders.test.mjs +0 -0
  491. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/replay-selection.test.mjs +0 -0
  492. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/replay-verdict.test.mjs +0 -0
  493. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/replay.test.mjs +0 -0
  494. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/resource-safety.test.mjs +0 -0
  495. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/resource-timing.test.mjs +0 -0
  496. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/runner-argv.test.mjs +0 -0
  497. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/runner-command.test.mjs +0 -0
  498. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/runner-discovery.test.mjs +0 -0
  499. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/runner-node-admission.test.mjs +0 -0
  500. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/runner-node-controller.test.mjs +0 -0
  501. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/runner-node-direct.test.mjs +0 -0
  502. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/runner-node-report.test.mjs +0 -0
  503. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/runner-options.test.mjs +0 -0
  504. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/runner-output-bounds.test.mjs +0 -0
  505. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/runner-playwright.test.mjs +0 -0
  506. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/runner-project-resolution.test.mjs +0 -0
  507. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/runner-python.test.mjs +0 -0
  508. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/runner-report-allocation.test.mjs +0 -0
  509. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/runner-report.test.mjs +0 -0
  510. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/runner-selection-blind.test.mjs +0 -0
  511. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/runner-vitest.test.mjs +0 -0
  512. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/runner-worker-argv.test.mjs +0 -0
  513. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/samples/playwright-report.json +0 -0
  514. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/samples/python-report-collect-error.json +0 -0
  515. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/samples/python-report.json +0 -0
  516. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/scaffold-admitted-source.test.mjs +0 -0
  517. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/scaffold-placeholder.test.mjs +0 -0
  518. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/scaffold.python.test.mjs +0 -0
  519. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/scaffold.test.mjs +0 -0
  520. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/snapshot.test.mjs +0 -0
  521. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/status.test.mjs +0 -0
  522. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/supply-concerns.test.mjs +0 -0
  523. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/supply-feedback.test.mjs +0 -0
  524. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/supply-persistence.test.mjs +0 -0
  525. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/supply-savepath.test.mjs +0 -0
  526. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/supply-select.test.mjs +0 -0
  527. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/surface.test.mjs +0 -0
  528. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/sweep-pool.test.mjs +0 -0
  529. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/sweep.fixture.test.mjs +0 -0
  530. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/sweep.test.mjs +0 -0
  531. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/vitest-config.test.mjs +0 -0
  532. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/worker-policy.test.mjs +0 -0
  533. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/worktree.test.mjs +0 -0
  534. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/test/writer.test.mjs +0 -0
  535. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/testguard.cost-budget.json +0 -0
  536. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/testguard.ignore.json +0 -0
  537. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/testguard_cli/__init__.py +0 -0
  538. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/testguard_cli/wrapper.py +0 -0
  539. {testguard_cli-0.19.0 → testguard_cli-0.20.0}/vitest.config.mjs +0 -0
@@ -61,6 +61,19 @@ branch `main`. Paste the prompt verbatim.
61
61
  | runner-scout | Weekly, Wednesday | `Follow .jules/routines/runner-scout.md exactly. Read .jules/RULES.md first. If preflight prints STOP, end the task with no changes and no pull request.` |
62
62
  | docs-drift | Weekly, Friday | `Follow .jules/routines/docs-drift.md exactly. Read .jules/RULES.md first. If preflight prints STOP, end the task with no changes and no pull request.` |
63
63
 
64
+ **A new task can show `Inactive`.** A task created from the Task Input box
65
+ can stay `Inactive` even though its menu offers "Pause schedule". Pause it,
66
+ then resume it, and it shows `Active`. Check the badge after creating each
67
+ task, because an `Inactive` task never runs.
68
+
69
+ **The VM is a shallow clone.** Jules runs `git clone --depth 1` and sets a
70
+ global `core.hooksPath /dev/null`.
71
+
72
+ - The routines only diff against `origin/main` and build scratch worktrees
73
+ from `HEAD`, so both work in that clone.
74
+ - Do not write a routine step that needs history, such as `git log` over
75
+ many commits or `replay` over old fixes.
76
+
64
77
  That is three tasks a week at most. On the free plan's 15 tasks a day the
65
78
  quota is never the limit; the review queue is.
66
79
 
@@ -7,7 +7,7 @@
7
7
  #
8
8
  # repos:
9
9
  # - repo: https://github.com/raccioly/testguard
10
- # rev: v0.19.0
10
+ # rev: v0.20.0
11
11
  # hooks:
12
12
  # - id: testguard-claims # fast: validates the claims file + drift
13
13
  # - id: testguard-gate # fast: every changed source file must carry a claim
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.20.0] - 2026-10-11
11
+
12
+ Automated weekly release — everything merged since `v0.19.0`.
13
+
14
+ ### Changed
15
+
16
+ - feat(spec): structured requirement references in source.ref (#214)
17
+ - docs(jules): note the Inactive-schedule quirk and the shallow VM clone (#213)
18
+ - chore(homebrew): sha256 for v0.19.0 (#212)
19
+
20
+
21
+ ### Added
22
+
23
+ - Structured requirement references: a claim's `source.ref` may name the requirement it defends as `req:<spec-id>#<requirement-id>` (kind `spec`). A malformed `req:` reference, or one under another kind, now fails validation; every other reference stays opaque. The claim source is now defined once in `common.schema.json` (`$defs/claimSource`), and `requirementRef()` in `spec/lib/origins.mjs` parses the same pattern. Older readers accept the form as an opaque string. This is the format DocGuard's requirement anchors read to report the tests that cite a changed requirement as re-verified.
24
+
10
25
  ## [0.19.0] - 2026-10-11
11
26
 
12
27
  Automated weekly release — everything merged since `v0.18.3`.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: testguard-cli
3
- Version: 0.19.0
3
+ Version: 0.20.0
4
4
  Summary: Breaks your code on purpose and reports every promise your tests did not notice breaking. Mutation testing bound to the claims a project makes — vitest, jest, Playwright, pytest and unittest. A wrapper that runs the Node.js CLI (requires Node.js 20+): a project-local node_modules/testguard-cli when present, otherwise the npm release of this same version through npx.
5
5
  Project-URL: Homepage, https://github.com/raccioly/testguard
6
6
  Project-URL: Documentation, https://github.com/raccioly/testguard#readme
@@ -153,9 +153,9 @@ raises coverage. TestGuard admits it because it fails when the claim is false.
153
153
  | npm | `npm i -D testguard-cli` then `npx testguard probe` |
154
154
  | pip | `pip install testguard-cli` then `testguard probe` (needs Node ≥ 20) |
155
155
  | Homebrew | `brew tap raccioly/tap && brew install testguard` |
156
- | GitHub Action | `uses: raccioly/testguard@v0.19.0` |
156
+ | GitHub Action | `uses: raccioly/testguard@v0.20.0` |
157
157
  | pre-commit | `repo: https://github.com/raccioly/testguard`, hooks `testguard-claims`, `testguard-gate`, `testguard-probe` |
158
- | GitLab CI | `include: - remote: https://raw.githubusercontent.com/raccioly/testguard/v0.19.0/packaging/gitlab/testguard.gitlab-ci.yml` |
158
+ | GitLab CI | `include: - remote: https://raw.githubusercontent.com/raccioly/testguard/v0.20.0/packaging/gitlab/testguard.gitlab-ci.yml` |
159
159
 
160
160
  Requirements, offline installs, `ENOVERSIONS` and every CI option are in the
161
161
  [installation guide](https://github.com/raccioly/testguard/blob/main/docs/installation.md).
@@ -129,9 +129,9 @@ raises coverage. TestGuard admits it because it fails when the claim is false.
129
129
  | npm | `npm i -D testguard-cli` then `npx testguard probe` |
130
130
  | pip | `pip install testguard-cli` then `testguard probe` (needs Node ≥ 20) |
131
131
  | Homebrew | `brew tap raccioly/tap && brew install testguard` |
132
- | GitHub Action | `uses: raccioly/testguard@v0.19.0` |
132
+ | GitHub Action | `uses: raccioly/testguard@v0.20.0` |
133
133
  | pre-commit | `repo: https://github.com/raccioly/testguard`, hooks `testguard-claims`, `testguard-gate`, `testguard-probe` |
134
- | GitLab CI | `include: - remote: https://raw.githubusercontent.com/raccioly/testguard/v0.19.0/packaging/gitlab/testguard.gitlab-ci.yml` |
134
+ | GitLab CI | `include: - remote: https://raw.githubusercontent.com/raccioly/testguard/v0.20.0/packaging/gitlab/testguard.gitlab-ci.yml` |
135
135
 
136
136
  Requirements, offline installs, `ENOVERSIONS` and every CI option are in the
137
137
  [installation guide](https://github.com/raccioly/testguard/blob/main/docs/installation.md).
@@ -50,7 +50,7 @@ inputs:
50
50
  version:
51
51
  description: 'testguard-cli version to run'
52
52
  required: false
53
- default: '0.19.0'
53
+ default: '0.20.0'
54
54
  node-version:
55
55
  description: 'Node.js version (20+)'
56
56
  required: false
@@ -100,7 +100,7 @@ jobs:
100
100
  - uses: actions/checkout@v7
101
101
  with:
102
102
  fetch-depth: 0 # the base branch must exist locally
103
- - uses: raccioly/testguard@v0.19.0
103
+ - uses: raccioly/testguard@v0.20.0
104
104
  with:
105
105
  command: gate # every changed source file needs a claim
106
106
 
@@ -114,7 +114,7 @@ jobs:
114
114
  with:
115
115
  node-version: 22
116
116
  - run: npm ci # the probe runs the project's own test runner
117
- - uses: raccioly/testguard@v0.19.0
117
+ - uses: raccioly/testguard@v0.20.0
118
118
  with:
119
119
  command: probe
120
120
  severity: high # fail only on new high or critical findings
@@ -162,7 +162,7 @@ jobs:
162
162
  testguard-evidence-
163
163
 
164
164
  - id: testguard
165
- uses: raccioly/testguard@v0.19.0
165
+ uses: raccioly/testguard@v0.20.0
166
166
  with:
167
167
  command: probe
168
168
 
@@ -211,7 +211,7 @@ the probe at the interpreter if it is not one TestGuard finds on its own
211
211
  with:
212
212
  python-version: '3.12'
213
213
  - run: python -m venv .venv && .venv/bin/pip install -r requirements.txt
214
- - uses: raccioly/testguard@v0.19.0
214
+ - uses: raccioly/testguard@v0.20.0
215
215
  with:
216
216
  command: probe
217
217
  runner: python # pytest if .venv can import it, else unittest
@@ -227,7 +227,7 @@ Each project in a monorepo gets its own step, because a passing parent gate
227
227
  says nothing about a child project's coverage:
228
228
 
229
229
  ```yaml
230
- - uses: raccioly/testguard@v0.19.0
230
+ - uses: raccioly/testguard@v0.20.0
231
231
  with:
232
232
  command: gate
233
233
  working-directory: services/billing
@@ -245,7 +245,7 @@ run that verified nothing must not look like a pass. During adoption set
245
245
  `allow-empty`:
246
246
 
247
247
  ```yaml
248
- - uses: raccioly/testguard@v0.19.0
248
+ - uses: raccioly/testguard@v0.20.0
249
249
  with:
250
250
  command: probe
251
251
  allow-empty: 'true'
@@ -17,7 +17,7 @@ move together:
17
17
 
18
18
  ```yaml
19
19
  include:
20
- - remote: 'https://raw.githubusercontent.com/raccioly/testguard/v0.19.0/packaging/gitlab/testguard.gitlab-ci.yml'
20
+ - remote: 'https://raw.githubusercontent.com/raccioly/testguard/v0.20.0/packaging/gitlab/testguard.gitlab-ci.yml'
21
21
  inputs:
22
22
  dir: backend # where testguard.claims.json lives (default ".")
23
23
  post_note: true # post the brief on the merge request; needs TESTGUARD_GITLAB_TOKEN
@@ -34,7 +34,7 @@ gate that sees a commit before it exists.
34
34
  default_install_hook_types: [pre-commit, pre-push]
35
35
  repos:
36
36
  - repo: https://github.com/raccioly/testguard
37
- rev: v0.19.0
37
+ rev: v0.20.0
38
38
  hooks:
39
39
  - id: testguard-claims
40
40
  stages: [pre-commit]
@@ -215,12 +215,12 @@ jobs:
215
215
  node-version: 22
216
216
  - run: npm ci # every workspace's dependencies, from the root
217
217
  - name: gate
218
- uses: raccioly/testguard@v0.19.0
218
+ uses: raccioly/testguard@v0.20.0
219
219
  with:
220
220
  command: gate
221
221
  working-directory: ${{ matrix.project }}
222
222
  - name: probe
223
- uses: raccioly/testguard@v0.19.0
223
+ uses: raccioly/testguard@v0.20.0
224
224
  with:
225
225
  command: probe
226
226
  working-directory: ${{ matrix.project }}
@@ -96,6 +96,23 @@ lowest, but a label never waives a finding. `producedBy.producer` is separate:
96
96
  it records who *wrote the entry*, while `source` records where the *intent*
97
97
  came from.
98
98
 
99
+ ### Naming the requirement a claim defends
100
+
101
+ `source.ref` is free text, except that the `req:` prefix is reserved for a
102
+ structured requirement reference:
103
+
104
+ ```json
105
+ "source": { "kind": "spec", "ref": "req:acme.billing#FR-003" }
106
+ ```
107
+
108
+ The part before `#` is the spec ID and the part after it is the requirement
109
+ ID. A requirement-tracing tool can then tell which evidence speaks for which
110
+ requirement without guessing from a file path; DocGuard uses it to report the
111
+ tests that cite a changed requirement as re-verified. The form must be
112
+ declared with `kind: "spec"`. A malformed `req:` reference, or one under
113
+ another kind, fails validation. TestGuard never resolves it, so a spec ID that
114
+ does not exist is still valid here; the consumer checks it.
115
+
99
116
  ## Faults
100
117
 
101
118
  A fault is one concrete way the claim could be false, written as an exact
@@ -147,9 +147,9 @@ falsa.
147
147
  | npm | `npm i -D testguard-cli` y luego `npx testguard probe` |
148
148
  | pip | `pip install testguard-cli` y luego `testguard probe` (requiere Node ≥ 20) |
149
149
  | Homebrew | `brew tap raccioly/tap && brew install testguard` |
150
- | GitHub Action | `uses: raccioly/testguard@v0.19.0` |
150
+ | GitHub Action | `uses: raccioly/testguard@v0.20.0` |
151
151
  | pre-commit | `repo: https://github.com/raccioly/testguard`, hooks `testguard-claims`, `testguard-gate`, `testguard-probe` |
152
- | GitLab CI | `include: - remote: https://raw.githubusercontent.com/raccioly/testguard/v0.19.0/packaging/gitlab/testguard.gitlab-ci.yml` |
152
+ | GitLab CI | `include: - remote: https://raw.githubusercontent.com/raccioly/testguard/v0.20.0/packaging/gitlab/testguard.gitlab-ci.yml` |
153
153
 
154
154
  Los requisitos, las instalaciones sin conexión, `ENOVERSIONS` y todas las
155
155
  opciones de CI están en la
@@ -145,9 +145,9 @@ a cobertura. O TestGuard o admite porque ele falha quando a alegação é falsa.
145
145
  | npm | `npm i -D testguard-cli` e depois `npx testguard probe` |
146
146
  | pip | `pip install testguard-cli` e depois `testguard probe` (requer Node ≥ 20) |
147
147
  | Homebrew | `brew tap raccioly/tap && brew install testguard` |
148
- | GitHub Action | `uses: raccioly/testguard@v0.19.0` |
148
+ | GitHub Action | `uses: raccioly/testguard@v0.20.0` |
149
149
  | pre-commit | `repo: https://github.com/raccioly/testguard`, hooks `testguard-claims`, `testguard-gate`, `testguard-probe` |
150
- | GitLab CI | `include: - remote: https://raw.githubusercontent.com/raccioly/testguard/v0.19.0/packaging/gitlab/testguard.gitlab-ci.yml` |
150
+ | GitLab CI | `include: - remote: https://raw.githubusercontent.com/raccioly/testguard/v0.20.0/packaging/gitlab/testguard.gitlab-ci.yml` |
151
151
 
152
152
  Requisitos, instalações offline, `ENOVERSIONS` e todas as opções de CI estão
153
153
  no [guia de instalação](https://github.com/raccioly/testguard/blob/main/docs/installation.md).
@@ -85,9 +85,9 @@ expect(store.writeAudit).toHaveBeenCalledWith(
85
85
  | npm | `npm i -D testguard-cli`,然后 `npx testguard probe` |
86
86
  | pip | `pip install testguard-cli`,然后 `testguard probe`(需要 Node ≥ 20) |
87
87
  | Homebrew | `brew tap raccioly/tap && brew install testguard` |
88
- | GitHub Action | `uses: raccioly/testguard@v0.19.0` |
88
+ | GitHub Action | `uses: raccioly/testguard@v0.20.0` |
89
89
  | pre-commit | `repo: https://github.com/raccioly/testguard`,钩子 `testguard-claims`、`testguard-gate`、`testguard-probe` |
90
- | GitLab CI | `include: - remote: https://raw.githubusercontent.com/raccioly/testguard/v0.19.0/packaging/gitlab/testguard.gitlab-ci.yml` |
90
+ | GitLab CI | `include: - remote: https://raw.githubusercontent.com/raccioly/testguard/v0.20.0/packaging/gitlab/testguard.gitlab-ci.yml` |
91
91
 
92
92
  环境要求、离线安装、`ENOVERSIONS` 以及所有 CI 选项,见
93
93
  [安装指南](https://github.com/raccioly/testguard/blob/main/docs/installation.md)。
@@ -31,9 +31,9 @@ packages in total.
31
31
  | npm devDependency | `npm i -D testguard-cli` then `npx testguard probe` | a JavaScript or TypeScript project: version pinned in the lockfile, and the local install the agent layer prefers |
32
32
  | pip | `pip install testguard-cli` then `testguard probe` | a Python team that does not want to touch npm directly (still needs Node ≥ 20) |
33
33
  | Homebrew | `brew tap raccioly/tap && brew install testguard` | a machine-wide `testguard` on `PATH` |
34
- | GitHub Action | `uses: raccioly/testguard@v0.19.0` | CI on GitHub |
34
+ | GitHub Action | `uses: raccioly/testguard@v0.20.0` | CI on GitHub |
35
35
  | pre-commit | `repo: https://github.com/raccioly/testguard` with a release tag as `rev:` ([below](#pre-commit)) | local hooks on commit and push |
36
- | GitLab CI | `include: - remote: https://raw.githubusercontent.com/raccioly/testguard/v0.19.0/packaging/gitlab/testguard.gitlab-ci.yml` | CI on GitLab |
36
+ | GitLab CI | `include: - remote: https://raw.githubusercontent.com/raccioly/testguard/v0.20.0/packaging/gitlab/testguard.gitlab-ci.yml` | CI on GitLab |
37
37
 
38
38
  ### npx
39
39
 
@@ -114,7 +114,7 @@ tarball, checked against a `sha256` recorded at release time.
114
114
  ```yaml
115
115
  - uses: actions/checkout@v7
116
116
  with: { fetch-depth: 0 }
117
- - uses: raccioly/testguard@v0.19.0
117
+ - uses: raccioly/testguard@v0.20.0
118
118
  with: { command: gate }
119
119
  ```
120
120
 
@@ -128,7 +128,7 @@ and complete pull-request and main-branch workflows, are in
128
128
  ```yaml
129
129
  repos:
130
130
  - repo: https://github.com/raccioly/testguard
131
- rev: v0.19.0
131
+ rev: v0.20.0
132
132
  hooks:
133
133
  - id: testguard-claims
134
134
  - id: testguard-gate
@@ -144,7 +144,7 @@ three hooks, their stages and their arguments are in
144
144
 
145
145
  ```yaml
146
146
  include:
147
- - remote: 'https://raw.githubusercontent.com/raccioly/testguard/v0.19.0/packaging/gitlab/testguard.gitlab-ci.yml'
147
+ - remote: 'https://raw.githubusercontent.com/raccioly/testguard/v0.20.0/packaging/gitlab/testguard.gitlab-ci.yml'
148
148
  inputs: { dir: . }
149
149
  ```
150
150
 
@@ -144,7 +144,7 @@
144
144
  <div class="page">
145
145
  <div class="masthead">
146
146
  <div class="wordmark">Test<span class="mark">Guard</span></div>
147
- <div class="meta">Technical Brief · v0.19.0 · MIT</div>
147
+ <div class="meta">Technical Brief · v0.20.0 · MIT</div>
148
148
  </div>
149
149
 
150
150
  <h1>Your tests pass. That is not the same as your tests working.</h1>
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "testguard-cli",
3
- "version": "0.19.0",
3
+ "version": "0.20.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "testguard-cli",
9
- "version": "0.19.0",
9
+ "version": "0.20.0",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "ajv": "8.20.0"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testguard-cli",
3
- "version": "0.19.0",
3
+ "version": "0.20.0",
4
4
  "description": "Breaks your code on purpose and reports every promise your tests did not notice breaking. Mutation testing bound to the claims a project makes — vitest, jest, Playwright, pytest and unittest.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -3,7 +3,7 @@
3
3
  # Include it from a project's .gitlab-ci.yml, pinned to a release:
4
4
  #
5
5
  # include:
6
- # - remote: 'https://raw.githubusercontent.com/raccioly/testguard/v0.19.0/packaging/gitlab/testguard.gitlab-ci.yml'
6
+ # - remote: 'https://raw.githubusercontent.com/raccioly/testguard/v0.20.0/packaging/gitlab/testguard.gitlab-ci.yml'
7
7
  # inputs:
8
8
  # dir: backend # where testguard.claims.json lives (default ".")
9
9
  # post_note: true # post the brief as a merge-request note (needs TESTGUARD_GITLAB_TOKEN, api scope)
@@ -33,7 +33,7 @@ spec:
33
33
  inputs:
34
34
  version:
35
35
  description: testguard-cli version to run
36
- default: "0.19.0"
36
+ default: "0.20.0"
37
37
  dir:
38
38
  description: directory whose test runner is invoked (where testguard.claims.json lives)
39
39
  default: "."
@@ -15,8 +15,8 @@
15
15
  class Testguard < Formula
16
16
  desc "Proves a test suite defends the claims a project makes"
17
17
  homepage "https://github.com/raccioly/testguard"
18
- url "https://registry.npmjs.org/testguard-cli/-/testguard-cli-0.19.0.tgz"
19
- sha256 "15ed175733cb66aa3ae5e5ee5ea1465d035c99280989bf4c15256a97ec3beb83"
18
+ url "https://registry.npmjs.org/testguard-cli/-/testguard-cli-0.20.0.tgz"
19
+ sha256 "05887f44c623920b7c0d7fa8c9d71039e86f6e5825b037049c4346c4ffbc6992"
20
20
  license "MIT"
21
21
 
22
22
  depends_on "node"
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "testguard-cli"
7
- version = "0.19.0"
7
+ version = "0.20.0"
8
8
  description = "Breaks your code on purpose and reports every promise your tests did not notice breaking. Mutation testing bound to the claims a project makes — vitest, jest, Playwright, pytest and unittest. A wrapper that runs the Node.js CLI (requires Node.js 20+): a project-local node_modules/testguard-cli when present, otherwise the npm release of this same version through npx."
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -16,6 +16,24 @@ These are declarations, not authentication of independence, chronology,
16
16
  production occurrence or correctness. The optional reference remains opaque
17
17
  metadata (at most 512 characters); verification does not fetch it. Producer
18
18
  provenance and measured test independence are separate signals.
19
+
20
+ One prefix is reserved. A `ref` that starts with `req:` is a structured
21
+ requirement reference, `req:<spec-id>#<requirement-id>`, with `<spec-id>`
22
+ matching `[A-Za-z0-9][A-Za-z0-9._-]{0,127}` and `<requirement-id>` matching
23
+ `[A-Za-z][A-Za-z0-9._-]{0,63}`. It must be declared with kind `spec`.
24
+ Validation rejects a malformed one at `/source/ref` and one under another kind
25
+ at `/source/kind`; it is never degraded to opaque, because a typo would
26
+ otherwise read as "no evidence for this requirement". Every other `ref` stays
27
+ opaque. A structured reference is still a declaration. TestGuard does not
28
+ resolve it, fetch the spec or check that the requirement exists. A consumer
29
+ that keeps a requirement index, such as DocGuard, compares
30
+ `<spec-id>#<requirement-id>` exactly against its own keys. `requirementRef()`
31
+ in `spec/lib/origins.mjs` parses the same pattern the shared
32
+ `$defs/claimSource` declares. Older readers accept the form as an opaque string,
33
+ so adopting it needs no upgrade; only readers with this rule catch a malformed
34
+ one. The reference is claim metadata: editing it makes saved evidence for that
35
+ claim stale, as any source edit does. Fingerprints, verdicts and gates do not
36
+ change.
19
37
  Adding kinds does not change verdicts, baseline/fingerprint identity or default
20
38
  gates. Existing ranking weights stay unchanged; new kinds use the existing 0.9
21
39
  fallback, not an invented strength hierarchy. Existing documents remain valid
@@ -5,6 +5,7 @@ import { rank } from '../../src/probe/rank.mjs';
5
5
  import { fileURLToPath } from 'node:url';
6
6
  import { scaffoldFile } from '../../src/scaffold/scaffold.mjs';
7
7
  import { poolDrafts } from '../../src/sweep/pool.mjs';
8
+ import { REQUIREMENT_REF_PATTERN, requirementRef } from '../lib/origins.mjs';
8
9
 
9
10
  const kinds = ['spec', 'adr', 'annotation', 'comment', 'manual', 'doc', 'bug', 'incident', 'review', 'inferred'];
10
11
  const example = (kind) => JSON.parse(readFileSync(new URL(`./examples/${kind}.json`, import.meta.url), 'utf8'));
@@ -64,3 +65,59 @@ describe('declared claim origins — vocabulary, not authenticated independence'
64
65
  expect(kinds.slice(5).map(score)).toEqual([0.9, 0.9, 0.9, 0.9, 0.9]);
65
66
  });
66
67
  });
68
+
69
+ // The contract table in GATE-SEMANTICS.md "Declared claim origins": the schema
70
+ // and requirementRef() must accept exactly the same structured references.
71
+ describe('structured requirement references — req:<spec-id>#<requirement-id>', () => {
72
+ const rows = [
73
+ [{ kind: 'spec', ref: 'req:acme.billing#FR-003' }, true, { specId: 'acme.billing', requirementId: 'FR-003' }],
74
+ [{ kind: 'spec', ref: 'req:Acme_Billing-2#NFR-01.2' }, true, { specId: 'Acme_Billing-2', requirementId: 'NFR-01.2' }],
75
+ [{ kind: 'spec', ref: `req:${'a'.repeat(128)}#${'R'.repeat(64)}` }, true, { specId: 'a'.repeat(128), requirementId: 'R'.repeat(64) }],
76
+ [{ kind: 'spec', ref: 'specs/001/spec.md#FR-003' }, true, null],
77
+ [{ kind: 'spec', ref: 'requirement FR-003' }, true, null],
78
+ [{ kind: 'spec' }, true, null],
79
+ [{ kind: 'doc', ref: 'docs/spec.md#req:acme#FR-1' }, true, null],
80
+ [{ kind: 'spec', ref: 'req:acme.billing' }, false, null],
81
+ [{ kind: 'spec', ref: 'req:#FR-1' }, false, null],
82
+ [{ kind: 'spec', ref: 'req:acme#' }, false, null],
83
+ [{ kind: 'spec', ref: 'req:acme billing#FR-1' }, false, null],
84
+ [{ kind: 'spec', ref: 'req:a/b#FR-1' }, false, null],
85
+ [{ kind: 'spec', ref: 'req:acme#FR-1#x' }, false, null],
86
+ [{ kind: 'spec', ref: 'req:acme#1FR' }, false, null],
87
+ [{ kind: 'spec', ref: 'req:acme:x#FR-1' }, false, null],
88
+ [{ kind: 'spec', ref: 'req:.acme#FR-1' }, false, null],
89
+ [{ kind: 'spec', ref: 'req:acme#FR-1\n' }, false, null],
90
+ [{ kind: 'spec', ref: `req:${'a'.repeat(129)}#FR-1` }, false, null],
91
+ [{ kind: 'spec', ref: `req:acme#R${'0'.repeat(64)}` }, false, null],
92
+ [{ kind: 'doc', ref: 'req:acme#FR-1' }, false, null],
93
+ [{ kind: 'inferred', ref: 'req:acme#FR-1' }, false, null],
94
+ ];
95
+ for (const format of ['claims', 'evidence']) {
96
+ it.each(rows)(`${format}: %o is valid=%s`, (source, valid) => {
97
+ const doc = example(format);
98
+ const target = sourceOf(format, doc);
99
+ for (const key of Object.keys(target)) delete target[key];
100
+ Object.assign(target, source);
101
+ const result = validate(format, doc);
102
+ expect(result.ok, JSON.stringify(result.errors)).toBe(valid);
103
+ if (!valid) expect(result.errors.some((e) => /\/source(?:\/(?:ref|kind))?$/.test(e.path ?? e.instancePath ?? ''))).toBe(true);
104
+ });
105
+ }
106
+ it.each(rows)('requirementRef(%o) parses only what the schema admits as structured', (source, valid, parsed) => {
107
+ expect(requirementRef(source)).toEqual(parsed);
108
+ if (parsed) expect(valid).toBe(true);
109
+ });
110
+ it('exports one pattern the schema shares', () => {
111
+ const common = JSON.parse(readFileSync(new URL('../schemas/common.schema.json', import.meta.url), 'utf8'));
112
+ const ref = common.$defs.claimSource.properties.ref;
113
+ expect(ref.pattern).toContain(REQUIREMENT_REF_PATTERN.source.replace(/^\^/, '').replace(/\$$/, ''));
114
+ for (const schema of ['claims', 'evidence']) {
115
+ expect(readFileSync(new URL(`../schemas/${schema}.schema.json`, import.meta.url), 'utf8')).toContain('urn:claimspec:v1:common#/$defs/claimSource');
116
+ }
117
+ });
118
+ it('rejects malformed or non-object sources without guessing', () => {
119
+ for (const source of [undefined, null, 'req:acme#FR-1', { ref: 'req:acme#FR-1' }, { kind: 'spec', ref: 42 }]) {
120
+ expect(requirementRef(source)).toBe(null);
121
+ }
122
+ });
123
+ });
@@ -5,6 +5,25 @@ import { isDeepStrictEqual } from 'node:util';
5
5
  const common = JSON.parse(readFileSync(new URL('../schemas/common.schema.json', import.meta.url), 'utf8'));
6
6
  export const CLAIM_SOURCE_KINDS = Object.freeze([...common.$defs.claimSourceKind.enum]);
7
7
  const kindSet = new Set(CLAIM_SOURCE_KINDS);
8
+
9
+ /**
10
+ * A structured requirement reference, `req:<spec-id>#<requirement-id>`, read
11
+ * from the one pattern the shared schema declares (`$defs/claimSource`). It is
12
+ * a declaration: nothing here resolves the spec or checks the requirement
13
+ * exists. Consumers compare `specId#requirementId` exactly.
14
+ */
15
+ const sourceRef = common.$defs.claimSource.properties.ref.pattern;
16
+ // The schema's second alternative is the structured form; the first keeps every other ref opaque.
17
+ export const REQUIREMENT_REF_PATTERN = new RegExp(`^${sourceRef.slice(sourceRef.indexOf('|^') + 2)}`, 'u');
18
+ const REQUIREMENT_REF_PARTS = /^req:([^#]+)#(.+)$/u;
19
+
20
+ /** `{ specId, requirementId }` for a valid structured `spec` reference; `null` for anything else. */
21
+ export function requirementRef(source) {
22
+ if (!source || typeof source !== 'object' || source.kind !== 'spec' || typeof source.ref !== 'string') return null;
23
+ if (!REQUIREMENT_REF_PATTERN.test(source.ref)) return null;
24
+ const [, specId, requirementId] = REQUIREMENT_REF_PARTS.exec(source.ref);
25
+ return { specId, requirementId };
26
+ }
8
27
  const counts = () => Object.fromEntries(CLAIM_SOURCE_KINDS.map((kind) => [kind, 0]));
9
28
 
10
29
  // Consumers validate their full document first. These narrow guards prevent
@@ -46,21 +46,7 @@
46
46
  "maxLength": 2000
47
47
  },
48
48
  "source": {
49
- "description": "Declared origin of claim intent. A source label or opaque reference does not authenticate independence, chronology or correctness. Producer provenance and measured test independence are separate.",
50
- "type": "object",
51
- "required": [
52
- "kind"
53
- ],
54
- "properties": {
55
- "kind": {
56
- "$ref": "urn:claimspec:v1:common#/$defs/claimSourceKind"
57
- },
58
- "ref": {
59
- "type": "string",
60
- "maxLength": 512
61
- }
62
- },
63
- "additionalProperties": false
49
+ "$ref": "urn:claimspec:v1:common#/$defs/claimSource"
64
50
  },
65
51
  "severity": {
66
52
  "$ref": "urn:claimspec:v1:common#/$defs/severity"
@@ -77,6 +77,22 @@
77
77
  "description": "Declared origin of claim intent, not authenticated independence or an evidence-strength order. References remain opaque; producer provenance and measured test independence are separate.",
78
78
  "enum": ["spec", "adr", "annotation", "comment", "manual", "doc", "bug", "incident", "review", "inferred"]
79
79
  },
80
+ "claimSource": {
81
+ "description": "Declared origin of claim intent. A source label or reference does not authenticate independence, chronology or correctness. Producer provenance and measured test independence are separate. `ref` is opaque, except that the `req:` prefix is reserved for a structured requirement reference, `req:<spec-id>#<requirement-id>`, which must be declared with kind `spec`. Neither form is ever resolved or fetched.",
82
+ "type": "object",
83
+ "required": ["kind"],
84
+ "properties": {
85
+ "kind": { "$ref": "#/$defs/claimSourceKind" },
86
+ "ref": {
87
+ "type": "string",
88
+ "maxLength": 512,
89
+ "pattern": "^(?!req:)[\\s\\S]*$|^req:[A-Za-z0-9][A-Za-z0-9._-]{0,127}#[A-Za-z][A-Za-z0-9._-]{0,63}$"
90
+ }
91
+ },
92
+ "additionalProperties": false,
93
+ "if": { "type": "object", "required": ["ref"], "properties": { "ref": { "type": "string", "pattern": "^req:" } } },
94
+ "then": { "properties": { "kind": { "const": "spec" } } }
95
+ },
80
96
  "nestedProject": {
81
97
  "description": "Changed files delegated to a separately validated descendant TestGuard project. This is not coverage or evidence; run that project's gate separately.",
82
98
  "type": "object",
@@ -339,20 +339,7 @@
339
339
  "$ref": "urn:claimspec:v1:common#/$defs/severity"
340
340
  },
341
341
  "source": {
342
- "type": "object",
343
- "required": [
344
- "kind"
345
- ],
346
- "properties": {
347
- "kind": {
348
- "$ref": "urn:claimspec:v1:common#/$defs/claimSourceKind"
349
- },
350
- "ref": {
351
- "type": "string",
352
- "maxLength": 512
353
- }
354
- },
355
- "additionalProperties": false
342
+ "$ref": "urn:claimspec:v1:common#/$defs/claimSource"
356
343
  },
357
344
  "producedBy": {
358
345
  "$ref": "urn:claimspec:v1:common#/$defs/provenance"