@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
@@ -8,6 +8,8 @@ import os
8
8
  from pathlib import Path
9
9
  from typing import Any
10
10
 
11
+ from runtime.runtime_contracts import write_run_state
12
+
11
13
 
12
14
  _SESSION_HEALTH_REL = Path(".omg") / "state" / "session_health"
13
15
  _DEFENSE_STATE_REL = Path(".omg") / "state" / "defense_state" / "current.json"
@@ -15,8 +17,9 @@ _CONTEXT_PRESSURE_REL = Path(".omg") / "state" / ".context-pressure.json"
15
17
  _JOURNAL_REL = Path(".omg") / "state" / "interaction_journal"
16
18
 
17
19
  _DEFAULT_THRESHOLDS: dict[str, Any] = {
18
- "contamination_risk": {"warn": 0.3, "block": 0.7},
19
- "overthinking_score": {"warn": 0.5, "block": 0.85},
20
+ "contamination_risk": {"reflect": 0.05, "block": 0.7},
21
+ "overthinking_score": {"reflect": 0.15, "block": 0.85},
22
+ "premature_fixer_score": {"reflect": 0.5},
20
23
  "context_health": {"warn": 0.4, "critical": 0.2},
21
24
  }
22
25
 
@@ -53,28 +56,52 @@ def compute_session_health(
53
56
  pressure_ratio,
54
57
  )
55
58
  )
59
+ premature_fixer_score = _clamp(_to_float(defense.get("premature_fixer_score"), 0.0))
60
+ clarification_sensitive = bool(defense.get("clarification_sensitive") is True)
56
61
 
57
62
  context_health = _compute_context_health(pressure_ratio, journal_count)
58
63
 
59
64
  verification_status = str(verification.get("status", "unknown"))
60
65
 
61
- recommended_action = _recommend_action(
66
+ action_recommendations = _recommend_actions(
62
67
  contamination_risk=contamination_risk,
63
68
  overthinking_score=overthinking_score,
69
+ premature_fixer_score=premature_fixer_score,
70
+ clarification_sensitive=clarification_sensitive,
64
71
  context_health=context_health,
65
72
  verification_status=verification_status,
66
73
  )
74
+ recommended_action = action_recommendations[0] if action_recommendations else "continue"
75
+ reflect_triggers = {
76
+ "contamination": contamination_risk > _DEFAULT_THRESHOLDS["contamination_risk"]["reflect"],
77
+ "overthinking": overthinking_score > _DEFAULT_THRESHOLDS["overthinking_score"]["reflect"],
78
+ "premature_fixer": premature_fixer_score > _DEFAULT_THRESHOLDS["premature_fixer_score"]["reflect"],
79
+ }
80
+
81
+ _ACTION_TO_STATUS = {
82
+ "continue": "ok",
83
+ "warn": "running",
84
+ "reflect": "running",
85
+ "block": "blocked",
86
+ }
87
+ status = _ACTION_TO_STATUS.get(recommended_action, "running")
67
88
 
68
89
  result: dict[str, Any] = {
69
90
  "schema": "SessionHealth",
70
91
  "schema_version": "1.0.0",
71
92
  "run_id": run_id,
93
+ "status": status,
72
94
  "contamination_risk": round(contamination_risk, 4),
73
95
  "overthinking_score": round(overthinking_score, 4),
96
+ "premature_fixer_score": round(premature_fixer_score, 4),
97
+ "clarification_sensitive": clarification_sensitive,
74
98
  "context_health": round(context_health, 4),
75
99
  "verification_status": verification_status,
76
100
  "journal_steps": journal_count,
77
101
  "recommended_action": recommended_action,
102
+ "action_recommendations": action_recommendations,
103
+ "defense_pause_required": bool(reflect_triggers["contamination"] or reflect_triggers["overthinking"]),
104
+ "reflect_triggers": reflect_triggers,
78
105
  "thresholds": dict(_DEFAULT_THRESHOLDS),
79
106
  "sources": {
80
107
  "defense_state": bool(defense),
@@ -85,37 +112,54 @@ def compute_session_health(
85
112
  "updated_at": datetime.now(timezone.utc).isoformat(),
86
113
  }
87
114
 
88
- _write_atomic(root / _SESSION_HEALTH_REL / f"{run_id}.json", result)
115
+ write_run_state(project_dir, "session_health", run_id, result)
89
116
  return result
90
117
 
91
118
 
92
- def _recommend_action(
119
+ def _recommend_actions(
93
120
  *,
94
121
  contamination_risk: float,
95
122
  overthinking_score: float,
123
+ premature_fixer_score: float,
124
+ clarification_sensitive: bool,
96
125
  context_health: float,
97
126
  verification_status: str,
98
- ) -> str:
127
+ ) -> list[str]:
99
128
  thresholds = _DEFAULT_THRESHOLDS
129
+ actions: list[str] = []
100
130
 
101
131
  if contamination_risk >= thresholds["contamination_risk"]["block"]:
102
- return "block"
132
+ actions.append("block")
103
133
  if overthinking_score >= thresholds["overthinking_score"]["block"]:
104
- return "block"
134
+ actions.append("block")
135
+
136
+ if actions:
137
+ return ["block"]
138
+
139
+ if clarification_sensitive:
140
+ if contamination_risk > thresholds["contamination_risk"]["reflect"]:
141
+ actions.append("reflect")
142
+ if overthinking_score > thresholds["overthinking_score"]["reflect"]:
143
+ actions.append("reflect")
144
+ if premature_fixer_score > thresholds["premature_fixer_score"]["reflect"]:
145
+ actions.append("reflect")
105
146
 
106
- if contamination_risk >= thresholds["contamination_risk"]["warn"]:
107
- return "reflect"
108
- if overthinking_score >= thresholds["overthinking_score"]["warn"]:
109
- return "reflect"
110
147
  if context_health <= thresholds["context_health"]["critical"]:
111
- return "reflect"
148
+ actions.append("reflect")
112
149
 
113
150
  if verification_status in ("error", "blocked"):
114
- return "warn"
151
+ actions.append("warn")
115
152
  if context_health <= thresholds["context_health"]["warn"]:
116
- return "warn"
153
+ actions.append("warn")
154
+
155
+ if actions:
156
+ deduped: list[str] = []
157
+ for action in actions:
158
+ if action not in deduped:
159
+ deduped.append(action)
160
+ return deduped
117
161
 
118
- return "continue"
162
+ return ["continue"]
119
163
 
120
164
 
121
165
  def _compute_context_health(pressure_ratio: float, journal_count: int) -> float:
@@ -22,6 +22,8 @@ _ROUTER_DIR = os.path.dirname(os.path.abspath(__file__))
22
22
  _OMG_ROOT = os.path.dirname(_ROUTER_DIR)
23
23
 
24
24
  _logger = logging.getLogger(__name__)
25
+ _ROUTING_MODE_DEFAULT = "normal"
26
+ _ROUTING_MODE_CLARIFICATION = "planning_read_only"
25
27
 
26
28
  # Import providers to trigger auto-registration in provider registry
27
29
  try:
@@ -32,18 +34,25 @@ except ImportError:
32
34
  pass
33
35
 
34
36
  from runtime.runtime_profile import resolve_parallel_workers
37
+ from runtime.runtime_contracts import write_run_state
38
+ from runtime.release_run_coordinator import resolve_current_run_id as resolve_coordinator_run_id
39
+ from runtime.context_engine import ContextEngine
40
+ from runtime.context_engine import render_profile_digest_text
41
+ from runtime.defense_state import DefenseState
35
42
  from runtime.equalizer import select_provider
36
43
  from runtime.router_executor import WorkerTask, execute_workers
37
44
  from runtime.router_critics import run_critics
38
45
  from runtime.router_selector import collect_cli_health as _selector_collect_cli_health
39
46
  from runtime.router_selector import infer_target as _selector_infer_target
40
47
  from runtime.router_selector import select_target
48
+ from runtime.session_health import compute_session_health
41
49
 
42
50
  @dataclass
43
51
  class TeamDispatchRequest:
44
52
  target: str # codex | gemini | ccg | auto
45
53
  problem: str
46
54
  context: str = ""
55
+ context_packet: dict[str, Any] | None = None
47
56
  files: list[str] | None = None
48
57
  expected_outcome: str = ""
49
58
 
@@ -192,6 +201,9 @@ def dispatch_team(req: TeamDispatchRequest) -> TeamDispatchResult:
192
201
  selected = select_target(req.problem, req.context)
193
202
  target = selected["target"]
194
203
 
204
+ clarification_status = _extract_clarification_status(req.context_packet)
205
+ clarification_required = bool(clarification_status.get("requires_clarification") is True)
206
+
195
207
  findings = [f"Target router selected: {target}", f"Problem: {req.problem}"]
196
208
  if req.files:
197
209
  findings.append(f"Focus files: {', '.join(req.files[:8])}")
@@ -243,12 +255,24 @@ def dispatch_team(req: TeamDispatchRequest) -> TeamDispatchResult:
243
255
  ]
244
256
  )
245
257
 
258
+ routing_mode = _ROUTING_MODE_DEFAULT
259
+ if clarification_required:
260
+ routing_mode = _ROUTING_MODE_CLARIFICATION
261
+ findings.append("Clarification unresolved; downgrading to read-only planning mode")
262
+ actions = [
263
+ "Collect missing details using read/search/review tools only",
264
+ "Draft a concrete execution plan without mutation-capable steps",
265
+ "Return a single clarification request before any edits or writes",
266
+ ]
267
+
246
268
  evidence = {
247
269
  "target": target,
248
270
  "equalizer": equalizer_decision,
249
271
  "generated_at": datetime.now(timezone.utc).isoformat(),
250
272
  "context_length": len(req.context or ""),
251
273
  "file_count": len(req.files or []),
274
+ "routing_mode": routing_mode,
275
+ "clarification_status": clarification_status,
252
276
  "cli_health": cli_health,
253
277
  "live_connection": all(h.get("live_connection") for h in cli_health.values()) if cli_health else True,
254
278
  }
@@ -335,19 +359,16 @@ def _read_working_memory(project_dir: str) -> str:
335
359
 
336
360
 
337
361
  def _read_profile_context(project_dir: str) -> str:
338
- """Read profile context from .omg/state/profile.yaml."""
339
362
  profile_path = os.path.join(project_dir, ".omg", "state", "profile.yaml")
340
363
  if not os.path.exists(profile_path):
341
364
  return ""
342
365
 
343
366
  try:
344
- with open(profile_path, "r", encoding="utf-8", errors="replace") as f:
345
- content = f.read()
346
- if len(content) > 300:
347
- content = content[:300] + "..."
348
- return content
367
+ return render_profile_digest_text(project_dir, max_chars=300)
349
368
  except (OSError, UnicodeDecodeError):
350
369
  return ""
370
+ except Exception:
371
+ return ""
351
372
 
352
373
 
353
374
  def _read_failure_history(project_dir: str) -> str:
@@ -507,9 +528,10 @@ def dispatch_to_model(agent_name: str, user_prompt: str, project_dir: str) -> di
507
528
  detect_available_models = getattr(agent_registry, "detect_available_models", lambda: {"claude": True})
508
529
  get_provider_with_equalizer = getattr(agent_registry, "get_provider_with_equalizer", None)
509
530
 
510
- agent = AGENT_REGISTRY.get(agent_name)
511
- if not agent:
531
+ agent_obj = AGENT_REGISTRY.get(agent_name)
532
+ if not isinstance(agent_obj, dict):
512
533
  return {"error": f"Unknown agent: {agent_name}", "fallback": "claude"}
534
+ agent = agent_obj
513
535
 
514
536
  available = detect_available_models()
515
537
  preferred = agent.get("preferred_model", "claude")
@@ -519,7 +541,8 @@ def dispatch_to_model(agent_name: str, user_prompt: str, project_dir: str) -> di
519
541
  project_dir=project_dir,
520
542
  agent_name=agent_name,
521
543
  )
522
- preferred = equalizer_info.get("preferred_model", preferred)
544
+ if isinstance(equalizer_info, dict):
545
+ preferred = str(equalizer_info.get("preferred_model", preferred))
523
546
  packaged = package_prompt(agent_name, user_prompt, project_dir)
524
547
 
525
548
  provider_name_map = {
@@ -692,11 +715,22 @@ def execute_crazy_mode(
692
715
  + "\n\nProvide a unified action plan with dependency ordering."
693
716
  )
694
717
 
695
- _ = run_critics(
718
+ run_id = resolve_coordinator_run_id(project_dir=project_dir)
719
+ context_packet = _build_router_context_packet(
720
+ project_dir=project_dir,
721
+ run_id=run_id,
722
+ summary=full_context,
723
+ files=files,
724
+ )
725
+
726
+ council_verdicts = run_critics(
696
727
  candidate={"output": synthesis_prompt},
697
- context_packet={"summary": full_context},
728
+ context_packet=context_packet,
698
729
  project_dir=project_dir,
699
730
  )
731
+ _persist_council_verdicts(project_dir, run_id, council_verdicts)
732
+ _update_post_council_state(project_dir=project_dir, run_id=run_id)
733
+ council_status = _council_status(council_verdicts)
700
734
 
701
735
  model_mix = {
702
736
  "gpt": [r.get("agent") for r in results if r.get("model") == "codex-cli"],
@@ -730,7 +764,9 @@ def execute_crazy_mode(
730
764
  f"GPT tracks: {len(model_mix['gpt'])}",
731
765
  f"Gemini tracks: {len(model_mix['gemini'])}",
732
766
  f"Claude tracks: {len(model_mix['claude'])}",
767
+ f"Council status: {council_status}",
733
768
  ],
769
+ "council_verdicts": council_verdicts,
734
770
  }
735
771
 
736
772
 
@@ -793,11 +829,22 @@ def execute_ccg_mode(
793
829
  + "\n\nProvide a unified action plan merging backend and frontend perspectives."
794
830
  )
795
831
 
796
- _ = run_critics(
832
+ run_id = resolve_coordinator_run_id(project_dir=project_dir)
833
+ context_packet = _build_router_context_packet(
834
+ project_dir=project_dir,
835
+ run_id=run_id,
836
+ summary=full_context,
837
+ files=files,
838
+ )
839
+
840
+ council_verdicts = run_critics(
797
841
  candidate={"output": synthesis_prompt},
798
- context_packet={"summary": full_context},
842
+ context_packet=context_packet,
799
843
  project_dir=project_dir,
800
844
  )
845
+ _persist_council_verdicts(project_dir, run_id, council_verdicts)
846
+ _update_post_council_state(project_dir=project_dir, run_id=run_id)
847
+ council_status = _council_status(council_verdicts)
801
848
 
802
849
  model_mix = {
803
850
  "gpt": [r.get("agent") for r in results if r.get("model") == "codex-cli"],
@@ -831,8 +878,104 @@ def execute_ccg_mode(
831
878
  f"GPT tracks: {len(model_mix['gpt'])}",
832
879
  f"Gemini tracks: {len(model_mix['gemini'])}",
833
880
  f"Claude tracks: {len(model_mix['claude'])}",
881
+ f"Council status: {council_status}",
834
882
  ],
883
+ "council_verdicts": council_verdicts,
884
+ }
885
+
886
+
887
+ def _build_router_context_packet(
888
+ *,
889
+ project_dir: str,
890
+ run_id: str | None,
891
+ summary: str,
892
+ files: list[str] | None,
893
+ ) -> dict[str, object]:
894
+ if run_id:
895
+ packet = ContextEngine(project_dir).build_packet(run_id=run_id, delta_only=True)
896
+ if summary and not str(packet.get("summary", "")).strip():
897
+ packet["summary"] = summary
898
+ if _requires_clarification(packet):
899
+ packet["routing_mode"] = _ROUTING_MODE_CLARIFICATION
900
+ return packet
901
+ return {
902
+ "summary": summary,
903
+ "artifact_pointers": [],
904
+ "clarification_status": {
905
+ "requires_clarification": False,
906
+ "intent_class": "",
907
+ "clarification_prompt": "",
908
+ "confidence": 0.0,
909
+ },
910
+ "routing_mode": _ROUTING_MODE_DEFAULT,
911
+ "files": list(files or []),
912
+ }
913
+
914
+
915
+ def _extract_clarification_status(context_packet: dict[str, Any] | None) -> dict[str, Any]:
916
+ if not isinstance(context_packet, dict):
917
+ return {
918
+ "requires_clarification": False,
919
+ "intent_class": "",
920
+ "clarification_prompt": "",
921
+ "confidence": 0.0,
922
+ }
923
+ status = context_packet.get("clarification_status")
924
+ if not isinstance(status, dict):
925
+ return {
926
+ "requires_clarification": False,
927
+ "intent_class": "",
928
+ "clarification_prompt": "",
929
+ "confidence": 0.0,
930
+ }
931
+ prompt = str(status.get("clarification_prompt", "")).strip().replace("\n", " ")
932
+ try:
933
+ confidence = float(status.get("confidence", 0.0))
934
+ except (TypeError, ValueError):
935
+ confidence = 0.0
936
+ return {
937
+ "requires_clarification": bool(status.get("requires_clarification") is True),
938
+ "intent_class": str(status.get("intent_class", "")).strip(),
939
+ "clarification_prompt": prompt,
940
+ "confidence": round(max(0.0, min(1.0, confidence)), 2),
941
+ }
942
+
943
+
944
+ def _requires_clarification(context_packet: dict[str, object]) -> bool:
945
+ status = _extract_clarification_status(cast(dict[str, Any], context_packet))
946
+ return bool(status.get("requires_clarification") is True)
947
+
948
+
949
+ def _persist_council_verdicts(project_dir: str, run_id: str | None, verdicts: dict[str, dict[str, Any]]) -> None:
950
+ if not run_id:
951
+ return
952
+
953
+ payload: dict[str, object] = {
954
+ "status": _council_status(verdicts),
955
+ "verification_status": _council_status(verdicts),
956
+ "verdicts": verdicts,
957
+ }
958
+ write_run_state(project_dir, "council_verdicts", run_id, payload)
959
+
960
+
961
+ def _update_post_council_state(*, project_dir: str, run_id: str | None) -> None:
962
+ DefenseState(project_dir).update()
963
+ compute_session_health(project_dir, run_id=run_id or "default")
964
+
965
+
966
+ def _council_status(verdicts: dict[str, dict[str, Any]]) -> str:
967
+ verdict_tokens = {
968
+ str(item.get("verdict", "")).strip().lower()
969
+ for item in verdicts.values()
970
+ if isinstance(item, dict)
835
971
  }
972
+ if "fail" in verdict_tokens:
973
+ return "blocked"
974
+ if "warn" in verdict_tokens:
975
+ return "running"
976
+ if "pass" in verdict_tokens:
977
+ return "ok"
978
+ return "pending"
836
979
 
837
980
 
838
981
  # =============================================================================
@@ -69,6 +69,79 @@ def verify_intent(project_dir: str, lock_id: str, results: dict[str, Any]) -> di
69
69
  return {"status": status, "lock_id": lock_id, "reasons": reasons}
70
70
 
71
71
 
72
+ def verify_lock(project_dir: str, run_id: str | None, lock_id: str | None = None) -> dict[str, Any]:
73
+ normalized_run_id = str(run_id or "").strip()
74
+ normalized_lock_id = str(lock_id or "").strip()
75
+
76
+ if normalized_lock_id:
77
+ payload = _load_lock_payload_from_project(project_dir, normalized_lock_id)
78
+ if payload is None:
79
+ return {
80
+ "status": "missing_lock",
81
+ "reason": "no_active_test_intent_lock",
82
+ "run_id": normalized_run_id or None,
83
+ "lock_id": normalized_lock_id,
84
+ }
85
+
86
+ contract_check = _check_run_contract(payload, normalized_run_id)
87
+ if contract_check is not None:
88
+ return {
89
+ "status": "lock_contract_mismatch",
90
+ "reason": contract_check,
91
+ "run_id": normalized_run_id or None,
92
+ "lock_id": normalized_lock_id,
93
+ }
94
+
95
+ return {
96
+ "status": "ok",
97
+ "reason": "active_test_intent_lock",
98
+ "run_id": normalized_run_id or None,
99
+ "lock_id": normalized_lock_id,
100
+ }
101
+
102
+ if not normalized_run_id:
103
+ return {
104
+ "status": "missing_lock",
105
+ "reason": "no_active_test_intent_lock",
106
+ "run_id": None,
107
+ "lock_id": None,
108
+ }
109
+
110
+ lock_dir = Path(project_dir) / ".omg" / "state" / "test-intent-lock"
111
+ if not lock_dir.exists():
112
+ return {
113
+ "status": "missing_lock",
114
+ "reason": "no_active_test_intent_lock",
115
+ "run_id": normalized_run_id,
116
+ "lock_id": None,
117
+ }
118
+
119
+ for path in sorted(lock_dir.glob("*.json"), key=lambda candidate: candidate.stat().st_mtime, reverse=True):
120
+ payload = _load_lock_payload_from_path(path)
121
+ if payload is None:
122
+ continue
123
+ intent = payload.get("intent")
124
+ intent_run_id = ""
125
+ if isinstance(intent, dict):
126
+ intent_run_id = str(intent.get("run_id", "")).strip()
127
+ if intent_run_id != normalized_run_id:
128
+ continue
129
+ lock_id_candidate = str(payload.get("lock_id", "")).strip() or path.stem
130
+ return {
131
+ "status": "ok",
132
+ "reason": "active_test_intent_lock",
133
+ "run_id": normalized_run_id,
134
+ "lock_id": lock_id_candidate,
135
+ }
136
+
137
+ return {
138
+ "status": "missing_lock",
139
+ "reason": "no_active_test_intent_lock",
140
+ "run_id": normalized_run_id,
141
+ "lock_id": None,
142
+ }
143
+
144
+
72
145
  def evaluate_test_delta(delta: dict[str, Any]) -> dict[str, Any]:
73
146
  override = delta.get("override")
74
147
  waiver_artifact = delta.get("waiver_artifact")
@@ -244,6 +317,35 @@ def _load_lock_payload(lock_id: str) -> dict[str, Any] | None:
244
317
  return payload
245
318
 
246
319
 
320
+ def _load_lock_payload_from_project(project_dir: str, lock_id: str) -> dict[str, Any] | None:
321
+ lock_path = Path(project_dir) / ".omg" / "state" / "test-intent-lock" / f"{lock_id}.json"
322
+ return _load_lock_payload_from_path(lock_path)
323
+
324
+
325
+ def _load_lock_payload_from_path(lock_path: Path) -> dict[str, Any] | None:
326
+ try:
327
+ payload = json.loads(lock_path.read_text(encoding="utf-8"))
328
+ except (OSError, json.JSONDecodeError):
329
+ return None
330
+ if not isinstance(payload, dict):
331
+ return None
332
+ return payload
333
+
334
+
335
+ def _check_run_contract(payload: dict[str, Any], run_id: str) -> str | None:
336
+ if not run_id:
337
+ return None
338
+ intent = payload.get("intent")
339
+ if not isinstance(intent, dict):
340
+ return "run_id_mismatch"
341
+ intent_run_id = str(intent.get("run_id", "")).strip()
342
+ if not intent_run_id:
343
+ return "run_id_mismatch"
344
+ if intent_run_id != run_id:
345
+ return "run_id_mismatch"
346
+ return None
347
+
348
+
247
349
  def _evaluate_locked_contract(
248
350
  lock_payload: dict[str, Any],
249
351
  selectors: list[str],