mcp-warden-cli 2.0.0__tar.gz → 2.2.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 (447) hide show
  1. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/.github/workflows/deps-locked.yml +70 -0
  2. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/.github/workflows/integrity-gate.yml +24 -0
  3. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/.github/workflows/release.yml +41 -16
  4. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/CHANGELOG.md +107 -1
  5. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/DOCUMENTATION_INDEX.md +35 -11
  6. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/PKG-INFO +34 -33
  7. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/README.md +30 -32
  8. mcp_warden_cli-2.2.0/RELEASING.md +306 -0
  9. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/SYSTEM_CONTEXT_DIAGRAM.md +31 -10
  10. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/action/requirements.lock +295 -296
  11. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/AGENT_GATES.md +23 -8
  12. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/AGENT_TRUST_KERNEL.md +27 -9
  13. mcp_warden_cli-2.2.0/docs/ARTIFACT_TRUST.md +160 -0
  14. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/COMMUNITY_CORPUS.md +10 -3
  15. mcp_warden_cli-2.2.0/docs/DECISION_RECEIPTS.md +265 -0
  16. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/POLICY_ENFORCEMENT.md +15 -8
  17. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/SIGNING.md +38 -2
  18. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/SPEC.md +6 -0
  19. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/THREAT_MODEL.md +19 -0
  20. mcp_warden_cli-2.2.0/docs/archive/2026-10-04-readme-community-consensus.md +30 -0
  21. mcp_warden_cli-2.2.0/docs/plans/2026-07-19-decision-receipts-design.md +314 -0
  22. mcp_warden_cli-2.2.0/docs/plans/2026-07-19-decision-receipts-implementation.md +542 -0
  23. mcp_warden_cli-2.2.0/docs/plans/2026-10-02-pypi-automation-repair.md +53 -0
  24. mcp_warden_cli-2.2.0/docs/plans/2026-10-03-checkpoint-artifact-trust.md +55 -0
  25. mcp_warden_cli-2.2.0/docs/plans/2026-10-04-dse717-council-fixes.md +48 -0
  26. mcp_warden_cli-2.2.0/docs/plans/2026-10-04-dse717-reconciliation.md +135 -0
  27. mcp_warden_cli-2.2.0/docs-site/artifact-trust.md +63 -0
  28. mcp_warden_cli-2.2.0/docs-site/decision-receipts.md +56 -0
  29. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/mkdocs.yml +2 -0
  30. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/pyproject.toml +4 -1
  31. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/requirements-dev.lock +15 -13
  32. mcp_warden_cli-2.2.0/scripts/verify_pypi_oidc.py +149 -0
  33. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/__init__.py +1 -1
  34. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/adapter_conformance.py +4 -0
  35. mcp_warden_cli-2.2.0/src/mcp_warden/artifact_payload.py +110 -0
  36. mcp_warden_cli-2.2.0/src/mcp_warden/artifact_trust.py +219 -0
  37. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/auth_audit.py +2 -180
  38. mcp_warden_cli-2.2.0/src/mcp_warden/auth_refs.py +230 -0
  39. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/capture.py +139 -63
  40. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/check_core.py +5 -3
  41. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/cli.py +14 -6
  42. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/cli_lock.py +89 -28
  43. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/cli_sign.py +61 -5
  44. mcp_warden_cli-2.2.0/src/mcp_warden/cli_trust.py +154 -0
  45. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/corpus.py +4 -2
  46. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/corpus_coordinate.py +8 -2
  47. mcp_warden_cli-2.2.0/src/mcp_warden/decision_governor.py +210 -0
  48. mcp_warden_cli-2.2.0/src/mcp_warden/decision_receipts.py +107 -0
  49. mcp_warden_cli-2.2.0/src/mcp_warden/enforcement_result_v2.py +110 -0
  50. mcp_warden_cli-2.2.0/src/mcp_warden/evidence_coordinator.py +290 -0
  51. mcp_warden_cli-2.2.0/src/mcp_warden/evidence_floor.py +60 -0
  52. mcp_warden_cli-2.2.0/src/mcp_warden/evidence_helpers.py +117 -0
  53. mcp_warden_cli-2.2.0/src/mcp_warden/evidence_latch.py +79 -0
  54. mcp_warden_cli-2.2.0/src/mcp_warden/evidence_models.py +229 -0
  55. mcp_warden_cli-2.2.0/src/mcp_warden/evidence_recovery.py +260 -0
  56. mcp_warden_cli-2.2.0/src/mcp_warden/evidence_reference.py +151 -0
  57. mcp_warden_cli-2.2.0/src/mcp_warden/evidence_state.py +262 -0
  58. mcp_warden_cli-2.2.0/src/mcp_warden/governance_integrity.py +62 -0
  59. mcp_warden_cli-2.2.0/src/mcp_warden/governed_decision.py +104 -0
  60. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/handler_identity.py +43 -3
  61. mcp_warden_cli-2.2.0/src/mcp_warden/policy_enforcement_v2.py +299 -0
  62. mcp_warden_cli-2.2.0/src/mcp_warden/policy_enforcement_v2_helpers.py +48 -0
  63. mcp_warden_cli-2.2.0/src/mcp_warden/receipt_conformance.py +240 -0
  64. mcp_warden_cli-2.2.0/src/mcp_warden/receipt_conformance_models.py +156 -0
  65. mcp_warden_cli-2.2.0/src/mcp_warden/receipt_kernel.py +224 -0
  66. mcp_warden_cli-2.2.0/src/mcp_warden/receipt_log.py +253 -0
  67. mcp_warden_cli-2.2.0/src/mcp_warden/receipt_models.py +188 -0
  68. mcp_warden_cli-2.2.0/src/mcp_warden/receipt_projection.py +106 -0
  69. mcp_warden_cli-2.2.0/src/mcp_warden/receipt_replay.py +278 -0
  70. mcp_warden_cli-2.2.0/src/mcp_warden/receipt_verification.py +168 -0
  71. mcp_warden_cli-2.2.0/src/mcp_warden/rule_engine.py +109 -0
  72. mcp_warden_cli-2.2.0/src/mcp_warden/rule_models.py +149 -0
  73. mcp_warden_cli-2.2.0/src/mcp_warden/signer_authorization.py +254 -0
  74. mcp_warden_cli-2.2.0/tests/dse717_council_fixtures.py +66 -0
  75. mcp_warden_cli-2.2.0/tests/fixtures/capability_server.py +38 -0
  76. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fixtures/gen_corpus.py +3 -2
  77. mcp_warden_cli-2.2.0/tests/fuzz/test_fuzz_receipts.py +207 -0
  78. mcp_warden_cli-2.2.0/tests/receipt_fixtures.py +312 -0
  79. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_adapter_conformance.py +21 -0
  80. mcp_warden_cli-2.2.0/tests/test_artifact_trust.py +190 -0
  81. mcp_warden_cli-2.2.0/tests/test_artifact_trust_integration.py +171 -0
  82. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_auth_audit.py +44 -0
  83. mcp_warden_cli-2.2.0/tests/test_capture_capabilities.py +31 -0
  84. mcp_warden_cli-2.2.0/tests/test_capture_page_cap.py +136 -0
  85. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_capture_pagination.py +80 -5
  86. mcp_warden_cli-2.2.0/tests/test_cli_trust.py +187 -0
  87. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_corpus.py +21 -11
  88. mcp_warden_cli-2.2.0/tests/test_decision_receipts.py +93 -0
  89. mcp_warden_cli-2.2.0/tests/test_dse717_council_fixes.py +183 -0
  90. mcp_warden_cli-2.2.0/tests/test_dse717_council_floors.py +82 -0
  91. mcp_warden_cli-2.2.0/tests/test_dse717_council_rotation.py +211 -0
  92. mcp_warden_cli-2.2.0/tests/test_dse717_review_regressions.py +272 -0
  93. mcp_warden_cli-2.2.0/tests/test_evidence_coordinator.py +90 -0
  94. mcp_warden_cli-2.2.0/tests/test_evidence_recovery.py +113 -0
  95. mcp_warden_cli-2.2.0/tests/test_evidence_state.py +83 -0
  96. mcp_warden_cli-2.2.0/tests/test_evidence_state_v2_contract.py +59 -0
  97. mcp_warden_cli-2.2.0/tests/test_handler_boundary.py +89 -0
  98. mcp_warden_cli-2.2.0/tests/test_lock_sign.py +219 -0
  99. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_policy_decision.py +16 -0
  100. mcp_warden_cli-2.2.0/tests/test_policy_enforcement_v2.py +131 -0
  101. mcp_warden_cli-2.2.0/tests/test_receipt_conformance.py +191 -0
  102. mcp_warden_cli-2.2.0/tests/test_receipt_hardening.py +58 -0
  103. mcp_warden_cli-2.2.0/tests/test_receipt_log.py +147 -0
  104. mcp_warden_cli-2.2.0/tests/test_receipt_projection.py +20 -0
  105. mcp_warden_cli-2.2.0/tests/test_receipt_replay.py +141 -0
  106. mcp_warden_cli-2.2.0/tests/test_receipt_verification.py +29 -0
  107. mcp_warden_cli-2.2.0/tests/test_release_oidc.py +199 -0
  108. mcp_warden_cli-2.2.0/tests/test_rule_engine.py +239 -0
  109. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_workflow_pins.py +14 -11
  110. mcp_warden_cli-2.0.0/.github/dependabot.yml +0 -29
  111. mcp_warden_cli-2.0.0/RELEASING.md +0 -217
  112. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  113. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  114. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  115. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  116. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/.github/workflows/action-test.yml +0 -0
  117. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/.github/workflows/docs.yml +0 -0
  118. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/.github/workflows/examples.yml +0 -0
  119. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/.github/workflows/sigstore-fixture.yml +0 -0
  120. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/.gitignore +0 -0
  121. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/.gitleaks.toml +0 -0
  122. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/.pre-commit-hooks.yaml +0 -0
  123. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/CODEOWNERS +0 -0
  124. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/CODE_OF_CONDUCT.md +0 -0
  125. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/CONTRIBUTING.md +0 -0
  126. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/LICENSE +0 -0
  127. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/Makefile +0 -0
  128. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/SECURITY.md +0 -0
  129. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/action/build-requirements.lock +0 -0
  130. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/action.yml +0 -0
  131. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/CHECKS.md +0 -0
  132. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/CONTENT_ENVELOPE.md +0 -0
  133. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/DOCTOR.md +0 -0
  134. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/GUARD_PROXY.md +0 -0
  135. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/GUARD_PROXY_V3.md +0 -0
  136. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/PIN_CHECK_DEMO.md +0 -0
  137. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/POLICY_MODEL.md +0 -0
  138. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/RESULT_INSPECTION.md +0 -0
  139. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/THREAT_MODEL_V2.md +0 -0
  140. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/WARDEN_LOCK_EXAMPLE.md +0 -0
  141. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/WARDEN_LOCK_SCHEMA.md +0 -0
  142. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/archive/2026-10-02-runtime-cli-examples.md +0 -0
  143. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/plans/2026-07-18-agent-trust-kernel-design.md +0 -0
  144. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/plans/2026-07-18-content-envelope-design.md +0 -0
  145. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/plans/2026-07-19-pdp-pep-design.md +0 -0
  146. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs/plans/2026-10-02-tool-integrity-upgrade.md +0 -0
  147. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs-site/checklist.md +0 -0
  148. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs-site/comparison.md +0 -0
  149. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs-site/index.md +0 -0
  150. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs-site/lock-format.md +0 -0
  151. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs-site/pin-in-ci.md +0 -0
  152. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs-site/quickstart.md +0 -0
  153. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs-site/rug-pull.md +0 -0
  154. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/docs-site/tool-poisoning.md +0 -0
  155. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/examples/README.md +0 -0
  156. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/examples/agent-gates/README.md +0 -0
  157. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/examples/agent-gates/evidence-fail.json +0 -0
  158. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/examples/agent-gates/evidence-pass.json +0 -0
  159. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/examples/agent-gates/gate-policy.json +0 -0
  160. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/examples/agent-gates/mcp-config-audit-demo.json +0 -0
  161. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/examples/github-actions/matrix-multiple-servers.yml +0 -0
  162. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/examples/github-actions/pin-on-merge-check-on-pr.yml +0 -0
  163. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/examples/github-actions/private-repo-no-sarif.yml +0 -0
  164. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/examples/github-actions/sarif-upload.yml +0 -0
  165. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/examples/gitlab-ci/.gitlab-ci.yml +0 -0
  166. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/examples/pinned-servers/server-everything/README.md +0 -0
  167. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/examples/pinned-servers/server-everything/warden.lock +0 -0
  168. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/examples/pinned-servers/server-memory/README.md +0 -0
  169. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/examples/pinned-servers/server-memory/warden.lock +0 -0
  170. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/examples/pinned-servers/server-sequential-thinking/README.md +0 -0
  171. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/examples/pinned-servers/server-sequential-thinking/warden.lock +0 -0
  172. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/examples/pre-commit/.pre-commit-config.yaml +0 -0
  173. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/packages/lock-ts/.gitignore +0 -0
  174. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/packages/lock-ts/LICENSE +0 -0
  175. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/packages/lock-ts/README.md +0 -0
  176. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/packages/lock-ts/package-lock.json +0 -0
  177. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/packages/lock-ts/package.json +0 -0
  178. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/packages/lock-ts/src/capabilities.ts +0 -0
  179. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/packages/lock-ts/src/digest.ts +0 -0
  180. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/packages/lock-ts/src/drift.ts +0 -0
  181. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/packages/lock-ts/src/index.ts +0 -0
  182. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/packages/lock-ts/src/jcs.ts +0 -0
  183. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/packages/lock-ts/src/lock.ts +0 -0
  184. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/packages/lock-ts/src/py.ts +0 -0
  185. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/packages/lock-ts/src/skeleton.ts +0 -0
  186. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/packages/lock-ts/test/vectors.test.ts +0 -0
  187. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/packages/lock-ts/tsconfig.json +0 -0
  188. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/checks.py +0 -0
  189. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/checks_secret.py +0 -0
  190. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/checks_supply.py +0 -0
  191. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/cli_auth.py +0 -0
  192. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/cli_corpus.py +0 -0
  193. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/cli_deploy_gate.py +0 -0
  194. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/cli_diff.py +0 -0
  195. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/cli_doctor.py +0 -0
  196. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/cli_guard.py +0 -0
  197. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/content_envelope.py +0 -0
  198. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/content_models.py +0 -0
  199. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/corpus_trust.py +0 -0
  200. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/corpus_verify.py +0 -0
  201. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/decision_models.py +0 -0
  202. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/deploy_gate.py +0 -0
  203. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/doctor.py +0 -0
  204. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/doctor_discovery.py +0 -0
  205. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/doctor_funnel.py +0 -0
  206. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/doctor_jsonc.py +0 -0
  207. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/doctor_paths.py +0 -0
  208. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/drift.py +0 -0
  209. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/drift_tool_metadata.py +0 -0
  210. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/emit_res.py +0 -0
  211. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/emitters.py +0 -0
  212. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/executable_bundle.py +0 -0
  213. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/framing.py +0 -0
  214. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/guard.py +0 -0
  215. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/guard_banner.py +0 -0
  216. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/guard_io.py +0 -0
  217. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/guard_lifecycle.py +0 -0
  218. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/guard_list_gate.py +0 -0
  219. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/guard_loop.py +0 -0
  220. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/guard_result.py +0 -0
  221. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/guard_strict.py +0 -0
  222. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/hashing.py +0 -0
  223. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/inspector.py +0 -0
  224. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/lockfile.py +0 -0
  225. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/models.py +0 -0
  226. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/net_rules.py +0 -0
  227. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/policy_decision.py +0 -0
  228. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/policy_enforcement.py +0 -0
  229. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/policy_eval.py +0 -0
  230. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/policy_model.py +0 -0
  231. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/precommit.py +0 -0
  232. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/provenance.py +0 -0
  233. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/redact.py +0 -0
  234. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/res_catalog.py +0 -0
  235. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/res_dns.py +0 -0
  236. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/res_net.py +0 -0
  237. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/res_rules.py +0 -0
  238. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/result_inspection.py +0 -0
  239. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/schema_diff.py +0 -0
  240. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/signing.py +0 -0
  241. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/tokenizer.py +0 -0
  242. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/src/mcp_warden/wire_block.py +0 -0
  243. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/__init__.py +0 -0
  244. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fixtures/_sdk_compat.py +0 -0
  245. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fixtures/clean.warden.lock +0 -0
  246. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fixtures/clean_listchange.warden.lock +0 -0
  247. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fixtures/clean_server.py +0 -0
  248. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fixtures/corpus/README.md +0 -0
  249. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fixtures/corpus/attesters.json +0 -0
  250. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__clean/1.0.0/alice.lock +0 -0
  251. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__clean/1.0.0/alice.lock.sigstore +0 -0
  252. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__clean/1.0.0/bob.lock +0 -0
  253. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__clean/1.0.0/bob.lock.sigstore +0 -0
  254. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__corrupt/1.0.0/alice.lock +0 -0
  255. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__corrupt/1.0.0/alice.lock.sigstore +0 -0
  256. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__nosig/1.0.0/alice.lock +0 -0
  257. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__other/1.0.0/alice.lock +0 -0
  258. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__other/1.0.0/alice.lock.sigstore +0 -0
  259. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__other/1.0.0/bob.lock +0 -0
  260. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__other/1.0.0/bob.lock.sigstore +0 -0
  261. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__solo/1.0.0/alice.lock +0 -0
  262. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__solo/1.0.0/alice.lock.sigstore +0 -0
  263. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__split/1.0.0/alice.lock +0 -0
  264. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__split/1.0.0/alice.lock.sigstore +0 -0
  265. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__split/1.0.0/bob.lock +0 -0
  266. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__split/1.0.0/bob.lock.sigstore +0 -0
  267. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__stranger/1.0.0/mallory.lock +0 -0
  268. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__stranger/1.0.0/mallory.lock.sigstore +0 -0
  269. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__unpinned/1.0.0/carol.lock +0 -0
  270. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__unpinned/1.0.0/carol.lock.sigstore +0 -0
  271. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__wrongsig/1.0.0/alice.lock +0 -0
  272. {mcp_warden_cli-2.0.0/tests/fixtures/corpus/locks → mcp_warden_cli-2.2.0/tests/fixtures/corpus/locks/schema-4}/npm/@example__wrongsig/1.0.0/alice.lock.sigstore +0 -0
  273. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fixtures/crash_server.py +0 -0
  274. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fixtures/fault_guard_launcher.py +0 -0
  275. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fixtures/legacy-v3.warden.lock +0 -0
  276. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fixtures/listchange_server.py +0 -0
  277. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fixtures/mutated_server.py +0 -0
  278. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fixtures/overcap_server.py +0 -0
  279. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fixtures/poison_server.py +0 -0
  280. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fixtures/tool_integrity_server.py +0 -0
  281. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fixtures/tool_metadata_listchange_server.py +0 -0
  282. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fuzz/__init__.py +0 -0
  283. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fuzz/conftest.py +0 -0
  284. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fuzz/test_fuzz_ansi.py +0 -0
  285. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fuzz/test_fuzz_content_envelope.py +0 -0
  286. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fuzz/test_fuzz_domain.py +0 -0
  287. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fuzz/test_fuzz_framing.py +0 -0
  288. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fuzz/test_fuzz_policy_decision.py +0 -0
  289. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/fuzz/test_fuzz_redact.py +0 -0
  290. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_action_yml.py +0 -0
  291. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_agent_gates_examples.py +0 -0
  292. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_capture_http.py +0 -0
  293. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_capture_model_dump.py +0 -0
  294. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_checks.py +0 -0
  295. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_cli_version.py +0 -0
  296. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_content_envelope.py +0 -0
  297. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_corpus_cli.py +0 -0
  298. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_deploy_gate.py +0 -0
  299. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_diff.py +0 -0
  300. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_doctor.py +0 -0
  301. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_doctor_cli.py +0 -0
  302. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_doctor_security.py +0 -0
  303. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_drift.py +0 -0
  304. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_e2e_pin_check.py +0 -0
  305. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_emitters.py +0 -0
  306. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_framing.py +0 -0
  307. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_guard_banner.py +0 -0
  308. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_guard_platform.py +0 -0
  309. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_guard_posture.py +0 -0
  310. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_guard_proxy.py +0 -0
  311. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_guard_strict.py +0 -0
  312. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_guard_v3.py +0 -0
  313. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_guard_windows.py +0 -0
  314. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_hashing.py +0 -0
  315. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_inspect_parity.py +0 -0
  316. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_inspection_policy.py +0 -0
  317. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_lockfile.py +0 -0
  318. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_policy.py +0 -0
  319. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_policy_enforcement.py +0 -0
  320. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_precommit.py +0 -0
  321. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_provenance.py +0 -0
  322. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_res_dns.py +0 -0
  323. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_result_inspection.py +0 -0
  324. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_schema_diff.py +0 -0
  325. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_schema_diff_refs.py +0 -0
  326. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_signing.py +0 -0
  327. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_signing_unit.py +0 -0
  328. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_spec_consistency.py +0 -0
  329. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_spec_vectors.py +0 -0
  330. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_tokenizer.py +0 -0
  331. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_tool_integrity.py +0 -0
  332. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_tool_integrity_guard.py +0 -0
  333. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/tests/test_wire_block.py +0 -0
  334. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/README.md +0 -0
  335. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/canonical-control-escapes.json +0 -0
  336. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/canonical-deep-nesting.json +0 -0
  337. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/canonical-depth-512-accepted.json +0 -0
  338. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/canonical-empty-array.json +0 -0
  339. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/canonical-empty-object.json +0 -0
  340. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/canonical-empty-string.json +0 -0
  341. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/canonical-key-escapes.json +0 -0
  342. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/canonical-nested-arrays.json +0 -0
  343. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/canonical-numbers-boundaries.json +0 -0
  344. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/canonical-numbers-es6.json +0 -0
  345. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/canonical-scalars.json +0 -0
  346. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/canonical-sorted-keys-utf16.json +0 -0
  347. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/canonical-surrogate-key-order.json +0 -0
  348. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/canonical-unicode-literal.json +0 -0
  349. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/digest-absence-rules.json +0 -0
  350. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/digest-capabilities-and-refs.json +0 -0
  351. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/digest-clean-fixture.json +0 -0
  352. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/digest-entry-sorting-astral.json +0 -0
  353. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/digest-entry-sorting.json +0 -0
  354. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/digest-enum-constraints-skeleton.json +0 -0
  355. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/digest-http-url-server.json +0 -0
  356. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/digest-malformed-input-schema.json +0 -0
  357. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/digest-minimal-single-tool.json +0 -0
  358. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/digest-tool-metadata-empty.json +0 -0
  359. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/digest-tool-metadata-full.json +0 -0
  360. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/digest-tool-metadata-null.json +0 -0
  361. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-capability-added.json +0 -0
  362. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-capability-removed.json +0 -0
  363. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-description-and-schema.json +0 -0
  364. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-description-modified.json +0 -0
  365. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-inspection-policy-modified.json +0 -0
  366. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-mixed-multi-entry.json +0 -0
  367. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-no-drift.json +0 -0
  368. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-prompt-added.json +0 -0
  369. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-prompt-modified.json +0 -0
  370. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-prompt-removed.json +0 -0
  371. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-resource-added.json +0 -0
  372. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-resource-modified.json +0 -0
  373. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-resource-removed.json +0 -0
  374. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-additional-props-opened-to-object.json +0 -0
  375. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-additional-props-opened.json +0 -0
  376. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-array-items-recursed.json +0 -0
  377. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-constraint-relaxed-bound-removed.json +0 -0
  378. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-constraint-relaxed-maxlength-up.json +0 -0
  379. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-constraint-relaxed-minimum-lowered.json +0 -0
  380. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-constraint-relaxed-pattern-removed.json +0 -0
  381. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-constraint-relaxed-required-to-optional.json +0 -0
  382. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-constraint-tightened.json +0 -0
  383. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-cosmetic-modified.json +0 -0
  384. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-enum-added.json +0 -0
  385. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-enum-disjoint-is-widened.json +0 -0
  386. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-enum-narrowed.json +0 -0
  387. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-enum-removed.json +0 -0
  388. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-enum-widened.json +0 -0
  389. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-modified-opaque-ref.json +0 -0
  390. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-modified-ref-redacted.json +0 -0
  391. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-modified-v1-fallback.json +0 -0
  392. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-out-added.json +0 -0
  393. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-out-constraint-relaxed.json +0 -0
  394. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-out-cosmetic-modified.json +0 -0
  395. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-out-extension-null.json +0 -0
  396. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-out-local-ref.json +0 -0
  397. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-out-ref-redacted.json +0 -0
  398. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-out-removed.json +0 -0
  399. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-out-type-broadened.json +0 -0
  400. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-pattern-changed-tightened.json +0 -0
  401. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-per-fact-emission.json +0 -0
  402. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-property-added.json +0 -0
  403. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-property-removed.json +0 -0
  404. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-ref-resolved-granular.json +0 -0
  405. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-required-added.json +0 -0
  406. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-required-removed.json +0 -0
  407. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-required-unconstrained-added.json +0 -0
  408. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-type-any-to-typed.json +0 -0
  409. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-type-broadened.json +0 -0
  410. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-type-changed.json +0 -0
  411. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-type-narrowed.json +0 -0
  412. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-unconstrained-added.json +0 -0
  413. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-schema-version-migrated.json +0 -0
  414. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-server-identity-url.json +0 -0
  415. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-server-identity.json +0 -0
  416. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-tool-added.json +0 -0
  417. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-tool-annotations-destructiveHint.json +0 -0
  418. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-tool-annotations-explicit-null.json +0 -0
  419. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-tool-annotations-extension.json +0 -0
  420. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-tool-annotations-idempotentHint.json +0 -0
  421. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-tool-annotations-nested-null.json +0 -0
  422. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-tool-annotations-openWorldHint.json +0 -0
  423. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-tool-annotations-readOnlyHint.json +0 -0
  424. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-tool-annotations-removed.json +0 -0
  425. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-tool-removed.json +0 -0
  426. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-unapproved-change.json +0 -0
  427. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-v3-to-v4-migration.json +0 -0
  428. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/drift-v3-unapproved-migration.json +0 -0
  429. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/malformed-deep-nesting-2000.json +0 -0
  430. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/malformed-depth-513-rejected.json +0 -0
  431. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/malformed-invalid-json.json +0 -0
  432. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/malformed-lock-depth-1200-rejected.json +0 -0
  433. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/malformed-missing-overall-digest.json +0 -0
  434. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/malformed-missing-pin.json +0 -0
  435. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/malformed-schema-version-above-implemented.json +0 -0
  436. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/malformed-schema-version-not-integer.json +0 -0
  437. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/malformed-server-missing-command-digest.json +0 -0
  438. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/malformed-tool-missing-entry-digest.json +0 -0
  439. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/malformed-tools-not-array.json +0 -0
  440. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/malformed-unpaired-surrogate-high.json +0 -0
  441. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/malformed-unpaired-surrogate-key.json +0 -0
  442. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/malformed-unpaired-surrogate-low.json +0 -0
  443. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/malformed-v4-missing-annotations_hash.json +0 -0
  444. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/malformed-v4-missing-output_schema_hash.json +0 -0
  445. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/cases/malformed-v4-missing-output_schema_skeleton.json +0 -0
  446. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/manifest.json +0 -0
  447. {mcp_warden_cli-2.0.0 → mcp_warden_cli-2.2.0}/vectors/tools/generate.py +0 -0
@@ -96,6 +96,49 @@ jobs:
96
96
  fi
97
97
  echo "requirements-dev.lock is in sync with pyproject.toml."
98
98
 
99
+ # --------------------------------------------------------------------
100
+ # 2b. Action lockfile-in-sync check (DSE-1538).
101
+ # action/requirements.lock is what the published composite action
102
+ # installs into CUSTOMER CI (action.yml, --require-hashes). Same
103
+ # preferred-baseline regeneration and body diff as step 2, with the
104
+ # runtime-only command printed in the lock's own header (no dev extra).
105
+ # --------------------------------------------------------------------
106
+ - name: Verify action lockfile is in sync with pyproject.toml
107
+ run: |
108
+ cp action/requirements.lock /tmp/action-requirements.regenerated.lock
109
+ uv pip compile --universal --generate-hashes --python-version 3.11 \
110
+ pyproject.toml -o /tmp/action-requirements.regenerated.lock
111
+ if ! diff -u \
112
+ <(grep -v '^#' action/requirements.lock) \
113
+ <(grep -v '^#' /tmp/action-requirements.regenerated.lock); then
114
+ echo "::error::action/requirements.lock is out of sync with pyproject.toml."
115
+ echo "Regenerate it (see CONTRIBUTING.md) and commit the result:"
116
+ echo " uv pip compile --universal --generate-hashes --python-version 3.11 pyproject.toml -o action/requirements.lock"
117
+ exit 1
118
+ fi
119
+ echo "action/requirements.lock is in sync with pyproject.toml."
120
+
121
+ # The action lock drifted behind the dev lock once and shipped advisories
122
+ # the dev lock had already fixed (DSE-1538). Every package both locks pin
123
+ # must be pinned to the same version, so customers run what CI tested.
124
+ - name: Verify action lock pins equal dev lock pins
125
+ shell: python
126
+ run: |
127
+ import re, sys
128
+ def pins(path):
129
+ out = {}
130
+ for name, ver in re.findall(r"^([A-Za-z0-9_.-]+)==(\S+)", open(path).read(), re.M):
131
+ out.setdefault(re.sub(r"[-_.]+", "-", name).lower(), set()).add(ver)
132
+ return out
133
+ dev, action = pins("requirements-dev.lock"), pins("action/requirements.lock")
134
+ bad = {n: (sorted(dev[n]), sorted(action[n])) for n in action if n in dev and dev[n] != action[n]}
135
+ if bad:
136
+ print("::error::action/requirements.lock pins differ from requirements-dev.lock")
137
+ for n, (d, a) in sorted(bad.items()):
138
+ print(f" {n}: dev={d} action={a}")
139
+ sys.exit(1)
140
+ print(f"All {sum(n in dev for n in action)} shared pins in action/requirements.lock equal requirements-dev.lock.")
141
+
99
142
  # --------------------------------------------------------------------
100
143
  # 3. The locked closure actually works — import the package + key deps.
101
144
  # --------------------------------------------------------------------
@@ -118,3 +161,30 @@ jobs:
118
161
 
119
162
  - name: CVE audit the locked closure (fail on any advisory)
120
163
  run: /tmp/locked/bin/python -m pip_audit --skip-editable
164
+
165
+ # --------------------------------------------------------------------
166
+ # 5. Action lock: hash-verified install + CVE gate (DSE-1538).
167
+ # Step 2b's diff keeps existing pins as the baseline, so on its own it
168
+ # cannot see a tampered hash or a downgrade that still satisfies
169
+ # pyproject.toml. Installing with --require-hashes rejects the former;
170
+ # pip-audit over the exact pins rejects a downgrade to a version with a
171
+ # known advisory. Same evidence the dev lock gets from steps 1 and 4.
172
+ # --------------------------------------------------------------------
173
+ - name: Install action closure with --require-hashes
174
+ run: |
175
+ python -m venv /tmp/action-locked
176
+ /tmp/action-locked/bin/python -m pip install --upgrade pip
177
+ /tmp/action-locked/bin/python -m pip install --require-hashes -r action/requirements.lock
178
+
179
+ # pip-audit evaluates environment markers against THIS runner and silently
180
+ # skips pins that do not match, so a win32- or PyPy-only pin would never be
181
+ # audited on ubuntu (proven, CSO review of DSE-1538). The action runs on
182
+ # Windows and macOS too: audit a copy with every marker stripped.
183
+ - name: CVE audit the action lock, all platforms (fail on any advisory)
184
+ run: |
185
+ sed -E 's/ ; [^\\]*\\$/ \\/' action/requirements.lock > /tmp/action-requirements.unmarked.txt
186
+ if grep -qE '^[A-Za-z0-9_.-]+==[^ ]+ ;' /tmp/action-requirements.unmarked.txt; then
187
+ echo "::error::a marker survived stripping; refusing a partial audit"
188
+ exit 1
189
+ fi
190
+ /tmp/locked/bin/python -m pip_audit --disable-pip --require-hashes -r /tmp/action-requirements.unmarked.txt
@@ -66,6 +66,30 @@ jobs:
66
66
  - name: Run property-fuzz suite (deterministic, seed=0)
67
67
  run: pytest tests/fuzz -p no:randomly --hypothesis-seed=0
68
68
 
69
+ # --------------------------------------------------------------------------
70
+ # Handler binding has an intentionally narrow, independently tested interpreter contract.
71
+ # Other MCP-Warden commands retain the package's broader Python support.
72
+ # --------------------------------------------------------------------------
73
+ test-handler-compatibility:
74
+ name: Handler contract (CPython ${{ matrix.python }})
75
+ runs-on: ubuntu-latest
76
+ strategy:
77
+ fail-fast: false
78
+ matrix:
79
+ python: ["3.11", "3.12", "3.13"]
80
+ steps:
81
+ - name: Checkout
82
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
83
+ - name: Set up supported CPython
84
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
85
+ with:
86
+ python-version: ${{ matrix.python }}
87
+ cache: pip
88
+ - name: Install measured handler dependencies
89
+ run: pip install -e ".[dev]"
90
+ - name: Verify handler binding and enforcement
91
+ run: pytest -q tests/test_handler_boundary.py tests/test_policy_enforcement.py tests/test_policy_enforcement_v2.py tests/test_adapter_conformance.py
92
+
69
93
  # --------------------------------------------------------------------------
70
94
  # Job 1a: mcp 1.x compatibility leg (#105)
71
95
  #
@@ -1,17 +1,10 @@
1
1
  # =============================================================================
2
2
  # Release & publish workflow (v1.0 — W1.1 / W1.2 / W2.3)
3
3
  #
4
- # !!! INERT UNTIL CONFIGURED — SAFE TO MERGE !!!
5
- #
6
- # This workflow does NOTHING until BOTH of the following are true:
7
- # (a) a GitHub *Release* is published (a pushed git tag ALONE does not trigger
8
- # it — the trigger is `release: published`, the explicit human gesture), AND
9
- # (b) the `mcp-warden-cli` PyPI project + its Trusted Publisher (OIDC) are configured
10
- # by the owner (see RELEASING.md "One-time PyPI setup").
11
- #
12
- # Until (a) AND (b) hold, merging this file changes nothing at runtime: no tag is
13
- # cut here, no version is bumped here, nothing is published here. Cutting v1.0.0 is
14
- # then a single tag + GitHub Release away (the full runbook is in RELEASING.md).
4
+ # A published GitHub Release builds and signs artifacts. Production uploads
5
+ # additionally require the existing PyPI Trusted Publisher and enabled repo gate.
6
+ # A pushed tag alone does not trigger publication. Manual choices are TestPyPI,
7
+ # build-only, or a production authentication-only check that uploads nothing.
15
8
  #
16
9
  # What it does WHEN a Release is published:
17
10
  # build — builds sdist + wheel, uploads them as workflow artifacts.
@@ -41,18 +34,23 @@ on:
41
34
  release:
42
35
  types: [published]
43
36
 
44
- # Manual escape hatch for a dry run to TestPyPI (no Release required, no signing,
45
- # no production PyPI). Nice-to-have; kept deliberately simple.
37
+ # Manual TestPyPI/build-only paths and an authentication-only production check.
46
38
  workflow_dispatch:
47
39
  inputs:
48
40
  publish-target:
49
- description: "Where to publish on a manual run"
41
+ description: "TestPyPI upload, build-only, or production OIDC verification (no upload)"
50
42
  required: true
51
43
  default: "testpypi"
52
44
  type: choice
53
45
  options:
54
46
  - testpypi
55
47
  - none
48
+ - verify-pypi
49
+ publisher-checked:
50
+ description: "verify-pypi only: inspected existing project publisher and no matching pending publisher in owner account"
51
+ type: boolean
52
+ required: true
53
+ default: false
56
54
 
57
55
  # Least-privilege at the top level; each job widens scope locally only as needed.
58
56
  permissions:
@@ -65,6 +63,7 @@ jobs:
65
63
  # --------------------------------------------------------------------------
66
64
  build:
67
65
  name: Build sdist + wheel
66
+ if: github.event_name != 'workflow_dispatch' || github.event.inputs.publish-target != 'verify-pypi'
68
67
  runs-on: ubuntu-latest
69
68
  permissions:
70
69
  contents: read
@@ -138,7 +137,7 @@ jobs:
138
137
  #
139
138
  # On a `release: published` run -> production PyPI.
140
139
  # On a manual `workflow_dispatch` with publish-target=testpypi -> TestPyPI only.
141
- # publish-target=none short-circuits (build + artifacts only).
140
+ # publish-target=none builds only; verify-pypi skips the build and upload jobs.
142
141
  # --------------------------------------------------------------------------
143
142
  pypi-publish:
144
143
  name: Publish to PyPI (OIDC Trusted Publishing)
@@ -159,7 +158,7 @@ jobs:
159
158
  if: >-
160
159
  vars.PYPI_TRUSTED_PUBLISHER == 'true' &&
161
160
  (github.event_name == 'release' ||
162
- (github.event_name == 'workflow_dispatch' && github.event.inputs.publish-target != 'none'))
161
+ (github.event_name == 'workflow_dispatch' && github.event.inputs.publish-target == 'testpypi'))
163
162
 
164
163
  steps:
165
164
  - name: Download dist artifacts
@@ -190,6 +189,32 @@ jobs:
190
189
  # Re-running a dry run no-ops on an already-uploaded TestPyPI version.
191
190
  skip-existing: true
192
191
 
192
+ # Authentication-only production check: no build, upload, signing or stored token.
193
+ # Uses this SAME workflow identity and no deployment environment, like publication.
194
+ pypi-verify:
195
+ name: Verify PyPI OIDC (no upload)
196
+ if: github.event_name == 'workflow_dispatch' && github.event.inputs.publish-target == 'verify-pypi'
197
+ runs-on: ubuntu-latest
198
+ permissions:
199
+ id-token: write
200
+ contents: read
201
+ env:
202
+ WARDEN_PYPI_PUBLISHER_CONFIRMED: ${{ github.event.inputs.publisher-checked }}
203
+ steps:
204
+ - name: Require reviewed main
205
+ if: github.ref != 'refs/heads/main'
206
+ run: |
207
+ echo '::error::Production verification requires reviewed main.'
208
+ exit 1
209
+ - name: Checkout
210
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
211
+ - name: Set up Python 3.11
212
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
213
+ with:
214
+ python-version: "3.11"
215
+ - name: Verify production OIDC exchange without uploading
216
+ run: python scripts/verify_pypi_oidc.py
217
+
193
218
  # --------------------------------------------------------------------------
194
219
  # Job 3: sign the release artifacts with Sigstore keyless ("heal thyself", W2.3).
195
220
  #
@@ -30,6 +30,110 @@ Streamable HTTP; the v0.3 `guard` proxy adds deterministic runtime *result* insp
30
30
 
31
31
  ## [Unreleased]
32
32
 
33
+ ## [2.2.0] — 2026-10-24
34
+
35
+ ### Community corpus layout (DSE-2143)
36
+
37
+ - `check --against-community` reads entries from `locks/schema-<N>/<ecosystem>/...`,
38
+ where `<N>` is the implemented lock schema (4). The schema-3 corpus written by 1.x
39
+ stays at `locks/<ecosystem>/...` and is no longer read: 2.0.0 and 2.1.0 refused every
40
+ entry there with `WRD-CONSENSUS-SCHEMA-MISMATCH`; it now reads as NOVEL until a
41
+ schema-4 entry exists. See `docs/COMMUNITY_CORPUS.md` §4.
42
+
43
+ ## [2.1.0] — 2026-10-23
44
+
45
+ ### Pagination (DSE-1539)
46
+
47
+ - `pin` and `check` take `--max-pages N` (default 256, `MAX_LIST_PAGES`): a list call
48
+ whose `nextCursor` chain runs past the cap fails capture with exit 2.
49
+ - Capture now refuses a surface that repeats a tool name, prompt name or resource URI
50
+ (typically across pages). Each is the entry's identity in the name-keyed drift diff,
51
+ so a repeat let one entry shadow the other. **Behaviour change:** a server that lists
52
+ a duplicate now fails `pin`/`check` with exit 2 instead of pinning.
53
+ - SPEC §8.2 states capture completeness and identity uniqueness normatively.
54
+ - `pin`/`check` escape capture errors before printing, so a server-supplied name with
55
+ console markup (`x[/red]`) cannot crash the CLI into exit 1 or restyle the output.
56
+
57
+ ### Auth audit
58
+
59
+ - `WRD-AUTH-TOKEN-IN-CONFIG` now catches tokens joined by `-` or `_` inside a path or
60
+ secret-manager URI (DSE-1540, CSO NF-2). `~/.aws/<uuid-shaped key>` and
61
+ `pass://a.b/tok_<hex>` were read as file names and reported nothing. A `-`/`_`-joined
62
+ piece of a segment (including the stem of a dotted name, so `<uuid>.json`) is now a
63
+ literal when a part is a token-shaped run with a digit, or when its non-word,
64
+ non-numeric parts switch between letters and digits 3+ times over 20+ characters
65
+ (16+ if mixed case). The same rule covers URI fragments and `${VAR:?msg}` messages.
66
+ `gcp-sa-key-prod-2024`, `id_ed25519_github-work`, GCP key files
67
+ (`<project>-123456-<hex>.json`) and `application_default_credentials` stay names.
68
+ - Reference, locator and placeholder heuristics move from `auth_audit.py` into
69
+ `auth_refs.py`; the rule above is the only behaviour change.
70
+
71
+ ### Capture integrity
72
+
73
+ - `pin`/`check` capture is capability-aware and fails closed (DSE-1538). A declared
74
+ `tools`/`resources`/`prompts` section whose list call errors now exits 2 instead of
75
+ being pinned as empty; an undeclared section is empty only on JSON-RPC `-32601`.
76
+ - CI regenerates and diffs `action/requirements.lock`, the lock the published action
77
+ installs, alongside `requirements-dev.lock`, then installs it with `--require-hashes`
78
+ and runs `pip-audit` over its exact pins with platform markers stripped, so
79
+ Windows-, macOS- and PyPy-only pins are audited too. The diff alone keeps existing pins
80
+ as its baseline, so it cannot see a tampered hash or an in-range downgrade. A further
81
+ step fails when any action-lock pin differs from the dev-lock pin CI tests.
82
+ - Security: the action lock had fallen behind the dev lock and shipped advisories in
83
+ `mcp` 2.1.1, `starlette` 1.2.1, `cryptography` 48.0.0 and `anyio` 4.13.0. Both locks
84
+ move to `mcp` 2.2.0, and every action-lock pin now equals the audited dev-lock pin.
85
+ - THREAT_MODEL §5.3.4 documents capture completeness and OS-trust-store TLS for `--url`.
86
+
87
+ ### Signing
88
+
89
+ - `mcp-warden lock sign <lock> [--coordinate C] [--identity-token T]` signs an existing
90
+ unsigned lock (DSE-1530), for attesters that capture inside a network-less sandbox and
91
+ sign afterwards. Same contract as `pin --sign`: v2 statement with `--coordinate`, v1
92
+ without, exit 1 on signing failure with no partial sidecar. It refuses (exit 2) a lock
93
+ that fails the integrity gate or carries a stale approval, an invalid coordinate, an
94
+ existing sidecar (a dangling symlink included), and a lock that already carries a
95
+ signature pointer, so it never overwrites or stacks a signature. The sidecar is placed
96
+ with `os.link` before the lock is rewritten, so a run that loses a race to another
97
+ signer exits 2 and leaves the winner's files untouched (a filesystem without hard
98
+ links fails closed with exit 1). A symlinked lock is resolved
99
+ so the sidecar sits beside the file that is verified.
100
+ - `pin --sign` and `lock sign` stage the bundle in a uniquely named `O_EXCL` temp file,
101
+ so a planted `.sigstore.tmp` symlink is never followed.
102
+
103
+ ### Decision receipt foundation
104
+
105
+ - Add protocol-neutral V2 enforcement with independently authorized signed decision
106
+ receipts before allowed effects, strengthening rules and exact finite noncritical
107
+ overrides. Every negative path attempts evidence; failed allow evidence creates a
108
+ separately bound deny and never invokes the handler.
109
+ - Add independent primary/fallback logs, protected-state and recovery-latch ports,
110
+ recovery with administrator approval, verified receipt chains, pure historical replay,
111
+ separate current eligibility and safe human/agent projections.
112
+ - Add mandatory receipt failure/restart corpus and property fuzzing. Reference
113
+ providers remain unsupported for real platform rollback resistance; live `guard`
114
+ integration and whole-kernel conformance remain separate gates.
115
+ - Harden frozen handlers against nested serialized code. Handler identity supports
116
+ CPython 3.11–3.13 only, with a dedicated CI matrix; other interpreters fail closed
117
+ at this SDK boundary. Existing artifact-signature domains and V1 defaults remain.
118
+
119
+ ### Artifact trust foundation
120
+
121
+ - Add opt-in Ed25519 verification for existing policy, runtime, adapter and
122
+ executable-bundle activation APIs, with an independently pinned public-key
123
+ configuration and explicit artifact-kind signer roles.
124
+ - Add `trust roots-digest`, `trust prepare` and `trust verify` for enrollment
125
+ inspection, unsigned canonical review/signing artifacts, and offline signature
126
+ checks. Human signing stays external; signature validity alone does not permit
127
+ effects. Durable receipts and live guard integration remain separate work.
128
+
129
+ ### Release engineering
130
+
131
+ - Add a manual `verify-pypi` production OIDC exchange check in the existing release
132
+ workflow, without building, signing, uploading or storing credentials. Identity
133
+ mismatches, redirects, failed exchanges and malformed responses fail closed.
134
+ - Correct release documentation: existing-project publisher setup, non-reserving
135
+ pending publishers, 2.0.0's manual recovery, and unchanged-artifact failed-job reruns.
136
+
33
137
  ## [2.0.0] — 2026-10-02
34
138
 
35
139
  ### Breaking compatibility
@@ -467,7 +571,9 @@ v1-strong foundation. Highlights of the 0.3.0 → 1.0.0 arc:
467
571
  declared surface, RFC 8785 (JCS) + SHA-256 canonicalization, SARIF output, and a live
468
572
  integrity-gate workflow with committed `clean.warden.lock`.
469
573
 
470
- [Unreleased]: https://github.com/DataScience-EngineeringExperts/mcp-warden/compare/v1.1.0...HEAD
574
+ [Unreleased]: https://github.com/DataScience-EngineeringExperts/mcp-warden/compare/v2.2.0...HEAD
575
+ [2.2.0]: https://github.com/DataScience-EngineeringExperts/mcp-warden/compare/v2.1.0...v2.2.0
576
+ [2.1.0]: https://github.com/DataScience-EngineeringExperts/mcp-warden/compare/v2.0.0...v2.1.0
471
577
  [1.1.0]: https://github.com/DataScience-EngineeringExperts/mcp-warden/compare/v1.0.1...v1.1.0
472
578
  [1.0.1]: https://github.com/DataScience-EngineeringExperts/mcp-warden/compare/v1.0.0...v1.0.1
473
579
  [1.0.0]: https://github.com/DataScience-EngineeringExperts/mcp-warden/releases/tag/v1.0.0
@@ -1,6 +1,6 @@
1
1
  # Documentation Index — mcp-warden
2
2
 
3
- Last Updated: 2026-10-02
3
+ Last Updated: 2026-10-22
4
4
 
5
5
  Master index of every document in this repository. The `docs/` files are the
6
6
  **security contract and source of truth** for all algorithms; the three core docs
@@ -12,7 +12,7 @@ describe and visualize the implementation that satisfies that contract.
12
12
 
13
13
  | # | Doc | Purpose |
14
14
  |---|-----|---------|
15
- | 1 | [`README.md`](README.md) | Project overview, install, the pin/check CI demo (full walkthrough archived to [`docs/PIN_CHECK_DEMO.md`](docs/PIN_CHECK_DEMO.md) to hold the 500-line core-doc limit), CLI reference (incl. v0.3 `lock rotate` + redacted offline `diff` viewer), GitHub Action usage section (Issue #18), **pre-commit hook section (Issue #22)** |
15
+ | 1 | [`README.md`](README.md) | Project overview, install, the pin/check CI demo (full walkthrough archived to [`docs/PIN_CHECK_DEMO.md`](docs/PIN_CHECK_DEMO.md) to hold the 500-line core-doc limit), CLI reference (incl. v0.3 `lock rotate`, DSE-1530 `lock sign`, DSE-1539 `--max-pages` + redacted offline `diff` viewer), GitHub Action usage section (Issue #18), **pre-commit hook section (Issue #22)** |
16
16
  | 2 | [`SYSTEM_CONTEXT_DIAGRAM.md`](SYSTEM_CONTEXT_DIAGRAM.md) | System context + pin/check sequence (mermaid); trust boundary; `conclave` as dev-time reviewer only; composite GitHub Action + **pre-commit hook** as consumer delivery vehicles |
17
17
  | 3 | [`DOCUMENTATION_INDEX.md`](DOCUMENTATION_INDEX.md) | This file |
18
18
 
@@ -47,6 +47,7 @@ is the MCP auth posture sound. Both reuse the `check` exit-code contract (0 clea
47
47
  | [`src/mcp_warden/deploy_gate.py`](src/mcp_warden/deploy_gate.py) | `WRD-GATE-*` engine: eval thresholds, guardrail presence, budget, approval receipt |
48
48
  | [`src/mcp_warden/cli_deploy_gate.py`](src/mcp_warden/cli_deploy_gate.py) | `deploy-gate` command body (register idiom) |
49
49
  | [`src/mcp_warden/auth_audit.py`](src/mcp_warden/auth_audit.py) | `WRD-AUTH-*` static config audit; reuses `checks_secret.scan_field` for vendor patterns (vendor hits are never downgraded); template fill-me-ins are `WRD-AUTH-PLACEHOLDER-SECRET` (low), matched on whole tokens |
50
+ | [`src/mcp_warden/auth_refs.py`](src/mcp_warden/auth_refs.py) | Reference / locator / placeholder heuristics behind `WRD-AUTH-*`: `${VAR}` forms, secret-manager URIs and credential paths, token-shaped segments (incl. `-`/`_`-joined tokens, DSE-1540), placeholder bounds |
50
51
  | [`src/mcp_warden/cli_auth.py`](src/mcp_warden/cli_auth.py) | `auth audit` sub-app command body |
51
52
  | [`tests/test_deploy_gate.py`](tests/test_deploy_gate.py) | Engine per-control pass/fail + CLI exit codes + fail-closed on malformed evidence |
52
53
  | [`tests/test_auth_audit.py`](tests/test_auth_audit.py) | Every rule, the deliberate non-flags (loopback, `${VAR}` refs, stdio), redaction, CLI/JSON/SARIF |
@@ -155,13 +156,15 @@ scope-honesty box and makes no compliance/regulatory claim.
155
156
 
156
157
  | Doc | Defines |
157
158
  |-----|---------|
159
+ | [`docs/ARTIFACT_TRUST.md`](docs/ARTIFACT_TRUST.md) | Opt-in Ed25519 implementation of DSE-716's external artifact verifier: explicit key/kind roles, independently pinned canonical roots, exact version/kind/key-bound signing frame, unsigned review preparation and offline signature verification. No private signing capability, durable receipts, live guard wiring or whole-kernel claim |
158
160
  | [`docs/PIN_CHECK_DEMO.md`](docs/PIN_CHECK_DEMO.md) | Full end-to-end pin/check walkthrough, archived out of `README.md` on 2026-08-24 to hold the 500-line core-doc limit |
159
161
  | [`docs/SPEC.md`](docs/SPEC.md) | **MCP Lock Format v1** — the vendor-neutral, self-contained format specification any tool can implement: on-disk `warden.lock` schema, RFC 8785 (JCS) canonicalization, SHA-256 `sha256:<hex>` hashing, `overall_digest` construction, the normative drift class + severity table, the optional per-tool inspection block, and a Conformance section (§12.1: passing `vectors/` **is** conformance) + worked example. `WARDEN_LOCK_SCHEMA.md` is the mcp-warden implementation of this format |
160
162
  | [`docs/THREAT_MODEL.md`](docs/THREAT_MODEL.md) | **(v0.1)** Positioning, trust model (TOFU + `--approve`), assets/actors, the four threat classes (MCP-DRIFT / MCP-CAPSURF / MCP-SECRET / MCP-SUPPLY), explicit out-of-scope limits, deliberate cuts |
161
163
  | [`docs/THREAT_MODEL_V2.md`](docs/THREAT_MODEL_V2.md) | **(v0.2)** Addendum extending the v0.1 model: T-RESULT vectors, the defends (BLOCK) / monitors (fuzzy) / still-does-NOT-defend (T-BEHAVE) table, runtime trust-model notes, retained + added cuts, shadow-default positioning |
162
- | [`docs/AGENT_TRUST_KERNEL.md`](docs/AGENT_TRUST_KERNEL.md) | **(DSE-714, design contract)** Normative invariants for the future deterministic Agent Trust Kernel: trust boundaries, complete mediation, default deny, non-overridable critical classes, evidence-before-effect, offline operation, residual risks, and bindings for DSE-715 through DSE-717. MCP-Warden v1.1 is explicitly not yet ATK-conformant |
164
+ | [`docs/AGENT_TRUST_KERNEL.md`](docs/AGENT_TRUST_KERNEL.md) | **(DSE-714, design contract)** Normative invariants for the future deterministic Agent Trust Kernel: trust boundaries, complete mediation, default deny, non-overridable critical classes, evidence-before-effect, offline operation, residual risks, and bindings for DSE-715 through DSE-717. MCP-Warden 2.1.0 is explicitly not yet ATK-conformant |
163
165
  | [`docs/CONTENT_ENVELOPE.md`](docs/CONTENT_ENVELOPE.md) | **(DSE-715, implemented foundation)** Strict immutable V1 content envelope, domain-separated exact-byte digests, canonical metadata boundary, bounded one-hop lineage, monotonic taint, stable code-only errors, and secret-safe public projection. Evidence only; no authority or whole-ATK conformance claim |
164
- | [`docs/POLICY_ENFORCEMENT.md`](docs/POLICY_ENFORCEMENT.md) | **(DSE-716, implemented foundation)** Versioned signed policy/runtime/adapter/executable-bundle activation, exact adapter/bundle-bound leases, mechanically derived frozen handler identity, deterministic default-deny PDP, evidence-gated structural PEP, stable reason/recovery matrix, caps, and non-optional fixed-corpus adapter harness. DSE-717 durable evidence is in progress but remains required for any whole-ATK claim |
166
+ | [`docs/POLICY_ENFORCEMENT.md`](docs/POLICY_ENFORCEMENT.md) | **(DSE-716, implemented foundation)** Versioned signed policy/runtime/adapter/executable-bundle activation, exact adapter/bundle-bound leases, mechanically derived frozen handler identity, deterministic default-deny PDP, evidence-gated structural PEP, stable reason/recovery matrix, caps, and non-optional fixed-corpus adapter harness. Separate DSE-717 V2 evidence foundation; real protected-platform and live-guard gates remain pending |
167
+ | [`docs/DECISION_RECEIPTS.md`](docs/DECISION_RECEIPTS.md) | **(DSE-717, development foundation)** Independently authorized signed receipts, strict strengthening rules and finite noncritical overrides; separate primary/fallback logs, protected-state/latch ports, authenticated recovery, pure historical replay, current eligibility, safe projections and nonoptional reference conformance. Reference providers cannot establish platform rollback resistance; first published in 2.1.0 |
165
168
  | [`docs/WARDEN_LOCK_SCHEMA.md`](docs/WARDEN_LOCK_SCHEMA.md) | **mcp-warden implementation of [`docs/SPEC.md`](docs/SPEC.md) (MCP Lock Format v1).** `warden.lock` format, RFC 8785 canonicalization + SHA-256 hashing, field/entry/overall digests, the normative drift definition + severities; **§5.1/§6.2 structural schema diff** (normalized per-tool `schema_skeleton`, `schema_version` 4 — annotations/output added at v4, skeleton added at v2, in-document `$ref` resolution at v3 (#29), granular `WRD-DRIFT-SCHEMA-*` taxonomy + severities, v1 fallback); **§8.1/§8.2 (v0.3, #19)** structured out-of-digest provenance (`pinner` / `attestations` / `rotation_count`, `PROVENANCE_VERSION`, B4 `bound_digest` format) + `lock rotate` digest-invariant semantics + the #16 signing implication; **§11 (v0.2)** optional per-tool inspection policy (`expected_output_charset` / `may_return_urls` / `secret_echo_applies`, fail-safe defaults, digest impact) |
166
169
  | [`docs/WARDEN_LOCK_EXAMPLE.md`](docs/WARDEN_LOCK_EXAMPLE.md) | Illustrative full `warden.lock` + a post-`lock rotate` `pin` block (archived from WARDEN_LOCK_SCHEMA §9 to keep that core doc under the line cap) |
167
170
  | [`docs/CHECKS.md`](docs/CHECKS.md) | The deterministic `WRD-*` static-check catalog (capability/secret/supply/robustness), the shared tokenizer, severity→SARIF mapping, redaction rule, CUT list. **Reused by v0.2** `WRD-RES-SECRET-ECHO` (the `WRD-SEC-*` patterns + redaction) |
@@ -169,7 +172,7 @@ scope-honesty box and makes no compliance/regulatory claim.
169
172
  | [`docs/RESULT_INSPECTION.md`](docs/RESULT_INSPECTION.md) | **(v0.2)** The `WRD-RES-*` result-inspection catalog: deterministic/fuzzy tier partition, per-rule exact match definitions (ANSI allowlist, secret-echo via `WRD-SEC-*`, exfil seed denylist, injection seed phrase list), severities, SARIF mapping, redaction, fail-safe per-tool precision. Run identically by `guard` and `inspect` |
170
173
  | [`docs/GUARD_PROXY.md`](docs/GUARD_PROXY.md) | **(v0.2 base, updated to v0.3 defaults)** The `guard` transparent stdio proxy + `inspect` offline analyzer contract: frame-handling discipline, single-loop framing (Content-Length + newline), incremental scan, subprocess lifecycle, runtime arg-policy + `tools/list_changed` gate, the **v0.3 default-block posture** + `--no-block-*` opt-outs + `--audit-only`, reserved codes `-32001`/`-32002`, and the exact on-the-wire "block" behavior |
171
174
  | [`docs/GUARD_PROXY_V3.md`](docs/GUARD_PROXY_V3.md) | **(v0.3)** The proxy-hardening contract: `notifications/cancelled`/`progress` untouched passthrough (§1), subprocess-lifecycle edge cases — server-crash `-32002` synthesis, client-disconnect process-group teardown, truncated/oversized-frame fail-open (§2), Windows experimental degradation (§3), the full v0.3 block-flag scheme + precedence (§4), and **(#21) `--strict` fail-CLOSED mode — terminate on an inspection-layer error, `-32003` non-retriable, exit `3` (§5)** |
172
- | [`docs/SIGNING.md`](docs/SIGNING.md) | **(v0.3, #16)** Sigstore keyless signing + verification of `warden.lock`: the optional `[sigstore]` extra, the deterministic `mcp-warden-lock-digest/v1` statement that binds ONLY `overall_digest` (survives `lock rotate`), `pin --sign` / `check --verify` usage, the **fixed-sidecar** verify contract (pointer field never trusted), the full fail-closed matrix, the TUF-cache/offline caveat, and the two accepted trade-offs (rotate-replay + committed-fixture coverage gap + refresh steps) |
175
+ | [`docs/SIGNING.md`](docs/SIGNING.md) | **(v0.3, #16)** Sigstore keyless signing + verification of `warden.lock`: the optional `[sigstore]` extra, the deterministic `mcp-warden-lock-digest/v1` statement that binds ONLY `overall_digest` (survives `lock rotate`), `pin --sign` / **`lock sign` (DSE-1530, exclusive placement, no overwrite/stacking)** / `check --verify` usage, the **fixed-sidecar** verify contract (pointer field never trusted), the full fail-closed matrix, the TUF-cache/offline caveat, and the two accepted trade-offs (rotate-replay + committed-fixture coverage gap + refresh steps) |
173
176
 
174
177
  ## Non-normative design and implementation plans
175
178
 
@@ -177,6 +180,12 @@ scope-honesty box and makes no compliance/regulatory claim.
177
180
 
178
181
  | Plan | Purpose |
179
182
  |---|---|
183
+ | [`docs/plans/2026-10-04-dse717-reconciliation.md`](docs/plans/2026-10-04-dse717-reconciliation.md) | Recovered-branch provenance, integration ownership, failure-path validation and exact-head security/external-review gates |
184
+ | [`docs/plans/2026-07-19-decision-receipts-design.md`](docs/plans/2026-07-19-decision-receipts-design.md) | Original DSE-717 receipt, deterministic rule, evidence, recovery and replay design |
185
+ | [`docs/plans/2026-07-19-decision-receipts-implementation.md`](docs/plans/2026-07-19-decision-receipts-implementation.md) | Original strict-TDD execution plan and independently reviewed release gates |
186
+ | [`docs/archive/2026-10-04-readme-community-consensus.md`](docs/archive/2026-10-04-readme-community-consensus.md) | Preserved advanced README community-consensus walkthrough: pinned attesters/corpus revision, verdict exit codes and required-consensus withholding protection |
187
+ | [`docs/plans/2026-10-04-dse717-council-fixes.md`](docs/plans/2026-10-04-dse717-council-fixes.md) | Council remediation: quarantine preservation, complete V2 floor presence, independently pinned historical signer/root rotation, regression evidence and bounded projection/conformance documentation |
188
+ | [`docs/plans/2026-10-03-checkpoint-artifact-trust.md`](docs/plans/2026-10-03-checkpoint-artifact-trust.md) | First human-checkpoint development wave: opt-in signature verification and unsigned review tooling, with unpublished DSE-717 work preserved and live DSE-1076 integration still dependent on it |
180
189
  | [`docs/plans/2026-07-18-agent-trust-kernel-design.md`](docs/plans/2026-07-18-agent-trust-kernel-design.md) | **Non-normative execution record.** Records the DSE-714 design decision and verification plan; binding requirements live in `docs/AGENT_TRUST_KERNEL.md` |
181
190
  | [`docs/plans/2026-07-18-content-envelope-design.md`](docs/plans/2026-07-18-content-envelope-design.md) | **Non-normative DSE-715 execution record.** Records the reviewed strict-TDD plan; verified behavior is documented in `docs/CONTENT_ENVELOPE.md` |
182
191
  | [`docs/plans/2026-07-19-pdp-pep-design.md`](docs/plans/2026-07-19-pdp-pep-design.md) | **Non-normative DSE-716 execution record.** Records the activated-snapshot, structural-PEP, TDD, and review plan; verified behavior is documented in `docs/POLICY_ENFORCEMENT.md` |
@@ -201,23 +210,35 @@ scope-honesty box and makes no compliance/regulatory claim.
201
210
 
202
211
  | Doc | Purpose |
203
212
  |-----|---------|
204
- | [`RELEASING.md`](RELEASING.md) | Operator runbook: one-time PyPI Trusted-Publisher (OIDC) setup, cut-a-release checklist, post-release verification, rollback/yank. PyPI dist name is `mcp-warden-cli`; CLI/repo stay `mcp-warden`. |
205
- | [`CHANGELOG.md`](CHANGELOG.md) | Keep-a-Changelog history through CLI 2.0.0 / schema level 4 with explicit in/out-of-scope. |
206
- | [`.github/workflows/release.yml`](.github/workflows/release.yml) | Publish-on-Release workflow: build Python distributions + tested TypeScript 0.2.0 tarball → publish Python to PyPI via OIDC Trusted Publishing (no stored token, **gated on repo var `PYPI_TRUSTED_PUBLISHER=true`** + `skip-existing`, #64) → Sigstore-keyless sign Python, TypeScript, and checksums and attach bundles to the Release. Live: `mcp-warden-cli` Trusted Publisher configured + the gate variable set. |
213
+ | [`RELEASING.md`](RELEASING.md) | Operator runbook: existing-project PyPI publisher settings, authentication-only verification, release delivery, post-release checks, failed-job recovery and rollback/yank. PyPI dist name is `mcp-warden-cli`; CLI/repo stay `mcp-warden`. |
214
+ | [`CHANGELOG.md`](CHANGELOG.md) | Keep-a-Changelog history through CLI 2.1.0 (schema level 4) with explicit in/out-of-scope. |
215
+ | [`.github/workflows/release.yml`](.github/workflows/release.yml) | Publish-on-Release: build Python + tested TypeScript tarball; upload only Python through OIDC (repo gate + `skip-existing`); Sigstore-sign artifacts/checksums. Manual `verify-pypi` exchanges credentials without build/upload/signing. The gate variable alone does not prove publisher alignment. |
216
+ | [`scripts/verify_pypi_oidc.py`](scripts/verify_pypi_oidc.py) | Standard-library OIDC probe: reviewed-main binding, owner inspection acknowledgment, bounded HTTPS, no redirects/token logs/storage/uploads. PyPI minting can mutate pending records; exchange does not prove project upload permission. |
217
+ | [`docs/plans/2026-10-02-pypi-automation-repair.md`](docs/plans/2026-10-02-pypi-automation-repair.md) | Bounded automation repair and session wrap plan, including the authenticated PyPI browser boundary. |
207
218
  | [`requirements-dev.lock`](requirements-dev.lock) · [`.github/workflows/deps-locked.yml`](.github/workflows/deps-locked.yml) | **(#59)** Hash-pinned dev/CI dependency lock + the "Hash-locked dev/CI install" check (verifies `--require-hashes` install + that the lock stays in sync with `pyproject.toml` without floating to latest, #65). Dependency-update policy lives in [`SECURITY.md`](SECURITY.md). |
208
219
 
209
220
  ---
210
221
 
211
222
  ## Source layout
212
223
 
224
+ `src/mcp_warden/artifact_payload.py`, `artifact_trust.py`, and `cli_trust.py` implement
225
+ the strict existing-artifact decoder, opt-in public-key verifier, and unsigned
226
+ review/signature CLI. Tests are `tests/test_artifact_trust.py`,
227
+ `test_cli_trust.py`, and `test_artifact_trust_integration.py`.
228
+
213
229
  | Module | Responsibility | Spec anchor |
214
230
  |--------|----------------|-------------|
231
+ | `receipt_models.py` · `decision_receipts.py` · `signer_authorization.py` · `receipt_kernel.py` | **(DSE-717)** Closed canonical receipts and independently activated, role-bound governance signatures; no product private-key loader | DECISION_RECEIPTS.md authority/events |
232
+ | `rule_models.py` · `rule_engine.py` · `decision_governor.py` · `governed_decision.py` | **(DSE-717)** Strengthening-only rules, exact finite noncritical overrides and canonical effective decisions | DECISION_RECEIPTS.md rules |
233
+ | `evidence_state.py` · `evidence_latch.py` · `evidence_reference.py` · `receipt_log.py` · `evidence_models.py` · `evidence_coordinator.py` · `evidence_recovery.py` | **(DSE-717)** Independent primary/fallback evidence, compare-and-advance protected-state ports and latch-clear-last recovery; reference protection unsupported | DECISION_RECEIPTS.md evidence/recovery |
234
+ | `policy_enforcement_v2.py` · `enforcement_result_v2.py` · `receipt_conformance.py` · `receipt_conformance_models.py` | **(DSE-717)** Evidence on every path, failed-allow deny conversion, pre-sink revalidation and mandatory eleven-scenario/five-fixed-case reference corpus | DECISION_RECEIPTS.md evidence/conformance |
235
+ | `receipt_verification.py` · `receipt_replay.py` · `receipt_projection.py` | **(DSE-717)** Canonical signature/chain verification with retained root-activated historical authority/verifier pins, strict separate live-floor checks, effect-free historical replay, current eligibility and primary-only human explanations | DECISION_RECEIPTS.md verification/replay |
215
236
  | `src/mcp_warden/hashing.py` | `canon()` (RFC 8785) + `hash()` + field hashes | WARDEN_LOCK_SCHEMA §3 |
216
237
  | `src/mcp_warden/content_models.py` · `content_envelope.py` | **(DSE-715)** Strict immutable evidence models; typed domain-separated byte hashing call surface; canonical constructors/parser; bounded derivation and one-hop lineage; explicit secret-safe projection | CONTENT_ENVELOPE.md / AGENT_TRUST_KERNEL ATK-01/02/05/06/09/12 |
217
238
  | `src/mcp_warden/decision_models.py` · `policy_decision.py` | **(DSE-716)** Strict V1 decision models; signed policy/runtime activation; exact lease/request binding; deterministic default-deny PDP; canonical digest-only decisions and stable recovery codes | POLICY_ENFORCEMENT.md / AGENT_TRUST_KERNEL ATK-03/05/06/07/08/09 |
218
239
  | `src/mcp_warden/policy_enforcement.py` · `handler_identity.py` · `executable_bundle.py` · `adapter_conformance.py` | **(DSE-716)** Signed adapter and executable-bundle closure; exact manifest-bound leases; closure-free mechanically code/dependency-derived frozen handlers; canonical effect binding; evidence-gated PEP; PEP-owned execution trace and multiple output-channel scans; mandatory versioned malformed-input corpus | POLICY_ENFORCEMENT.md / AGENT_TRUST_KERNEL ATK-03/04/06/08 |
219
240
  | `src/mcp_warden/tokenizer.py` | Shared tokenizer + capability derivation (single source of truth) | CHECKS §3 / WARDEN_LOCK_SCHEMA §5.4 |
220
- | `src/mcp_warden/capture.py` | Declared-surface capture over stdio (argv array, no shell) or Streamable HTTP (`--url`); shared list normalization, timeouts, and errors | THREAT_MODEL §3.3 / WARDEN_LOCK_SCHEMA §4.1 |
241
+ | `src/mcp_warden/capture.py` | Declared-surface capture over stdio (argv array, no shell) or Streamable HTTP (`--url`) through one `_capture_session`; capability-aware, fail-closed list calls (DSE-1538); `--max-pages` cursor cap (default `MAX_LIST_PAGES` 256) and duplicate tool-name / resource-URI / prompt-name rejection (DSE-1539); timeouts and errors | THREAT_MODEL §3.3 / WARDEN_LOCK_SCHEMA §4.1 |
221
242
  | `src/mcp_warden/models.py` | Pydantic models for captured surface + lock (incl. `Pinner`/`Attestation` provenance) | WARDEN_LOCK_SCHEMA §2–§8 |
222
243
  | `src/mcp_warden/lockfile.py` | Lock builder + reader/writer + overall digest | WARDEN_LOCK_SCHEMA §5–§6, §9 |
223
244
  | `src/mcp_warden/check_core.py` | **(#22)** Shared check verdict core (`run_check` / `run_check_full`): read_lock→capture→checks→build_lock(in-memory)→compute_drift. Single source of truth for `cli.py:check` AND the pre-commit wrapper | WARDEN_LOCK_SCHEMA §6.2 |
@@ -248,13 +269,16 @@ scope-honesty box and makes no compliance/regulatory claim.
248
269
  | `src/mcp_warden/wire_block.py` | **(v0.2/v0.3)** on-wire block synthesis: `-32001` error-response + redacted-content (`_meta.warden.modified`); **v0.3** `-32002` `transport_error`; **(#21)** `-32003` `strict_abort_error` (non-retriable) | GUARD_PROXY §7 · V3 §2.6, §5 |
249
270
  | `src/mcp_warden/inspector.py` | **(v0.2)** offline JSONL analyzer over recorded sessions (same catalog) | GUARD_PROXY §3 |
250
271
  | `src/mcp_warden/emit_res.py` | **(v0.2)** SARIF 2.1.0 + JSONL emitters for `ResultFinding` (action/direction/tier) | GUARD_PROXY §10 |
251
- | `src/mcp_warden/cli.py` · `cli_guard.py` · `cli_lock.py` · `cli_diff.py` | `typer` CLI (`pin`/`check`/`policy`/`guard`/`inspect`/`lock rotate`/`diff`), exit codes; **`check` delegates its verdict to `check_core.run_check_full` (#22)**; `guard`/`inspect` bodies in `cli_guard`, `lock rotate` + integrity gate in `cli_lock`, **(v0.3) `diff` redacted offline lock viewer (`SAFE_PROVENANCE_FIELDS` allowlist, never reads `server.command`/`args`)** in `cli_diff` | all |
272
+ | `src/mcp_warden/cli.py` · `cli_guard.py` · `cli_lock.py` · `cli_diff.py` | `typer` CLI (`pin`/`check`/`policy`/`guard`/`inspect`/`lock rotate`/`lock sign`/`diff`), exit codes; **`check` delegates its verdict to `check_core.run_check_full` (#22)**; `guard`/`inspect` bodies in `cli_guard`, `lock rotate` + `lock sign` (DSE-1530) + shared integrity / stale-approval gate in `cli_lock`, **(v0.3) `diff` redacted offline lock viewer (`SAFE_PROVENANCE_FIELDS` allowlist, never reads `server.command`/`args`)** in `cli_diff` | all |
252
273
  | `src/mcp_warden/precommit.py` | **(#22)** `mcp-warden-precommit` pre-commit entry point — wraps `check_core.run_check`; check-only (never imports `pin`/lock-writer, never opens the lock for write) | README pre-commit section |
253
274
 
254
275
  ## Tests
255
276
 
256
277
  | File | Covers |
257
278
  |------|--------|
279
+ | `tests/test_dse717_council_fixes.py` | **(DSE-717)** Critical/rule quarantine preservation after rejected overrides, closed governor errors, every mandatory V2 floor omission, conditional override/legacy compatibility, retired live signer rejection and root/key rotation followed by append/reopen/chain verification |
280
+ | `tests/test_receipt_conformance.py` · `test_dse717_review_regressions.py` · `test_policy_enforcement_v2.py` · `test_handler_boundary.py` | **(DSE-717)** Mandatory failure/restart corpus, actual evidence/projection scans, negative sink absence, distinct failed-allow conversion, closed hostile inputs and supported interpreter/serialized-code boundaries |
281
+ | `tests/test_decision_receipts.py` · `test_receipt_hardening.py` · `test_rule_engine.py` · `test_evidence_coordinator.py` · `test_evidence_recovery.py` · `test_receipt_verification.py` · `test_receipt_replay.py` · `test_receipt_projection.py` | **(DSE-717)** Canonical signing/authority isolation, strict rules/finite overrides, independent log/state/latch failures, authenticated recovery, chain verification, effect-free replay and closed projections |
258
282
  | `tests/test_hashing.py` | JCS+SHA-256 reproducibility, canonical-form pins, null handling |
259
283
  | `tests/test_content_envelope.py` | **(DSE-715)** Strict/frozen models, typed digest domains, nine ingress kinds, canonical/cap boundary, deterministic lineage, parser rejection matrix, atomic digest verification, and planted-secret output/error/log scans |
260
284
  | `tests/test_policy_decision.py` · `test_policy_enforcement.py` · `test_adapter_conformance.py` | **(DSE-716)** Exact policy/runtime/adapter/bundle activation, deterministic decisions, every subject/effect/lease/manifest binding, trusted-time/rollback/revocation matrix, critical floor, hostile nested construction, callable drift resistance, evidence/sink ordering, fixed-corpus enforcement, cap boundaries, and deterministic reports |
@@ -277,7 +301,7 @@ scope-honesty box and makes no compliance/regulatory claim.
277
301
  | `tests/test_guard_v3.py` | **(v0.3)** opt-out demotes to shadow (`--no-block-*`/`--allow-exfil-domain`/`--no-block-deterministic`), `tools/list_changed` gate block+shadow, policy deny block+shadow, audit-only override, cancel/progress passthrough, **server-crash → `-32002` for every pending id**, client-disconnect child reap (no orphan), truncated + oversized frame fail-open |
278
302
  | `tests/test_guard_strict.py` | **(#21)** `--strict` fail-CLOSED: 4 terminate sites (request-policy / result-inspect / list-gate / nested-hash re-raise) → exit `3` + one `strict_abort` stderr line + `-32003` client frame + child reaped; negatives (truncated/over-cap/unparseable/clean) do NOT abort; default `--no-strict` byte-identical fail-open regression; secret-leak redaction; CLI threading; double-emission single line; `StrictInspectionAbort` is `BaseException`-not-`Exception` + anyio `ExceptionGroup` unwrap |
279
303
  | `tests/test_inspect_parity.py` | **(v0.2)** guard↔inspect finding parity on the same recorded frames + inspect exit codes |
280
- | `tests/fuzz/` (`test_fuzz_framing.py` · `test_fuzz_ansi.py` · `test_fuzz_domain.py` · `test_fuzz_redact.py` · `test_fuzz_content_envelope.py` · `test_fuzz_policy_decision.py`) | **(#17 / DSE-715 / DSE-716)** `hypothesis` property-fuzzing of the live runtime attack surface, content envelopes, identity substitution, arbitrary effect bytes, explicit trusted-time boundaries, deterministic decisions, and planted-secret absence. `ci`/`fuzz` profiles in `tests/fuzz/conftest.py`; deep soak via `make fuzz` |
304
+ | `tests/fuzz/` (`test_fuzz_framing.py` · `test_fuzz_ansi.py` · `test_fuzz_domain.py` · `test_fuzz_redact.py` · `test_fuzz_content_envelope.py` · `test_fuzz_policy_decision.py` · `test_fuzz_receipts.py`) | **(#17 / DSE-715 / DSE-716)** `hypothesis` property-fuzzing of the live runtime attack surface, content envelopes, identity substitution, arbitrary effect bytes, explicit trusted-time boundaries, deterministic decisions, and planted-secret absence. `ci`/`fuzz` profiles in `tests/fuzz/conftest.py`; deep soak via `make fuzz` |
281
305
  | `tests/fixtures/clean_server.py` · `mutated_server.py` | Real MCP SDK stdio fixtures |
282
306
  | `tests/fixtures/poison_server.py` | **(v0.2)** result-poisoning fixture server (ANSI/secret-echo/exfil/inject/clean tools) |
283
307
  | `tests/fixtures/crash_server.py` · `listchange_server.py` · `clean_listchange.warden.lock` | **(v0.3)** raw-stdio lifecycle fixtures: crash-mid-call (`-32002`) and `tools/list_changed` rug-pull + its pinned clean lock |