@trac3er/oh-my-god 2.1.0 → 2.1.4

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 (371) hide show
  1. package/.agents/skills/omg/AGENTS.fragment.md +2 -2
  2. package/.agents/skills/omg/algorithms/SKILL.md +1 -1
  3. package/.agents/skills/omg/algorithms/openai.yaml +1 -1
  4. package/.agents/skills/omg/api-twin/SKILL.md +1 -1
  5. package/.agents/skills/omg/api-twin/openai.yaml +1 -1
  6. package/.agents/skills/omg/claim-judge/SKILL.md +1 -1
  7. package/.agents/skills/omg/claim-judge/openai.yaml +1 -1
  8. package/.agents/skills/omg/codex-rules.md +1 -1
  9. package/.agents/skills/omg/control-plane/SKILL.md +1 -1
  10. package/.agents/skills/omg/control-plane/openai.yaml +1 -1
  11. package/.agents/skills/omg/data-lineage/SKILL.md +1 -1
  12. package/.agents/skills/omg/data-lineage/openai.yaml +1 -1
  13. package/.agents/skills/omg/delta-classifier/SKILL.md +1 -1
  14. package/.agents/skills/omg/delta-classifier/openai.yaml +1 -1
  15. package/.agents/skills/omg/eval-gate/SKILL.md +1 -1
  16. package/.agents/skills/omg/eval-gate/openai.yaml +1 -1
  17. package/.agents/skills/omg/health/SKILL.md +1 -1
  18. package/.agents/skills/omg/health/openai.yaml +1 -1
  19. package/.agents/skills/omg/hook-governor/SKILL.md +1 -1
  20. package/.agents/skills/omg/hook-governor/openai.yaml +1 -1
  21. package/.agents/skills/omg/incident-replay/SKILL.md +1 -1
  22. package/.agents/skills/omg/incident-replay/openai.yaml +1 -1
  23. package/.agents/skills/omg/lsp-pack/SKILL.md +1 -1
  24. package/.agents/skills/omg/lsp-pack/openai.yaml +1 -1
  25. package/.agents/skills/omg/mcp-fabric/SKILL.md +1 -1
  26. package/.agents/skills/omg/mcp-fabric/openai.yaml +1 -1
  27. package/.agents/skills/omg/plan-council/SKILL.md +1 -1
  28. package/.agents/skills/omg/plan-council/openai.yaml +1 -1
  29. package/.agents/skills/omg/preflight/SKILL.md +1 -1
  30. package/.agents/skills/omg/preflight/openai.yaml +1 -1
  31. package/.agents/skills/omg/proof-gate/SKILL.md +1 -1
  32. package/.agents/skills/omg/proof-gate/openai.yaml +1 -1
  33. package/.agents/skills/omg/remote-supervisor/SKILL.md +1 -1
  34. package/.agents/skills/omg/remote-supervisor/openai.yaml +1 -1
  35. package/.agents/skills/omg/robotics/SKILL.md +1 -1
  36. package/.agents/skills/omg/robotics/openai.yaml +1 -1
  37. package/.agents/skills/omg/secure-worktree-pipeline/SKILL.md +1 -1
  38. package/.agents/skills/omg/secure-worktree-pipeline/openai.yaml +1 -1
  39. package/.agents/skills/omg/security-check/SKILL.md +1 -1
  40. package/.agents/skills/omg/security-check/openai.yaml +1 -1
  41. package/.agents/skills/omg/test-intent-lock/SKILL.md +1 -1
  42. package/.agents/skills/omg/test-intent-lock/openai.yaml +1 -1
  43. package/.agents/skills/omg/tracebank/SKILL.md +1 -1
  44. package/.agents/skills/omg/tracebank/openai.yaml +1 -1
  45. package/.agents/skills/omg/vision/SKILL.md +1 -1
  46. package/.agents/skills/omg/vision/openai.yaml +1 -1
  47. package/.claude-plugin/marketplace.json +3 -3
  48. package/.claude-plugin/plugin.json +1 -1
  49. package/CHANGELOG.md +16 -0
  50. package/CLI-ADAPTER-MAP.md +3 -3
  51. package/OMG-setup.sh +114 -1
  52. package/OMG_COMPAT_CONTRACT.md +1 -1
  53. package/README.md +2 -1
  54. package/artifacts/release/.claude-plugin/marketplace.json +3 -3
  55. package/artifacts/release/.claude-plugin/plugin.json +1 -1
  56. package/artifacts/release/OMG_COMPAT_CONTRACT.md +1 -1
  57. package/artifacts/release/dist/enterprise/bundle/.claude-plugin/marketplace.json +3 -3
  58. package/artifacts/release/dist/enterprise/bundle/.claude-plugin/plugin.json +1 -1
  59. package/artifacts/release/dist/enterprise/bundle/OMG_COMPAT_CONTRACT.md +1 -1
  60. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/plugin.json +26 -9
  61. package/artifacts/release/dist/enterprise/bundle/registry/bundles/algorithms.yaml +1 -1
  62. package/artifacts/release/dist/enterprise/bundle/registry/bundles/api-twin.yaml +1 -1
  63. package/artifacts/release/dist/enterprise/bundle/registry/bundles/claim-judge.yaml +1 -1
  64. package/artifacts/release/dist/enterprise/bundle/registry/bundles/control-plane.yaml +1 -1
  65. package/artifacts/release/dist/enterprise/bundle/registry/bundles/data-lineage.yaml +1 -1
  66. package/artifacts/release/dist/enterprise/bundle/registry/bundles/delta-classifier.yaml +1 -1
  67. package/artifacts/release/dist/enterprise/bundle/registry/bundles/eval-gate.yaml +1 -1
  68. package/artifacts/release/dist/enterprise/bundle/registry/bundles/health.yaml +1 -1
  69. package/artifacts/release/dist/enterprise/bundle/registry/bundles/hook-governor.yaml +1 -1
  70. package/artifacts/release/dist/enterprise/bundle/registry/bundles/incident-replay.yaml +1 -1
  71. package/artifacts/release/dist/enterprise/bundle/registry/bundles/lsp-pack.yaml +1 -1
  72. package/artifacts/release/dist/enterprise/bundle/registry/bundles/mcp-fabric.yaml +1 -1
  73. package/artifacts/release/dist/enterprise/bundle/registry/bundles/plan-council.yaml +1 -1
  74. package/artifacts/release/dist/enterprise/bundle/registry/bundles/preflight.yaml +1 -1
  75. package/artifacts/release/dist/enterprise/bundle/registry/bundles/proof-gate.yaml +1 -1
  76. package/artifacts/release/dist/enterprise/bundle/registry/bundles/remote-supervisor.yaml +1 -1
  77. package/artifacts/release/dist/enterprise/bundle/registry/bundles/robotics.yaml +1 -1
  78. package/artifacts/release/dist/enterprise/bundle/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  79. package/artifacts/release/dist/enterprise/bundle/registry/bundles/security-check.yaml +1 -1
  80. package/artifacts/release/dist/enterprise/bundle/registry/bundles/test-intent-lock.yaml +1 -1
  81. package/artifacts/release/dist/enterprise/bundle/registry/bundles/tracebank.yaml +1 -1
  82. package/artifacts/release/dist/enterprise/bundle/registry/bundles/vision.yaml +1 -1
  83. package/artifacts/release/dist/enterprise/bundle/registry/omg-capability.schema.json +1 -1
  84. package/artifacts/release/dist/enterprise/bundle/settings.json +3 -3
  85. package/artifacts/release/dist/enterprise/manifest.json +30 -40
  86. package/artifacts/release/dist/public/bundle/.claude-plugin/marketplace.json +3 -3
  87. package/artifacts/release/dist/public/bundle/.claude-plugin/plugin.json +1 -1
  88. package/artifacts/release/dist/public/bundle/OMG_COMPAT_CONTRACT.md +1 -1
  89. package/artifacts/release/dist/public/bundle/plugins/advanced/plugin.json +26 -9
  90. package/artifacts/release/dist/public/bundle/registry/bundles/algorithms.yaml +1 -1
  91. package/artifacts/release/dist/public/bundle/registry/bundles/api-twin.yaml +1 -1
  92. package/artifacts/release/dist/public/bundle/registry/bundles/claim-judge.yaml +1 -1
  93. package/artifacts/release/dist/public/bundle/registry/bundles/control-plane.yaml +1 -1
  94. package/artifacts/release/dist/public/bundle/registry/bundles/data-lineage.yaml +1 -1
  95. package/artifacts/release/dist/public/bundle/registry/bundles/delta-classifier.yaml +1 -1
  96. package/artifacts/release/dist/public/bundle/registry/bundles/eval-gate.yaml +1 -1
  97. package/artifacts/release/dist/public/bundle/registry/bundles/health.yaml +1 -1
  98. package/artifacts/release/dist/public/bundle/registry/bundles/hook-governor.yaml +1 -1
  99. package/artifacts/release/dist/public/bundle/registry/bundles/incident-replay.yaml +1 -1
  100. package/artifacts/release/dist/public/bundle/registry/bundles/lsp-pack.yaml +1 -1
  101. package/artifacts/release/dist/public/bundle/registry/bundles/mcp-fabric.yaml +1 -1
  102. package/artifacts/release/dist/public/bundle/registry/bundles/plan-council.yaml +1 -1
  103. package/artifacts/release/dist/public/bundle/registry/bundles/preflight.yaml +1 -1
  104. package/artifacts/release/dist/public/bundle/registry/bundles/proof-gate.yaml +1 -1
  105. package/artifacts/release/dist/public/bundle/registry/bundles/remote-supervisor.yaml +1 -1
  106. package/artifacts/release/dist/public/bundle/registry/bundles/robotics.yaml +1 -1
  107. package/artifacts/release/dist/public/bundle/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  108. package/artifacts/release/dist/public/bundle/registry/bundles/security-check.yaml +1 -1
  109. package/artifacts/release/dist/public/bundle/registry/bundles/test-intent-lock.yaml +1 -1
  110. package/artifacts/release/dist/public/bundle/registry/bundles/tracebank.yaml +1 -1
  111. package/artifacts/release/dist/public/bundle/registry/bundles/vision.yaml +1 -1
  112. package/artifacts/release/dist/public/bundle/registry/omg-capability.schema.json +1 -1
  113. package/artifacts/release/dist/public/bundle/settings.json +3 -3
  114. package/artifacts/release/dist/public/manifest.json +30 -40
  115. package/artifacts/release/plugins/advanced/plugin.json +26 -9
  116. package/artifacts/release/registry/bundles/algorithms.yaml +1 -1
  117. package/artifacts/release/registry/bundles/api-twin.yaml +1 -1
  118. package/artifacts/release/registry/bundles/claim-judge.yaml +1 -1
  119. package/artifacts/release/registry/bundles/control-plane.yaml +1 -1
  120. package/artifacts/release/registry/bundles/data-lineage.yaml +1 -1
  121. package/artifacts/release/registry/bundles/delta-classifier.yaml +1 -1
  122. package/artifacts/release/registry/bundles/eval-gate.yaml +1 -1
  123. package/artifacts/release/registry/bundles/health.yaml +1 -1
  124. package/artifacts/release/registry/bundles/hook-governor.yaml +1 -1
  125. package/artifacts/release/registry/bundles/incident-replay.yaml +1 -1
  126. package/artifacts/release/registry/bundles/lsp-pack.yaml +1 -1
  127. package/artifacts/release/registry/bundles/mcp-fabric.yaml +1 -1
  128. package/artifacts/release/registry/bundles/plan-council.yaml +1 -1
  129. package/artifacts/release/registry/bundles/preflight.yaml +1 -1
  130. package/artifacts/release/registry/bundles/proof-gate.yaml +1 -1
  131. package/artifacts/release/registry/bundles/remote-supervisor.yaml +1 -1
  132. package/artifacts/release/registry/bundles/robotics.yaml +1 -1
  133. package/artifacts/release/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  134. package/artifacts/release/registry/bundles/security-check.yaml +1 -1
  135. package/artifacts/release/registry/bundles/test-intent-lock.yaml +1 -1
  136. package/artifacts/release/registry/bundles/tracebank.yaml +1 -1
  137. package/artifacts/release/registry/bundles/vision.yaml +1 -1
  138. package/artifacts/release/registry/omg-capability.schema.json +1 -1
  139. package/artifacts/release/settings.json +3 -3
  140. package/build/lib/commands/OMG:profile-review.md +43 -0
  141. package/build/lib/commands/OMG:validate.md +59 -0
  142. package/build/lib/control_plane/service.py +40 -1
  143. package/build/lib/hooks/_agent_registry.py +2 -0
  144. package/build/lib/hooks/firewall.py +263 -4
  145. package/build/lib/hooks/intentgate-keyword-detector.py +15 -3
  146. package/build/lib/hooks/policy_engine.py +77 -0
  147. package/build/lib/hooks/prompt-enhancer.py +146 -0
  148. package/build/lib/hooks/session-end-capture.py +374 -6
  149. package/build/lib/hooks/session-start.py +13 -35
  150. package/build/lib/hooks/setup_wizard.py +333 -1
  151. package/build/lib/hooks/shadow_manager.py +111 -2
  152. package/build/lib/hooks/stop_dispatcher.py +108 -4
  153. package/build/lib/plugins/advanced/plugin.json +26 -9
  154. package/build/lib/plugins/core/plugin.json +44 -11
  155. package/build/lib/registry/bundles/algorithms.yaml +1 -1
  156. package/build/lib/registry/bundles/api-twin.yaml +1 -1
  157. package/build/lib/registry/bundles/claim-judge.yaml +1 -1
  158. package/build/lib/registry/bundles/control-plane.yaml +1 -1
  159. package/build/lib/registry/bundles/data-lineage.yaml +1 -1
  160. package/build/lib/registry/bundles/delta-classifier.yaml +1 -1
  161. package/build/lib/registry/bundles/eval-gate.yaml +1 -1
  162. package/build/lib/registry/bundles/health.yaml +1 -1
  163. package/build/lib/registry/bundles/hook-governor.yaml +1 -1
  164. package/build/lib/registry/bundles/incident-replay.yaml +1 -1
  165. package/build/lib/registry/bundles/lsp-pack.yaml +1 -1
  166. package/build/lib/registry/bundles/mcp-fabric.yaml +1 -1
  167. package/build/lib/registry/bundles/plan-council.yaml +1 -1
  168. package/build/lib/registry/bundles/preflight.yaml +1 -1
  169. package/build/lib/registry/bundles/proof-gate.yaml +1 -1
  170. package/build/lib/registry/bundles/remote-supervisor.yaml +1 -1
  171. package/build/lib/registry/bundles/robotics.yaml +1 -1
  172. package/build/lib/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  173. package/build/lib/registry/bundles/security-check.yaml +1 -1
  174. package/build/lib/registry/bundles/test-intent-lock.yaml +1 -1
  175. package/build/lib/registry/bundles/tracebank.yaml +1 -1
  176. package/build/lib/registry/bundles/vision.yaml +1 -1
  177. package/build/lib/registry/omg-capability.schema.json +1 -1
  178. package/build/lib/runtime/adoption.py +1 -1
  179. package/build/lib/runtime/background_verification.py +62 -0
  180. package/build/lib/runtime/claim_judge.py +165 -5
  181. package/build/lib/runtime/compat.py +15 -1
  182. package/build/lib/runtime/context_engine.py +261 -4
  183. package/build/lib/runtime/contract_compiler.py +370 -93
  184. package/build/lib/runtime/defense_state.py +79 -8
  185. package/build/lib/runtime/delta_classifier.py +80 -2
  186. package/build/lib/runtime/evidence_query.py +56 -4
  187. package/build/lib/runtime/evidence_registry.py +16 -0
  188. package/build/lib/runtime/evidence_requirements.py +47 -0
  189. package/build/lib/runtime/forge_agents.py +179 -9
  190. package/build/lib/runtime/forge_contracts.py +208 -2
  191. package/build/lib/runtime/interaction_journal.py +318 -42
  192. package/build/lib/runtime/memory_store.py +134 -1
  193. package/build/lib/runtime/mutation_gate.py +57 -11
  194. package/build/lib/runtime/omg_compat_contract_snapshot.json +2 -2
  195. package/build/lib/runtime/omg_mcp_server.py +14 -4
  196. package/build/lib/runtime/preflight.py +14 -0
  197. package/build/lib/runtime/profile_io.py +294 -0
  198. package/build/lib/runtime/proof_gate.py +122 -7
  199. package/build/lib/runtime/release_run_coordinator.py +339 -0
  200. package/build/lib/runtime/release_surfaces.py +243 -0
  201. package/build/lib/runtime/rollback_manifest.py +136 -0
  202. package/build/lib/runtime/router_critics.py +50 -0
  203. package/build/lib/runtime/runtime_contracts.py +137 -0
  204. package/build/lib/runtime/security_check.py +16 -0
  205. package/build/lib/runtime/session_health.py +60 -16
  206. package/build/lib/runtime/team_router.py +156 -13
  207. package/build/lib/runtime/test_intent_lock.py +102 -0
  208. package/build/lib/runtime/tool_plan_gate.py +249 -24
  209. package/build/lib/runtime/validate.py +194 -0
  210. package/build/lib/runtime/verification_controller.py +52 -2
  211. package/commands/OMG:diagnose-plugins.md +33 -0
  212. package/commands/OMG:profile-review.md +43 -0
  213. package/commands/OMG:setup.md +4 -1
  214. package/commands/OMG:validate.md +59 -0
  215. package/control_plane/service.py +40 -1
  216. package/dist/enterprise/bundle/.claude-plugin/marketplace.json +3 -3
  217. package/dist/enterprise/bundle/.claude-plugin/plugin.json +1 -1
  218. package/dist/enterprise/bundle/OMG_COMPAT_CONTRACT.md +1 -1
  219. package/dist/enterprise/bundle/plugins/advanced/plugin.json +26 -9
  220. package/dist/enterprise/bundle/registry/bundles/algorithms.yaml +1 -1
  221. package/dist/enterprise/bundle/registry/bundles/api-twin.yaml +1 -1
  222. package/dist/enterprise/bundle/registry/bundles/claim-judge.yaml +1 -1
  223. package/dist/enterprise/bundle/registry/bundles/control-plane.yaml +1 -1
  224. package/dist/enterprise/bundle/registry/bundles/data-lineage.yaml +1 -1
  225. package/dist/enterprise/bundle/registry/bundles/delta-classifier.yaml +1 -1
  226. package/dist/enterprise/bundle/registry/bundles/eval-gate.yaml +1 -1
  227. package/dist/enterprise/bundle/registry/bundles/health.yaml +1 -1
  228. package/dist/enterprise/bundle/registry/bundles/hook-governor.yaml +1 -1
  229. package/dist/enterprise/bundle/registry/bundles/incident-replay.yaml +1 -1
  230. package/dist/enterprise/bundle/registry/bundles/lsp-pack.yaml +1 -1
  231. package/dist/enterprise/bundle/registry/bundles/mcp-fabric.yaml +1 -1
  232. package/dist/enterprise/bundle/registry/bundles/plan-council.yaml +1 -1
  233. package/dist/enterprise/bundle/registry/bundles/preflight.yaml +1 -1
  234. package/dist/enterprise/bundle/registry/bundles/proof-gate.yaml +1 -1
  235. package/dist/enterprise/bundle/registry/bundles/remote-supervisor.yaml +1 -1
  236. package/dist/enterprise/bundle/registry/bundles/robotics.yaml +1 -1
  237. package/dist/enterprise/bundle/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  238. package/dist/enterprise/bundle/registry/bundles/security-check.yaml +1 -1
  239. package/dist/enterprise/bundle/registry/bundles/test-intent-lock.yaml +1 -1
  240. package/dist/enterprise/bundle/registry/bundles/tracebank.yaml +1 -1
  241. package/dist/enterprise/bundle/registry/bundles/vision.yaml +1 -1
  242. package/dist/enterprise/bundle/registry/omg-capability.schema.json +1 -1
  243. package/dist/enterprise/bundle/settings.json +3 -3
  244. package/dist/enterprise/manifest.json +30 -40
  245. package/dist/oh_my_god-2.1.4-py3-none-any.whl +0 -0
  246. package/dist/oh_my_god-2.1.4.tar.gz +0 -0
  247. package/dist/public/bundle/.claude-plugin/marketplace.json +3 -3
  248. package/dist/public/bundle/.claude-plugin/plugin.json +1 -1
  249. package/dist/public/bundle/OMG_COMPAT_CONTRACT.md +1 -1
  250. package/dist/public/bundle/plugins/advanced/plugin.json +26 -9
  251. package/dist/public/bundle/registry/bundles/algorithms.yaml +1 -1
  252. package/dist/public/bundle/registry/bundles/api-twin.yaml +1 -1
  253. package/dist/public/bundle/registry/bundles/claim-judge.yaml +1 -1
  254. package/dist/public/bundle/registry/bundles/control-plane.yaml +1 -1
  255. package/dist/public/bundle/registry/bundles/data-lineage.yaml +1 -1
  256. package/dist/public/bundle/registry/bundles/delta-classifier.yaml +1 -1
  257. package/dist/public/bundle/registry/bundles/eval-gate.yaml +1 -1
  258. package/dist/public/bundle/registry/bundles/health.yaml +1 -1
  259. package/dist/public/bundle/registry/bundles/hook-governor.yaml +1 -1
  260. package/dist/public/bundle/registry/bundles/incident-replay.yaml +1 -1
  261. package/dist/public/bundle/registry/bundles/lsp-pack.yaml +1 -1
  262. package/dist/public/bundle/registry/bundles/mcp-fabric.yaml +1 -1
  263. package/dist/public/bundle/registry/bundles/plan-council.yaml +1 -1
  264. package/dist/public/bundle/registry/bundles/preflight.yaml +1 -1
  265. package/dist/public/bundle/registry/bundles/proof-gate.yaml +1 -1
  266. package/dist/public/bundle/registry/bundles/remote-supervisor.yaml +1 -1
  267. package/dist/public/bundle/registry/bundles/robotics.yaml +1 -1
  268. package/dist/public/bundle/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  269. package/dist/public/bundle/registry/bundles/security-check.yaml +1 -1
  270. package/dist/public/bundle/registry/bundles/test-intent-lock.yaml +1 -1
  271. package/dist/public/bundle/registry/bundles/tracebank.yaml +1 -1
  272. package/dist/public/bundle/registry/bundles/vision.yaml +1 -1
  273. package/dist/public/bundle/registry/omg-capability.schema.json +1 -1
  274. package/dist/public/bundle/settings.json +3 -3
  275. package/dist/public/manifest.json +30 -40
  276. package/docs/install/opencode.md +30 -0
  277. package/docs/proof.md +11 -0
  278. package/docs/release-checklist.md +14 -1
  279. package/hooks/_agent_registry.py +2 -0
  280. package/hooks/firewall.py +263 -4
  281. package/hooks/intentgate-keyword-detector.py +15 -3
  282. package/hooks/policy_engine.py +77 -0
  283. package/hooks/prompt-enhancer.py +146 -0
  284. package/hooks/session-end-capture.py +374 -6
  285. package/hooks/session-start.py +13 -35
  286. package/hooks/setup_wizard.py +342 -2
  287. package/hooks/shadow_manager.py +111 -2
  288. package/hooks/stop_dispatcher.py +108 -4
  289. package/hud/omg-hud.mjs +30 -6
  290. package/lab/pipeline.py +197 -26
  291. package/package.json +1 -1
  292. package/plugins/advanced/plugin.json +26 -9
  293. package/plugins/core/plugin.json +51 -12
  294. package/pyproject.toml +10 -2
  295. package/registry/bundles/algorithms.yaml +1 -1
  296. package/registry/bundles/api-twin.yaml +1 -1
  297. package/registry/bundles/claim-judge.yaml +1 -1
  298. package/registry/bundles/control-plane.yaml +1 -1
  299. package/registry/bundles/data-lineage.yaml +1 -1
  300. package/registry/bundles/delta-classifier.yaml +1 -1
  301. package/registry/bundles/eval-gate.yaml +1 -1
  302. package/registry/bundles/health.yaml +1 -1
  303. package/registry/bundles/hook-governor.yaml +1 -1
  304. package/registry/bundles/incident-replay.yaml +1 -1
  305. package/registry/bundles/lsp-pack.yaml +1 -1
  306. package/registry/bundles/mcp-fabric.yaml +1 -1
  307. package/registry/bundles/plan-council.yaml +1 -1
  308. package/registry/bundles/preflight.yaml +1 -1
  309. package/registry/bundles/proof-gate.yaml +1 -1
  310. package/registry/bundles/remote-supervisor.yaml +1 -1
  311. package/registry/bundles/robotics.yaml +1 -1
  312. package/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  313. package/registry/bundles/security-check.yaml +1 -1
  314. package/registry/bundles/test-intent-lock.yaml +1 -1
  315. package/registry/bundles/tracebank.yaml +1 -1
  316. package/registry/bundles/vision.yaml +1 -1
  317. package/registry/omg-capability.schema.json +1 -1
  318. package/runtime/adoption.py +7 -5
  319. package/runtime/background_verification.py +62 -0
  320. package/runtime/claim_judge.py +165 -5
  321. package/runtime/compat.py +48 -1
  322. package/runtime/context_engine.py +261 -4
  323. package/runtime/contract_compiler.py +370 -93
  324. package/runtime/defense_state.py +79 -8
  325. package/runtime/delta_classifier.py +80 -2
  326. package/runtime/evidence_query.py +56 -4
  327. package/runtime/evidence_registry.py +16 -0
  328. package/runtime/evidence_requirements.py +47 -0
  329. package/runtime/forge_agents.py +179 -9
  330. package/runtime/forge_contracts.py +208 -2
  331. package/runtime/hook_governor.py +19 -1
  332. package/runtime/interaction_journal.py +318 -42
  333. package/runtime/memory_store.py +134 -1
  334. package/runtime/mutation_gate.py +57 -11
  335. package/runtime/omg_compat_contract_snapshot.json +2 -2
  336. package/runtime/omg_mcp_server.py +14 -4
  337. package/runtime/plugin_diagnostics.py +248 -0
  338. package/runtime/plugin_interop.py +1007 -0
  339. package/runtime/preflight.py +14 -0
  340. package/runtime/profile_io.py +294 -0
  341. package/runtime/proof_gate.py +122 -7
  342. package/runtime/providers/opencode_provider.py +94 -0
  343. package/runtime/release_run_coordinator.py +339 -0
  344. package/runtime/release_surfaces.py +243 -0
  345. package/runtime/rollback_manifest.py +136 -0
  346. package/runtime/router_critics.py +50 -0
  347. package/runtime/runtime_contracts.py +137 -0
  348. package/runtime/security_check.py +16 -0
  349. package/runtime/session_health.py +60 -16
  350. package/runtime/team_router.py +156 -13
  351. package/runtime/test_intent_lock.py +102 -0
  352. package/runtime/tool_plan_gate.py +218 -19
  353. package/runtime/validate.py +289 -0
  354. package/runtime/verification_controller.py +52 -2
  355. package/scripts/omg.py +306 -3
  356. package/scripts/prepare-release-proof-fixtures.py +191 -7
  357. package/scripts/print-canonical-version.py +80 -0
  358. package/scripts/sync-release-identity.py +476 -0
  359. package/scripts/validate-release-identity.py +246 -0
  360. package/scripts/verify-standalone.sh +3 -0
  361. package/settings.json +3 -3
  362. package/templates/plugins-allowlist.yaml +19 -0
  363. package/artifacts/release/dist/enterprise/bundle/.gemini/settings.json +0 -11
  364. package/artifacts/release/dist/enterprise/bundle/.kimi/mcp.json +0 -11
  365. package/artifacts/release/dist/public/bundle/.gemini/settings.json +0 -11
  366. package/artifacts/release/dist/public/bundle/.kimi/mcp.json +0 -11
  367. package/build/lib/yaml.py +0 -321
  368. package/dist/enterprise/bundle/.gemini/settings.json +0 -11
  369. package/dist/enterprise/bundle/.kimi/mcp.json +0 -11
  370. package/dist/public/bundle/.gemini/settings.json +0 -11
  371. package/dist/public/bundle/.kimi/mcp.json +0 -11
@@ -4,6 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  from datetime import datetime, timezone
6
6
  import os
7
+ from pathlib import Path
7
8
  from typing import Any
8
9
 
9
10
  from hooks.policy_engine import (
@@ -20,6 +21,7 @@ from runtime.guide_assert import guide_assert
20
21
  from runtime.dispatcher import dispatch_runtime
21
22
  from runtime.claim_judge import judge_claims
22
23
  from runtime.mutation_gate import check_mutation_allowed
24
+ from runtime.runtime_contracts import read_run_state
23
25
  from runtime.security_check import run_security_check
24
26
  from runtime.test_intent_lock import lock_intent, verify_intent
25
27
 
@@ -275,15 +277,24 @@ class ControlPlaneService:
275
277
  file_path = payload.get("file_path")
276
278
  lock_id = payload.get("lock_id")
277
279
  exemption = payload.get("exemption")
280
+ command = payload.get("command")
281
+ run_id = payload.get("run_id")
282
+ metadata = payload.get("metadata")
278
283
 
279
284
  if not isinstance(tool, str) or not tool.strip():
280
285
  raise ValueError("tool is required")
281
- if not isinstance(file_path, str) or not file_path.strip():
286
+ if not isinstance(file_path, str) or (tool != "Bash" and not file_path.strip()):
282
287
  raise ValueError("file_path is required")
283
288
  if lock_id is not None and not isinstance(lock_id, str):
284
289
  raise ValueError("lock_id must be a string when provided")
285
290
  if exemption is not None and not isinstance(exemption, str):
286
291
  raise ValueError("exemption must be a string when provided")
292
+ if command is not None and not isinstance(command, str):
293
+ raise ValueError("command must be a string when provided")
294
+ if run_id is not None and not isinstance(run_id, str):
295
+ raise ValueError("run_id must be a string when provided")
296
+ if metadata is not None and not isinstance(metadata, dict):
297
+ raise ValueError("metadata must be an object when provided")
287
298
 
288
299
  result = check_mutation_allowed(
289
300
  tool=tool,
@@ -291,9 +302,37 @@ class ControlPlaneService:
291
302
  project_dir=self.project_dir,
292
303
  lock_id=lock_id,
293
304
  exemption=exemption,
305
+ command=command,
306
+ run_id=run_id,
307
+ metadata=metadata,
294
308
  )
295
309
  return 200, result
296
310
 
311
+ def session_health(self, payload: dict[str, Any]) -> tuple[int, dict[str, Any]]:
312
+ run_id = payload.get("run_id")
313
+ if isinstance(run_id, str) and run_id.strip():
314
+ state = read_run_state(self.project_dir, "session_health", run_id.strip())
315
+ if state is None:
316
+ return 404, {"status": "error", "message": f"No session health for run_id: {run_id}"}
317
+ return 200, dict(state)
318
+
319
+ health_dir = Path(self.project_dir) / ".omg" / "state" / "session_health"
320
+ if not health_dir.exists():
321
+ return 404, {"status": "error", "message": "No session health state found"}
322
+
323
+ candidates = sorted(
324
+ (f for f in health_dir.iterdir() if f.suffix == ".json" and not f.name.endswith(".tmp")),
325
+ key=lambda p: p.stat().st_mtime,
326
+ )
327
+ if not candidates:
328
+ return 404, {"status": "error", "message": "No session health state found"}
329
+
330
+ latest_run_id = candidates[-1].stem
331
+ state = read_run_state(self.project_dir, "session_health", latest_run_id)
332
+ if state is None:
333
+ return 404, {"status": "error", "message": "Failed to read session health state"}
334
+ return 200, dict(state)
335
+
297
336
  def scoreboard_baseline(self) -> tuple[int, dict[str, Any]]:
298
337
  return 200, {
299
338
  "generated_at": datetime.now(timezone.utc).isoformat(),
@@ -224,6 +224,8 @@ INTENT_ROUTING = {
224
224
  "INTENT_EXPLORE": "explore", # explore/find → fast search agent
225
225
  "INTENT_REVIEW": "reviewer", # review/audit → code review agent
226
226
  "INTENT_QUICK": "quick_task", # quick/simple → fast task agent
227
+ # Clarification intent (Task 3) — halts mutation-capable execution
228
+ "INTENT_CLARIFICATION": None, # clarification needed → halt (no agent dispatch)
227
229
  }
228
230
 
229
231
  # Core agent model preferences. NOT keyword-matched — used by orchestration pipeline only. model_version is informational (not passed to CLI).
@@ -7,23 +7,234 @@ one centralized decision model.
7
7
  import json
8
8
  import os
9
9
  import sys
10
+ from pathlib import Path
11
+ from typing import Any
10
12
 
11
13
  HOOKS_DIR = os.path.dirname(__file__)
12
- if HOOKS_DIR not in sys.path:
13
- sys.path.insert(0, HOOKS_DIR)
14
+ PROJECT_ROOT = os.path.dirname(HOOKS_DIR)
15
+ for path in (HOOKS_DIR, PROJECT_ROOT):
16
+ if path not in sys.path:
17
+ sys.path.insert(0, path)
14
18
 
15
- from _common import setup_crash_handler, json_input, deny_decision, is_bypass_mode
19
+ from _common import setup_crash_handler, json_input, deny_decision, is_bypass_mode, get_project_dir # pyright: ignore[reportImplicitRelativeImport]
16
20
 
17
21
  # Fail-closed: deny on crash (security hook)
18
22
  setup_crash_handler("firewall", fail_closed=True)
19
23
 
20
24
  try:
21
- from policy_engine import evaluate_bash_command, to_pretool_hook_output
25
+ from policy_engine import evaluate_bash_command, to_pretool_hook_output, scan_mutation_command, ask, deny # pyright: ignore[reportImplicitRelativeImport]
26
+ from runtime.defense_state import DefenseState
27
+ from runtime.session_health import compute_session_health
28
+ from runtime.mutation_gate import check_mutation_allowed
29
+ from runtime.tool_plan_gate import journal_mutation_bash
22
30
  except Exception as _import_err:
23
31
  print(f"OMG firewall: policy_engine import failed: {_import_err}", file=sys.stderr)
24
32
  deny_decision(f"OMG firewall crash: policy_engine import failed: {_import_err}. Denying for safety.")
25
33
  sys.exit(0)
26
34
 
35
+
36
+ def _enrich_risk_context(decision, payload: dict[str, object]):
37
+ try:
38
+ project_dir = os.environ.get("CLAUDE_PROJECT_DIR", os.getcwd())
39
+ run_id = _resolve_run_id(payload)
40
+
41
+ suffixes: list[str] = []
42
+ defense_risk = _read_defense_risk(project_dir)
43
+ if defense_risk:
44
+ suffixes.append(f"defense risk={defense_risk}")
45
+
46
+ council_signal = _read_council_signal(project_dir, run_id)
47
+ if council_signal:
48
+ suffixes.append(council_signal)
49
+
50
+ if suffixes:
51
+ decision.reason = f"{decision.reason} [{'; '.join(suffixes)}]".strip()
52
+ except Exception:
53
+ return decision
54
+ return decision
55
+
56
+
57
+ def _resolve_run_id(payload: dict[str, object]) -> str:
58
+ if isinstance(payload, dict):
59
+ run_id = payload.get("run_id")
60
+ if isinstance(run_id, str) and run_id.strip():
61
+ return run_id.strip()
62
+ tool_input = payload.get("tool_input")
63
+ if isinstance(tool_input, dict):
64
+ metadata = tool_input.get("metadata")
65
+ if isinstance(metadata, dict):
66
+ metadata_run_id = metadata.get("run_id")
67
+ if isinstance(metadata_run_id, str) and metadata_run_id.strip():
68
+ return metadata_run_id.strip()
69
+ env_run_id = os.environ.get("OMG_RUN_ID", "")
70
+ return env_run_id.strip()
71
+
72
+
73
+ def _resolve_active_run_id(project_dir: str) -> str:
74
+ active_run_path = Path(project_dir) / ".omg" / "shadow" / "active-run"
75
+ if not active_run_path.exists():
76
+ return ""
77
+ try:
78
+ return active_run_path.read_text(encoding="utf-8").strip()
79
+ except OSError:
80
+ return ""
81
+
82
+
83
+ def _read_defense_risk(project_dir: str) -> str:
84
+ path = Path(project_dir) / ".omg" / "state" / "defense_state" / "current.json"
85
+ if not path.exists():
86
+ return ""
87
+ try:
88
+ payload = json.loads(path.read_text(encoding="utf-8"))
89
+ except (OSError, json.JSONDecodeError):
90
+ return ""
91
+ if not isinstance(payload, dict):
92
+ return ""
93
+ return str(payload.get("risk_level", "")).strip().lower()
94
+
95
+
96
+ def _read_council_signal(project_dir: str, run_id: str) -> str:
97
+ if not run_id:
98
+ return ""
99
+ path = Path(project_dir) / ".omg" / "state" / "council_verdicts" / f"{run_id}.json"
100
+ if not path.exists():
101
+ return ""
102
+ try:
103
+ payload = json.loads(path.read_text(encoding="utf-8"))
104
+ except (OSError, json.JSONDecodeError):
105
+ return ""
106
+ if not isinstance(payload, dict):
107
+ return ""
108
+
109
+ verdicts = payload.get("verdicts")
110
+ if not isinstance(verdicts, dict):
111
+ return ""
112
+ evidence = verdicts.get("evidence_completeness")
113
+ if not isinstance(evidence, dict):
114
+ return ""
115
+ verdict = str(evidence.get("verdict", "")).strip().lower()
116
+ findings = evidence.get("findings")
117
+ findings_count = len(findings) if isinstance(findings, list) else 0
118
+ if not verdict:
119
+ return ""
120
+ return f"council evidence={verdict} findings={findings_count}"
121
+
122
+
123
+ def _read_clarification_state(project_dir: str, run_id: str) -> dict[str, object]:
124
+ if not run_id:
125
+ return {
126
+ "requires_clarification": False,
127
+ "intent_class": "",
128
+ "clarification_prompt": "",
129
+ "confidence": 0.0,
130
+ }
131
+ path = Path(project_dir) / ".omg" / "state" / "intent_gate" / f"{run_id}.json"
132
+ if not path.exists():
133
+ return {
134
+ "requires_clarification": False,
135
+ "intent_class": "",
136
+ "clarification_prompt": "",
137
+ "confidence": 0.0,
138
+ }
139
+ try:
140
+ payload = json.loads(path.read_text(encoding="utf-8"))
141
+ except (OSError, json.JSONDecodeError):
142
+ return {
143
+ "requires_clarification": False,
144
+ "intent_class": "",
145
+ "clarification_prompt": "",
146
+ "confidence": 0.0,
147
+ }
148
+ if not isinstance(payload, dict):
149
+ return {
150
+ "requires_clarification": False,
151
+ "intent_class": "",
152
+ "clarification_prompt": "",
153
+ "confidence": 0.0,
154
+ }
155
+ prompt = " ".join(str(payload.get("clarification_prompt", "")).split())
156
+ try:
157
+ confidence = float(payload.get("confidence", 0.0))
158
+ except (TypeError, ValueError):
159
+ confidence = 0.0
160
+ return {
161
+ "requires_clarification": bool(payload.get("requires_clarification") is True),
162
+ "intent_class": str(payload.get("intent_class", "")).strip(),
163
+ "clarification_prompt": prompt,
164
+ "confidence": round(max(0.0, min(1.0, confidence)), 2),
165
+ }
166
+
167
+
168
+ def _clarification_reason(clarification_prompt: str) -> str:
169
+ prompt = " ".join(str(clarification_prompt or "").split())
170
+ if prompt:
171
+ return f"Clarification required before mutation: {prompt}"
172
+ return "Clarification required before mutation: provide the missing intent details."
173
+
174
+
175
+ def _to_float(value: Any, default: float) -> float:
176
+ try:
177
+ return float(value)
178
+ except (TypeError, ValueError):
179
+ return default
180
+
181
+
182
+ def _mutating_defense_decision(
183
+ *,
184
+ project_dir: str,
185
+ cmd: str,
186
+ run_id: str,
187
+ ):
188
+ scan = scan_mutation_command(cmd)
189
+ defense_state = DefenseState(project_dir).update(
190
+ injection_hits=int(_to_float(scan.get("injection_hits"), 0.0)),
191
+ contamination_score=_to_float(scan.get("contamination_score"), 0.0),
192
+ overthinking_score=_to_float(scan.get("overthinking_score"), 0.0),
193
+ premature_fixer_score=_to_float(scan.get("premature_fixer_score"), 0.0),
194
+ )
195
+
196
+ resolved_run_id = run_id.strip() or _resolve_active_run_id(project_dir) or "default"
197
+ session_health = compute_session_health(project_dir, run_id=resolved_run_id)
198
+
199
+ contamination = _to_float(session_health.get("contamination_risk"), _to_float(defense_state.get("contamination_score"), 0.0))
200
+ overthinking = _to_float(session_health.get("overthinking_score"), _to_float(defense_state.get("overthinking_score"), 0.0))
201
+ premature_fixer = _to_float(defense_state.get("premature_fixer_score"), 0.0)
202
+ health_action = str(session_health.get("recommended_action", "continue"))
203
+ thresholds = session_health.get("thresholds") if isinstance(session_health, dict) else {}
204
+ contamination_thresholds = thresholds.get("contamination_risk") if isinstance(thresholds, dict) else {}
205
+ overthinking_thresholds = thresholds.get("overthinking_score") if isinstance(thresholds, dict) else {}
206
+ reflect_contamination = _to_float(contamination_thresholds.get("reflect") if isinstance(contamination_thresholds, dict) else None, 0.05)
207
+ reflect_overthinking = _to_float(overthinking_thresholds.get("reflect") if isinstance(overthinking_thresholds, dict) else None, 0.15)
208
+ reflect_triggers = session_health.get("reflect_triggers") if isinstance(session_health, dict) else {}
209
+ contamination_trigger = bool(reflect_triggers.get("contamination")) if isinstance(reflect_triggers, dict) else contamination > reflect_contamination
210
+ overthinking_trigger = bool(reflect_triggers.get("overthinking")) if isinstance(reflect_triggers, dict) else overthinking > reflect_overthinking
211
+ pause_required = bool(session_health.get("defense_pause_required") is True) if isinstance(session_health, dict) else (contamination_trigger or overthinking_trigger)
212
+ signal_text = ", ".join(str(item) for item in scan.get("signals", []) if str(item)) or "none"
213
+ context = (
214
+ f"defense hits={int(_to_float(defense_state.get('injection_hits'), 0.0))} "
215
+ f"contamination={contamination:.4f} overthinking={overthinking:.4f} "
216
+ f"premature_fixer={premature_fixer:.4f} "
217
+ f"session_health={health_action} signals={signal_text}"
218
+ )
219
+
220
+ if health_action == "block":
221
+ return deny(
222
+ f"Blocked: mutation denied by defense/session-health reducer [{context}]",
223
+ "high",
224
+ ["defense-reducer", "session-health"],
225
+ )
226
+
227
+ if pause_required or contamination_trigger or overthinking_trigger:
228
+ return ask(
229
+ "Pause: mutation requires reflection before execution "
230
+ f"[{context}; thresholds contamination>{reflect_contamination:.2f} "
231
+ f"overthinking>{reflect_overthinking:.2f}]",
232
+ "high",
233
+ ["reflect", "defense-reducer", "session-health"],
234
+ )
235
+
236
+ return None
237
+
27
238
  data = json_input()
28
239
 
29
240
  tool = data.get("tool_name", "")
@@ -36,11 +247,59 @@ if not cmd:
36
247
 
37
248
  decision = evaluate_bash_command(cmd)
38
249
 
250
+ tool_input = data.get("tool_input")
251
+ metadata = tool_input.get("metadata") if isinstance(tool_input, dict) else None
252
+ lock_id = tool_input.get("lock_id") if isinstance(tool_input, dict) else None
253
+ if not isinstance(lock_id, str) and isinstance(metadata, dict):
254
+ lock_id = metadata.get("lock_id")
255
+ run_id = _resolve_run_id(data)
256
+
257
+ gate_result = check_mutation_allowed(
258
+ tool="Bash",
259
+ file_path=cmd,
260
+ project_dir=get_project_dir(),
261
+ lock_id=lock_id if isinstance(lock_id, str) else None,
262
+ command=cmd,
263
+ run_id=run_id or None,
264
+ metadata=metadata if isinstance(metadata, dict) else None,
265
+ )
266
+ is_mutation_capable = str(gate_result.get("reason", "")) != "tool is read-only for mutation gate"
267
+ clarification_state = _read_clarification_state(get_project_dir(), run_id)
268
+ if is_mutation_capable:
269
+ defense_decision = _mutating_defense_decision(
270
+ project_dir=get_project_dir(),
271
+ cmd=cmd,
272
+ run_id=run_id,
273
+ )
274
+ if defense_decision is not None:
275
+ decision = defense_decision
276
+
277
+ if clarification_state.get("requires_clarification") is True and is_mutation_capable:
278
+ deny_decision(_clarification_reason(str(clarification_state.get("clarification_prompt", ""))))
279
+ sys.exit(0)
280
+
281
+ if is_mutation_capable and gate_result.get("status") == "blocked":
282
+ deny_decision(str(gate_result.get("reason", "mutation denied by test intent lock gate")))
283
+ sys.exit(0)
284
+
285
+ decision = _enrich_risk_context(decision, data)
286
+
39
287
  # In bypass-permission mode, only enforce hard denials (critical safety).
40
288
  # Skip "ask" decisions so the user is not prompted for confirmation.
41
289
  if is_bypass_mode(data) and decision.action != "deny":
42
290
  sys.exit(0)
43
291
 
292
+ if decision.action == "allow" and is_mutation_capable:
293
+ try:
294
+ journal_mutation_bash(
295
+ project_dir=get_project_dir(),
296
+ command=cmd,
297
+ run_id=run_id or None,
298
+ metadata=metadata if isinstance(metadata, dict) else None,
299
+ )
300
+ except Exception:
301
+ pass
302
+
44
303
  out = to_pretool_hook_output(decision)
45
304
  if out:
46
305
  json.dump(out, sys.stdout)
@@ -38,7 +38,7 @@ try:
38
38
  get_feature_flag,
39
39
  _resolve_project_dir,
40
40
  check_performance_budget,
41
- PRE_TOOL_INJECT_MAX_MS,
41
+ PRE_TOOL_INJECT_MAX_MS as pre_tool_inject_max_ms,
42
42
  )
43
43
  except ImportError:
44
44
  import importlib
@@ -48,7 +48,7 @@ except ImportError:
48
48
  get_feature_flag = _common.get_feature_flag
49
49
  _resolve_project_dir = _common._resolve_project_dir
50
50
  check_performance_budget = _common.check_performance_budget
51
- PRE_TOOL_INJECT_MAX_MS = _common.PRE_TOOL_INJECT_MAX_MS
51
+ pre_tool_inject_max_ms = _common.PRE_TOOL_INJECT_MAX_MS
52
52
 
53
53
  setup_crash_handler("intentgate-keyword-detector", fail_closed=False)
54
54
 
@@ -64,6 +64,18 @@ KEYWORD_INTENT_MAP = {
64
64
  "search": "INTENT_SEARCH",
65
65
  "stop": "INTENT_STOP",
66
66
  "crazy": "INTENT_CRAZY",
67
+ "auth": "INTENT_AUTH_SETUP",
68
+ "login": "INTENT_AUTH_SETUP",
69
+ "credentials": "INTENT_AUTH_SETUP",
70
+ "setup my credentials": "INTENT_AUTH_SETUP",
71
+ "setup credentials": "INTENT_AUTH_SETUP",
72
+ "remember my settings": "INTENT_PREFERENCE_MEMORY",
73
+ "remember settings": "INTENT_PREFERENCE_MEMORY",
74
+ "preferences": "INTENT_PREFERENCE_MEMORY",
75
+ "memory style": "INTENT_PREFERENCE_MEMORY",
76
+ "setup preferences": "INTENT_AMBIGUOUS_CONFIG",
77
+ "configure preferences": "INTENT_AMBIGUOUS_CONFIG",
78
+ "remember setup": "INTENT_AMBIGUOUS_CONFIG",
67
79
  }
68
80
 
69
81
 
@@ -179,7 +191,7 @@ if detected_intents:
179
191
  # PERFORMANCE BUDGET CHECK
180
192
  # ═══════════════════════════════════════════════════════════
181
193
  elapsed_ms = (time.time() - start_time) * 1000
182
- check_performance_budget("intentgate-keyword-detector", elapsed_ms, PRE_TOOL_INJECT_MAX_MS)
194
+ check_performance_budget("intentgate-keyword-detector", elapsed_ms, pre_tool_inject_max_ms)
183
195
 
184
196
  # ═══════════════════════════════════════════════════════════
185
197
  # OUTPUT
@@ -126,6 +126,33 @@ UNTRUSTED_MUTATION_PATTERNS = [
126
126
  TRUSTED_CONTENT_TIERS = frozenset({"local", "balanced"})
127
127
  UNTRUSTED_EXTERNAL_TIERS = frozenset({"research", "browser"})
128
128
 
129
+ INJECTION_MARKER_PATTERNS: tuple[tuple[re.Pattern[str], float, str], ...] = (
130
+ (re.compile(r"\bIGNORE\s+(?:ALL\s+)?PREVIOUS(?:\s+INSTRUCTIONS?)?\b", re.IGNORECASE), 0.03, "ignore-previous-instructions"),
131
+ (re.compile(r"<\|im_start\|>", re.IGNORECASE), 0.03, "im-start-token"),
132
+ (re.compile(r"<\|im_end\|>", re.IGNORECASE), 0.03, "im-end-token"),
133
+ (re.compile(r"\[INST\]", re.IGNORECASE), 0.03, "inst-token"),
134
+ (re.compile(r"\[/INST\]", re.IGNORECASE), 0.03, "inst-close-token"),
135
+ )
136
+
137
+ HIDDEN_INSTRUCTION_PATTERNS: tuple[tuple[re.Pattern[str], float, str], ...] = (
138
+ (re.compile(r"(?:^|\s)SYSTEM\s*:", re.IGNORECASE), 0.02, "system-role-token"),
139
+ (re.compile(r"(?:^|\s)ASSISTANT\s*:", re.IGNORECASE), 0.02, "assistant-role-token"),
140
+ (re.compile(r"(?:(?:#|//|/\*|<!--).{0,80})\b(?:ignore|override|jailbreak|bypass)\b", re.IGNORECASE), 0.01, "comment-hidden-instruction"),
141
+ (re.compile(r"\bbase64\s+(?:-d|--decode)\b", re.IGNORECASE), 0.01, "base64-decoder-token"),
142
+ (re.compile(r"\b[A-Za-z0-9+/]{48,}={0,2}\b"), 0.01, "opaque-base64-payload"),
143
+ )
144
+
145
+ CACHE_POISONING_PATTERNS: tuple[tuple[re.Pattern[str], float, str], ...] = (
146
+ (re.compile(r"(?:>|>>|tee\b|cp\b|mv\b|rm\b|sed\s+-i\b).{0,120}/\.omg/state/", re.IGNORECASE), 0.04, "state-path-overwrite-attempt"),
147
+ (re.compile(r"(?:>|>>|tee\b|cp\b|mv\b|rm\b|sed\s+-i\b).{0,120}/\.omg/shadow/active-run", re.IGNORECASE), 0.04, "active-run-overwrite-attempt"),
148
+ (re.compile(r"\b(?:cache|state)\s*(?:poison|override|overwrite|tamper)\b", re.IGNORECASE), 0.02, "cache-poisoning-language"),
149
+ )
150
+
151
+ CLARIFICATION_AMBIGUITY_PATTERNS: tuple[tuple[re.Pattern[str], float, str], ...] = (
152
+ (re.compile(r"\b(?:without\s+asking|no\s+questions\s+asked|skip\s+clarif(?:y|ication))\b", re.IGNORECASE), 0.08, "clarification-bypass-language"),
153
+ (re.compile(r"\b(?:just\s+fix\s+it|fix\s+everything|do\s+whatever\s+it\s+takes)\b", re.IGNORECASE), 0.08, "ambiguous-mutation-intent"),
154
+ )
155
+
129
156
 
130
157
  def _project_dir() -> str:
131
158
  return os.environ.get("CLAUDE_PROJECT_DIR", os.getcwd())
@@ -211,6 +238,56 @@ def _is_untrusted_content_mode_active() -> bool:
211
238
  return False
212
239
 
213
240
 
241
+ def scan_mutation_command(cmd: str) -> dict[str, Any]:
242
+ text = str(cmd or "")
243
+ if not text.strip():
244
+ return {
245
+ "injection_hits": 0,
246
+ "contamination_score": 0.0,
247
+ "overthinking_score": 0.0,
248
+ "premature_fixer_score": 0.0,
249
+ "signals": [],
250
+ }
251
+
252
+ contamination_score = 0.0
253
+ overthinking_score = 0.0
254
+ premature_fixer_score = 0.0
255
+ injection_hits = 0
256
+ signals: list[str] = []
257
+
258
+ for pattern, weight, label in INJECTION_MARKER_PATTERNS:
259
+ if pattern.search(text):
260
+ injection_hits += 1
261
+ contamination_score += weight
262
+ signals.append(label)
263
+
264
+ for pattern, weight, label in HIDDEN_INSTRUCTION_PATTERNS:
265
+ if pattern.search(text):
266
+ injection_hits += 1
267
+ contamination_score += weight
268
+ signals.append(label)
269
+
270
+ for pattern, weight, label in CACHE_POISONING_PATTERNS:
271
+ if pattern.search(text):
272
+ injection_hits += 1
273
+ contamination_score += weight
274
+ signals.append(label)
275
+
276
+ for pattern, weight, label in CLARIFICATION_AMBIGUITY_PATTERNS:
277
+ if pattern.search(text):
278
+ overthinking_score += weight
279
+ premature_fixer_score += weight
280
+ signals.append(label)
281
+
282
+ return {
283
+ "injection_hits": max(0, injection_hits),
284
+ "contamination_score": round(max(0.0, min(1.0, contamination_score)), 4),
285
+ "overthinking_score": round(max(0.0, min(1.0, overthinking_score)), 4),
286
+ "premature_fixer_score": round(max(0.0, min(1.0, premature_fixer_score)), 4),
287
+ "signals": signals,
288
+ }
289
+
290
+
214
291
  def evaluate_bash_command(cmd: str) -> PolicyDecision:
215
292
  if not cmd:
216
293
  return allow("empty command")