ai-safe2 0.9.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 (219) hide show
  1. ai_safe2-0.9.0/.gitignore +14 -0
  2. ai_safe2-0.9.0/LICENSE +47 -0
  3. ai_safe2-0.9.0/MIGRATION.md +143 -0
  4. ai_safe2-0.9.0/PKG-INFO +608 -0
  5. ai_safe2-0.9.0/README.md +548 -0
  6. ai_safe2-0.9.0/aisafe2_mcp_tools/__init__.py +2 -0
  7. ai_safe2-0.9.0/aisafe2_mcp_tools/scan/__init__.py +0 -0
  8. ai_safe2-0.9.0/aisafe2_mcp_tools/scan/__main__.py +111 -0
  9. ai_safe2-0.9.0/aisafe2_mcp_tools/scan/analyzer.py +134 -0
  10. ai_safe2-0.9.0/aisafe2_mcp_tools/scan/ast_analyzer.py +100 -0
  11. ai_safe2-0.9.0/aisafe2_mcp_tools/scan/dep_checker.py +261 -0
  12. ai_safe2-0.9.0/aisafe2_mcp_tools/scan/findings.py +138 -0
  13. ai_safe2-0.9.0/aisafe2_mcp_tools/scan/fixes/CTI-001.template +46 -0
  14. ai_safe2-0.9.0/aisafe2_mcp_tools/scan/fixes/INJ-001.template +19 -0
  15. ai_safe2-0.9.0/aisafe2_mcp_tools/scan/fixes/LOG-001.template +25 -0
  16. ai_safe2-0.9.0/aisafe2_mcp_tools/scan/fixes/RCE-001.template +26 -0
  17. ai_safe2-0.9.0/aisafe2_mcp_tools/scan/fixes/RCE-002.template +17 -0
  18. ai_safe2-0.9.0/aisafe2_mcp_tools/scan/fixes/RCE-003.template +30 -0
  19. ai_safe2-0.9.0/aisafe2_mcp_tools/scan/fixes/RCE-004.template +15 -0
  20. ai_safe2-0.9.0/aisafe2_mcp_tools/scan/fixes/RCE-005.template +22 -0
  21. ai_safe2-0.9.0/aisafe2_mcp_tools/scan/fixes/RCE-006.template +39 -0
  22. ai_safe2-0.9.0/aisafe2_mcp_tools/scan/fixes/SEC-001.template +24 -0
  23. ai_safe2-0.9.0/aisafe2_mcp_tools/scan/fixes/STP-001.template +65 -0
  24. ai_safe2-0.9.0/aisafe2_mcp_tools/scan/pattern_scanner.py +609 -0
  25. ai_safe2-0.9.0/aisafe2_mcp_tools/scan/reporter.py +186 -0
  26. ai_safe2-0.9.0/aisafe2_mcp_tools/score/__init__.py +0 -0
  27. ai_safe2-0.9.0/aisafe2_mcp_tools/score/__main__.py +163 -0
  28. ai_safe2-0.9.0/aisafe2_mcp_tools/score/assessor.py +666 -0
  29. ai_safe2-0.9.0/aisafe2_mcp_tools/score/auth_checker.py +96 -0
  30. ai_safe2-0.9.0/aisafe2_mcp_tools/score/badge.py +236 -0
  31. ai_safe2-0.9.0/aisafe2_mcp_tools/score/header_checker.py +68 -0
  32. ai_safe2-0.9.0/aisafe2_mcp_tools/score/models.py +77 -0
  33. ai_safe2-0.9.0/aisafe2_mcp_tools/score/reporter.py +344 -0
  34. ai_safe2-0.9.0/aisafe2_mcp_tools/score/schema_scanner.py +110 -0
  35. ai_safe2-0.9.0/aisafe2_mcp_tools/score/scorer.py +108 -0
  36. ai_safe2-0.9.0/aisafe2_mcp_tools/score/ssrf_detector.py +50 -0
  37. ai_safe2-0.9.0/aisafe2_mcp_tools/shared/__init__.py +0 -0
  38. ai_safe2-0.9.0/aisafe2_mcp_tools/shared/patterns.py +345 -0
  39. ai_safe2-0.9.0/aisafe2_mcp_tools/wrap/__init__.py +0 -0
  40. ai_safe2-0.9.0/aisafe2_mcp_tools/wrap/__main__.py +112 -0
  41. ai_safe2-0.9.0/aisafe2_mcp_tools/wrap/audit.py +175 -0
  42. ai_safe2-0.9.0/aisafe2_mcp_tools/wrap/proxy.py +193 -0
  43. ai_safe2-0.9.0/aisafe2_mcp_tools/wrap/ratelimit.py +91 -0
  44. ai_safe2-0.9.0/aisafe2_mcp_tools/wrap/scanner.py +90 -0
  45. ai_safe2-0.9.0/aisafe2_mcp_tools/wrap/wrapper.py +151 -0
  46. ai_safe2-0.9.0/examples/aism-decision-card/README.md +52 -0
  47. ai_safe2-0.9.0/examples/aism-decision-card/assessment.json +91 -0
  48. ai_safe2-0.9.0/examples/aism-decision-card/safe2-example.json +17 -0
  49. ai_safe2-0.9.0/examples/aism-decision-card/smoke_test.py +37 -0
  50. ai_safe2-0.9.0/examples/aism-remediation/README.md +46 -0
  51. ai_safe2-0.9.0/examples/aism-remediation/safe2-example.json +12 -0
  52. ai_safe2-0.9.0/examples/aism-remediation/smoke_test.py +154 -0
  53. ai_safe2-0.9.0/examples/challenge-controlled-executor/README.md +51 -0
  54. ai_safe2-0.9.0/examples/challenge-controlled-executor/executor.py +32 -0
  55. ai_safe2-0.9.0/examples/challenge-controlled-executor/safe2-example.json +14 -0
  56. ai_safe2-0.9.0/examples/challenge-controlled-executor/smoke_test.py +34 -0
  57. ai_safe2-0.9.0/examples/environment-decision-card/README.md +52 -0
  58. ai_safe2-0.9.0/examples/environment-decision-card/safe2-example.json +10 -0
  59. ai_safe2-0.9.0/examples/environment-decision-card/smoke_test.py +126 -0
  60. ai_safe2-0.9.0/gateway/README.md +179 -0
  61. ai_safe2-0.9.0/gateway/main.py +1288 -0
  62. ai_safe2-0.9.0/gateway/provider_adapters.py +622 -0
  63. ai_safe2-0.9.0/gateway/test_gateway.py +481 -0
  64. ai_safe2-0.9.0/pyproject.toml +119 -0
  65. ai_safe2-0.9.0/safe2/README.md +465 -0
  66. ai_safe2-0.9.0/safe2/__init__.py +8 -0
  67. ai_safe2-0.9.0/safe2/__main__.py +6 -0
  68. ai_safe2-0.9.0/safe2/aism/__init__.py +5 -0
  69. ai_safe2-0.9.0/safe2/aism/card.py +246 -0
  70. ai_safe2-0.9.0/safe2/aism/ingest.py +86 -0
  71. ai_safe2-0.9.0/safe2/aism/model.py +20 -0
  72. ai_safe2-0.9.0/safe2/aism/remediation.py +422 -0
  73. ai_safe2-0.9.0/safe2/aism/scoring.py +283 -0
  74. ai_safe2-0.9.0/safe2/bounded_files.py +32 -0
  75. ai_safe2-0.9.0/safe2/bounded_process.py +76 -0
  76. ai_safe2-0.9.0/safe2/challenge/README.md +34 -0
  77. ai_safe2-0.9.0/safe2/challenge/__init__.py +4 -0
  78. ai_safe2-0.9.0/safe2/challenge/adapters.py +148 -0
  79. ai_safe2-0.9.0/safe2/challenge/bundle.py +192 -0
  80. ai_safe2-0.9.0/safe2/challenge/compare.py +136 -0
  81. ai_safe2-0.9.0/safe2/challenge/execution.py +333 -0
  82. ai_safe2-0.9.0/safe2/challenge/grading.py +158 -0
  83. ai_safe2-0.9.0/safe2/challenge/integrity.py +115 -0
  84. ai_safe2-0.9.0/safe2/challenge/io.py +141 -0
  85. ai_safe2-0.9.0/safe2/challenge/model.py +198 -0
  86. ai_safe2-0.9.0/safe2/challenge/protocol.py +64 -0
  87. ai_safe2-0.9.0/safe2/challenge/report.py +184 -0
  88. ai_safe2-0.9.0/safe2/challenge/runner.py +94 -0
  89. ai_safe2-0.9.0/safe2/cli.py +111 -0
  90. ai_safe2-0.9.0/safe2/commands/__init__.py +0 -0
  91. ai_safe2-0.9.0/safe2/commands/aism.py +275 -0
  92. ai_safe2-0.9.0/safe2/commands/challenge.py +375 -0
  93. ai_safe2-0.9.0/safe2/commands/doctor.py +223 -0
  94. ai_safe2-0.9.0/safe2/commands/evidence.py +362 -0
  95. ai_safe2-0.9.0/safe2/commands/example.py +132 -0
  96. ai_safe2-0.9.0/safe2/commands/feedback.py +307 -0
  97. ai_safe2-0.9.0/safe2/commands/gate.py +141 -0
  98. ai_safe2-0.9.0/safe2/commands/mcp.py +103 -0
  99. ai_safe2-0.9.0/safe2/commands/report.py +133 -0
  100. ai_safe2-0.9.0/safe2/commands/scan.py +86 -0
  101. ai_safe2-0.9.0/safe2/commands/schema.py +76 -0
  102. ai_safe2-0.9.0/safe2/commands/score.py +93 -0
  103. ai_safe2-0.9.0/safe2/contracts.py +102 -0
  104. ai_safe2-0.9.0/safe2/data/__init__.py +1 -0
  105. ai_safe2-0.9.0/safe2/data/ai-safe2-controls-v3.0.json +3892 -0
  106. ai_safe2-0.9.0/safe2/data/aism-assessment-v1.schema.json +141 -0
  107. ai_safe2-0.9.0/safe2/data/aism-model-v1.json +65 -0
  108. ai_safe2-0.9.0/safe2/data/aism-remediation-plan-v1.schema.json +119 -0
  109. ai_safe2-0.9.0/safe2/data/aism-remediation-source-v1.schema.json +74 -0
  110. ai_safe2-0.9.0/safe2/data/assessment-scope-manifest-v1.schema.json +63 -0
  111. ai_safe2-0.9.0/safe2/data/assessment-scope-source-demo.json +73 -0
  112. ai_safe2-0.9.0/safe2/data/assessment-scope-source-v1.schema.json +66 -0
  113. ai_safe2-0.9.0/safe2/data/challenge-bundle-v1.schema.json +106 -0
  114. ai_safe2-0.9.0/safe2/data/challenge-comparison-v1.schema.json +324 -0
  115. ai_safe2-0.9.0/safe2/data/challenge-execution-plan-v1.schema.json +59 -0
  116. ai_safe2-0.9.0/safe2/data/challenge-execution-receipt-v1.schema.json +57 -0
  117. ai_safe2-0.9.0/safe2/data/challenge-run-v1.schema.json +968 -0
  118. ai_safe2-0.9.0/safe2/data/challenge-source-v1.schema.json +352 -0
  119. ai_safe2-0.9.0/safe2/data/challenge_001_protocol.json +68 -0
  120. ai_safe2-0.9.0/safe2/data/change-attribution-manifest-v1.schema.json +13 -0
  121. ai_safe2-0.9.0/safe2/data/change-attribution-source-v1.schema.json +21 -0
  122. ai_safe2-0.9.0/safe2/data/change-monitor-v1.schema.json +21 -0
  123. ai_safe2-0.9.0/safe2/data/cli-0.6-assessment-scope-source.json +9 -0
  124. ai_safe2-0.9.0/safe2/data/cli-0.6-system-identity-source.json +32 -0
  125. ai_safe2-0.9.0/safe2/data/discovery-drift-v1.schema.json +25 -0
  126. ai_safe2-0.9.0/safe2/data/discovery-v1.schema.json +51 -0
  127. ai_safe2-0.9.0/safe2/data/environment-policy-decision-v1.schema.json +26 -0
  128. ai_safe2-0.9.0/safe2/data/environment-policy-v1.schema.json +29 -0
  129. ai_safe2-0.9.0/safe2/data/environment-posture-v1.schema.json +16 -0
  130. ai_safe2-0.9.0/safe2/data/failure-diagnosis-v1.schema.json +97 -0
  131. ai_safe2-0.9.0/safe2/data/failure-source-demo.json +46 -0
  132. ai_safe2-0.9.0/safe2/data/failure-source-v1.schema.json +78 -0
  133. ai_safe2-0.9.0/safe2/data/friction-event-v1.schema.json +34 -0
  134. ai_safe2-0.9.0/safe2/data/friction-summary-v1.schema.json +35 -0
  135. ai_safe2-0.9.0/safe2/data/harness-evidence-v1.schema.json +31 -0
  136. ai_safe2-0.9.0/safe2/data/harness-source-demo.json +24 -0
  137. ai_safe2-0.9.0/safe2/data/harness-source-v1.schema.json +98 -0
  138. ai_safe2-0.9.0/safe2/data/nexus-evidence-v1.schema.json +18 -0
  139. ai_safe2-0.9.0/safe2/data/operational-truth-manifest-v1.schema.json +23 -0
  140. ai_safe2-0.9.0/safe2/data/operational-truth-source-demo.json +18 -0
  141. ai_safe2-0.9.0/safe2/data/operational-truth-source-v1.schema.json +17 -0
  142. ai_safe2-0.9.0/safe2/data/pytest-capture-v1.schema.json +26 -0
  143. ai_safe2-0.9.0/safe2/data/release-readiness-manifest-v1.schema.json +11 -0
  144. ai_safe2-0.9.0/safe2/data/release-readiness-source-demo.json +18 -0
  145. ai_safe2-0.9.0/safe2/data/release-readiness-source-v1.schema.json +17 -0
  146. ai_safe2-0.9.0/safe2/data/report-attestation-v1.schema.json +18 -0
  147. ai_safe2-0.9.0/safe2/data/run-manifest-v1.schema.json +52 -0
  148. ai_safe2-0.9.0/safe2/data/skillspector-evidence-v1.schema.json +20 -0
  149. ai_safe2-0.9.0/safe2/data/system-identity-manifest-v1.schema.json +67 -0
  150. ai_safe2-0.9.0/safe2/data/system-identity-source-demo.json +43 -0
  151. ai_safe2-0.9.0/safe2/data/system-identity-source-v1.schema.json +103 -0
  152. ai_safe2-0.9.0/safe2/data/task-receipt-demo.json +19 -0
  153. ai_safe2-0.9.0/safe2/data/task-receipt-demo.txt +1 -0
  154. ai_safe2-0.9.0/safe2/data/task-receipt-input-v1.schema.json +59 -0
  155. ai_safe2-0.9.0/safe2/data/task-receipt-v1.schema.json +65 -0
  156. ai_safe2-0.9.0/safe2/data/task-test-receipt-demo.json +15 -0
  157. ai_safe2-0.9.0/safe2/data/task-tool-receipt-demo.json +18 -0
  158. ai_safe2-0.9.0/safe2/data/test-result-demo.json +9 -0
  159. ai_safe2-0.9.0/safe2/data/test-result-v1.schema.json +36 -0
  160. ai_safe2-0.9.0/safe2/data/tool-result-demo.json +10 -0
  161. ai_safe2-0.9.0/safe2/data/tool-result-v1.schema.json +32 -0
  162. ai_safe2-0.9.0/safe2/data/usage-summary-v1.schema.json +35 -0
  163. ai_safe2-0.9.0/safe2/discovery/__init__.py +29 -0
  164. ai_safe2-0.9.0/safe2/discovery/assets.py +162 -0
  165. ai_safe2-0.9.0/safe2/discovery/card.py +284 -0
  166. ai_safe2-0.9.0/safe2/discovery/config.py +206 -0
  167. ai_safe2-0.9.0/safe2/discovery/drift.py +238 -0
  168. ai_safe2-0.9.0/safe2/discovery/integrity.py +47 -0
  169. ai_safe2-0.9.0/safe2/discovery/local.py +147 -0
  170. ai_safe2-0.9.0/safe2/discovery/policy.py +153 -0
  171. ai_safe2-0.9.0/safe2/discovery/posix.py +144 -0
  172. ai_safe2-0.9.0/safe2/discovery/posture.py +294 -0
  173. ai_safe2-0.9.0/safe2/engines/__init__.py +0 -0
  174. ai_safe2-0.9.0/safe2/engines/project.py +49 -0
  175. ai_safe2-0.9.0/safe2/engines/skill_gate.py +165 -0
  176. ai_safe2-0.9.0/safe2/evidence/__init__.py +1 -0
  177. ai_safe2-0.9.0/safe2/evidence/attribution.py +80 -0
  178. ai_safe2-0.9.0/safe2/evidence/change_monitor.py +126 -0
  179. ai_safe2-0.9.0/safe2/evidence/diagnosis.py +186 -0
  180. ai_safe2-0.9.0/safe2/evidence/diagnosis_card.py +64 -0
  181. ai_safe2-0.9.0/safe2/evidence/friction.py +215 -0
  182. ai_safe2-0.9.0/safe2/evidence/harness.py +100 -0
  183. ai_safe2-0.9.0/safe2/evidence/junit.py +97 -0
  184. ai_safe2-0.9.0/safe2/evidence/manifest.py +171 -0
  185. ai_safe2-0.9.0/safe2/evidence/nexus.py +179 -0
  186. ai_safe2-0.9.0/safe2/evidence/operational_truth.py +130 -0
  187. ai_safe2-0.9.0/safe2/evidence/operational_truth_card.py +16 -0
  188. ai_safe2-0.9.0/safe2/evidence/process_capture.py +85 -0
  189. ai_safe2-0.9.0/safe2/evidence/pytest_capture.py +112 -0
  190. ai_safe2-0.9.0/safe2/evidence/readiness.py +74 -0
  191. ai_safe2-0.9.0/safe2/evidence/readiness_card.py +25 -0
  192. ai_safe2-0.9.0/safe2/evidence/report_auth.py +86 -0
  193. ai_safe2-0.9.0/safe2/evidence/scope.py +237 -0
  194. ai_safe2-0.9.0/safe2/evidence/skillspector.py +107 -0
  195. ai_safe2-0.9.0/safe2/evidence/system_identity.py +172 -0
  196. ai_safe2-0.9.0/safe2/evidence/task_receipt.py +201 -0
  197. ai_safe2-0.9.0/safe2/evidence/test_result.py +41 -0
  198. ai_safe2-0.9.0/safe2/evidence/tool_result.py +52 -0
  199. ai_safe2-0.9.0/safe2/evidence/usage.py +69 -0
  200. ai_safe2-0.9.0/safe2/reporting/__init__.py +0 -0
  201. ai_safe2-0.9.0/safe2/reporting/formats.py +175 -0
  202. ai_safe2-0.9.0/scanner/README.md +199 -0
  203. ai_safe2-0.9.0/scanner/__init__.py +1 -0
  204. ai_safe2-0.9.0/scanner/cli.py +262 -0
  205. ai_safe2-0.9.0/scanner/config/default_rules.yaml +137 -0
  206. ai_safe2-0.9.0/scanner/report.py +330 -0
  207. ai_safe2-0.9.0/scanner/requirements.txt +4 -0
  208. ai_safe2-0.9.0/scanner/rules/__init__.py +11 -0
  209. ai_safe2-0.9.0/scanner/rules/base.py +112 -0
  210. ai_safe2-0.9.0/scanner/rules/cross_pillar.py +363 -0
  211. ai_safe2-0.9.0/scanner/rules/mcp_profile.py +456 -0
  212. ai_safe2-0.9.0/scanner/rules/p1_sanitize.py +419 -0
  213. ai_safe2-0.9.0/scanner/rules/p2_audit.py +231 -0
  214. ai_safe2-0.9.0/scanner/rules/p3_failsafe.py +207 -0
  215. ai_safe2-0.9.0/scanner/rules/p4_monitor.py +266 -0
  216. ai_safe2-0.9.0/scanner/rules/p5_evolve.py +220 -0
  217. ai_safe2-0.9.0/scanner/scanner.py +692 -0
  218. ai_safe2-0.9.0/scanner/tests/test_hardening.py +47 -0
  219. ai_safe2-0.9.0/scanner/tests/test_v31_mcp_profile.py +39 -0
@@ -0,0 +1,14 @@
1
+ .safe2/
2
+ __pycache__/
3
+ .test-temp*/
4
+ .uv-cache/
5
+ .venv/
6
+ .venv-challenge/
7
+ .uv-challenge-cache/
8
+ .release-venv/
9
+ .pytest_cache/
10
+ .mypy_cache/
11
+ .ruff_cache/
12
+ dist-final/
13
+ dist-qa*/
14
+ dist-stranger-ready/
ai_safe2-0.9.0/LICENSE ADDED
@@ -0,0 +1,47 @@
1
+ DUAL LICENSE AGREEMENT
2
+ ======================
3
+
4
+ This repository is comprised of two distinct components: The Source Code and The Framework/Documentation. They are licensed as follows:
5
+
6
+ 1. THE SOFTWARE (CODE)
7
+ ----------------------
8
+ Applies to: All files ending in .py, .json, .html, .js, .css, and script files.
9
+
10
+ Licensed under the MIT License.
11
+
12
+ Copyright (c) 2025-2026 Cyber Strategy Institute
13
+
14
+ Permission is hereby granted, free of charge, to any person obtaining a copy
15
+ of this software and associated documentation files (the "Software"), to deal
16
+ in the Software without restriction, including without limitation the rights
17
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
+ copies of the Software, and to permit persons to whom the Software is
19
+ furnished to do so, subject to the following conditions:
20
+
21
+ The above copyright notice and this permission notice shall be included in all
22
+ copies or substantial portions of the Software.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
+ SOFTWARE.
31
+
32
+
33
+ 2. THE FRAMEWORK (DOCUMENTATION & TAXONOMY)
34
+ -------------------------------------------
35
+ Applies to: The AI SAFE² methodology, pillar definitions, README files, PDFs, and Markdown documentation (.md).
36
+
37
+ Licensed under the Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0).
38
+
39
+ You are free to:
40
+ * Share — copy and redistribute the material in any medium or format.
41
+ * Adapt — remix, transform, and build upon the material for any purpose, even commercially.
42
+
43
+ Under the following terms:
44
+ * Attribution — You must give appropriate credit to "Cyber Strategy Institute", provide a link to the license, and indicate if changes were made.
45
+ * ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
46
+
47
+ Full Legal Code: https://creativecommons.org/licenses/by-sa/4.0/legalcode
@@ -0,0 +1,143 @@
1
+ # safe2 CLI consolidation
2
+
3
+ PART 3 diagnosis: *"Two failed release rounds. Parallel half-builds compete
4
+ with each other."* This is that consolidation. Before this change, four
5
+ CLI-shaped security tools existed in this repo, none installable from the
6
+ repo root, none aware of each other:
7
+
8
+ | Old location | What it did | New home |
9
+ |---|---|---|
10
+ | `scanner/` (no console entry point at all) | 161-control static project audit | `safe2 scan project` / `safe2 gate project` / `safe2 score project` |
11
+ | `scripts/skill_trust_gate.py` (loose script, no package) | Skill package trust gate | `safe2 scan skill` / `safe2 gate skill` |
12
+ | `examples/mcp-security-toolkit/` (filed as an *example*; `mcp-score`, `mcp-scan`, `mcp-safe-wrap`, 134 tests) | MCP server static/remote scanning + runtime wrapping | `safe2 scan mcp` / `safe2 score mcp` / `safe2 gate mcp` / `safe2 mcp wrap-stdio` / `safe2 mcp wrap-proxy` |
13
+ | `gateway/` (separate `ai-safe2-gateway` package) | Runtime enforcement proxy | `safe2 serve` (thin launcher; still its own package, now reachable through one entry point) |
14
+
15
+ One package now, `ai-safe2`, one console script, `safe2`, with operational
16
+ groups for scanning, gating, scoring, reporting, MCP protection, attributed
17
+ evidence collection, AISM decision support, and executable examples.
18
+
19
+ ## Agent-facing AISM and evidence additions
20
+
21
+ - `safe2 aism init|ingest|score|compare` implements the documented 5-pillar by
22
+ 6-dimension AISM calculation and preserves the Low/Medium/High cell rubric.
23
+ - JSON is the canonical agent contract. Markdown and self-contained HTML
24
+ Decision Cards are human views generated from the same result.
25
+ - Facts, assumptions, conflicts, unknowns, impacts, alternatives, history, and
26
+ recommendations remain separate fields.
27
+ - Probability inputs require an outcome, time horizon, method, confidence, and
28
+ range. The engine emits `NOT ESTIMABLE` rather than inventing a probability.
29
+ - `safe2 evidence nexus` collects attributed static or read-only runtime NEXUS
30
+ evidence without claiming conformance.
31
+ - `safe2 evidence skillspector` consumes NVIDIA SkillSpector's JSON contract as
32
+ an optional independent provider without implying NVIDIA endorsement.
33
+ - `safe2 example list|verify` inventories the repository's executable example
34
+ surfaces and validates versioned example manifests.
35
+
36
+ AI SAFE² remains 161 controls and CP.1 through CP.10. UAS is identified as the
37
+ `UAS-1.0` regulatory profile extension with 27 profile requirements; it does not
38
+ increase the core control count or create CP.11 as a core Cross-Pillar control.
39
+
40
+ ## Ship criterion (met)
41
+
42
+ ```
43
+ git clone <repo>
44
+ cd ai-safe2-framework
45
+ python -m venv .venv && source .venv/bin/activate
46
+ pip install -e ".[all,dev]"
47
+ pytest tests/ scanner/tests/
48
+ ```
49
+
50
+ The consolidated suite includes the original 214 tests plus AISM, UAS profile,
51
+ NEXUS evidence, SkillSpector adapter, and executable-example tests. Run it rather
52
+ than relying on a fixed historical count:
53
+
54
+ ```
55
+ pytest tests/ scanner/tests/
56
+ ```
57
+
58
+ The suite includes `tests/test_cli_smoke.py` and
59
+ `tests/test_skill_gate_engine.py`, the original `scanner/tests/`, and the
60
+ original MCP toolkit suite (`tests/mcp_toolkit/`, moved unchanged from
61
+ `examples/mcp-security-toolkit/tests/` except for five path-resolution
62
+ fixes — see below).
63
+
64
+ ## What actually changed in the code, vs. what's just new glue
65
+
66
+ - `scanner/` and `aisafe2_mcp_tools/` (moved from `examples/mcp-security-toolkit/src/`)
67
+ are **unmodified business logic**, imported as-is. `safe2` does not
68
+ reimplement any detection rule, scoring check, or injection pattern —
69
+ it only adds CLI wiring, a shared exit-code contract, and a markdown
70
+ renderer (the one format none of the four originals produced).
71
+ - `scripts/skill_trust_gate.py`'s two functions (`scan`, `decision_for`)
72
+ were initially copied into `safe2/engines/skill_gate.py`. CLI 0.2.0 hardens
73
+ coverage and adds TG-007 through TG-012. The standalone script now exits
74
+ 3 without scanning or writing reports; update automation to
75
+ `safe2 gate skill PATH --strict`. This intentionally breaks the vulnerable
76
+ legacy path rather than maintaining a second rule set. See
77
+ [CSI-2026-001](docs/advisories/2026-09-09-skill-gate-executable-scope.md).
78
+ - Five tests in the migrated `tests/mcp_toolkit/` suite hardcoded a path
79
+ relative to the old `examples/mcp-security-toolkit/tests/` location to
80
+ find the `scan/fixes/*.template` directory. Fixed to resolve the fixes
81
+ directory from the installed `aisafe2_mcp_tools.scan` package location
82
+ instead of a relative-to-test-file guess — this is a real fix, not a
83
+ skip; all five now pass in the new layout.
84
+
85
+ ## Exit-code contract (new — see `safe2/commands/gate.py`)
86
+
87
+ The three old tools each had their own gate semantics: `skill_trust_gate.py`
88
+ returned bare 0/2, `mcp-scan --ci` and `mcp-score --ci-fail-below` both used
89
+ bare 0/1, and `scanner/cli.py`'s tier logic was a fourth variant. `safe2
90
+ gate *` now uses one contract everywhere: 0 pass, 1 fail/reject, 2 hold for
91
+ review (skill gate only), 3 input error. Update any CI pipeline that was
92
+ shell-scripted against the old bare 0/1 assumptions.
93
+
94
+ ## Backward compatibility
95
+
96
+ `pip install ai-safe2` still installs `mcp-score`, `mcp-scan`, and
97
+ `mcp-safe-wrap` as console scripts (pointed at the same underlying code),
98
+ so the old README's `pip install aisafe2-mcp-tools` instructions don't
99
+ break anyone already using them. They're marked deprecated in favor of
100
+ `safe2 scan mcp` / `safe2 score mcp` / `safe2 mcp wrap-*`.
101
+
102
+ ## Deliberately out of scope this pass
103
+
104
+ - **`skills/mcp/` (the AI SAFE2 MCP *knowledge* server — `ai-safe2-mcp`,
105
+ exposing the 161 controls as MCP resources/tools).** This is a different
106
+ product from the MCP *Security Toolkit* absorbed above, despite the
107
+ similar name, and folding it into `safe2 mcp serve` without a full
108
+ read-through of its 388-line `app.py` would mean claiming an integration
109
+ that wasn't actually verified. `safe2 mcp serve` is a stub that says so
110
+ and points at the existing `ai-safe2-mcp` console script. Natural next PR.
111
+ - **`gateway/`'s internals.** `safe2 serve` launches it via `uvicorn
112
+ gateway.main:app` (real, not faked) behind the optional `gateway` extra,
113
+ but its 1288-line `main.py` and `provider_adapters.py` were not
114
+ refactored into the safe2 package — it stays a separate, larger service
115
+ reached through one entry point rather than merged code.
116
+
117
+ ## To finish the migration in the real repo
118
+
119
+ This was built and tested in a local clone; nothing has been pushed. Once
120
+ reviewed:
121
+
122
+ ```
123
+ git add safe2/ aisafe2_mcp_tools/ pyproject.toml MIGRATION.md \
124
+ scripts/skill_trust_gate.py examples/mcp-security-toolkit/README.md \
125
+ tests/
126
+ git commit -m "Consolidate scanner, skill trust gate, and MCP toolkit into one safe2 CLI"
127
+ ```
128
+
129
+ Leave `examples/mcp-security-toolkit/src` and `scripts/skill_trust_gate.py`
130
+ in place until you're satisfied the new paths are solid in production, then
131
+ `git rm -r examples/mcp-security-toolkit/src` (keep its README's redirect
132
+ notice, or remove the whole directory) and the deprecated script.
133
+
134
+ ## Known pre-existing scanner limitation (not introduced by this change)
135
+
136
+ Running `safe2 scan project` against `safe2/` itself surfaces false
137
+ positives from the 161-control heuristics — e.g. it flags
138
+ `subprocess.call(["uvicorn", ...])` in `safe2/cli.py` as "LLM API call
139
+ without logging context." The pattern-matching is keying on generic
140
+ subprocess/call shapes, not actual LLM API usage. This is an existing
141
+ characteristic of `scanner/rules/`'s heuristics, unchanged by this
142
+ consolidation — worth a follow-up pass on the P4/P5 rule precision, flagged
143
+ here rather than silently left for someone to rediscover.