decisionlock 0.2.0rc4__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 (296) hide show
  1. decisionlock-0.2.0rc4/.dockerignore +19 -0
  2. decisionlock-0.2.0rc4/.github/CODE_OF_CONDUCT.md +38 -0
  3. decisionlock-0.2.0rc4/.github/CONTRIBUTING.md +41 -0
  4. decisionlock-0.2.0rc4/.github/SECURITY.md +37 -0
  5. decisionlock-0.2.0rc4/.github/SUPPORT.md +14 -0
  6. decisionlock-0.2.0rc4/.github/dependabot.yml +27 -0
  7. decisionlock-0.2.0rc4/.github/workflows/ci.yml +184 -0
  8. decisionlock-0.2.0rc4/.github/workflows/codeql.yml +41 -0
  9. decisionlock-0.2.0rc4/.github/workflows/decisionlock.yml +70 -0
  10. decisionlock-0.2.0rc4/.github/workflows/security.yml +42 -0
  11. decisionlock-0.2.0rc4/.github/workflows/self-hosted-validation.yml +242 -0
  12. decisionlock-0.2.0rc4/CHANGELOG.md +306 -0
  13. decisionlock-0.2.0rc4/CITATION.cff +10 -0
  14. decisionlock-0.2.0rc4/Dockerfile +34 -0
  15. decisionlock-0.2.0rc4/LICENSE +9 -0
  16. decisionlock-0.2.0rc4/MANIFEST.in +20 -0
  17. decisionlock-0.2.0rc4/Makefile +37 -0
  18. decisionlock-0.2.0rc4/PKG-INFO +569 -0
  19. decisionlock-0.2.0rc4/README.md +527 -0
  20. decisionlock-0.2.0rc4/benchmarks/benchmark-card.json +21 -0
  21. decisionlock-0.2.0rc4/benchmarks/benchmark-results.json +33 -0
  22. decisionlock-0.2.0rc4/benchmarks/run_benchmark.py +76 -0
  23. decisionlock-0.2.0rc4/docs/COLLABORATION.md +143 -0
  24. decisionlock-0.2.0rc4/docs/DEMO.md +261 -0
  25. decisionlock-0.2.0rc4/docs/FAQ.md +109 -0
  26. decisionlock-0.2.0rc4/docs/PROGRESS_TRACKER.md +455 -0
  27. decisionlock-0.2.0rc4/docs/RELEASE.md +156 -0
  28. decisionlock-0.2.0rc4/docs/adr/0001-action-integrity-kernel.md +16 -0
  29. decisionlock-0.2.0rc4/docs/adr/0002-default-deny.md +10 -0
  30. decisionlock-0.2.0rc4/docs/adr/0003-provider-neutral-broker.md +12 -0
  31. decisionlock-0.2.0rc4/docs/adr/0004-provider-external-effect-contract.md +107 -0
  32. decisionlock-0.2.0rc4/docs/adr/0005-production-credential-authority.md +164 -0
  33. decisionlock-0.2.0rc4/docs/adr/0006-provider-durable-reconciliation.md +188 -0
  34. decisionlock-0.2.0rc4/docs/adr/0007-service-multiprocess-deployment.md +158 -0
  35. decisionlock-0.2.0rc4/docs/architecture.md +160 -0
  36. decisionlock-0.2.0rc4/docs/credential-contract.md +225 -0
  37. decisionlock-0.2.0rc4/docs/limitations.md +126 -0
  38. decisionlock-0.2.0rc4/docs/migration-v1-to-v2.md +65 -0
  39. decisionlock-0.2.0rc4/docs/product-boundary.md +137 -0
  40. decisionlock-0.2.0rc4/docs/production-deployment.md +126 -0
  41. decisionlock-0.2.0rc4/docs/project-status.md +188 -0
  42. decisionlock-0.2.0rc4/docs/release-process.md +49 -0
  43. decisionlock-0.2.0rc4/docs/research/FREEZE_V2_CLOSURE.md +113 -0
  44. decisionlock-0.2.0rc4/docs/research/FREEZE_V2_RESULT_ADJUDICATION.md +98 -0
  45. decisionlock-0.2.0rc4/docs/scenarios.md +142 -0
  46. decisionlock-0.2.0rc4/docs/security-assumptions.md +13 -0
  47. decisionlock-0.2.0rc4/docs/threat-model.md +79 -0
  48. decisionlock-0.2.0rc4/examples/argument-mutation/README.md +3 -0
  49. decisionlock-0.2.0rc4/examples/dangerous_mcp_config.json +20 -0
  50. decisionlock-0.2.0rc4/examples/demo_tool_calls.jsonl +3 -0
  51. decisionlock-0.2.0rc4/examples/excessive-scope/README.md +3 -0
  52. decisionlock-0.2.0rc4/examples/harness/README.md +72 -0
  53. decisionlock-0.2.0rc4/examples/harness/policy.yaml +35 -0
  54. decisionlock-0.2.0rc4/examples/harness/provider.py +275 -0
  55. decisionlock-0.2.0rc4/examples/harness/run_demo.py +651 -0
  56. decisionlock-0.2.0rc4/examples/indirect-injection/README.md +3 -0
  57. decisionlock-0.2.0rc4/examples/mcp_config.json +15 -0
  58. decisionlock-0.2.0rc4/examples/mcp_posture_bypass.json +19 -0
  59. decisionlock-0.2.0rc4/examples/mcp_posture_protected.json +15 -0
  60. decisionlock-0.2.0rc4/examples/policy.yaml +44 -0
  61. decisionlock-0.2.0rc4/examples/policy_with_exception.yaml +53 -0
  62. decisionlock-0.2.0rc4/examples/replay/README.md +3 -0
  63. decisionlock-0.2.0rc4/examples/safe_mcp_config.json +12 -0
  64. decisionlock-0.2.0rc4/examples/scoped-refund/README.md +3 -0
  65. decisionlock-0.2.0rc4/examples/scoped-refund/policy.yaml +64 -0
  66. decisionlock-0.2.0rc4/examples/scoped-refund/request.json +23 -0
  67. decisionlock-0.2.0rc4/pyproject.toml +101 -0
  68. decisionlock-0.2.0rc4/requirements/build-hashed.txt +23 -0
  69. decisionlock-0.2.0rc4/requirements/confirmatory-runtime-lock.txt +28 -0
  70. decisionlock-0.2.0rc4/requirements/runtime-validated.txt +10 -0
  71. decisionlock-0.2.0rc4/requirements/validation.txt +10 -0
  72. decisionlock-0.2.0rc4/schemas/action-intent-v1.schema.json +827 -0
  73. decisionlock-0.2.0rc4/schemas/approval-receipt-v1.schema.json +217 -0
  74. decisionlock-0.2.0rc4/schemas/audit-checkpoint-v1.schema.json +59 -0
  75. decisionlock-0.2.0rc4/schemas/audit-event-v1.schema.json +201 -0
  76. decisionlock-0.2.0rc4/schemas/authority-analysis-v1.schema.json +249 -0
  77. decisionlock-0.2.0rc4/schemas/authority-grant-v1.schema.json +275 -0
  78. decisionlock-0.2.0rc4/schemas/authority-reference-v1.schema.json +29 -0
  79. decisionlock-0.2.0rc4/schemas/capability-lease-v1.schema.json +71 -0
  80. decisionlock-0.2.0rc4/schemas/causal-execution-graph-v1.schema.json +142 -0
  81. decisionlock-0.2.0rc4/schemas/credential-grant-v1.schema.json +114 -0
  82. decisionlock-0.2.0rc4/schemas/credential-request-v1.schema.json +75 -0
  83. decisionlock-0.2.0rc4/schemas/decision-receipt-v1.schema.json +459 -0
  84. decisionlock-0.2.0rc4/schemas/evidence-attestation-v1.schema.json +39 -0
  85. decisionlock-0.2.0rc4/schemas/execution-attestation-v1.schema.json +388 -0
  86. decisionlock-0.2.0rc4/schemas/execution-outcome-v1.schema.json +93 -0
  87. decisionlock-0.2.0rc4/schemas/execution-request-v1.schema.json +1570 -0
  88. decisionlock-0.2.0rc4/schemas/execution-resolution-v1.schema.json +119 -0
  89. decisionlock-0.2.0rc4/schemas/field-provenance-statement-v1.schema.json +138 -0
  90. decisionlock-0.2.0rc4/schemas/field-release-receipt-v1.schema.json +154 -0
  91. decisionlock-0.2.0rc4/schemas/policy-decision-analysis-v1.schema.json +100 -0
  92. decisionlock-0.2.0rc4/schemas/policy-v2.schema.json +856 -0
  93. decisionlock-0.2.0rc4/schemas/prepared-execution-v1.schema.json +148 -0
  94. decisionlock-0.2.0rc4/schemas/reconciliation-evidence-v1.schema.json +84 -0
  95. decisionlock-0.2.0rc4/scripts/check_architecture.py +10 -0
  96. decisionlock-0.2.0rc4/scripts/check_release_metadata.py +64 -0
  97. decisionlock-0.2.0rc4/scripts/check_secrets.py +39 -0
  98. decisionlock-0.2.0rc4/scripts/generate_release_manifest.py +68 -0
  99. decisionlock-0.2.0rc4/scripts/generate_sbom.py +102 -0
  100. decisionlock-0.2.0rc4/scripts/generate_schemas.py +94 -0
  101. decisionlock-0.2.0rc4/scripts/normalize_sdist.py +59 -0
  102. decisionlock-0.2.0rc4/scripts/security_scan.py +107 -0
  103. decisionlock-0.2.0rc4/scripts/smoke_install.py +13 -0
  104. decisionlock-0.2.0rc4/scripts/verify_release.py +559 -0
  105. decisionlock-0.2.0rc4/setup.cfg +4 -0
  106. decisionlock-0.2.0rc4/setup.py +3 -0
  107. decisionlock-0.2.0rc4/src/decisionlock/__init__.py +5 -0
  108. decisionlock-0.2.0rc4/src/decisionlock/__main__.py +4 -0
  109. decisionlock-0.2.0rc4/src/decisionlock/_meta.py +12 -0
  110. decisionlock-0.2.0rc4/src/decisionlock/_version.py +1 -0
  111. decisionlock-0.2.0rc4/src/decisionlock/adapters/__init__.py +1 -0
  112. decisionlock-0.2.0rc4/src/decisionlock/adapters/broker/__init__.py +17 -0
  113. decisionlock-0.2.0rc4/src/decisionlock/adapters/broker/mock.py +63 -0
  114. decisionlock-0.2.0rc4/src/decisionlock/adapters/broker/production.py +337 -0
  115. decisionlock-0.2.0rc4/src/decisionlock/adapters/crypto/__init__.py +15 -0
  116. decisionlock-0.2.0rc4/src/decisionlock/adapters/crypto/ed25519.py +131 -0
  117. decisionlock-0.2.0rc4/src/decisionlock/adapters/evidence/__init__.py +19 -0
  118. decisionlock-0.2.0rc4/src/decisionlock/adapters/evidence/bundle.py +308 -0
  119. decisionlock-0.2.0rc4/src/decisionlock/adapters/executor/__init__.py +3 -0
  120. decisionlock-0.2.0rc4/src/decisionlock/adapters/executor/memory.py +58 -0
  121. decisionlock-0.2.0rc4/src/decisionlock/adapters/protocols/__init__.py +1 -0
  122. decisionlock-0.2.0rc4/src/decisionlock/adapters/protocols/mcp/__init__.py +64 -0
  123. decisionlock-0.2.0rc4/src/decisionlock/adapters/protocols/mcp/http_executor.py +232 -0
  124. decisionlock-0.2.0rc4/src/decisionlock/adapters/protocols/mcp/http_gateway.py +502 -0
  125. decisionlock-0.2.0rc4/src/decisionlock/adapters/protocols/mcp/http_gateway_types.py +26 -0
  126. decisionlock-0.2.0rc4/src/decisionlock/adapters/protocols/mcp/http_security.py +46 -0
  127. decisionlock-0.2.0rc4/src/decisionlock/adapters/protocols/mcp/http_server.py +268 -0
  128. decisionlock-0.2.0rc4/src/decisionlock/adapters/protocols/mcp/intent.py +74 -0
  129. decisionlock-0.2.0rc4/src/decisionlock/adapters/protocols/mcp/jsonrpc.py +42 -0
  130. decisionlock-0.2.0rc4/src/decisionlock/adapters/protocols/mcp/modern.py +382 -0
  131. decisionlock-0.2.0rc4/src/decisionlock/adapters/protocols/mcp/protected.py +1139 -0
  132. decisionlock-0.2.0rc4/src/decisionlock/adapters/protocols/mcp/schema.py +28 -0
  133. decisionlock-0.2.0rc4/src/decisionlock/adapters/protocols/mcp/stdio.py +340 -0
  134. decisionlock-0.2.0rc4/src/decisionlock/adapters/reconciliation/__init__.py +16 -0
  135. decisionlock-0.2.0rc4/src/decisionlock/adapters/reconciliation/mcp_http.py +249 -0
  136. decisionlock-0.2.0rc4/src/decisionlock/adapters/reconciliation/mcp_http_worker.py +30 -0
  137. decisionlock-0.2.0rc4/src/decisionlock/adapters/reconciliation/memory.py +15 -0
  138. decisionlock-0.2.0rc4/src/decisionlock/adapters/reconciliation/provider_store.py +203 -0
  139. decisionlock-0.2.0rc4/src/decisionlock/adapters/storage/__init__.py +0 -0
  140. decisionlock-0.2.0rc4/src/decisionlock/adapters/storage/sqlite/__init__.py +12 -0
  141. decisionlock-0.2.0rc4/src/decisionlock/adapters/storage/sqlite/reconciliation.py +455 -0
  142. decisionlock-0.2.0rc4/src/decisionlock/adapters/storage/sqlite/state.py +1494 -0
  143. decisionlock-0.2.0rc4/src/decisionlock/application/__init__.py +22 -0
  144. decisionlock-0.2.0rc4/src/decisionlock/application/provider_reconciliation.py +66 -0
  145. decisionlock-0.2.0rc4/src/decisionlock/application/reconciliation_worker.py +211 -0
  146. decisionlock-0.2.0rc4/src/decisionlock/application/service.py +1052 -0
  147. decisionlock-0.2.0rc4/src/decisionlock/audit.py +530 -0
  148. decisionlock-0.2.0rc4/src/decisionlock/changed.py +58 -0
  149. decisionlock-0.2.0rc4/src/decisionlock/cli/__init__.py +79 -0
  150. decisionlock-0.2.0rc4/src/decisionlock/cli/__main__.py +4 -0
  151. decisionlock-0.2.0rc4/src/decisionlock/cli/app.py +861 -0
  152. decisionlock-0.2.0rc4/src/decisionlock/cli/io.py +60 -0
  153. decisionlock-0.2.0rc4/src/decisionlock/compatibility/__init__.py +3 -0
  154. decisionlock-0.2.0rc4/src/decisionlock/compatibility/policy_v1.py +42 -0
  155. decisionlock-0.2.0rc4/src/decisionlock/compatibility/v1_cli.py +614 -0
  156. decisionlock-0.2.0rc4/src/decisionlock/compatibility/v1_demo.py +129 -0
  157. decisionlock-0.2.0rc4/src/decisionlock/demo.py +147 -0
  158. decisionlock-0.2.0rc4/src/decisionlock/discovery.py +82 -0
  159. decisionlock-0.2.0rc4/src/decisionlock/doctor.py +108 -0
  160. decisionlock-0.2.0rc4/src/decisionlock/domain/__init__.py +181 -0
  161. decisionlock-0.2.0rc4/src/decisionlock/domain/credential_authority.py +115 -0
  162. decisionlock-0.2.0rc4/src/decisionlock/domain/enums.py +126 -0
  163. decisionlock-0.2.0rc4/src/decisionlock/domain/models.py +838 -0
  164. decisionlock-0.2.0rc4/src/decisionlock/domain/policy.py +136 -0
  165. decisionlock-0.2.0rc4/src/decisionlock/domain/provider_contracts.py +176 -0
  166. decisionlock-0.2.0rc4/src/decisionlock/engine/__init__.py +1 -0
  167. decisionlock-0.2.0rc4/src/decisionlock/engine/attestation.py +122 -0
  168. decisionlock-0.2.0rc4/src/decisionlock/engine/authority.py +212 -0
  169. decisionlock-0.2.0rc4/src/decisionlock/engine/canonical.py +58 -0
  170. decisionlock-0.2.0rc4/src/decisionlock/engine/causal.py +143 -0
  171. decisionlock-0.2.0rc4/src/decisionlock/engine/checkpoints.py +72 -0
  172. decisionlock-0.2.0rc4/src/decisionlock/engine/credentials.py +129 -0
  173. decisionlock-0.2.0rc4/src/decisionlock/engine/execution.py +362 -0
  174. decisionlock-0.2.0rc4/src/decisionlock/engine/field_integrity.py +376 -0
  175. decisionlock-0.2.0rc4/src/decisionlock/engine/policy.py +267 -0
  176. decisionlock-0.2.0rc4/src/decisionlock/engine/policy_intelligence.py +140 -0
  177. decisionlock-0.2.0rc4/src/decisionlock/engine/provider_contracts.py +59 -0
  178. decisionlock-0.2.0rc4/src/decisionlock/engine/provider_results.py +50 -0
  179. decisionlock-0.2.0rc4/src/decisionlock/engine/receipts.py +261 -0
  180. decisionlock-0.2.0rc4/src/decisionlock/gate.py +20 -0
  181. decisionlock-0.2.0rc4/src/decisionlock/http_cli.py +263 -0
  182. decisionlock-0.2.0rc4/src/decisionlock/mcp_stdio.py +679 -0
  183. decisionlock-0.2.0rc4/src/decisionlock/models.py +157 -0
  184. decisionlock-0.2.0rc4/src/decisionlock/policy.py +606 -0
  185. decisionlock-0.2.0rc4/src/decisionlock/policy_packs.py +184 -0
  186. decisionlock-0.2.0rc4/src/decisionlock/ports/__init__.py +63 -0
  187. decisionlock-0.2.0rc4/src/decisionlock/ports/interfaces.py +318 -0
  188. decisionlock-0.2.0rc4/src/decisionlock/ports/reconciliation_work.py +49 -0
  189. decisionlock-0.2.0rc4/src/decisionlock/posture.py +244 -0
  190. decisionlock-0.2.0rc4/src/decisionlock/py.typed +0 -0
  191. decisionlock-0.2.0rc4/src/decisionlock/reconcile_cli.py +162 -0
  192. decisionlock-0.2.0rc4/src/decisionlock/reconcile_worker_cli.py +246 -0
  193. decisionlock-0.2.0rc4/src/decisionlock/render.py +217 -0
  194. decisionlock-0.2.0rc4/src/decisionlock/resources/default_policy_v2.yaml +64 -0
  195. decisionlock-0.2.0rc4/src/decisionlock/resources/demo-intent.json +23 -0
  196. decisionlock-0.2.0rc4/src/decisionlock/risk.py +158 -0
  197. decisionlock-0.2.0rc4/src/decisionlock/secrets.py +89 -0
  198. decisionlock-0.2.0rc4/src/decisionlock/security/__init__.py +5 -0
  199. decisionlock-0.2.0rc4/src/decisionlock/security/files.py +137 -0
  200. decisionlock-0.2.0rc4/src/decisionlock/service_deployment.py +51 -0
  201. decisionlock-0.2.0rc4/src/decisionlock.egg-info/PKG-INFO +569 -0
  202. decisionlock-0.2.0rc4/src/decisionlock.egg-info/SOURCES.txt +294 -0
  203. decisionlock-0.2.0rc4/src/decisionlock.egg-info/dependency_links.txt +1 -0
  204. decisionlock-0.2.0rc4/src/decisionlock.egg-info/entry_points.txt +5 -0
  205. decisionlock-0.2.0rc4/src/decisionlock.egg-info/requires.txt +22 -0
  206. decisionlock-0.2.0rc4/src/decisionlock.egg-info/top_level.txt +1 -0
  207. decisionlock-0.2.0rc4/tests/__init__.py +0 -0
  208. decisionlock-0.2.0rc4/tests/adversarial/test_policy_revalidation.py +143 -0
  209. decisionlock-0.2.0rc4/tests/adversarial/test_rc2_hardening.py +233 -0
  210. decisionlock-0.2.0rc4/tests/adversarial/test_receipt_entrypoints.py +169 -0
  211. decisionlock-0.2.0rc4/tests/adversarial/test_security_controls.py +106 -0
  212. decisionlock-0.2.0rc4/tests/conformance/test_mcp.py +84 -0
  213. decisionlock-0.2.0rc4/tests/conformance/test_models.py +33 -0
  214. decisionlock-0.2.0rc4/tests/conformance/test_schemas.py +47 -0
  215. decisionlock-0.2.0rc4/tests/conformance/test_security_timestamps.py +95 -0
  216. decisionlock-0.2.0rc4/tests/conftest.py +63 -0
  217. decisionlock-0.2.0rc4/tests/fixtures/fake_mcp_server.py +117 -0
  218. decisionlock-0.2.0rc4/tests/integration/__init__.py +0 -0
  219. decisionlock-0.2.0rc4/tests/integration/test_approval_flow.py +114 -0
  220. decisionlock-0.2.0rc4/tests/integration/test_authority_graph.py +375 -0
  221. decisionlock-0.2.0rc4/tests/integration/test_cli.py +348 -0
  222. decisionlock-0.2.0rc4/tests/integration/test_credential_issuance.py +164 -0
  223. decisionlock-0.2.0rc4/tests/integration/test_demo.py +14 -0
  224. decisionlock-0.2.0rc4/tests/integration/test_end_to_end.py +98 -0
  225. decisionlock-0.2.0rc4/tests/integration/test_evidence.py +193 -0
  226. decisionlock-0.2.0rc4/tests/integration/test_execution_attestation_reconciliation.py +345 -0
  227. decisionlock-0.2.0rc4/tests/integration/test_market_controls.py +160 -0
  228. decisionlock-0.2.0rc4/tests/integration/test_mcp_processor.py +285 -0
  229. decisionlock-0.2.0rc4/tests/integration/test_mcp_protected_cli.py +205 -0
  230. decisionlock-0.2.0rc4/tests/integration/test_mcp_protected_execution.py +942 -0
  231. decisionlock-0.2.0rc4/tests/integration/test_mcp_proxy_lifecycle.py +182 -0
  232. decisionlock-0.2.0rc4/tests/integration/test_phase5_complete.py +920 -0
  233. decisionlock-0.2.0rc4/tests/integration/test_phase5_complete_cli.py +197 -0
  234. decisionlock-0.2.0rc4/tests/integration/test_phase5cd_cli.py +250 -0
  235. decisionlock-0.2.0rc4/tests/integration/test_phase6ab_modern_mcp_http.py +397 -0
  236. decisionlock-0.2.0rc4/tests/integration/test_phase6ab_real_http_upstream.py +186 -0
  237. decisionlock-0.2.0rc4/tests/integration/test_phase6c_credential_http.py +274 -0
  238. decisionlock-0.2.0rc4/tests/integration/test_phase6d_mcp_reconciliation.py +306 -0
  239. decisionlock-0.2.0rc4/tests/integration/test_phase6d_real_http_reconciliation.py +124 -0
  240. decisionlock-0.2.0rc4/tests/integration/test_phase6e_multiprocess_leases.py +70 -0
  241. decisionlock-0.2.0rc4/tests/integration/test_phase6e_service_health.py +74 -0
  242. decisionlock-0.2.0rc4/tests/integration/test_protected_execution.py +931 -0
  243. decisionlock-0.2.0rc4/tests/research/test_authorization_lineage_canonical_session.py +825 -0
  244. decisionlock-0.2.0rc4/tests/research/test_authorization_lineage_confirmatory_evidence.py +399 -0
  245. decisionlock-0.2.0rc4/tests/research/test_authorization_lineage_experiment.py +275 -0
  246. decisionlock-0.2.0rc4/tests/research/test_authorization_lineage_freeze_controls.py +414 -0
  247. decisionlock-0.2.0rc4/tests/research/test_authorization_lineage_sequence_identity.py +114 -0
  248. decisionlock-0.2.0rc4/tests/research/test_authorization_lineage_sqlite_lifecycle.py +372 -0
  249. decisionlock-0.2.0rc4/tests/research/test_freeze_v2_component_binding.py +106 -0
  250. decisionlock-0.2.0rc4/tests/test_audit.py +279 -0
  251. decisionlock-0.2.0rc4/tests/test_changed.py +71 -0
  252. decisionlock-0.2.0rc4/tests/test_cli_approvals.py +194 -0
  253. decisionlock-0.2.0rc4/tests/test_cli_audit_chain.py +75 -0
  254. decisionlock-0.2.0rc4/tests/test_cli_gate.py +126 -0
  255. decisionlock-0.2.0rc4/tests/test_cli_init.py +43 -0
  256. decisionlock-0.2.0rc4/tests/test_demo.py +63 -0
  257. decisionlock-0.2.0rc4/tests/test_demo_examples.py +29 -0
  258. decisionlock-0.2.0rc4/tests/test_discovery.py +28 -0
  259. decisionlock-0.2.0rc4/tests/test_doctor.py +43 -0
  260. decisionlock-0.2.0rc4/tests/test_entrypoints.py +102 -0
  261. decisionlock-0.2.0rc4/tests/test_example_policies_default_deny.py +90 -0
  262. decisionlock-0.2.0rc4/tests/test_execution_preflight_rename.py +88 -0
  263. decisionlock-0.2.0rc4/tests/test_findings_report.py +81 -0
  264. decisionlock-0.2.0rc4/tests/test_gate.py +24 -0
  265. decisionlock-0.2.0rc4/tests/test_mcp_real_server_smoke.py +182 -0
  266. decisionlock-0.2.0rc4/tests/test_mcp_stdio.py +719 -0
  267. decisionlock-0.2.0rc4/tests/test_mcp_v2_real_server_smoke.py +251 -0
  268. decisionlock-0.2.0rc4/tests/test_phase2_happy_path.py +327 -0
  269. decisionlock-0.2.0rc4/tests/test_policy.py +211 -0
  270. decisionlock-0.2.0rc4/tests/test_policy_packs.py +51 -0
  271. decisionlock-0.2.0rc4/tests/test_release_readiness.py +110 -0
  272. decisionlock-0.2.0rc4/tests/test_release_verification.py +794 -0
  273. decisionlock-0.2.0rc4/tests/test_research_excluded_from_distribution.py +62 -0
  274. decisionlock-0.2.0rc4/tests/test_secrets.py +18 -0
  275. decisionlock-0.2.0rc4/tests/test_security_scan.py +68 -0
  276. decisionlock-0.2.0rc4/tests/test_supply_chain_config.py +110 -0
  277. decisionlock-0.2.0rc4/tests/unit/test_canonical.py +52 -0
  278. decisionlock-0.2.0rc4/tests/unit/test_credentials.py +167 -0
  279. decisionlock-0.2.0rc4/tests/unit/test_crypto.py +53 -0
  280. decisionlock-0.2.0rc4/tests/unit/test_phase6ab_modern_profile.py +285 -0
  281. decisionlock-0.2.0rc4/tests/unit/test_phase6d_provider_reconciliation.py +449 -0
  282. decisionlock-0.2.0rc4/tests/unit/test_phase6d_reconcile_cli.py +298 -0
  283. decisionlock-0.2.0rc4/tests/unit/test_phase6e_fenced_resolution_semantics.py +299 -0
  284. decisionlock-0.2.0rc4/tests/unit/test_phase6e_reconcile_worker_cli.py +137 -0
  285. decisionlock-0.2.0rc4/tests/unit/test_phase6e_reconciliation_time.py +77 -0
  286. decisionlock-0.2.0rc4/tests/unit/test_phase6e_reconciliation_worker.py +1197 -0
  287. decisionlock-0.2.0rc4/tests/unit/test_phase6e_service_deployment.py +119 -0
  288. decisionlock-0.2.0rc4/tests/unit/test_policy.py +216 -0
  289. decisionlock-0.2.0rc4/tests/unit/test_production_credential_authority.py +176 -0
  290. decisionlock-0.2.0rc4/tests/unit/test_production_credential_authority_edges.py +469 -0
  291. decisionlock-0.2.0rc4/tests/unit/test_provider_contracts.py +214 -0
  292. decisionlock-0.2.0rc4/tests/unit/test_provider_results.py +97 -0
  293. decisionlock-0.2.0rc4/tests/unit/test_receipts.py +213 -0
  294. decisionlock-0.2.0rc4/tests/unit/test_release_metadata.py +14 -0
  295. decisionlock-0.2.0rc4/tests/unit/test_serialized_time_correctness.py +851 -0
  296. decisionlock-0.2.0rc4/tests/unit/test_storage.py +217 -0
@@ -0,0 +1,19 @@
1
+ .git
2
+ .github
3
+ .pytest_cache
4
+ .mypy_cache
5
+ .ruff_cache
6
+ .coverage
7
+ coverage.xml
8
+ htmlcov
9
+ __pycache__
10
+ *.py[cod]
11
+ .venv
12
+ venv
13
+ build
14
+ dist
15
+ *.egg-info
16
+ .decisionlock
17
+ *.sqlite*
18
+ *.db
19
+ .env*
@@ -0,0 +1,38 @@
1
+ # Code of Conduct
2
+
3
+ ## Scope
4
+
5
+ This policy applies to repository issues, pull requests, reviews, discussions, and other project-managed communication spaces.
6
+
7
+ ## Expected behavior
8
+
9
+ Participants must:
10
+
11
+ - communicate precisely, respectfully, and in good faith;
12
+ - distinguish verified evidence from assumptions;
13
+ - review security-sensitive changes without personal attacks;
14
+ - protect private data, credentials, vulnerability details, and affected users;
15
+ - accept correction and revise claims when evidence changes.
16
+
17
+ ## Unacceptable behavior
18
+
19
+ The following are not accepted:
20
+
21
+ - harassment, discrimination, threats, or targeted intimidation;
22
+ - publishing private information or live credentials;
23
+ - reckless or coercive vulnerability disclosure;
24
+ - deliberately misleading technical claims;
25
+ - sustained disruption of reviews, issues, or incident response;
26
+ - retaliation against a person who reports a security or conduct concern.
27
+
28
+ ## Reporting
29
+
30
+ Do not place incident details, names, screenshots, private messages, or other sensitive evidence in a public issue.
31
+
32
+ To request a private reporting channel, open a minimal issue titled `Private conduct report contact request` and include no incident details. The maintainer will provide a private channel before the report or evidence is shared, then close the public request.
33
+
34
+ The private report should include the relevant links, dates, participants, and a factual description. Avoid speculation and unnecessary personal data.
35
+
36
+ ## Enforcement
37
+
38
+ The maintainer may edit or remove content, restrict participation, close discussions, or block accounts when necessary to protect contributors, users, or the security process. Enforcement decisions should be proportional, documented, and based on available evidence.
@@ -0,0 +1,41 @@
1
+ # Contributing
2
+
3
+ DecisionLock is security-sensitive software. Small changes can alter authorization, replay, credential, and audit semantics.
4
+
5
+ ## Development setup
6
+
7
+ Use Python 3.11 or newer.
8
+
9
+ ```bash
10
+ python -m venv .venv
11
+ . .venv/bin/activate
12
+ python -m pip install -e '.[dev]'
13
+ make check
14
+ ```
15
+
16
+ `make check` is the minimum local gate before opening a pull request.
17
+
18
+ ## Pull-request requirements
19
+
20
+ A pull request must:
21
+
22
+ - describe the security or operational behavior being changed;
23
+ - remain narrowly scoped;
24
+ - include tests for the changed behavior;
25
+ - preserve deterministic reason codes and fail-closed behavior;
26
+ - update schemas and documentation when public contracts change;
27
+ - avoid unrelated formatting, refactoring, or dependency churn;
28
+ - pass the exact GitHub Actions checks for its final head commit.
29
+
30
+ Security-sensitive changes should test applicable allow, deny, approval, replay, mutation, stale-state, concurrency, and failure paths.
31
+
32
+ ## Architecture rules
33
+
34
+ - Domain and policy code must remain independent of transport, CLI, database, telemetry, and provider SDKs.
35
+ - External systems must connect through typed ports and adapters.
36
+ - An adapter must not silently weaken policy, credential ceilings, replay protection, or audit guarantees.
37
+ - Provider-specific work requires an explicit, separately reviewed scope and must not become a core dependency.
38
+
39
+ ## Reporting vulnerabilities
40
+
41
+ Do not open a public issue for a vulnerability. Follow [SECURITY.md](SECURITY.md).
@@ -0,0 +1,37 @@
1
+ # Security Policy
2
+
3
+ DecisionLock is prerelease security software. It is not production-certified and must be deployed behind independent identity, secret-management, network, process, and operating-system controls.
4
+
5
+ ## Supported versions
6
+
7
+ Security fixes are evaluated for the current `main` branch and the latest maintained prerelease. Older prereleases and the v0.1 compatibility surface may receive fixes only when the issue affects the maintained code path.
8
+
9
+ ## Report a vulnerability
10
+
11
+ Do not open a public issue containing vulnerability details.
12
+
13
+ Use GitHub private vulnerability reporting:
14
+
15
+ 1. Open the repository's **Security** tab.
16
+ 2. Select **Advisories**.
17
+ 3. Select **Report a vulnerability** and submit the report privately.
18
+
19
+ If the private-reporting button is unavailable, open a minimal public issue titled `Private security contact request` without technical details, affected versions, reproduction steps, names, credentials, or evidence. The maintainer will provide a private channel before any sensitive information is shared.
20
+
21
+ Include in the private report:
22
+
23
+ - affected version or commit;
24
+ - reproduction steps or a minimal proof of concept;
25
+ - expected and observed behavior;
26
+ - security impact and realistic attack conditions;
27
+ - suggested remediation, when known.
28
+
29
+ Do not include live credentials, private keys, personal data, customer data, or production secrets. Use synthetic test data.
30
+
31
+ ## Response expectations
32
+
33
+ There is no commercial support or response-time SLA. Reports will be triaged according to reproducibility, exploitability, affected trust boundary, and potential impact. Public disclosure should occur only after a remediation and release plan is agreed.
34
+
35
+ ## Deployment responsibility
36
+
37
+ DecisionLock does not replace process isolation, network egress controls, secret-manager policy, identity proofing, centralized transactional state, or an independent audit/checkpoint store.
@@ -0,0 +1,14 @@
1
+ # Support
2
+
3
+ DecisionLock is a prerelease open-source project. It has no uptime, incident-response, compatibility, or production-support SLA.
4
+
5
+ Use GitHub issues for:
6
+
7
+ - reproducible non-security defects;
8
+ - documentation errors;
9
+ - narrowly scoped feature proposals;
10
+ - design discussions grounded in a concrete use case.
11
+
12
+ Include the DecisionLock version or commit, operating system, Python version, command, minimal configuration, expected behavior, observed behavior, and relevant redacted logs.
13
+
14
+ Do not use public issues for vulnerabilities, credentials, private data, or production incident details. Follow [SECURITY.md](SECURITY.md) for security reports.
@@ -0,0 +1,27 @@
1
+ version: 2
2
+ updates:
3
+ # Version-update pull requests are enabled. They were paused for the RC2
4
+ # demonstration; the pause is lifted as part of the Phase 0 supply-chain
5
+ # stabilization. Every PR is validated by the same `make check` gate as any
6
+ # other change, and direct runtime constraints live in
7
+ # requirements/runtime-validated.txt.
8
+ - package-ecosystem: pip
9
+ directory: /
10
+ schedule:
11
+ interval: weekly
12
+ open-pull-requests-limit: 5
13
+ groups:
14
+ python-runtime:
15
+ dependency-type: production
16
+ python-development:
17
+ dependency-type: development
18
+ reviewers:
19
+ - TensorScholar
20
+
21
+ - package-ecosystem: github-actions
22
+ directory: /
23
+ schedule:
24
+ interval: weekly
25
+ open-pull-requests-limit: 5
26
+ reviewers:
27
+ - TensorScholar
@@ -0,0 +1,184 @@
1
+ name: CI
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ permissions:
7
+ contents: read
8
+
9
+ concurrency:
10
+ group: ci-${{ github.workflow }}-${{ github.ref }}
11
+ cancel-in-progress: true
12
+
13
+ jobs:
14
+ quality:
15
+ name: Python ${{ matrix.python-version }} quality
16
+ runs-on: ubuntu-latest
17
+ timeout-minutes: 20
18
+ strategy:
19
+ fail-fast: false
20
+ matrix:
21
+ python-version: ["3.11", "3.12", "3.13"]
22
+ steps:
23
+ - name: Checkout
24
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
25
+ with:
26
+ persist-credentials: false
27
+ - name: Set up Python
28
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
29
+ with:
30
+ python-version: ${{ matrix.python-version }}
31
+ cache: pip
32
+ - name: Install
33
+ run: |
34
+ python -m pip install --upgrade pip
35
+ python -m pip install -c requirements/runtime-validated.txt -e '.[http]'
36
+ python -m pip install -r requirements/validation.txt
37
+ - name: Verify
38
+ run: make check
39
+
40
+ compatibility:
41
+ name: ${{ matrix.os }} / Python 3.13
42
+ runs-on: ${{ matrix.os }}
43
+ timeout-minutes: 20
44
+ strategy:
45
+ fail-fast: false
46
+ matrix:
47
+ os: [ubuntu-latest, macos-latest, windows-latest]
48
+ steps:
49
+ - name: Checkout
50
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
51
+ with:
52
+ persist-credentials: false
53
+ - name: Set up Python
54
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
55
+ with:
56
+ python-version: "3.13"
57
+ cache: pip
58
+ - name: Install
59
+ run: |
60
+ python -m pip install --upgrade pip
61
+ python -m pip install -c requirements/runtime-validated.txt -e '.[http]'
62
+ python -m pip install -r requirements/validation.txt
63
+ - name: Compile
64
+ run: python -m compileall -q src tests
65
+ - name: Test
66
+ run: python -m pytest
67
+
68
+ package:
69
+ name: Package, reproducibility and clean-install smoke
70
+ runs-on: ubuntu-latest
71
+ timeout-minutes: 30
72
+ steps:
73
+ - name: Checkout
74
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
75
+ with:
76
+ persist-credentials: false
77
+ fetch-depth: 0
78
+ - name: Set up Python
79
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
80
+ with:
81
+ python-version: "3.13"
82
+ cache: pip
83
+ - name: Verify hash-pinned build backend
84
+ shell: bash
85
+ run: |
86
+ set -euo pipefail
87
+ # The build backend is fetched from the network during the build. Pin it
88
+ # by hash so the build does not depend on whatever the index serves.
89
+ python -m venv /tmp/decisionlock-build-venv
90
+ /tmp/decisionlock-build-venv/bin/python -m pip install --upgrade pip
91
+ /tmp/decisionlock-build-venv/bin/python -m pip install \
92
+ --require-hashes -r requirements/build-hashed.txt
93
+ # The pinned backend must be the one pyproject declares.
94
+ /tmp/decisionlock-build-venv/bin/python - <<'PY'
95
+ import pathlib, re, tomllib
96
+ import setuptools
97
+ spec = tomllib.loads(pathlib.Path("pyproject.toml").read_text())
98
+ declared = spec["build-system"]["requires"]
99
+ expected = re.match(r"setuptools==([0-9.]+)", next(d for d in declared if "setuptools" in d))
100
+ assert expected, f"build-system must pin setuptools exactly, got {declared!r}"
101
+ installed = setuptools.__version__
102
+ assert installed == expected.group(1), (
103
+ f"build backend version mismatch: pyproject pins {expected.group(1)}, "
104
+ f"hash-pinned toolchain installed {installed}"
105
+ )
106
+ print(f"build backend hash-pinned and version-matched: setuptools=={installed}")
107
+ PY
108
+ - name: Build reproducibly with the hash-pinned backend
109
+ shell: bash
110
+ run: |
111
+ set -euo pipefail
112
+ /tmp/decisionlock-build-venv/bin/python -m pip install build twine
113
+ export SOURCE_DATE_EPOCH="$(git log -1 --format=%ct)"
114
+ rm -rf dist dist-a dist-b release
115
+ /tmp/decisionlock-build-venv/bin/python -m build --no-isolation --outdir dist-a
116
+ /tmp/decisionlock-build-venv/bin/python -m build --no-isolation --outdir dist-b
117
+
118
+ WHEEL_A="$(find dist-a -maxdepth 1 -name '*.whl' -print -quit)"
119
+ WHEEL_B="$(find dist-b -maxdepth 1 -name '*.whl' -print -quit)"
120
+ SDIST_A="$(find dist-a -maxdepth 1 -name '*.tar.gz' -print -quit)"
121
+ SDIST_B="$(find dist-b -maxdepth 1 -name '*.tar.gz' -print -quit)"
122
+ test -n "$WHEEL_A" && test -n "$WHEEL_B" && test -n "$SDIST_A" && test -n "$SDIST_B"
123
+
124
+ cmp "$WHEEL_A" "$WHEEL_B"
125
+ python scripts/normalize_sdist.py "$SDIST_A" /tmp/decisionlock-sdist-a.tar.gz
126
+ python scripts/normalize_sdist.py "$SDIST_B" /tmp/decisionlock-sdist-b.tar.gz
127
+ cmp /tmp/decisionlock-sdist-a.tar.gz /tmp/decisionlock-sdist-b.tar.gz
128
+
129
+ mkdir -p dist release
130
+ cp "$WHEEL_A" dist/
131
+ cp /tmp/decisionlock-sdist-a.tar.gz "dist/$(basename "$SDIST_A")"
132
+ python -m twine check dist/*
133
+ python scripts/generate_sbom.py --output release/decisionlock.cdx.json
134
+ python scripts/generate_release_manifest.py \
135
+ --dist dist \
136
+ --commit "$GITHUB_SHA" \
137
+ --output release/release-manifest.json
138
+ sha256sum dist/* release/decisionlock.cdx.json release/release-manifest.json \
139
+ > release/SHA256SUMS
140
+ - name: Base-wheel clean-install smoke
141
+ shell: bash
142
+ run: |
143
+ set -euo pipefail
144
+ WHEEL="$(realpath "$(find dist -maxdepth 1 -name '*.whl' -print -quit)")"
145
+ python -m venv /tmp/decisionlock-wheel-smoke
146
+ /tmp/decisionlock-wheel-smoke/bin/python -m pip install "$WHEEL"
147
+ /tmp/decisionlock-wheel-smoke/bin/decisionlock --version
148
+ /tmp/decisionlock-wheel-smoke/bin/decisionlock --help >/dev/null
149
+ /tmp/decisionlock-wheel-smoke/bin/decisionlock-mcp-http --help >/dev/null
150
+ /tmp/decisionlock-wheel-smoke/bin/decisionlock-reconcile --help >/dev/null
151
+ /tmp/decisionlock-wheel-smoke/bin/decisionlock-reconcile-worker --help >/dev/null
152
+ /tmp/decisionlock-wheel-smoke/bin/decisionlock demo --output /tmp/decisionlock-demo
153
+ /tmp/decisionlock-wheel-smoke/bin/decisionlock evidence-verify /tmp/decisionlock-demo/evidence
154
+ /tmp/decisionlock-wheel-smoke/bin/python -m pip check
155
+ - name: HTTP-extra wheel smoke
156
+ shell: bash
157
+ run: |
158
+ set -euo pipefail
159
+ WHEEL="$(realpath "$(find dist -maxdepth 1 -name '*.whl' -print -quit)")"
160
+ python -m venv /tmp/decisionlock-http-wheel-smoke
161
+ /tmp/decisionlock-http-wheel-smoke/bin/python -m pip install "decisionlock[http] @ file://$WHEEL"
162
+ /tmp/decisionlock-http-wheel-smoke/bin/decisionlock-mcp-http --help >/dev/null
163
+ /tmp/decisionlock-http-wheel-smoke/bin/decisionlock-reconcile --help >/dev/null
164
+ /tmp/decisionlock-http-wheel-smoke/bin/decisionlock-reconcile-worker --help >/dev/null
165
+ /tmp/decisionlock-http-wheel-smoke/bin/python -m decisionlock.http_cli --help >/dev/null
166
+ /tmp/decisionlock-http-wheel-smoke/bin/python -m pip check
167
+ - name: Container smoke
168
+ shell: bash
169
+ run: |
170
+ set -euo pipefail
171
+ docker build --tag decisionlock-ci .
172
+ test "$(docker run --rm --entrypoint id decisionlock-ci -u)" = "10001"
173
+ docker run --rm decisionlock-ci --version
174
+ docker run --rm --entrypoint decisionlock-mcp-http decisionlock-ci --help >/dev/null
175
+ docker run --rm --entrypoint python decisionlock-ci \
176
+ -c 'import httpx, starlette, uvicorn; import decisionlock; print(decisionlock.__version__)'
177
+ - name: Upload release-candidate artifacts
178
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
179
+ with:
180
+ name: decisionlock-release-candidate
181
+ path: |
182
+ dist/*
183
+ release/*
184
+ if-no-files-found: error
@@ -0,0 +1,41 @@
1
+ name: CodeQL
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ permissions:
7
+ actions: read
8
+ contents: read
9
+ # Required for the analyze step to publish results and for findings to fail
10
+ # the check. Without this the previous configuration published no results at
11
+ # all and nothing could fail.
12
+ security-events: write
13
+
14
+ jobs:
15
+ analyze:
16
+ runs-on: ubuntu-latest
17
+ timeout-minutes: 20
18
+ steps:
19
+ - name: Checkout
20
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
21
+ with:
22
+ persist-credentials: false
23
+ - name: Initialize CodeQL
24
+ uses: github/codeql-action/init@adfda868f108ac4222129de456ea554034a27db7 # v4
25
+ with:
26
+ languages: python
27
+ - name: Analyze
28
+ # Results are uploaded to code scanning so that an alert fails this
29
+ # check. This step must not be continue-on-error: a CodeQL failure is a
30
+ # build failure.
31
+ uses: github/codeql-action/analyze@adfda868f108ac4222129de456ea554034a27db7 # v4
32
+ with:
33
+ category: "/language:python"
34
+ output: codeql-results
35
+ - name: Retain CodeQL SARIF as build evidence
36
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
37
+ with:
38
+ name: codeql-sarif
39
+ path: codeql-results/*.sarif
40
+ retention-days: 30
41
+ if-no-files-found: error
@@ -0,0 +1,70 @@
1
+ name: DecisionLock
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ permissions:
7
+ contents: read
8
+
9
+ jobs:
10
+ mcp-security-gate:
11
+ name: MCP security gate
12
+ runs-on: ubuntu-latest
13
+ timeout-minutes: 15
14
+
15
+ steps:
16
+ - name: Checkout
17
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
18
+ with:
19
+ persist-credentials: false
20
+ fetch-depth: 0
21
+
22
+ - name: Set up Python
23
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
24
+ with:
25
+ python-version: "3.12"
26
+
27
+ - name: Install DecisionLock
28
+ run: python -m pip install -c requirements/runtime-validated.txt -e .
29
+
30
+ - name: Run changed-config gate
31
+ shell: bash
32
+ run: |
33
+ set +e
34
+ if [ "${{ github.event_name }}" = "pull_request" ]; then
35
+ BASE_REF="${{ github.event.pull_request.base.sha }}"
36
+ else
37
+ BASE_REF="${{ github.event.before }}"
38
+ fi
39
+
40
+ if [[ "$BASE_REF" =~ ^0+$ ]]; then
41
+ python -m decisionlock.cli scan \
42
+ --format findings-json \
43
+ --output decisionlock-findings.json \
44
+ --summary-output decisionlock-summary.md
45
+ STATUS=$?
46
+ else
47
+ python -m decisionlock.cli gate \
48
+ --changed-from "$BASE_REF" \
49
+ --fail-on-risk high \
50
+ --format findings-json \
51
+ --output decisionlock-findings.json \
52
+ --summary-output decisionlock-summary.md
53
+ STATUS=$?
54
+ fi
55
+
56
+ if [ -n "${GITHUB_STEP_SUMMARY:-}" ] && [ -f decisionlock-summary.md ]; then
57
+ cat decisionlock-summary.md >> "$GITHUB_STEP_SUMMARY"
58
+ fi
59
+
60
+ exit "$STATUS"
61
+
62
+ - name: Upload DecisionLock report
63
+ if: always()
64
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
65
+ with:
66
+ name: decisionlock-scan
67
+ path: |
68
+ decisionlock-findings.json
69
+ decisionlock-summary.md
70
+ if-no-files-found: error
@@ -0,0 +1,42 @@
1
+ name: Security
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ permissions:
7
+ contents: read
8
+
9
+ concurrency:
10
+ group: security-${{ github.workflow }}-${{ github.ref }}
11
+ cancel-in-progress: true
12
+
13
+ jobs:
14
+ audit:
15
+ runs-on: ubuntu-latest
16
+ timeout-minutes: 20
17
+ steps:
18
+ - name: Checkout
19
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
20
+ with:
21
+ persist-credentials: false
22
+ - name: Set up Python
23
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
24
+ with:
25
+ python-version: "3.13"
26
+ cache: pip
27
+ - name: Install
28
+ run: |
29
+ python -m pip install --upgrade pip
30
+ python -m pip install -c requirements/runtime-validated.txt -e '.[http]'
31
+ python -m pip install -r requirements/validation.txt
32
+ - name: Architecture boundary
33
+ run: python scripts/check_architecture.py
34
+ - name: Repository secret scan
35
+ run: python scripts/check_secrets.py
36
+ - name: Static security scan
37
+ run: python scripts/security_scan.py
38
+ - name: Dependency audit
39
+ run: |
40
+ python -m pip_audit \
41
+ --progress-spinner off \
42
+ --timeout 60