@trac3er/oh-my-god 2.0.5 → 2.0.8

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 (660) hide show
  1. package/.agents/skills/omg/AGENTS.fragment.md +57 -4
  2. package/.agents/skills/omg/claim-judge/SKILL.md +11 -0
  3. package/.agents/skills/omg/claim-judge/openai.yaml +13 -0
  4. package/.agents/skills/omg/codex-rules.md +33 -0
  5. package/.agents/skills/omg/plan-council/SKILL.md +11 -0
  6. package/.agents/skills/omg/plan-council/openai.yaml +12 -0
  7. package/.agents/skills/omg/proof-gate/SKILL.md +11 -0
  8. package/.agents/skills/omg/proof-gate/openai.yaml +13 -0
  9. package/.agents/skills/omg/test-intent-lock/SKILL.md +11 -0
  10. package/.agents/skills/omg/test-intent-lock/openai.yaml +13 -0
  11. package/.claude-plugin/marketplace.json +5 -5
  12. package/.claude-plugin/plugin.json +1 -1
  13. package/.claude-plugin/scripts/uninstall.sh +1 -1
  14. package/.mcp.json +0 -22
  15. package/CHANGELOG.md +20 -0
  16. package/OMG-setup.sh +64 -14
  17. package/OMG_COMPAT_CONTRACT.md +8 -1
  18. package/README.md +9 -7
  19. package/agents/omg-security-auditor.md +1 -1
  20. package/artifacts/release/.agents/skills/omg/AGENTS.fragment.md +58 -0
  21. package/artifacts/release/.agents/skills/omg/algorithms/SKILL.md +11 -0
  22. package/artifacts/release/.agents/skills/omg/algorithms/openai.yaml +11 -0
  23. package/artifacts/release/.agents/skills/omg/api-twin/SKILL.md +11 -0
  24. package/artifacts/release/.agents/skills/omg/api-twin/openai.yaml +12 -0
  25. package/artifacts/release/.agents/skills/omg/claim-judge/SKILL.md +11 -0
  26. package/artifacts/release/.agents/skills/omg/claim-judge/openai.yaml +13 -0
  27. package/artifacts/release/.agents/skills/omg/codex-mcp.toml +4 -0
  28. package/artifacts/release/.agents/skills/omg/codex-rules.md +33 -0
  29. package/artifacts/release/.agents/skills/omg/control-plane/SKILL.md +11 -0
  30. package/artifacts/release/.agents/skills/omg/control-plane/openai.yaml +14 -0
  31. package/artifacts/release/.agents/skills/omg/data-lineage/SKILL.md +11 -0
  32. package/artifacts/release/.agents/skills/omg/data-lineage/openai.yaml +12 -0
  33. package/artifacts/release/.agents/skills/omg/delta-classifier/SKILL.md +11 -0
  34. package/artifacts/release/.agents/skills/omg/delta-classifier/openai.yaml +12 -0
  35. package/artifacts/release/.agents/skills/omg/eval-gate/SKILL.md +11 -0
  36. package/artifacts/release/.agents/skills/omg/eval-gate/openai.yaml +12 -0
  37. package/artifacts/release/.agents/skills/omg/health/SKILL.md +11 -0
  38. package/artifacts/release/.agents/skills/omg/health/openai.yaml +11 -0
  39. package/artifacts/release/.agents/skills/omg/hook-governor/SKILL.md +11 -0
  40. package/artifacts/release/.agents/skills/omg/hook-governor/openai.yaml +11 -0
  41. package/artifacts/release/.agents/skills/omg/incident-replay/SKILL.md +11 -0
  42. package/artifacts/release/.agents/skills/omg/incident-replay/openai.yaml +12 -0
  43. package/artifacts/release/.agents/skills/omg/lsp-pack/SKILL.md +11 -0
  44. package/artifacts/release/.agents/skills/omg/lsp-pack/openai.yaml +11 -0
  45. package/artifacts/release/.agents/skills/omg/mcp-fabric/SKILL.md +11 -0
  46. package/artifacts/release/.agents/skills/omg/mcp-fabric/openai.yaml +13 -0
  47. package/artifacts/release/.agents/skills/omg/plan-council/SKILL.md +11 -0
  48. package/artifacts/release/.agents/skills/omg/plan-council/openai.yaml +12 -0
  49. package/artifacts/release/.agents/skills/omg/preflight/SKILL.md +11 -0
  50. package/artifacts/release/.agents/skills/omg/preflight/openai.yaml +12 -0
  51. package/artifacts/release/.agents/skills/omg/proof-gate/SKILL.md +11 -0
  52. package/artifacts/release/.agents/skills/omg/proof-gate/openai.yaml +13 -0
  53. package/artifacts/release/.agents/skills/omg/remote-supervisor/SKILL.md +11 -0
  54. package/artifacts/release/.agents/skills/omg/remote-supervisor/openai.yaml +12 -0
  55. package/artifacts/release/.agents/skills/omg/robotics/SKILL.md +11 -0
  56. package/artifacts/release/.agents/skills/omg/robotics/openai.yaml +11 -0
  57. package/artifacts/release/.agents/skills/omg/secure-worktree-pipeline/SKILL.md +11 -0
  58. package/artifacts/release/.agents/skills/omg/secure-worktree-pipeline/openai.yaml +12 -0
  59. package/artifacts/release/.agents/skills/omg/security-check/SKILL.md +11 -0
  60. package/artifacts/release/.agents/skills/omg/security-check/openai.yaml +13 -0
  61. package/artifacts/release/.agents/skills/omg/test-intent-lock/SKILL.md +11 -0
  62. package/artifacts/release/.agents/skills/omg/test-intent-lock/openai.yaml +13 -0
  63. package/artifacts/release/.agents/skills/omg/tracebank/SKILL.md +11 -0
  64. package/artifacts/release/.agents/skills/omg/tracebank/openai.yaml +12 -0
  65. package/artifacts/release/.agents/skills/omg/vision/SKILL.md +11 -0
  66. package/artifacts/release/.agents/skills/omg/vision/openai.yaml +11 -0
  67. package/artifacts/release/.claude-plugin/marketplace.json +36 -0
  68. package/artifacts/release/.claude-plugin/plugin.json +23 -0
  69. package/artifacts/release/.mcp.json +18 -0
  70. package/artifacts/release/OMG_COMPAT_CONTRACT.md +99 -0
  71. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/AGENTS.fragment.md +58 -0
  72. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/algorithms/SKILL.md +11 -0
  73. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/algorithms/openai.yaml +11 -0
  74. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/api-twin/SKILL.md +11 -0
  75. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/api-twin/openai.yaml +12 -0
  76. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/claim-judge/SKILL.md +11 -0
  77. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/claim-judge/openai.yaml +13 -0
  78. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/codex-mcp.toml +4 -0
  79. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/codex-rules.md +33 -0
  80. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/control-plane/SKILL.md +11 -0
  81. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/control-plane/openai.yaml +14 -0
  82. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/data-lineage/SKILL.md +11 -0
  83. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/data-lineage/openai.yaml +12 -0
  84. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/delta-classifier/SKILL.md +11 -0
  85. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/delta-classifier/openai.yaml +12 -0
  86. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/eval-gate/SKILL.md +11 -0
  87. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/eval-gate/openai.yaml +12 -0
  88. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/health/SKILL.md +11 -0
  89. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/health/openai.yaml +11 -0
  90. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/hook-governor/SKILL.md +11 -0
  91. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/hook-governor/openai.yaml +11 -0
  92. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/incident-replay/SKILL.md +11 -0
  93. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/incident-replay/openai.yaml +12 -0
  94. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/lsp-pack/SKILL.md +11 -0
  95. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/lsp-pack/openai.yaml +11 -0
  96. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/mcp-fabric/SKILL.md +11 -0
  97. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/mcp-fabric/openai.yaml +13 -0
  98. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/plan-council/SKILL.md +11 -0
  99. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/plan-council/openai.yaml +12 -0
  100. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/preflight/SKILL.md +11 -0
  101. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/preflight/openai.yaml +12 -0
  102. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/proof-gate/SKILL.md +11 -0
  103. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/proof-gate/openai.yaml +13 -0
  104. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/remote-supervisor/SKILL.md +11 -0
  105. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/remote-supervisor/openai.yaml +12 -0
  106. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/robotics/SKILL.md +11 -0
  107. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/robotics/openai.yaml +11 -0
  108. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/secure-worktree-pipeline/SKILL.md +11 -0
  109. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/secure-worktree-pipeline/openai.yaml +12 -0
  110. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/security-check/SKILL.md +11 -0
  111. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/security-check/openai.yaml +13 -0
  112. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/test-intent-lock/SKILL.md +11 -0
  113. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/test-intent-lock/openai.yaml +13 -0
  114. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/tracebank/SKILL.md +11 -0
  115. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/tracebank/openai.yaml +12 -0
  116. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/vision/SKILL.md +11 -0
  117. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/vision/openai.yaml +11 -0
  118. package/artifacts/release/dist/enterprise/bundle/.claude-plugin/marketplace.json +36 -0
  119. package/artifacts/release/dist/enterprise/bundle/.claude-plugin/plugin.json +23 -0
  120. package/artifacts/release/dist/enterprise/bundle/.mcp.json +18 -0
  121. package/artifacts/release/dist/enterprise/bundle/OMG_COMPAT_CONTRACT.md +99 -0
  122. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/commands/OMG:code-review.md +114 -0
  123. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/commands/OMG:deep-plan.md +266 -0
  124. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/commands/OMG:handoff.md +115 -0
  125. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/commands/OMG:learn.md +110 -0
  126. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/commands/OMG:maintainer.md +31 -0
  127. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/commands/OMG:ralph-start.md +43 -0
  128. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/commands/OMG:ralph-stop.md +23 -0
  129. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/commands/OMG:security-review.md +16 -0
  130. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/commands/OMG:sequential-thinking.md +20 -0
  131. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/commands/OMG:ship.md +46 -0
  132. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/plugin.json +87 -0
  133. package/artifacts/release/dist/enterprise/bundle/registry/bundles/algorithms.yaml +45 -0
  134. package/artifacts/release/dist/enterprise/bundle/registry/bundles/api-twin.yaml +48 -0
  135. package/artifacts/release/dist/enterprise/bundle/registry/bundles/claim-judge.yaml +49 -0
  136. package/artifacts/release/dist/enterprise/bundle/registry/bundles/control-plane.yaml +151 -0
  137. package/artifacts/release/dist/enterprise/bundle/registry/bundles/data-lineage.yaml +47 -0
  138. package/artifacts/release/dist/enterprise/bundle/registry/bundles/delta-classifier.yaml +47 -0
  139. package/artifacts/release/dist/enterprise/bundle/registry/bundles/eval-gate.yaml +47 -0
  140. package/artifacts/release/dist/enterprise/bundle/registry/bundles/health.yaml +45 -0
  141. package/artifacts/release/dist/enterprise/bundle/registry/bundles/hook-governor.yaml +97 -0
  142. package/artifacts/release/dist/enterprise/bundle/registry/bundles/incident-replay.yaml +47 -0
  143. package/artifacts/release/dist/enterprise/bundle/registry/bundles/lsp-pack.yaml +48 -0
  144. package/artifacts/release/dist/enterprise/bundle/registry/bundles/mcp-fabric.yaml +53 -0
  145. package/artifacts/release/dist/enterprise/bundle/registry/bundles/plan-council.yaml +51 -0
  146. package/artifacts/release/dist/enterprise/bundle/registry/bundles/preflight.yaml +48 -0
  147. package/artifacts/release/dist/enterprise/bundle/registry/bundles/proof-gate.yaml +49 -0
  148. package/artifacts/release/dist/enterprise/bundle/registry/bundles/remote-supervisor.yaml +49 -0
  149. package/artifacts/release/dist/enterprise/bundle/registry/bundles/robotics.yaml +45 -0
  150. package/artifacts/release/dist/enterprise/bundle/registry/bundles/secure-worktree-pipeline.yaml +54 -0
  151. package/artifacts/release/dist/enterprise/bundle/registry/bundles/security-check.yaml +50 -0
  152. package/artifacts/release/dist/enterprise/bundle/registry/bundles/test-intent-lock.yaml +49 -0
  153. package/artifacts/release/dist/enterprise/bundle/registry/bundles/tracebank.yaml +47 -0
  154. package/artifacts/release/dist/enterprise/bundle/registry/bundles/vision.yaml +45 -0
  155. package/artifacts/release/dist/enterprise/bundle/registry/omg-capability.schema.json +296 -0
  156. package/artifacts/release/dist/enterprise/bundle/settings.json +598 -0
  157. package/artifacts/release/dist/enterprise/manifest.json +351 -0
  158. package/artifacts/release/dist/public/bundle/.agents/skills/omg/AGENTS.fragment.md +58 -0
  159. package/artifacts/release/dist/public/bundle/.agents/skills/omg/algorithms/SKILL.md +11 -0
  160. package/artifacts/release/dist/public/bundle/.agents/skills/omg/algorithms/openai.yaml +11 -0
  161. package/artifacts/release/dist/public/bundle/.agents/skills/omg/api-twin/SKILL.md +11 -0
  162. package/artifacts/release/dist/public/bundle/.agents/skills/omg/api-twin/openai.yaml +12 -0
  163. package/artifacts/release/dist/public/bundle/.agents/skills/omg/claim-judge/SKILL.md +11 -0
  164. package/artifacts/release/dist/public/bundle/.agents/skills/omg/claim-judge/openai.yaml +13 -0
  165. package/artifacts/release/dist/public/bundle/.agents/skills/omg/codex-mcp.toml +4 -0
  166. package/artifacts/release/dist/public/bundle/.agents/skills/omg/codex-rules.md +33 -0
  167. package/artifacts/release/dist/public/bundle/.agents/skills/omg/control-plane/SKILL.md +11 -0
  168. package/artifacts/release/dist/public/bundle/.agents/skills/omg/control-plane/openai.yaml +14 -0
  169. package/artifacts/release/dist/public/bundle/.agents/skills/omg/data-lineage/SKILL.md +11 -0
  170. package/artifacts/release/dist/public/bundle/.agents/skills/omg/data-lineage/openai.yaml +12 -0
  171. package/artifacts/release/dist/public/bundle/.agents/skills/omg/delta-classifier/SKILL.md +11 -0
  172. package/artifacts/release/dist/public/bundle/.agents/skills/omg/delta-classifier/openai.yaml +12 -0
  173. package/artifacts/release/dist/public/bundle/.agents/skills/omg/eval-gate/SKILL.md +11 -0
  174. package/artifacts/release/dist/public/bundle/.agents/skills/omg/eval-gate/openai.yaml +12 -0
  175. package/artifacts/release/dist/public/bundle/.agents/skills/omg/health/SKILL.md +11 -0
  176. package/artifacts/release/dist/public/bundle/.agents/skills/omg/health/openai.yaml +11 -0
  177. package/artifacts/release/dist/public/bundle/.agents/skills/omg/hook-governor/SKILL.md +11 -0
  178. package/artifacts/release/dist/public/bundle/.agents/skills/omg/hook-governor/openai.yaml +11 -0
  179. package/artifacts/release/dist/public/bundle/.agents/skills/omg/incident-replay/SKILL.md +11 -0
  180. package/artifacts/release/dist/public/bundle/.agents/skills/omg/incident-replay/openai.yaml +12 -0
  181. package/artifacts/release/dist/public/bundle/.agents/skills/omg/lsp-pack/SKILL.md +11 -0
  182. package/artifacts/release/dist/public/bundle/.agents/skills/omg/lsp-pack/openai.yaml +11 -0
  183. package/artifacts/release/dist/public/bundle/.agents/skills/omg/mcp-fabric/SKILL.md +11 -0
  184. package/artifacts/release/dist/public/bundle/.agents/skills/omg/mcp-fabric/openai.yaml +13 -0
  185. package/artifacts/release/dist/public/bundle/.agents/skills/omg/plan-council/SKILL.md +11 -0
  186. package/artifacts/release/dist/public/bundle/.agents/skills/omg/plan-council/openai.yaml +12 -0
  187. package/artifacts/release/dist/public/bundle/.agents/skills/omg/preflight/SKILL.md +11 -0
  188. package/artifacts/release/dist/public/bundle/.agents/skills/omg/preflight/openai.yaml +12 -0
  189. package/artifacts/release/dist/public/bundle/.agents/skills/omg/proof-gate/SKILL.md +11 -0
  190. package/artifacts/release/dist/public/bundle/.agents/skills/omg/proof-gate/openai.yaml +13 -0
  191. package/artifacts/release/dist/public/bundle/.agents/skills/omg/remote-supervisor/SKILL.md +11 -0
  192. package/artifacts/release/dist/public/bundle/.agents/skills/omg/remote-supervisor/openai.yaml +12 -0
  193. package/artifacts/release/dist/public/bundle/.agents/skills/omg/robotics/SKILL.md +11 -0
  194. package/artifacts/release/dist/public/bundle/.agents/skills/omg/robotics/openai.yaml +11 -0
  195. package/artifacts/release/dist/public/bundle/.agents/skills/omg/secure-worktree-pipeline/SKILL.md +11 -0
  196. package/artifacts/release/dist/public/bundle/.agents/skills/omg/secure-worktree-pipeline/openai.yaml +12 -0
  197. package/artifacts/release/dist/public/bundle/.agents/skills/omg/security-check/SKILL.md +11 -0
  198. package/artifacts/release/dist/public/bundle/.agents/skills/omg/security-check/openai.yaml +13 -0
  199. package/artifacts/release/dist/public/bundle/.agents/skills/omg/test-intent-lock/SKILL.md +11 -0
  200. package/artifacts/release/dist/public/bundle/.agents/skills/omg/test-intent-lock/openai.yaml +13 -0
  201. package/artifacts/release/dist/public/bundle/.agents/skills/omg/tracebank/SKILL.md +11 -0
  202. package/artifacts/release/dist/public/bundle/.agents/skills/omg/tracebank/openai.yaml +12 -0
  203. package/artifacts/release/dist/public/bundle/.agents/skills/omg/vision/SKILL.md +11 -0
  204. package/artifacts/release/dist/public/bundle/.agents/skills/omg/vision/openai.yaml +11 -0
  205. package/artifacts/release/dist/public/bundle/.claude-plugin/marketplace.json +36 -0
  206. package/artifacts/release/dist/public/bundle/.claude-plugin/plugin.json +23 -0
  207. package/artifacts/release/dist/public/bundle/.mcp.json +18 -0
  208. package/artifacts/release/dist/public/bundle/OMG_COMPAT_CONTRACT.md +99 -0
  209. package/artifacts/release/dist/public/bundle/plugins/advanced/commands/OMG:code-review.md +114 -0
  210. package/artifacts/release/dist/public/bundle/plugins/advanced/commands/OMG:deep-plan.md +266 -0
  211. package/artifacts/release/dist/public/bundle/plugins/advanced/commands/OMG:handoff.md +115 -0
  212. package/artifacts/release/dist/public/bundle/plugins/advanced/commands/OMG:learn.md +110 -0
  213. package/artifacts/release/dist/public/bundle/plugins/advanced/commands/OMG:maintainer.md +31 -0
  214. package/artifacts/release/dist/public/bundle/plugins/advanced/commands/OMG:ralph-start.md +43 -0
  215. package/artifacts/release/dist/public/bundle/plugins/advanced/commands/OMG:ralph-stop.md +23 -0
  216. package/artifacts/release/dist/public/bundle/plugins/advanced/commands/OMG:security-review.md +16 -0
  217. package/artifacts/release/dist/public/bundle/plugins/advanced/commands/OMG:sequential-thinking.md +20 -0
  218. package/artifacts/release/dist/public/bundle/plugins/advanced/commands/OMG:ship.md +46 -0
  219. package/artifacts/release/dist/public/bundle/plugins/advanced/plugin.json +87 -0
  220. package/artifacts/release/dist/public/bundle/registry/bundles/algorithms.yaml +45 -0
  221. package/artifacts/release/dist/public/bundle/registry/bundles/api-twin.yaml +48 -0
  222. package/artifacts/release/dist/public/bundle/registry/bundles/claim-judge.yaml +49 -0
  223. package/artifacts/release/dist/public/bundle/registry/bundles/control-plane.yaml +151 -0
  224. package/artifacts/release/dist/public/bundle/registry/bundles/data-lineage.yaml +47 -0
  225. package/artifacts/release/dist/public/bundle/registry/bundles/delta-classifier.yaml +47 -0
  226. package/artifacts/release/dist/public/bundle/registry/bundles/eval-gate.yaml +47 -0
  227. package/artifacts/release/dist/public/bundle/registry/bundles/health.yaml +45 -0
  228. package/artifacts/release/dist/public/bundle/registry/bundles/hook-governor.yaml +97 -0
  229. package/artifacts/release/dist/public/bundle/registry/bundles/incident-replay.yaml +47 -0
  230. package/artifacts/release/dist/public/bundle/registry/bundles/lsp-pack.yaml +48 -0
  231. package/artifacts/release/dist/public/bundle/registry/bundles/mcp-fabric.yaml +53 -0
  232. package/artifacts/release/dist/public/bundle/registry/bundles/plan-council.yaml +51 -0
  233. package/artifacts/release/dist/public/bundle/registry/bundles/preflight.yaml +48 -0
  234. package/artifacts/release/dist/public/bundle/registry/bundles/proof-gate.yaml +49 -0
  235. package/artifacts/release/dist/public/bundle/registry/bundles/remote-supervisor.yaml +49 -0
  236. package/artifacts/release/dist/public/bundle/registry/bundles/robotics.yaml +45 -0
  237. package/artifacts/release/dist/public/bundle/registry/bundles/secure-worktree-pipeline.yaml +54 -0
  238. package/artifacts/release/dist/public/bundle/registry/bundles/security-check.yaml +50 -0
  239. package/artifacts/release/dist/public/bundle/registry/bundles/test-intent-lock.yaml +49 -0
  240. package/artifacts/release/dist/public/bundle/registry/bundles/tracebank.yaml +47 -0
  241. package/artifacts/release/dist/public/bundle/registry/bundles/vision.yaml +45 -0
  242. package/artifacts/release/dist/public/bundle/registry/omg-capability.schema.json +296 -0
  243. package/artifacts/release/dist/public/bundle/settings.json +598 -0
  244. package/artifacts/release/dist/public/manifest.json +351 -0
  245. package/artifacts/release/plugins/advanced/commands/OMG:code-review.md +114 -0
  246. package/artifacts/release/plugins/advanced/commands/OMG:deep-plan.md +266 -0
  247. package/artifacts/release/plugins/advanced/commands/OMG:handoff.md +115 -0
  248. package/artifacts/release/plugins/advanced/commands/OMG:learn.md +110 -0
  249. package/artifacts/release/plugins/advanced/commands/OMG:maintainer.md +31 -0
  250. package/artifacts/release/plugins/advanced/commands/OMG:ralph-start.md +43 -0
  251. package/artifacts/release/plugins/advanced/commands/OMG:ralph-stop.md +23 -0
  252. package/artifacts/release/plugins/advanced/commands/OMG:security-review.md +16 -0
  253. package/artifacts/release/plugins/advanced/commands/OMG:sequential-thinking.md +20 -0
  254. package/artifacts/release/plugins/advanced/commands/OMG:ship.md +46 -0
  255. package/artifacts/release/plugins/advanced/plugin.json +87 -0
  256. package/artifacts/release/registry/bundles/algorithms.yaml +45 -0
  257. package/artifacts/release/registry/bundles/api-twin.yaml +48 -0
  258. package/artifacts/release/registry/bundles/claim-judge.yaml +49 -0
  259. package/artifacts/release/registry/bundles/control-plane.yaml +151 -0
  260. package/artifacts/release/registry/bundles/data-lineage.yaml +47 -0
  261. package/artifacts/release/registry/bundles/delta-classifier.yaml +47 -0
  262. package/artifacts/release/registry/bundles/eval-gate.yaml +47 -0
  263. package/artifacts/release/registry/bundles/health.yaml +45 -0
  264. package/artifacts/release/registry/bundles/hook-governor.yaml +97 -0
  265. package/artifacts/release/registry/bundles/incident-replay.yaml +47 -0
  266. package/artifacts/release/registry/bundles/lsp-pack.yaml +48 -0
  267. package/artifacts/release/registry/bundles/mcp-fabric.yaml +53 -0
  268. package/artifacts/release/registry/bundles/plan-council.yaml +51 -0
  269. package/artifacts/release/registry/bundles/preflight.yaml +48 -0
  270. package/artifacts/release/registry/bundles/proof-gate.yaml +49 -0
  271. package/artifacts/release/registry/bundles/remote-supervisor.yaml +49 -0
  272. package/artifacts/release/registry/bundles/robotics.yaml +45 -0
  273. package/artifacts/release/registry/bundles/secure-worktree-pipeline.yaml +54 -0
  274. package/artifacts/release/registry/bundles/security-check.yaml +50 -0
  275. package/artifacts/release/registry/bundles/test-intent-lock.yaml +49 -0
  276. package/artifacts/release/registry/bundles/tracebank.yaml +47 -0
  277. package/artifacts/release/registry/bundles/vision.yaml +45 -0
  278. package/artifacts/release/registry/omg-capability.schema.json +296 -0
  279. package/artifacts/release/settings.json +598 -0
  280. package/build/lib/agents/__init__.py +1 -0
  281. package/build/lib/agents/designer.md +67 -0
  282. package/build/lib/agents/explore.md +60 -0
  283. package/build/lib/agents/model_roles.py +196 -0
  284. package/build/lib/agents/omg-api-builder.md +23 -0
  285. package/build/lib/agents/omg-architect-mode.md +41 -0
  286. package/build/lib/agents/omg-architect.md +13 -0
  287. package/build/lib/agents/omg-backend-engineer.md +41 -0
  288. package/build/lib/agents/omg-critic.md +16 -0
  289. package/build/lib/agents/omg-database-engineer.md +41 -0
  290. package/build/lib/agents/omg-escalation-router.md +17 -0
  291. package/build/lib/agents/omg-executor.md +12 -0
  292. package/build/lib/agents/omg-frontend-designer.md +41 -0
  293. package/build/lib/agents/omg-implement-mode.md +49 -0
  294. package/build/lib/agents/omg-infra-engineer.md +41 -0
  295. package/build/lib/agents/omg-qa-tester.md +16 -0
  296. package/build/lib/agents/omg-research-mode.md +41 -0
  297. package/build/lib/agents/omg-security-auditor.md +41 -0
  298. package/build/lib/agents/omg-testing-engineer.md +41 -0
  299. package/build/lib/agents/plan.md +80 -0
  300. package/build/lib/agents/quick_task.md +64 -0
  301. package/build/lib/agents/reviewer.md +83 -0
  302. package/build/lib/agents/task.md +71 -0
  303. package/build/lib/commands/OMG:ai-commit.md +113 -0
  304. package/build/lib/commands/OMG:api-twin.md +22 -0
  305. package/build/lib/commands/OMG:arch.md +313 -0
  306. package/build/lib/commands/OMG:ccg.md +22 -0
  307. package/build/lib/commands/OMG:compat.md +57 -0
  308. package/build/lib/commands/OMG:cost.md +181 -0
  309. package/build/lib/commands/OMG:crazy.md +125 -0
  310. package/build/lib/commands/OMG:create-agent.md +183 -0
  311. package/build/lib/commands/OMG:deps.md +248 -0
  312. package/build/lib/commands/OMG:doctor.md +37 -0
  313. package/build/lib/commands/OMG:domain-init.md +11 -0
  314. package/build/lib/commands/OMG:escalate.md +52 -0
  315. package/build/lib/commands/OMG:health-check.md +45 -0
  316. package/build/lib/commands/OMG:init.md +134 -0
  317. package/build/lib/commands/OMG:mode.md +44 -0
  318. package/build/lib/commands/OMG:preflight.md +26 -0
  319. package/build/lib/commands/OMG:project-init.md +11 -0
  320. package/build/lib/commands/OMG:ralph-start.md +43 -0
  321. package/build/lib/commands/OMG:ralph-stop.md +23 -0
  322. package/build/lib/commands/OMG:security-check.md +28 -0
  323. package/build/lib/commands/OMG:session-branch.md +85 -0
  324. package/build/lib/commands/OMG:session-fork.md +53 -0
  325. package/build/lib/commands/OMG:session-merge.md +134 -0
  326. package/build/lib/commands/OMG:setup.md +78 -0
  327. package/build/lib/commands/OMG:stats.md +225 -0
  328. package/build/lib/commands/OMG:teams.md +39 -0
  329. package/build/lib/commands/OMG:theme.md +44 -0
  330. package/build/lib/commands/__init__.py +1 -0
  331. package/build/lib/control_plane/__init__.py +2 -0
  332. package/build/lib/control_plane/openapi.yaml +260 -0
  333. package/build/lib/control_plane/server.py +147 -0
  334. package/build/lib/control_plane/service.py +222 -0
  335. package/build/lib/hooks/__init__.py +0 -0
  336. package/build/lib/hooks/_agent_registry.py +423 -0
  337. package/build/lib/hooks/_analytics.py +291 -0
  338. package/build/lib/hooks/_budget.py +31 -0
  339. package/build/lib/hooks/_common.py +569 -0
  340. package/build/lib/hooks/_compression_optimizer.py +119 -0
  341. package/build/lib/hooks/_cost_ledger.py +176 -0
  342. package/build/lib/hooks/_learnings.py +126 -0
  343. package/build/lib/hooks/_memory.py +103 -0
  344. package/build/lib/hooks/_protected_context.py +150 -0
  345. package/build/lib/hooks/_token_counter.py +221 -0
  346. package/build/lib/hooks/branch_manager.py +236 -0
  347. package/build/lib/hooks/budget_governor.py +232 -0
  348. package/build/lib/hooks/circuit-breaker.py +270 -0
  349. package/build/lib/hooks/compression_feedback.py +254 -0
  350. package/build/lib/hooks/config-guard.py +216 -0
  351. package/build/lib/hooks/context_pressure.py +53 -0
  352. package/build/lib/hooks/credential_store.py +1020 -0
  353. package/build/lib/hooks/fetch-rate-limits.py +212 -0
  354. package/build/lib/hooks/firewall.py +48 -0
  355. package/build/lib/hooks/hashline-formatter-bridge.py +224 -0
  356. package/build/lib/hooks/hashline-injector.py +273 -0
  357. package/build/lib/hooks/hashline-validator.py +216 -0
  358. package/build/lib/hooks/idle-detector.py +95 -0
  359. package/build/lib/hooks/intentgate-keyword-detector.py +188 -0
  360. package/build/lib/hooks/magic-keyword-router.py +195 -0
  361. package/build/lib/hooks/policy_engine.py +641 -0
  362. package/build/lib/hooks/post-tool-failure.py +19 -0
  363. package/build/lib/hooks/post-write.py +219 -0
  364. package/build/lib/hooks/post_write.py +46 -0
  365. package/build/lib/hooks/pre-compact.py +398 -0
  366. package/build/lib/hooks/pre-tool-inject.py +98 -0
  367. package/build/lib/hooks/prompt-enhancer.py +672 -0
  368. package/build/lib/hooks/quality-runner.py +191 -0
  369. package/build/lib/hooks/query.py +512 -0
  370. package/build/lib/hooks/secret-guard.py +61 -0
  371. package/build/lib/hooks/secret_audit.py +144 -0
  372. package/build/lib/hooks/security_validators.py +75 -0
  373. package/build/lib/hooks/session-end-capture.py +137 -0
  374. package/build/lib/hooks/session-start.py +277 -0
  375. package/build/lib/hooks/setup_wizard.py +646 -0
  376. package/build/lib/hooks/shadow_manager.py +344 -0
  377. package/build/lib/hooks/state_migration.py +225 -0
  378. package/build/lib/hooks/stop-gate.py +7 -0
  379. package/build/lib/hooks/stop_dispatcher.py +945 -0
  380. package/build/lib/hooks/test-validator.py +361 -0
  381. package/build/lib/hooks/test_generator_hook.py +123 -0
  382. package/build/lib/hooks/todo-state-tracker.py +114 -0
  383. package/build/lib/hooks/tool-ledger.py +149 -0
  384. package/build/lib/hooks/trust_review.py +585 -0
  385. package/build/lib/plugins/README.md +60 -0
  386. package/build/lib/plugins/__init__.py +1 -0
  387. package/build/lib/plugins/advanced/commands/OMG:code-review.md +114 -0
  388. package/build/lib/plugins/advanced/commands/OMG:deep-plan.md +266 -0
  389. package/build/lib/plugins/advanced/commands/OMG:handoff.md +115 -0
  390. package/build/lib/plugins/advanced/commands/OMG:learn.md +110 -0
  391. package/build/lib/plugins/advanced/commands/OMG:maintainer.md +31 -0
  392. package/build/lib/plugins/advanced/commands/OMG:ralph-start.md +43 -0
  393. package/build/lib/plugins/advanced/commands/OMG:ralph-stop.md +23 -0
  394. package/build/lib/plugins/advanced/commands/OMG:security-review.md +16 -0
  395. package/build/lib/plugins/advanced/commands/OMG:sequential-thinking.md +20 -0
  396. package/build/lib/plugins/advanced/commands/OMG:ship.md +46 -0
  397. package/build/lib/plugins/advanced/plugin.json +87 -0
  398. package/build/lib/plugins/core/plugin.json +145 -0
  399. package/build/lib/plugins/dephealth/__init__.py +0 -0
  400. package/build/lib/plugins/dephealth/cve_scanner.py +188 -0
  401. package/build/lib/plugins/dephealth/license_checker.py +135 -0
  402. package/build/lib/plugins/dephealth/manifest_detector.py +423 -0
  403. package/build/lib/plugins/dephealth/vuln_analyzer.py +169 -0
  404. package/build/lib/plugins/testgen/__init__.py +0 -0
  405. package/build/lib/plugins/testgen/codamosa_engine.py +402 -0
  406. package/build/lib/plugins/testgen/edge_case_synthesizer.py +184 -0
  407. package/build/lib/plugins/testgen/framework_detector.py +271 -0
  408. package/build/lib/plugins/testgen/skeleton_generator.py +219 -0
  409. package/build/lib/plugins/viz/__init__.py +0 -0
  410. package/build/lib/plugins/viz/ast_parser.py +139 -0
  411. package/build/lib/plugins/viz/diagram_generator.py +192 -0
  412. package/build/lib/plugins/viz/graph_builder.py +444 -0
  413. package/build/lib/plugins/viz/native_parsers.py +259 -0
  414. package/build/lib/plugins/viz/regex_parser.py +112 -0
  415. package/build/lib/registry/__init__.py +1 -0
  416. package/build/lib/registry/bundles/algorithms.yaml +45 -0
  417. package/build/lib/registry/bundles/api-twin.yaml +48 -0
  418. package/build/lib/registry/bundles/claim-judge.yaml +49 -0
  419. package/build/lib/registry/bundles/control-plane.yaml +151 -0
  420. package/build/lib/registry/bundles/data-lineage.yaml +47 -0
  421. package/build/lib/registry/bundles/delta-classifier.yaml +47 -0
  422. package/build/lib/registry/bundles/eval-gate.yaml +47 -0
  423. package/build/lib/registry/bundles/health.yaml +45 -0
  424. package/build/lib/registry/bundles/hook-governor.yaml +97 -0
  425. package/build/lib/registry/bundles/incident-replay.yaml +47 -0
  426. package/build/lib/registry/bundles/lsp-pack.yaml +48 -0
  427. package/build/lib/registry/bundles/mcp-fabric.yaml +53 -0
  428. package/build/lib/registry/bundles/plan-council.yaml +51 -0
  429. package/build/lib/registry/bundles/preflight.yaml +48 -0
  430. package/build/lib/registry/bundles/proof-gate.yaml +49 -0
  431. package/build/lib/registry/bundles/remote-supervisor.yaml +49 -0
  432. package/build/lib/registry/bundles/robotics.yaml +45 -0
  433. package/build/lib/registry/bundles/secure-worktree-pipeline.yaml +54 -0
  434. package/build/lib/registry/bundles/security-check.yaml +50 -0
  435. package/build/lib/registry/bundles/test-intent-lock.yaml +49 -0
  436. package/build/lib/registry/bundles/tracebank.yaml +47 -0
  437. package/build/lib/registry/bundles/vision.yaml +45 -0
  438. package/build/lib/registry/omg-capability.schema.json +296 -0
  439. package/build/lib/registry/verify_artifact.py +90 -0
  440. package/build/lib/runtime/__init__.py +32 -0
  441. package/build/lib/runtime/adapters/__init__.py +13 -0
  442. package/build/lib/runtime/adapters/claude.py +63 -0
  443. package/build/lib/runtime/adapters/gpt.py +56 -0
  444. package/build/lib/runtime/adapters/local.py +56 -0
  445. package/build/lib/runtime/adoption.py +212 -0
  446. package/build/lib/runtime/api_twin.py +450 -0
  447. package/build/lib/runtime/asset_loader.py +62 -0
  448. package/build/lib/runtime/business_workflow.py +234 -0
  449. package/build/lib/runtime/claim_judge.py +95 -0
  450. package/build/lib/runtime/cli_provider.py +85 -0
  451. package/build/lib/runtime/compat.py +1459 -0
  452. package/build/lib/runtime/contract_compiler.py +1989 -0
  453. package/build/lib/runtime/custom_agent_loader.py +366 -0
  454. package/build/lib/runtime/data_lineage.py +73 -0
  455. package/build/lib/runtime/delta_classifier.py +81 -0
  456. package/build/lib/runtime/dispatcher.py +47 -0
  457. package/build/lib/runtime/domain_packs.py +46 -0
  458. package/build/lib/runtime/ecosystem.py +371 -0
  459. package/build/lib/runtime/eval_gate.py +96 -0
  460. package/build/lib/runtime/guide_assert.py +45 -0
  461. package/build/lib/runtime/incident_replay.py +47 -0
  462. package/build/lib/runtime/legacy_compat.py +7 -0
  463. package/build/lib/runtime/mcp_config_writers.py +233 -0
  464. package/build/lib/runtime/mcp_lifecycle.py +175 -0
  465. package/build/lib/runtime/mcp_memory_server.py +135 -0
  466. package/build/lib/runtime/memory_parsers/__init__.py +0 -0
  467. package/build/lib/runtime/memory_parsers/chatgpt_parser.py +257 -0
  468. package/build/lib/runtime/memory_parsers/claude_import.py +107 -0
  469. package/build/lib/runtime/memory_parsers/export.py +97 -0
  470. package/build/lib/runtime/memory_parsers/gemini_import.py +91 -0
  471. package/build/lib/runtime/memory_parsers/kimi_import.py +91 -0
  472. package/build/lib/runtime/memory_store.py +215 -0
  473. package/build/lib/runtime/omc_compat.py +7 -0
  474. package/build/lib/runtime/omg_compat_contract_snapshot.json +916 -0
  475. package/build/lib/runtime/omg_contract_snapshot.json +916 -0
  476. package/build/lib/runtime/omg_mcp_server.py +212 -0
  477. package/build/lib/runtime/playwright_pack.py +169 -0
  478. package/build/lib/runtime/preflight.py +117 -0
  479. package/build/lib/runtime/proof_chain.py +228 -0
  480. package/build/lib/runtime/proof_gate.py +163 -0
  481. package/build/lib/runtime/providers/__init__.py +0 -0
  482. package/build/lib/runtime/providers/codex_provider.py +102 -0
  483. package/build/lib/runtime/providers/gemini_provider.py +109 -0
  484. package/build/lib/runtime/providers/kimi_provider.py +132 -0
  485. package/build/lib/runtime/remote_supervisor.py +64 -0
  486. package/build/lib/runtime/runtime_profile.py +61 -0
  487. package/build/lib/runtime/security_check.py +965 -0
  488. package/build/lib/runtime/subagent_dispatcher.py +469 -0
  489. package/build/lib/runtime/team_router.py +1167 -0
  490. package/build/lib/runtime/test_intent_lock.py +91 -0
  491. package/build/lib/runtime/tmux_session_manager.py +169 -0
  492. package/build/lib/runtime/tracebank.py +95 -0
  493. package/build/lib/runtime/untrusted_content.py +269 -0
  494. package/commands/OMG:doctor.md +37 -0
  495. package/commands/OMG:preflight.md +1 -1
  496. package/control_plane/openapi.yaml +33 -1
  497. package/control_plane/server.py +26 -2
  498. package/control_plane/service.py +37 -0
  499. package/dist/enterprise/bundle/.agents/skills/omg/AGENTS.fragment.md +57 -4
  500. package/dist/enterprise/bundle/.agents/skills/omg/claim-judge/SKILL.md +11 -0
  501. package/dist/enterprise/bundle/.agents/skills/omg/claim-judge/openai.yaml +13 -0
  502. package/dist/enterprise/bundle/.agents/skills/omg/codex-rules.md +33 -0
  503. package/dist/enterprise/bundle/.agents/skills/omg/plan-council/SKILL.md +11 -0
  504. package/dist/enterprise/bundle/.agents/skills/omg/plan-council/openai.yaml +12 -0
  505. package/dist/enterprise/bundle/.agents/skills/omg/proof-gate/SKILL.md +11 -0
  506. package/dist/enterprise/bundle/.agents/skills/omg/proof-gate/openai.yaml +13 -0
  507. package/dist/enterprise/bundle/.agents/skills/omg/test-intent-lock/SKILL.md +11 -0
  508. package/dist/enterprise/bundle/.agents/skills/omg/test-intent-lock/openai.yaml +13 -0
  509. package/dist/enterprise/bundle/.claude-plugin/marketplace.json +5 -5
  510. package/dist/enterprise/bundle/.claude-plugin/plugin.json +1 -1
  511. package/dist/enterprise/bundle/.mcp.json +0 -22
  512. package/dist/enterprise/bundle/OMG_COMPAT_CONTRACT.md +8 -1
  513. package/dist/enterprise/bundle/plugins/advanced/commands/OMG:code-review.md +114 -0
  514. package/dist/enterprise/bundle/plugins/advanced/commands/OMG:deep-plan.md +266 -0
  515. package/dist/enterprise/bundle/plugins/advanced/commands/OMG:handoff.md +115 -0
  516. package/dist/enterprise/bundle/plugins/advanced/commands/OMG:learn.md +110 -0
  517. package/dist/enterprise/bundle/plugins/advanced/commands/OMG:maintainer.md +31 -0
  518. package/dist/enterprise/bundle/plugins/advanced/commands/OMG:ralph-start.md +43 -0
  519. package/dist/enterprise/bundle/plugins/advanced/commands/OMG:ralph-stop.md +23 -0
  520. package/dist/enterprise/bundle/plugins/advanced/commands/OMG:security-review.md +16 -0
  521. package/dist/enterprise/bundle/plugins/advanced/commands/OMG:sequential-thinking.md +20 -0
  522. package/dist/enterprise/bundle/plugins/advanced/commands/OMG:ship.md +46 -0
  523. package/dist/enterprise/bundle/plugins/advanced/plugin.json +87 -0
  524. package/dist/enterprise/bundle/registry/bundles/algorithms.yaml +1 -1
  525. package/dist/enterprise/bundle/registry/bundles/api-twin.yaml +1 -1
  526. package/dist/enterprise/bundle/registry/bundles/claim-judge.yaml +49 -0
  527. package/dist/enterprise/bundle/registry/bundles/control-plane.yaml +91 -1
  528. package/dist/enterprise/bundle/registry/bundles/data-lineage.yaml +1 -1
  529. package/dist/enterprise/bundle/registry/bundles/delta-classifier.yaml +1 -1
  530. package/dist/enterprise/bundle/registry/bundles/eval-gate.yaml +1 -1
  531. package/dist/enterprise/bundle/registry/bundles/health.yaml +1 -1
  532. package/dist/enterprise/bundle/registry/bundles/hook-governor.yaml +1 -1
  533. package/dist/enterprise/bundle/registry/bundles/incident-replay.yaml +1 -1
  534. package/dist/enterprise/bundle/registry/bundles/lsp-pack.yaml +1 -1
  535. package/dist/enterprise/bundle/registry/bundles/mcp-fabric.yaml +1 -1
  536. package/dist/enterprise/bundle/registry/bundles/plan-council.yaml +51 -0
  537. package/dist/enterprise/bundle/registry/bundles/preflight.yaml +1 -1
  538. package/dist/enterprise/bundle/registry/bundles/proof-gate.yaml +49 -0
  539. package/dist/enterprise/bundle/registry/bundles/remote-supervisor.yaml +1 -1
  540. package/dist/enterprise/bundle/registry/bundles/robotics.yaml +1 -1
  541. package/dist/enterprise/bundle/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  542. package/dist/enterprise/bundle/registry/bundles/security-check.yaml +1 -1
  543. package/dist/enterprise/bundle/registry/bundles/test-intent-lock.yaml +49 -0
  544. package/dist/enterprise/bundle/registry/bundles/tracebank.yaml +1 -1
  545. package/dist/enterprise/bundle/registry/bundles/vision.yaml +1 -1
  546. package/dist/enterprise/bundle/registry/omg-capability.schema.json +217 -1
  547. package/dist/enterprise/bundle/settings.json +223 -6
  548. package/dist/enterprise/manifest.json +122 -26
  549. package/dist/public/bundle/.agents/skills/omg/AGENTS.fragment.md +57 -4
  550. package/dist/public/bundle/.agents/skills/omg/claim-judge/SKILL.md +11 -0
  551. package/dist/public/bundle/.agents/skills/omg/claim-judge/openai.yaml +13 -0
  552. package/dist/public/bundle/.agents/skills/omg/codex-rules.md +33 -0
  553. package/dist/public/bundle/.agents/skills/omg/plan-council/SKILL.md +11 -0
  554. package/dist/public/bundle/.agents/skills/omg/plan-council/openai.yaml +12 -0
  555. package/dist/public/bundle/.agents/skills/omg/proof-gate/SKILL.md +11 -0
  556. package/dist/public/bundle/.agents/skills/omg/proof-gate/openai.yaml +13 -0
  557. package/dist/public/bundle/.agents/skills/omg/test-intent-lock/SKILL.md +11 -0
  558. package/dist/public/bundle/.agents/skills/omg/test-intent-lock/openai.yaml +13 -0
  559. package/dist/public/bundle/.claude-plugin/marketplace.json +5 -5
  560. package/dist/public/bundle/.claude-plugin/plugin.json +1 -1
  561. package/dist/public/bundle/.mcp.json +0 -22
  562. package/dist/public/bundle/OMG_COMPAT_CONTRACT.md +8 -1
  563. package/dist/public/bundle/plugins/advanced/commands/OMG:code-review.md +114 -0
  564. package/dist/public/bundle/plugins/advanced/commands/OMG:deep-plan.md +266 -0
  565. package/dist/public/bundle/plugins/advanced/commands/OMG:handoff.md +115 -0
  566. package/dist/public/bundle/plugins/advanced/commands/OMG:learn.md +110 -0
  567. package/dist/public/bundle/plugins/advanced/commands/OMG:maintainer.md +31 -0
  568. package/dist/public/bundle/plugins/advanced/commands/OMG:ralph-start.md +43 -0
  569. package/dist/public/bundle/plugins/advanced/commands/OMG:ralph-stop.md +23 -0
  570. package/dist/public/bundle/plugins/advanced/commands/OMG:security-review.md +16 -0
  571. package/dist/public/bundle/plugins/advanced/commands/OMG:sequential-thinking.md +20 -0
  572. package/dist/public/bundle/plugins/advanced/commands/OMG:ship.md +46 -0
  573. package/dist/public/bundle/plugins/advanced/plugin.json +87 -0
  574. package/dist/public/bundle/registry/bundles/algorithms.yaml +1 -1
  575. package/dist/public/bundle/registry/bundles/api-twin.yaml +1 -1
  576. package/dist/public/bundle/registry/bundles/claim-judge.yaml +49 -0
  577. package/dist/public/bundle/registry/bundles/control-plane.yaml +91 -1
  578. package/dist/public/bundle/registry/bundles/data-lineage.yaml +1 -1
  579. package/dist/public/bundle/registry/bundles/delta-classifier.yaml +1 -1
  580. package/dist/public/bundle/registry/bundles/eval-gate.yaml +1 -1
  581. package/dist/public/bundle/registry/bundles/health.yaml +1 -1
  582. package/dist/public/bundle/registry/bundles/hook-governor.yaml +1 -1
  583. package/dist/public/bundle/registry/bundles/incident-replay.yaml +1 -1
  584. package/dist/public/bundle/registry/bundles/lsp-pack.yaml +1 -1
  585. package/dist/public/bundle/registry/bundles/mcp-fabric.yaml +1 -1
  586. package/dist/public/bundle/registry/bundles/plan-council.yaml +51 -0
  587. package/dist/public/bundle/registry/bundles/preflight.yaml +1 -1
  588. package/dist/public/bundle/registry/bundles/proof-gate.yaml +49 -0
  589. package/dist/public/bundle/registry/bundles/remote-supervisor.yaml +1 -1
  590. package/dist/public/bundle/registry/bundles/robotics.yaml +1 -1
  591. package/dist/public/bundle/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  592. package/dist/public/bundle/registry/bundles/security-check.yaml +1 -1
  593. package/dist/public/bundle/registry/bundles/test-intent-lock.yaml +49 -0
  594. package/dist/public/bundle/registry/bundles/tracebank.yaml +1 -1
  595. package/dist/public/bundle/registry/bundles/vision.yaml +1 -1
  596. package/dist/public/bundle/registry/omg-capability.schema.json +217 -1
  597. package/dist/public/bundle/settings.json +222 -3
  598. package/dist/public/manifest.json +122 -26
  599. package/docs/proof.md +22 -12
  600. package/docs/release-checklist.md +2 -0
  601. package/hooks/policy_engine.py +122 -17
  602. package/hooks/setup_wizard.py +52 -12
  603. package/hooks/shadow_manager.py +21 -0
  604. package/package.json +2 -2
  605. package/plugins/README.md +5 -1
  606. package/plugins/advanced/commands/OMG:deep-plan.md +51 -6
  607. package/plugins/advanced/commands/OMG:ship.md +1 -1
  608. package/plugins/advanced/plugin.json +1 -10
  609. package/plugins/core/plugin.json +7 -1
  610. package/pyproject.toml +6 -2
  611. package/registry/bundles/algorithms.yaml +1 -1
  612. package/registry/bundles/api-twin.yaml +1 -1
  613. package/registry/bundles/claim-judge.yaml +49 -0
  614. package/registry/bundles/control-plane.yaml +91 -1
  615. package/registry/bundles/data-lineage.yaml +1 -1
  616. package/registry/bundles/delta-classifier.yaml +1 -1
  617. package/registry/bundles/eval-gate.yaml +1 -1
  618. package/registry/bundles/health.yaml +1 -1
  619. package/registry/bundles/hook-governor.yaml +1 -1
  620. package/registry/bundles/incident-replay.yaml +1 -1
  621. package/registry/bundles/lsp-pack.yaml +1 -1
  622. package/registry/bundles/mcp-fabric.yaml +1 -1
  623. package/registry/bundles/plan-council.yaml +51 -0
  624. package/registry/bundles/preflight.yaml +1 -1
  625. package/registry/bundles/proof-gate.yaml +49 -0
  626. package/registry/bundles/remote-supervisor.yaml +1 -1
  627. package/registry/bundles/robotics.yaml +1 -1
  628. package/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  629. package/registry/bundles/security-check.yaml +1 -1
  630. package/registry/bundles/test-intent-lock.yaml +49 -0
  631. package/registry/bundles/tracebank.yaml +1 -1
  632. package/registry/bundles/vision.yaml +1 -1
  633. package/registry/omg-capability.schema.json +217 -1
  634. package/runtime/adoption.py +1 -1
  635. package/runtime/api_twin.py +279 -8
  636. package/runtime/business_workflow.py +14 -0
  637. package/runtime/claim_judge.py +95 -0
  638. package/runtime/compat.py +139 -0
  639. package/runtime/contract_compiler.py +1170 -28
  640. package/runtime/ecosystem.py +1 -1
  641. package/runtime/eval_gate.py +48 -2
  642. package/runtime/mcp_config_writers.py +12 -0
  643. package/runtime/mcp_lifecycle.py +31 -9
  644. package/runtime/mcp_memory_server.py +1 -1
  645. package/runtime/omg_compat_contract_snapshot.json +2 -2
  646. package/runtime/omg_contract_snapshot.json +2 -2
  647. package/runtime/omg_mcp_server.py +13 -8
  648. package/runtime/playwright_pack.py +169 -0
  649. package/runtime/preflight.py +45 -1
  650. package/runtime/proof_chain.py +228 -0
  651. package/runtime/proof_gate.py +163 -0
  652. package/runtime/security_check.py +523 -22
  653. package/runtime/team_router.py +6 -6
  654. package/runtime/test_intent_lock.py +91 -0
  655. package/runtime/tracebank.py +43 -1
  656. package/runtime/untrusted_content.py +172 -5
  657. package/scripts/check-omg-public-ready.py +77 -0
  658. package/scripts/omg.py +28 -9
  659. package/scripts/verify-standalone.sh +7 -0
  660. package/settings.json +223 -6
@@ -0,0 +1,1989 @@
1
+ """Canonical OMG contract registry, compiler, and release-readiness checks."""
2
+ from __future__ import annotations
3
+
4
+ import hashlib
5
+ import asyncio
6
+ import importlib
7
+ import json
8
+ import os
9
+ from pathlib import Path
10
+ import re
11
+ import shutil
12
+ import subprocess
13
+ import sys
14
+ import tempfile
15
+ from typing import Any, Iterable
16
+ from urllib.parse import urlparse
17
+ import zipfile
18
+
19
+ import yaml
20
+
21
+ from runtime.asset_loader import resolve_asset, resolve_assets
22
+ from runtime.adoption import (
23
+ CANONICAL_MARKETPLACE_ID,
24
+ CANONICAL_PACKAGE_NAME,
25
+ CANONICAL_PLUGIN_ID,
26
+ CANONICAL_REPO_URL,
27
+ CANONICAL_VERSION,
28
+ )
29
+
30
+
31
+ CONTRACT_DOC_PATH = Path("OMG_COMPAT_CONTRACT.md")
32
+ SCHEMA_PATH = Path("registry") / "omg-capability.schema.json"
33
+ BUNDLES_DIR = Path("registry") / "bundles"
34
+ SUPPORTED_HOSTS = ("claude", "codex")
35
+ SUPPORTED_CHANNELS = ("public", "enterprise")
36
+ DEFAULT_REQUIRED_BUNDLES = (
37
+ "control-plane",
38
+ "plan-council",
39
+ "claim-judge",
40
+ "test-intent-lock",
41
+ "proof-gate",
42
+ "hook-governor",
43
+ "mcp-fabric",
44
+ "lsp-pack",
45
+ "secure-worktree-pipeline",
46
+ "security-check",
47
+ "api-twin",
48
+ "preflight",
49
+ "robotics",
50
+ "vision",
51
+ "algorithms",
52
+ "health",
53
+ "tracebank",
54
+ "eval-gate",
55
+ "delta-classifier",
56
+ "incident-replay",
57
+ "data-lineage",
58
+ "remote-supervisor",
59
+ )
60
+ TRUTH_COUNCIL_BUNDLES = (
61
+ "plan-council",
62
+ "claim-judge",
63
+ "test-intent-lock",
64
+ "proof-gate",
65
+ )
66
+ REQUIRED_ADVANCED_PLUGIN_ARTIFACTS = (
67
+ "bundle/plugins/advanced/plugin.json",
68
+ "bundle/plugins/advanced/commands/OMG:deep-plan.md",
69
+ "bundle/plugins/advanced/commands/OMG:security-review.md",
70
+ )
71
+ REQUIRED_DOC_TOKENS = (
72
+ "execution_contract",
73
+ "tool_policy",
74
+ "invocation_policy",
75
+ "host_compilation_rules",
76
+ "local_supervisor",
77
+ )
78
+ REQUIRED_BUNDLE_FIELDS = (
79
+ "id",
80
+ "kind",
81
+ "version",
82
+ "title",
83
+ "description",
84
+ "hosts",
85
+ "assets",
86
+ "invocation_policy",
87
+ "tool_policy",
88
+ "lifecycle_hooks",
89
+ "mcp_contract",
90
+ "lsp_contract",
91
+ "evidence_outputs",
92
+ "execution_contract",
93
+ "channel_overrides",
94
+ )
95
+ REQUIRED_POLICY_MODEL_FIELDS = (
96
+ "trust_tiers",
97
+ "tool_policies",
98
+ "protected_paths",
99
+ "evidence_contract",
100
+ "host_rules",
101
+ )
102
+ REQUIRED_CLAUDE_HOOK_EVENTS = (
103
+ "UserPromptSubmit",
104
+ "PreToolUse",
105
+ "PostToolUse",
106
+ "PostToolUseFailure",
107
+ "InstructionsLoaded",
108
+ )
109
+ REQUIRED_CLAUDE_SUBAGENT_NAMES = ("security-reviewer", "release-manager")
110
+ REQUIRED_CODEX_AGENTS_SECTIONS = (
111
+ "## Build & Test",
112
+ "## Protected Paths",
113
+ "## Evidence Contract",
114
+ "## Required Skills",
115
+ "## Web Search Policy",
116
+ "## Approval Constraints",
117
+ )
118
+ REQUIRED_CODEX_OUTPUTS = (
119
+ "AGENTS.fragment.md",
120
+ "codex-rules.md",
121
+ "codex-mcp.toml",
122
+ )
123
+
124
+
125
+ def _ensure_list(
126
+ *,
127
+ bundle_id: str,
128
+ path: str,
129
+ value: Any,
130
+ errors: list[str],
131
+ min_items: int = 1,
132
+ ) -> list[Any]:
133
+ if not isinstance(value, list):
134
+ errors.append(f"{bundle_id}: {path} must be a list")
135
+ return []
136
+ if len(value) < min_items:
137
+ errors.append(f"{bundle_id}: {path} must contain at least {min_items} item(s)")
138
+ return value
139
+
140
+
141
+ def _ensure_dict(*, bundle_id: str, path: str, value: Any, errors: list[str]) -> dict[str, Any]:
142
+ if not isinstance(value, dict):
143
+ errors.append(f"{bundle_id}: {path} must be an object")
144
+ return {}
145
+ return value
146
+
147
+
148
+ def _validate_host_rule(
149
+ *,
150
+ bundle_id: str,
151
+ host_name: str,
152
+ host_rule: Any,
153
+ required_fields: tuple[str, ...],
154
+ errors: list[str],
155
+ ) -> None:
156
+ path = f"policy_model.host_rules.{host_name}"
157
+ host_payload = _ensure_dict(bundle_id=bundle_id, path=path, value=host_rule, errors=errors)
158
+ if not host_payload:
159
+ return
160
+ for field in required_fields:
161
+ if field not in host_payload:
162
+ errors.append(f"{bundle_id}: malformed host_rules entry for {host_name}: missing '{field}'")
163
+ continue
164
+ _ensure_list(
165
+ bundle_id=bundle_id,
166
+ path=f"{path}.{field}",
167
+ value=host_payload[field],
168
+ errors=errors,
169
+ min_items=1,
170
+ )
171
+
172
+
173
+ def _validate_policy_model(bundle_id: str, policy_model: Any) -> list[str]:
174
+ errors: list[str] = []
175
+ payload = _ensure_dict(bundle_id=bundle_id, path="policy_model", value=policy_model, errors=errors)
176
+ if not payload:
177
+ return errors
178
+
179
+ for field in REQUIRED_POLICY_MODEL_FIELDS:
180
+ if field not in payload:
181
+ errors.append(f"{bundle_id}: policy_model missing field {field}")
182
+
183
+ tier_names: set[str] = set()
184
+ for index, tier in enumerate(
185
+ _ensure_list(
186
+ bundle_id=bundle_id,
187
+ path="policy_model.trust_tiers",
188
+ value=payload.get("trust_tiers", []),
189
+ errors=errors,
190
+ )
191
+ ):
192
+ tier_payload = _ensure_dict(
193
+ bundle_id=bundle_id,
194
+ path=f"policy_model.trust_tiers[{index}]",
195
+ value=tier,
196
+ errors=errors,
197
+ )
198
+ if not tier_payload:
199
+ continue
200
+ for field in ("name", "level", "label", "allowed_sources"):
201
+ if field not in tier_payload:
202
+ errors.append(f"{bundle_id}: policy_model.trust_tiers[{index}] missing field {field}")
203
+ if isinstance(tier_payload.get("name"), str) and tier_payload["name"].strip():
204
+ tier_names.add(tier_payload["name"].strip())
205
+ if "allowed_sources" in tier_payload:
206
+ _ensure_list(
207
+ bundle_id=bundle_id,
208
+ path=f"policy_model.trust_tiers[{index}].allowed_sources",
209
+ value=tier_payload.get("allowed_sources"),
210
+ errors=errors,
211
+ min_items=1,
212
+ )
213
+
214
+ for index, tool in enumerate(
215
+ _ensure_list(
216
+ bundle_id=bundle_id,
217
+ path="policy_model.tool_policies",
218
+ value=payload.get("tool_policies", []),
219
+ errors=errors,
220
+ )
221
+ ):
222
+ tool_payload = _ensure_dict(
223
+ bundle_id=bundle_id,
224
+ path=f"policy_model.tool_policies[{index}]",
225
+ value=tool,
226
+ errors=errors,
227
+ )
228
+ if not tool_payload:
229
+ continue
230
+ for field in ("tool_name", "allowed_tiers", "requires_approval"):
231
+ if field not in tool_payload:
232
+ errors.append(f"{bundle_id}: policy_model.tool_policies[{index}] missing field {field}")
233
+ allowed_tiers = _ensure_list(
234
+ bundle_id=bundle_id,
235
+ path=f"policy_model.tool_policies[{index}].allowed_tiers",
236
+ value=tool_payload.get("allowed_tiers", []),
237
+ errors=errors,
238
+ min_items=1,
239
+ )
240
+ if tier_names:
241
+ unknown_tiers = sorted(
242
+ tier_name
243
+ for tier_name in allowed_tiers
244
+ if isinstance(tier_name, str) and tier_name not in tier_names
245
+ )
246
+ if unknown_tiers:
247
+ errors.append(
248
+ f"{bundle_id}: policy_model.tool_policies[{index}] references unknown tiers {unknown_tiers}"
249
+ )
250
+
251
+ for index, item in enumerate(
252
+ _ensure_list(
253
+ bundle_id=bundle_id,
254
+ path="policy_model.protected_paths",
255
+ value=payload.get("protected_paths", []),
256
+ errors=errors,
257
+ )
258
+ ):
259
+ path_payload = _ensure_dict(
260
+ bundle_id=bundle_id,
261
+ path=f"policy_model.protected_paths[{index}]",
262
+ value=item,
263
+ errors=errors,
264
+ )
265
+ if not path_payload:
266
+ continue
267
+ for field in ("path_pattern", "required_tier"):
268
+ if field not in path_payload:
269
+ errors.append(f"{bundle_id}: policy_model.protected_paths[{index}] missing field {field}")
270
+ required_tier = path_payload.get("required_tier")
271
+ if tier_names and isinstance(required_tier, str) and required_tier not in tier_names:
272
+ errors.append(
273
+ f"{bundle_id}: policy_model.protected_paths[{index}] references unknown tier '{required_tier}'"
274
+ )
275
+
276
+ evidence_contract = _ensure_dict(
277
+ bundle_id=bundle_id,
278
+ path="policy_model.evidence_contract",
279
+ value=payload.get("evidence_contract", {}),
280
+ errors=errors,
281
+ )
282
+ for field in ("timestamp", "executor", "trace_id", "lineage"):
283
+ if field not in evidence_contract:
284
+ errors.append(f"{bundle_id}: policy_model.evidence_contract missing field {field}")
285
+
286
+ host_rules = _ensure_dict(
287
+ bundle_id=bundle_id,
288
+ path="policy_model.host_rules",
289
+ value=payload.get("host_rules", {}),
290
+ errors=errors,
291
+ )
292
+ _validate_host_rule(
293
+ bundle_id=bundle_id,
294
+ host_name="claude",
295
+ host_rule=host_rules.get("claude"),
296
+ required_fields=("compilation_targets", "hooks", "subagents", "skills"),
297
+ errors=errors,
298
+ )
299
+ _validate_host_rule(
300
+ bundle_id=bundle_id,
301
+ host_name="codex",
302
+ host_rule=host_rules.get("codex"),
303
+ required_fields=("compilation_targets", "skills", "agents_fragments", "rules", "automations"),
304
+ errors=errors,
305
+ )
306
+ return errors
307
+
308
+
309
+ def _policy_model_for_bundle(bundles: Iterable[dict[str, Any]], bundle_id: str) -> dict[str, Any] | None:
310
+ for bundle in bundles:
311
+ if str(bundle.get("id", "")) == bundle_id and isinstance(bundle.get("policy_model"), dict):
312
+ return dict(bundle["policy_model"])
313
+ return None
314
+
315
+
316
+ def _policy_protected_paths(policy_model: dict[str, Any] | None, *, channel: str) -> list[str]:
317
+ if not policy_model:
318
+ return _protected_paths_for_channel(channel)
319
+ values: list[str] = []
320
+ for item in policy_model.get("protected_paths", []):
321
+ if isinstance(item, dict):
322
+ pattern = str(item.get("path_pattern", "")).strip()
323
+ if pattern:
324
+ values.append(pattern)
325
+ return values or _protected_paths_for_channel(channel)
326
+
327
+
328
+ def _resolve_root(root_dir: str | Path | None) -> Path:
329
+ if root_dir is None:
330
+ return Path(__file__).resolve().parents[1]
331
+ return Path(root_dir).resolve()
332
+
333
+
334
+ def _resolve_output_root(root_dir: Path, output_root: str | Path | None) -> Path:
335
+ if output_root is None or str(output_root).strip() == "":
336
+ return root_dir
337
+ return Path(output_root).resolve()
338
+
339
+
340
+ def _load_json(path: Path) -> dict[str, Any]:
341
+ parsed = json.loads(path.read_text(encoding="utf-8"))
342
+ if not isinstance(parsed, dict):
343
+ raise ValueError(f"Expected JSON object in {path}")
344
+ return parsed
345
+
346
+
347
+ def _write_json(path: Path, payload: dict[str, Any]) -> None:
348
+ path.parent.mkdir(parents=True, exist_ok=True)
349
+ path.write_text(json.dumps(payload, indent=2, ensure_ascii=True) + "\n", encoding="utf-8")
350
+
351
+
352
+ def _write_text(path: Path, content: str) -> None:
353
+ path.parent.mkdir(parents=True, exist_ok=True)
354
+ path.write_text(content, encoding="utf-8")
355
+
356
+
357
+ def _sha256_file(path: Path) -> str:
358
+ digest = hashlib.sha256()
359
+ with path.open("rb") as handle:
360
+ for chunk in iter(lambda: handle.read(65536), b""):
361
+ digest.update(chunk)
362
+ return digest.hexdigest()
363
+
364
+
365
+ def load_contract_doc(root_dir: str | Path | None = None) -> str:
366
+ if root_dir is not None:
367
+ root = _resolve_root(root_dir)
368
+ candidate = root / CONTRACT_DOC_PATH
369
+ if candidate.exists():
370
+ return candidate.read_text(encoding="utf-8")
371
+ return resolve_asset(CONTRACT_DOC_PATH).read_text(encoding="utf-8")
372
+
373
+
374
+ def load_contract_schema(root_dir: str | Path | None = None) -> dict[str, Any]:
375
+ if root_dir is not None:
376
+ root = _resolve_root(root_dir)
377
+ candidate = root / SCHEMA_PATH
378
+ if candidate.exists():
379
+ return _load_json(candidate)
380
+ return _load_json(resolve_asset(SCHEMA_PATH))
381
+
382
+
383
+ def load_contract_bundles(root_dir: str | Path | None = None) -> list[dict[str, Any]]:
384
+ root = _resolve_root(root_dir)
385
+ bundles: list[dict[str, Any]] = []
386
+ paths = sorted((root / BUNDLES_DIR).glob("*.yaml")) if (root / BUNDLES_DIR).exists() else resolve_assets(BUNDLES_DIR, suffix=".yaml")
387
+ for path in paths:
388
+ parsed = yaml.safe_load(path.read_text(encoding="utf-8"))
389
+ if not isinstance(parsed, dict):
390
+ raise ValueError(f"Expected mapping bundle manifest in {path}")
391
+ bundle = dict(parsed)
392
+ try:
393
+ bundle["_path"] = str(path.relative_to(root))
394
+ except ValueError:
395
+ bundle["_path"] = str(Path(BUNDLES_DIR) / path.name)
396
+ bundles.append(bundle)
397
+ return bundles
398
+
399
+
400
+ def _bundle_summary(bundle: dict[str, Any]) -> dict[str, Any]:
401
+ return {
402
+ "id": bundle.get("id", ""),
403
+ "kind": bundle.get("kind", ""),
404
+ "version": bundle.get("version", ""),
405
+ "title": bundle.get("title", ""),
406
+ "hosts": list(bundle.get("hosts", [])),
407
+ "path": bundle.get("_path", ""),
408
+ }
409
+
410
+
411
+ def validate_contract_registry(root_dir: str | Path | None = None) -> dict[str, Any]:
412
+ root = _resolve_root(root_dir)
413
+ errors: list[str] = []
414
+
415
+ try:
416
+ doc_text = load_contract_doc(root)
417
+ except FileNotFoundError:
418
+ errors.append(f"missing contract doc: {CONTRACT_DOC_PATH}")
419
+ doc_text = ""
420
+ else:
421
+ for token in REQUIRED_DOC_TOKENS:
422
+ if token not in doc_text:
423
+ errors.append(f"contract doc missing token: {token}")
424
+ if CANONICAL_VERSION not in doc_text:
425
+ errors.append(f"contract doc missing version: {CANONICAL_VERSION}")
426
+
427
+ try:
428
+ schema_payload = load_contract_schema(root)
429
+ except FileNotFoundError:
430
+ errors.append(f"missing contract schema: {SCHEMA_PATH}")
431
+ schema_payload: dict[str, Any] = {}
432
+ else:
433
+ if str(schema_payload.get("version", "")) != CANONICAL_VERSION:
434
+ errors.append(f"contract schema version drift: {schema_payload.get('version')!r}")
435
+
436
+ bundles = load_contract_bundles(root)
437
+ if not bundles:
438
+ errors.append(f"missing bundles directory: {BUNDLES_DIR}")
439
+
440
+ bundle_ids = set()
441
+ bundle_summaries: list[dict[str, Any]] = []
442
+ for bundle in bundles:
443
+ bundle_summaries.append(_bundle_summary(bundle))
444
+ bundle_id = str(bundle.get("id", "")).strip()
445
+ if not bundle_id:
446
+ errors.append(f"bundle missing id: {bundle.get('_path', '<unknown>')}")
447
+ continue
448
+ if bundle_id in bundle_ids:
449
+ errors.append(f"duplicate bundle id: {bundle_id}")
450
+ bundle_ids.add(bundle_id)
451
+ for field in REQUIRED_BUNDLE_FIELDS:
452
+ if field not in bundle:
453
+ errors.append(f"{bundle_id}: missing field {field}")
454
+ if bundle.get("version") != CANONICAL_VERSION:
455
+ errors.append(f"{bundle_id}: version drift {bundle.get('version')!r}")
456
+ hosts = bundle.get("hosts", [])
457
+ if not isinstance(hosts, list) or not hosts:
458
+ errors.append(f"{bundle_id}: hosts must be a non-empty list")
459
+ else:
460
+ bad_hosts = [host for host in hosts if host not in SUPPORTED_HOSTS]
461
+ if bad_hosts:
462
+ errors.append(f"{bundle_id}: unsupported hosts {bad_hosts}")
463
+ if "policy_model" in bundle:
464
+ errors.extend(_validate_policy_model(bundle_id, bundle.get("policy_model")))
465
+
466
+ missing_bundles = [bundle_id for bundle_id in DEFAULT_REQUIRED_BUNDLES if bundle_id not in bundle_ids]
467
+ for bundle_id in missing_bundles:
468
+ errors.append(f"missing required bundle: {bundle_id}")
469
+
470
+ contract = {
471
+ "path": str(CONTRACT_DOC_PATH),
472
+ "schema_path": str(SCHEMA_PATH),
473
+ "version": CANONICAL_VERSION,
474
+ "bundle_count": len(bundle_summaries),
475
+ }
476
+ return {
477
+ "schema": "OmgContractValidationResult",
478
+ "status": "ok" if not errors else "error",
479
+ "contract": contract,
480
+ "bundles": bundle_summaries,
481
+ "errors": errors,
482
+ }
483
+
484
+
485
+ def _copy_contract_inputs(root: Path, output_root: Path) -> list[Path]:
486
+ copied: list[Path] = []
487
+ for rel_path in [CONTRACT_DOC_PATH, SCHEMA_PATH]:
488
+ src = resolve_asset(rel_path)
489
+ dst = output_root / rel_path
490
+ _write_text(dst, src.read_text(encoding="utf-8"))
491
+ copied.append(dst)
492
+ for bundle in load_contract_bundles(root):
493
+ rel_path = Path(str(bundle["_path"]))
494
+ src = resolve_asset(rel_path)
495
+ dst = output_root / rel_path
496
+ _write_text(dst, src.read_text(encoding="utf-8"))
497
+ copied.append(dst)
498
+
499
+ # Copy advanced plugin artifacts (plugin.json + all command markdown files)
500
+ advanced_plugin_json = Path("plugins") / "advanced" / "plugin.json"
501
+ try:
502
+ src = resolve_asset(advanced_plugin_json)
503
+ dst = output_root / advanced_plugin_json
504
+ _write_text(dst, src.read_text(encoding="utf-8"))
505
+ copied.append(dst)
506
+ except FileNotFoundError:
507
+ pass
508
+
509
+ advanced_commands = resolve_assets(Path("plugins") / "advanced" / "commands", suffix=".md")
510
+ for src in advanced_commands:
511
+ rel = Path("plugins") / "advanced" / "commands" / src.name
512
+ dst = output_root / rel
513
+ _write_text(dst, src.read_text(encoding="utf-8"))
514
+ copied.append(dst)
515
+
516
+ return copied
517
+
518
+
519
+ def _base_mcp_servers() -> dict[str, Any]:
520
+ return {
521
+ "filesystem": {
522
+ "command": "npx",
523
+ "args": ["@modelcontextprotocol/server-filesystem@2026.1.14", "."],
524
+ },
525
+ "omg-control": {
526
+ "command": "python3",
527
+ "args": ["-m", "runtime.omg_mcp_server"],
528
+ },
529
+ }
530
+
531
+
532
+ def _build_claude_plugin() -> dict[str, Any]:
533
+ return {
534
+ "name": CANONICAL_PLUGIN_ID,
535
+ "version": CANONICAL_VERSION,
536
+ "description": "OMG plugin layer for Claude Code with native setup, orchestration, and interop.",
537
+ "author": {"name": "trac3er00"},
538
+ "repository": CANONICAL_REPO_URL,
539
+ "homepage": CANONICAL_REPO_URL,
540
+ "license": "MIT",
541
+ "keywords": [
542
+ "claude-code",
543
+ "plugin",
544
+ "orchestration",
545
+ "multi-agent",
546
+ "omg",
547
+ "codex",
548
+ "gemini",
549
+ "crazy-mode",
550
+ "escalation",
551
+ ],
552
+ "mcpServers": "./.mcp.json",
553
+ }
554
+
555
+
556
+ def _build_claude_marketplace() -> dict[str, Any]:
557
+ return {
558
+ "name": CANONICAL_MARKETPLACE_ID,
559
+ "description": "Marketplace metadata for the OMG Claude plugin",
560
+ "owner": {"name": "trac3er00"},
561
+ "metadata": {
562
+ "description": "OMG - Oh-My-God for Claude Code and supported agent hosts",
563
+ "version": CANONICAL_VERSION,
564
+ "homepage": CANONICAL_REPO_URL,
565
+ "repository": CANONICAL_REPO_URL,
566
+ },
567
+ "plugins": [
568
+ {
569
+ "name": CANONICAL_PLUGIN_ID,
570
+ "description": "OMG plugin layer for Claude Code and supported agent hosts with native setup, orchestration, and interop.",
571
+ "version": CANONICAL_VERSION,
572
+ "source": "./",
573
+ "author": {"name": "trac3er00"},
574
+ "license": "MIT",
575
+ "category": "productivity",
576
+ "tags": [
577
+ "orchestration",
578
+ "automation",
579
+ "multi-agent",
580
+ "omg",
581
+ "codex",
582
+ "gemini",
583
+ "crazy-mode",
584
+ ],
585
+ }
586
+ ],
587
+ "version": CANONICAL_VERSION,
588
+ }
589
+
590
+
591
+ def _bundle_map(bundles: Iterable[dict[str, Any]]) -> dict[str, dict[str, Any]]:
592
+ return {str(bundle["id"]): bundle for bundle in bundles}
593
+
594
+
595
+ def _compile_hook_settings(bundle: dict[str, Any]) -> dict[str, Any]:
596
+ events = bundle.get("compiled_hooks", {})
597
+ if not isinstance(events, dict):
598
+ return {}
599
+
600
+ compiled: dict[str, Any] = {}
601
+ for event_name, items in events.items():
602
+ if not isinstance(items, list):
603
+ continue
604
+ compiled_entries: list[dict[str, Any]] = []
605
+ for item in items:
606
+ if not isinstance(item, dict):
607
+ continue
608
+ command = str(item.get("command", "")).strip()
609
+ if not command:
610
+ continue
611
+ hook_payload: dict[str, Any] = {"type": "command", "command": command}
612
+ timeout = item.get("timeout")
613
+ if isinstance(timeout, int):
614
+ hook_payload["timeout"] = timeout
615
+ entry: dict[str, Any] = {"hooks": [hook_payload]}
616
+ if "matcher" in item:
617
+ entry["matcher"] = str(item.get("matcher", ""))
618
+ compiled_entries.append(entry)
619
+ if compiled_entries:
620
+ compiled[str(event_name)] = compiled_entries
621
+ return compiled
622
+
623
+
624
+ def _protected_paths_for_channel(channel: str) -> list[str]:
625
+ paths = [".omg/**", ".agents/**", ".codex/**", ".claude/**"]
626
+ if channel == "enterprise":
627
+ paths.extend(["registry/**", "dist/**"])
628
+ return paths
629
+
630
+
631
+ def _default_claude_hook_registrations() -> dict[str, list[dict[str, Any]]]:
632
+ """Default OMG hook registrations for each required Claude event."""
633
+ return {
634
+ "UserPromptSubmit": [
635
+ {
636
+ "hooks": [
637
+ {
638
+ "type": "command",
639
+ "command": 'python3 "$HOME/.claude/hooks/user-prompt-submit.py"',
640
+ "timeout": 10,
641
+ }
642
+ ],
643
+ }
644
+ ],
645
+ "PreToolUse": [
646
+ {
647
+ "hooks": [
648
+ {
649
+ "type": "command",
650
+ "command": 'python3 "$HOME/.claude/hooks/firewall.py"',
651
+ "timeout": 10,
652
+ }
653
+ ],
654
+ "matcher": "Bash",
655
+ },
656
+ {
657
+ "hooks": [
658
+ {
659
+ "type": "command",
660
+ "command": 'python3 "$HOME/.claude/hooks/secret-guard.py"',
661
+ "timeout": 10,
662
+ }
663
+ ],
664
+ "matcher": "Read|Write|Edit|MultiEdit",
665
+ },
666
+ ],
667
+ "PostToolUse": [
668
+ {
669
+ "hooks": [
670
+ {
671
+ "type": "command",
672
+ "command": 'python3 "$HOME/.claude/hooks/tool-ledger.py"',
673
+ "timeout": 10,
674
+ }
675
+ ],
676
+ "matcher": "Write|Edit|MultiEdit",
677
+ },
678
+ ],
679
+ "PostToolUseFailure": [
680
+ {
681
+ "hooks": [
682
+ {
683
+ "type": "command",
684
+ "command": 'python3 "$HOME/.claude/hooks/post-tool-failure.py"',
685
+ }
686
+ ],
687
+ }
688
+ ],
689
+ "InstructionsLoaded": [
690
+ {
691
+ "hooks": [
692
+ {
693
+ "type": "command",
694
+ "command": 'python3 "$HOME/.claude/hooks/instructions-loaded.py"',
695
+ "timeout": 10,
696
+ }
697
+ ],
698
+ }
699
+ ],
700
+ }
701
+
702
+
703
+ def _build_claude_subagents(protected_paths: list[str]) -> list[dict[str, Any]]:
704
+ """Build narrow-tool Claude subagent definitions. No bypassPermissions allowed."""
705
+ return [
706
+ {
707
+ "name": "security-reviewer",
708
+ "description": "Read-only security review subagent with scoped tool access.",
709
+ "tools": [
710
+ "Read",
711
+ "Grep",
712
+ "Glob",
713
+ "Bash(grep *)",
714
+ "Bash(find *)",
715
+ "Bash(git log *)",
716
+ "Bash(git diff *)",
717
+ ],
718
+ "bypassPermissions": False,
719
+ },
720
+ {
721
+ "name": "release-manager",
722
+ "description": "Release management subagent with write access governed by protected-path policy.",
723
+ "tools": [
724
+ "Read",
725
+ "Write",
726
+ "Edit",
727
+ "Grep",
728
+ "Glob",
729
+ "Bash(git *)",
730
+ "Bash(python3 scripts/omg.py *)",
731
+ ],
732
+ "bypassPermissions": False,
733
+ "protectedPaths": protected_paths,
734
+ },
735
+ ]
736
+
737
+
738
+ def _build_claude_skills(policy_model: dict[str, Any] | None) -> list[dict[str, Any]]:
739
+ """Build Claude skill definitions from the policy model host_rules."""
740
+ skill_refs: list[str] = []
741
+ if isinstance(policy_model, dict):
742
+ host_rules = policy_model.get("host_rules", {})
743
+ if isinstance(host_rules, dict):
744
+ claude_rules = host_rules.get("claude", {})
745
+ if isinstance(claude_rules, dict):
746
+ skill_refs = [str(s) for s in claude_rules.get("skills", []) if str(s).strip()]
747
+ skills: list[dict[str, Any]] = []
748
+ for ref in skill_refs:
749
+ skills.append({"name": ref, "source": f".agents/skills/{ref}/"})
750
+ return skills
751
+
752
+
753
+ def _validate_compiled_claude_output(output_root: Path) -> list[str]:
754
+ """Validate compiled Claude settings.json contains required hooks and subagents."""
755
+ settings_path = output_root / "settings.json"
756
+ if not settings_path.exists():
757
+ return ["claude: missing compiled settings.json"]
758
+
759
+ settings = _load_json(settings_path)
760
+ errors: list[str] = []
761
+
762
+ hooks = settings.get("hooks", {})
763
+ for event in REQUIRED_CLAUDE_HOOK_EVENTS:
764
+ if event not in hooks or not hooks[event]:
765
+ errors.append(f"claude: missing required hook event '{event}'")
766
+
767
+ omg = settings.get("_omg", {})
768
+ generated = omg.get("generated", {})
769
+ subagents = generated.get("subagents", [])
770
+ subagent_names = {sa.get("name") for sa in subagents if isinstance(sa, dict)}
771
+ for name in REQUIRED_CLAUDE_SUBAGENT_NAMES:
772
+ if name not in subagent_names:
773
+ errors.append(f"claude: missing required subagent '{name}'")
774
+
775
+ for sa in subagents:
776
+ if isinstance(sa, dict) and sa.get("bypassPermissions"):
777
+ errors.append(
778
+ f"claude: subagent '{sa.get('name', '<unknown>')}' has bypassPermissions enabled"
779
+ )
780
+
781
+ return errors
782
+
783
+
784
+ def _compile_claude_outputs(
785
+ *,
786
+ root: Path,
787
+ output_root: Path,
788
+ bundles: list[dict[str, Any]],
789
+ channel: str,
790
+ policy_model: dict[str, Any] | None,
791
+ ) -> list[Path]:
792
+ artifacts: list[Path] = []
793
+
794
+ _write_json(output_root / ".claude-plugin" / "plugin.json", _build_claude_plugin())
795
+ artifacts.append(output_root / ".claude-plugin" / "plugin.json")
796
+
797
+ _write_json(output_root / ".claude-plugin" / "marketplace.json", _build_claude_marketplace())
798
+ artifacts.append(output_root / ".claude-plugin" / "marketplace.json")
799
+
800
+ mcp_payload = {"mcpServers": _base_mcp_servers()}
801
+ _write_json(output_root / ".mcp.json", mcp_payload)
802
+ artifacts.append(output_root / ".mcp.json")
803
+
804
+ settings_path = root / "settings.json"
805
+ if not settings_path.exists():
806
+ settings_path = resolve_asset("settings.json")
807
+ settings = _load_json(settings_path)
808
+ hook_bundle = _bundle_map(bundles)["hook-governor"]
809
+ compiled_hooks = _compile_hook_settings(hook_bundle)
810
+ defaults = _default_claude_hook_registrations()
811
+ for event in REQUIRED_CLAUDE_HOOK_EVENTS:
812
+ if event not in compiled_hooks or not compiled_hooks[event]:
813
+ compiled_hooks[event] = defaults[event]
814
+ settings["hooks"] = compiled_hooks
815
+
816
+ protected_paths = _policy_protected_paths(policy_model, channel=channel)
817
+ subagents = _build_claude_subagents(protected_paths)
818
+ skills = _build_claude_skills(policy_model)
819
+
820
+ omg_settings = dict(settings.get("_omg", {}))
821
+ omg_settings["_version"] = CANONICAL_VERSION
822
+ omg_settings["generated"] = {
823
+ "contract_version": CANONICAL_VERSION,
824
+ "channel": channel,
825
+ "required_bundles": list(DEFAULT_REQUIRED_BUNDLES),
826
+ "protected_paths": protected_paths,
827
+ "emulated_events": list(hook_bundle.get("lifecycle_hooks", {}).get("emulated", [])),
828
+ "policy_model": policy_model or {},
829
+ "subagents": subagents,
830
+ "skills": skills,
831
+ }
832
+ settings["_omg"] = omg_settings
833
+ _write_json(output_root / "settings.json", settings)
834
+ artifacts.append(output_root / "settings.json")
835
+
836
+ return artifacts
837
+
838
+
839
+ def _yaml_string(value: str) -> str:
840
+ return json.dumps(value, ensure_ascii=True)
841
+
842
+
843
+ def _render_codex_skill(bundle: dict[str, Any], channel: str) -> str:
844
+ execution_modes = ", ".join(str(mode) for mode in bundle.get("execution_contract", {}).get("modes", []))
845
+ mcp_servers = ", ".join(str(name) for name in bundle.get("mcp_contract", {}).get("servers", []))
846
+ return (
847
+ f"---\n"
848
+ f"name: omg-{bundle['id']}\n"
849
+ f"description: {_yaml_string(str(bundle['description']))}\n"
850
+ f"---\n\n"
851
+ f"# {bundle['title']}\n\n"
852
+ f"- Channel: `{channel}`\n"
853
+ f"- Execution modes: `{execution_modes}`\n"
854
+ f"- MCP servers: `{mcp_servers}`\n"
855
+ f"- Evidence outputs: `{', '.join(bundle.get('evidence_outputs', {}).get('artifacts', []))}`\n"
856
+ )
857
+
858
+
859
+ def _render_openai_yaml(bundle: dict[str, Any], channel: str) -> str:
860
+ invocation = bundle.get("invocation_policy", {})
861
+ servers = bundle.get("mcp_contract", {}).get("servers", [])
862
+ tools = bundle.get("tool_policy", {}).get("allowed_tools", {}).get("codex", [])
863
+ lines = [
864
+ f"name: omg-{bundle['id']}",
865
+ f"description: {_yaml_string(str(bundle['description']))}",
866
+ f"allow_implicit_invocation: {'true' if invocation.get('allow_implicit_invocation') else 'false'}",
867
+ "metadata:",
868
+ f" channel: {channel}",
869
+ f" bundle_id: {bundle['id']}",
870
+ f" title: {_yaml_string(str(bundle['title']))}",
871
+ "mcp_servers:",
872
+ ]
873
+ for server in servers:
874
+ lines.append(f" - {server}")
875
+ lines.append("allowed_tools:")
876
+ for tool in tools:
877
+ lines.append(f" - {_yaml_string(str(tool))}")
878
+ return "\n".join(lines) + "\n"
879
+
880
+
881
+ def _codex_skill_refs(policy_model: dict[str, Any] | None) -> list[str]:
882
+ """Extract skill references from policy_model.host_rules.codex.skills."""
883
+ if not isinstance(policy_model, dict):
884
+ return []
885
+ host_rules = policy_model.get("host_rules", {})
886
+ if not isinstance(host_rules, dict):
887
+ return []
888
+ codex_rules = host_rules.get("codex", {})
889
+ if not isinstance(codex_rules, dict):
890
+ return []
891
+ return [str(s) for s in codex_rules.get("skills", []) if str(s).strip()]
892
+
893
+
894
+ def _codex_evidence_fields(policy_model: dict[str, Any] | None) -> list[str]:
895
+ """Extract required evidence contract fields from the policy model."""
896
+ if not isinstance(policy_model, dict):
897
+ return []
898
+ ec = policy_model.get("evidence_contract", {})
899
+ if not isinstance(ec, dict):
900
+ return []
901
+ return sorted(ec.keys())
902
+
903
+
904
+ def _codex_protected_planning_skills(bundles: Iterable[dict[str, Any]]) -> list[str]:
905
+ protected: list[str] = []
906
+ for bundle in bundles:
907
+ if "codex" not in bundle.get("hosts", []):
908
+ continue
909
+ if str(bundle.get("kind", "")).strip().lower() != "planning":
910
+ continue
911
+ invocation = bundle.get("invocation_policy", {})
912
+ if not isinstance(invocation, dict):
913
+ continue
914
+ if invocation.get("allow_implicit_invocation") is False:
915
+ protected.append(f"omg/{bundle['id']}")
916
+ return sorted(set(protected))
917
+
918
+
919
+ def _render_codex_agents_fragment(
920
+ *,
921
+ channel: str,
922
+ protected_paths: list[str],
923
+ codex_rules: list[str],
924
+ codex_automations: list[str],
925
+ codex_skills: list[str],
926
+ evidence_fields: list[str],
927
+ protected_planning_skills: list[str],
928
+ ) -> str:
929
+ """Render a comprehensive AGENTS.fragment.md for Codex host."""
930
+ sections: list[str] = []
931
+
932
+ # Header
933
+ sections.append(f"# OMG Codex Governance (channel: {channel})\n")
934
+
935
+ # Build & Test
936
+ sections.append("## Build & Test\n")
937
+ sections.append("```bash")
938
+ sections.append("python3 -m pytest tests -q")
939
+ sections.append("python3 scripts/omg.py contract validate")
940
+ sections.append(f"python3 scripts/omg.py contract compile --host codex --channel {channel}")
941
+ sections.append("```\n")
942
+
943
+ # Protected Paths
944
+ sections.append("## Protected Paths\n")
945
+ sections.append("The following paths require tier-gated review before mutation:\n")
946
+ for path in protected_paths:
947
+ sections.append(f"- `{path}`")
948
+ sections.append("")
949
+
950
+ # Evidence Contract
951
+ sections.append("## Evidence Contract\n")
952
+ sections.append("Every production action must emit evidence containing these fields:\n")
953
+ if evidence_fields:
954
+ for field in evidence_fields:
955
+ sections.append(f"- `{field}`")
956
+ else:
957
+ sections.append("- `timestamp`")
958
+ sections.append("- `executor`")
959
+ sections.append("- `trace_id`")
960
+ sections.append("- `lineage`")
961
+ sections.append("")
962
+
963
+ # Required Skills
964
+ sections.append("## Required Skills\n")
965
+ if codex_skills:
966
+ for skill in codex_skills:
967
+ sections.append(f"- `{skill}`")
968
+ else:
969
+ sections.append("- `omg/control-plane`")
970
+ sections.append("")
971
+
972
+ sections.append("## Protected Planning Surface\n")
973
+ if protected_planning_skills:
974
+ sections.append("Council planning skills are protected and explicit-invocation only:")
975
+ sections.append("")
976
+ for skill in protected_planning_skills:
977
+ sections.append(f"- `{skill}`")
978
+ else:
979
+ sections.append("- No protected planning skills configured.")
980
+ sections.append("")
981
+
982
+ # Web Search Policy
983
+ sections.append("## Web Search Policy\n")
984
+ sections.append("- Prefer cached results over live network requests.")
985
+ sections.append("- Do NOT initiate live web searches unless explicitly instructed.")
986
+ sections.append("- Use `context7` or local documentation before external lookups.")
987
+ sections.append("- Set `cached_web_search: prefer_cached` as the default.\n")
988
+
989
+ # Approval Constraints
990
+ sections.append("## Approval Constraints\n")
991
+ sections.append("- Destructive file operations require explicit user approval.")
992
+ sections.append("- `git push --force` and branch deletions require explicit approval.")
993
+ sections.append("- Production deployments require explicit approval.")
994
+ sections.append("- Mutations to protected paths require tier-gated approval.\n")
995
+
996
+ # Rules & Automations (compact summary)
997
+ sections.append("## Rules & Automations\n")
998
+ rules_str = ", ".join(codex_rules) if codex_rules else "protected_paths, explicit_invocation"
999
+ auto_str = ", ".join(codex_automations) if codex_automations else "contract-compile"
1000
+ sections.append(f"- Rules: `{rules_str}`")
1001
+ sections.append(f"- Automations: `{auto_str}`")
1002
+ sections.append("- Require explicit invocation for protected production planning skills.")
1003
+ sections.append("")
1004
+
1005
+ return "\n".join(sections)
1006
+
1007
+
1008
+ def _render_codex_rules(
1009
+ *,
1010
+ channel: str,
1011
+ protected_paths: list[str],
1012
+ codex_skills: list[str],
1013
+ protected_planning_skills: list[str],
1014
+ ) -> str:
1015
+ """Render a codex-rules.md config fragment encoding defaults."""
1016
+ lines: list[str] = []
1017
+ lines.append(f"# OMG Codex Rules (channel: {channel})\n")
1018
+
1019
+ lines.append("## Defaults\n")
1020
+ lines.append("- `cached_web_search: prefer_cached`")
1021
+ lines.append("- `live_network: deny_by_default`")
1022
+ lines.append("- `destructive_approval: required`\n")
1023
+
1024
+ lines.append("## Protected Paths\n")
1025
+ for path in protected_paths:
1026
+ lines.append(f"- `{path}`")
1027
+ lines.append("")
1028
+
1029
+ lines.append("## Required Skills\n")
1030
+ for skill in (codex_skills or ["omg/control-plane"]):
1031
+ lines.append(f"- `{skill}`")
1032
+ lines.append("")
1033
+
1034
+ lines.append("## Protected Planning Surface\n")
1035
+ if protected_planning_skills:
1036
+ for skill in protected_planning_skills:
1037
+ lines.append(f"- `{skill}` (explicit invocation only)")
1038
+ else:
1039
+ lines.append("- none")
1040
+ lines.append("")
1041
+
1042
+ lines.append("## Approval Matrix\n")
1043
+ lines.append("| Action | Approval Required |")
1044
+ lines.append("|--------|------------------|")
1045
+ lines.append("| Read / Grep | No |")
1046
+ lines.append("| Write to protected paths | Yes |")
1047
+ lines.append("| Bash (python3:*) | Yes (balanced+ tier) |")
1048
+ lines.append("| git push --force | Yes |")
1049
+ lines.append("| Production deploy | Yes |")
1050
+ lines.append("")
1051
+
1052
+ return "\n".join(lines)
1053
+
1054
+
1055
+ def _validate_compiled_codex_output(output_root: Path) -> list[str]:
1056
+ """Validate compiled Codex output contains required AGENTS sections and artifacts."""
1057
+ errors: list[str] = []
1058
+ shared_dir = output_root / ".agents" / "skills" / "omg"
1059
+
1060
+ for required_file in REQUIRED_CODEX_OUTPUTS:
1061
+ path = shared_dir / required_file
1062
+ if not path.exists():
1063
+ errors.append(f"codex: missing required output '{required_file}'")
1064
+
1065
+ agents_path = shared_dir / "AGENTS.fragment.md"
1066
+ if agents_path.exists():
1067
+ content = agents_path.read_text(encoding="utf-8")
1068
+ for section in REQUIRED_CODEX_AGENTS_SECTIONS:
1069
+ if section not in content:
1070
+ errors.append(f"codex: AGENTS.fragment.md missing required section '{section}'")
1071
+ else:
1072
+ errors.append("codex: cannot validate AGENTS.fragment.md — file missing")
1073
+
1074
+ return errors
1075
+
1076
+
1077
+ def _compile_codex_outputs(
1078
+ *,
1079
+ output_root: Path,
1080
+ bundles: list[dict[str, Any]],
1081
+ channel: str,
1082
+ policy_model: dict[str, Any] | None,
1083
+ ) -> list[Path]:
1084
+ artifacts: list[Path] = []
1085
+ shared_dir = output_root / ".agents" / "skills" / "omg"
1086
+ shared_dir.mkdir(parents=True, exist_ok=True)
1087
+
1088
+ protected_paths = _policy_protected_paths(policy_model, channel=channel)
1089
+ codex_rules: list[str] = []
1090
+ codex_automations: list[str] = []
1091
+ if isinstance(policy_model, dict):
1092
+ host_rules = policy_model.get("host_rules", {})
1093
+ if isinstance(host_rules, dict):
1094
+ codex_policy = host_rules.get("codex", {})
1095
+ if isinstance(codex_policy, dict):
1096
+ codex_rules = [str(item) for item in codex_policy.get("rules", []) if str(item).strip()]
1097
+ codex_automations = [
1098
+ str(item) for item in codex_policy.get("automations", []) if str(item).strip()
1099
+ ]
1100
+
1101
+ codex_skills = _codex_skill_refs(policy_model)
1102
+ evidence_fields = _codex_evidence_fields(policy_model)
1103
+ protected_planning_skills = _codex_protected_planning_skills(bundles)
1104
+
1105
+ agents_fragment = _render_codex_agents_fragment(
1106
+ channel=channel,
1107
+ protected_paths=protected_paths,
1108
+ codex_rules=codex_rules,
1109
+ codex_automations=codex_automations,
1110
+ codex_skills=codex_skills,
1111
+ evidence_fields=evidence_fields,
1112
+ protected_planning_skills=protected_planning_skills,
1113
+ )
1114
+ _write_text(shared_dir / "AGENTS.fragment.md", agents_fragment)
1115
+ artifacts.append(shared_dir / "AGENTS.fragment.md")
1116
+
1117
+ rules_content = _render_codex_rules(
1118
+ channel=channel,
1119
+ protected_paths=protected_paths,
1120
+ codex_skills=codex_skills,
1121
+ protected_planning_skills=protected_planning_skills,
1122
+ )
1123
+ _write_text(shared_dir / "codex-rules.md", rules_content)
1124
+ artifacts.append(shared_dir / "codex-rules.md")
1125
+
1126
+ from runtime.mcp_config_writers import write_codex_mcp_stdio_config
1127
+
1128
+ codex_mcp_path = shared_dir / "codex-mcp.toml"
1129
+ write_codex_mcp_stdio_config(
1130
+ command="python3",
1131
+ args=["-m", "runtime.omg_mcp_server"],
1132
+ server_name="omg-control",
1133
+ config_path=codex_mcp_path,
1134
+ )
1135
+ artifacts.append(codex_mcp_path)
1136
+
1137
+ for bundle in bundles:
1138
+ if "codex" not in bundle.get("hosts", []):
1139
+ continue
1140
+ skill_dir = shared_dir / str(bundle["id"])
1141
+ _write_text(skill_dir / "SKILL.md", _render_codex_skill(bundle, channel))
1142
+ _write_text(skill_dir / "openai.yaml", _render_openai_yaml(bundle, channel))
1143
+ artifacts.extend([skill_dir / "SKILL.md", skill_dir / "openai.yaml"])
1144
+
1145
+ return artifacts
1146
+
1147
+
1148
+ def _copy_release_bundle(
1149
+ *,
1150
+ output_root: Path,
1151
+ channel: str,
1152
+ artifacts: list[Path],
1153
+ ) -> list[Path]:
1154
+ bundle_root = output_root / "dist" / channel / "bundle"
1155
+ if bundle_root.exists():
1156
+ shutil.rmtree(bundle_root)
1157
+ copied: list[Path] = []
1158
+ for path in sorted(set(artifacts)):
1159
+ rel_path = path.relative_to(output_root)
1160
+ dst = bundle_root / rel_path
1161
+ dst.parent.mkdir(parents=True, exist_ok=True)
1162
+ shutil.copy2(path, dst)
1163
+ copied.append(dst)
1164
+ return copied
1165
+
1166
+
1167
+ def _build_dist_manifest(output_root: Path, *, channel: str, artifacts: list[Path]) -> Path:
1168
+ dist_root = output_root / "dist" / channel
1169
+ payload = {
1170
+ "schema": "OmgCompiledArtifactManifest",
1171
+ "channel": channel,
1172
+ "contract_version": CANONICAL_VERSION,
1173
+ "artifacts": [
1174
+ {
1175
+ "path": str(path.relative_to(dist_root)),
1176
+ "sha256": _sha256_file(path),
1177
+ }
1178
+ for path in sorted(set(artifacts))
1179
+ ],
1180
+ }
1181
+ out_path = dist_root / "manifest.json"
1182
+ _write_json(out_path, payload)
1183
+ return out_path
1184
+
1185
+
1186
+ def compile_contract_outputs(
1187
+ *,
1188
+ root_dir: str | Path | None = None,
1189
+ output_root: str | Path | None = None,
1190
+ hosts: list[str] | tuple[str, ...] | None = None,
1191
+ channel: str = "public",
1192
+ ) -> dict[str, Any]:
1193
+ root = _resolve_root(root_dir)
1194
+ output = _resolve_output_root(root, output_root)
1195
+ validation = validate_contract_registry(root)
1196
+ if validation["status"] != "ok":
1197
+ return {
1198
+ "schema": "OmgContractCompileResult",
1199
+ "status": "error",
1200
+ "channel": channel,
1201
+ "hosts": list(hosts or SUPPORTED_HOSTS),
1202
+ "errors": validation["errors"],
1203
+ "artifacts": [],
1204
+ }
1205
+
1206
+ if channel not in SUPPORTED_CHANNELS:
1207
+ return {
1208
+ "schema": "OmgContractCompileResult",
1209
+ "status": "error",
1210
+ "channel": channel,
1211
+ "hosts": list(hosts or SUPPORTED_HOSTS),
1212
+ "errors": [f"unsupported channel: {channel}"],
1213
+ "artifacts": [],
1214
+ }
1215
+
1216
+ selected_hosts = list(hosts or SUPPORTED_HOSTS)
1217
+ bad_hosts = [host for host in selected_hosts if host not in SUPPORTED_HOSTS]
1218
+ if bad_hosts:
1219
+ return {
1220
+ "schema": "OmgContractCompileResult",
1221
+ "status": "error",
1222
+ "channel": channel,
1223
+ "hosts": selected_hosts,
1224
+ "errors": [f"unsupported hosts: {bad_hosts}"],
1225
+ "artifacts": [],
1226
+ }
1227
+
1228
+ bundles = load_contract_bundles(root)
1229
+ policy_model = _policy_model_for_bundle(bundles, "control-plane")
1230
+ artifacts = _copy_contract_inputs(root, output)
1231
+
1232
+ if "claude" in selected_hosts:
1233
+ artifacts.extend(
1234
+ _compile_claude_outputs(
1235
+ root=root,
1236
+ output_root=output,
1237
+ bundles=bundles,
1238
+ channel=channel,
1239
+ policy_model=policy_model,
1240
+ )
1241
+ )
1242
+ claude_errors = _validate_compiled_claude_output(output)
1243
+ if claude_errors:
1244
+ return {
1245
+ "schema": "OmgContractCompileResult",
1246
+ "status": "error",
1247
+ "channel": channel,
1248
+ "hosts": selected_hosts,
1249
+ "errors": claude_errors,
1250
+ "artifacts": [],
1251
+ }
1252
+ if "codex" in selected_hosts:
1253
+ artifacts.extend(
1254
+ _compile_codex_outputs(
1255
+ output_root=output,
1256
+ bundles=bundles,
1257
+ channel=channel,
1258
+ policy_model=policy_model,
1259
+ )
1260
+ )
1261
+ codex_errors = _validate_compiled_codex_output(output)
1262
+ if codex_errors:
1263
+ return {
1264
+ "schema": "OmgContractCompileResult",
1265
+ "status": "error",
1266
+ "channel": channel,
1267
+ "hosts": selected_hosts,
1268
+ "errors": codex_errors,
1269
+ "artifacts": [],
1270
+ }
1271
+
1272
+ bundled_artifacts = _copy_release_bundle(output_root=output, channel=channel, artifacts=artifacts)
1273
+ manifest_path = _build_dist_manifest(output, channel=channel, artifacts=bundled_artifacts)
1274
+ artifacts.append(manifest_path)
1275
+
1276
+ return {
1277
+ "schema": "OmgContractCompileResult",
1278
+ "status": "ok",
1279
+ "channel": channel,
1280
+ "hosts": selected_hosts,
1281
+ "artifacts": [str(path.relative_to(output)) for path in artifacts],
1282
+ "manifest": str(manifest_path.relative_to(output)),
1283
+ }
1284
+
1285
+
1286
+ def _provider_statuses() -> dict[str, dict[str, Any]]:
1287
+ ready_override = {
1288
+ item.strip()
1289
+ for item in os.environ.get("OMG_RELEASE_READY_PROVIDERS", "").split(",")
1290
+ if item.strip()
1291
+ }
1292
+ statuses: dict[str, dict[str, Any]] = {}
1293
+
1294
+ for provider_name in ("claude", "codex"):
1295
+ if provider_name in ready_override:
1296
+ statuses[provider_name] = {"ready": True, "source": "env"}
1297
+ continue
1298
+
1299
+ if provider_name == "claude":
1300
+ claude_bin = os.environ.get("OMG_CLAUDE_BIN", "claude")
1301
+ cmd = os.environ.get("OMG_CLAUDE_WORKER_CMD", "").strip()
1302
+ ready = bool(cmd) or shutil.which(claude_bin) is not None
1303
+ statuses[provider_name] = {
1304
+ "ready": ready,
1305
+ "source": "env-cmd" if cmd else "path",
1306
+ "detail": cmd or claude_bin,
1307
+ }
1308
+ continue
1309
+
1310
+ import runtime.providers.codex_provider # noqa: F401
1311
+ from runtime.cli_provider import get_provider
1312
+
1313
+ provider = get_provider("codex")
1314
+ ready = bool(provider and provider.detect())
1315
+ statuses[provider_name] = {"ready": ready, "source": "provider"}
1316
+
1317
+ return statuses
1318
+
1319
+
1320
+ def _check_mcp_fabric() -> dict[str, Any]:
1321
+ import runtime.omg_mcp_server as omg_mcp_server
1322
+
1323
+ prompts = asyncio.run(omg_mcp_server.mcp.list_prompts())
1324
+ resources = asyncio.run(omg_mcp_server.mcp.list_resources())
1325
+ instructions = getattr(omg_mcp_server.mcp, "instructions", "")
1326
+ return {
1327
+ "ready": isinstance(instructions, str) and bool(instructions.strip()) and len(prompts) >= 1 and len(resources) >= 1,
1328
+ "prompt_count": len(prompts),
1329
+ "resource_count": len(resources),
1330
+ }
1331
+
1332
+
1333
+ def _check_version_identity_drift(root: Path) -> dict[str, Any]:
1334
+ """Check version/identity drift across all public surface files.
1335
+
1336
+ Returns a dict with:
1337
+ - status: "ok" or "error"
1338
+ - blockers: list of named blockers for each mismatch
1339
+ - drift_details: dict mapping file paths to their found versions
1340
+ """
1341
+ canonical_version = CANONICAL_VERSION
1342
+ blockers: list[str] = []
1343
+ drift_details: dict[str, str] = {}
1344
+
1345
+ # Files to check with their JSON paths to extract version
1346
+ files_to_check = [
1347
+ ("package.json", ["version"]),
1348
+ ("pyproject.toml", None), # Special case: extract from version = "X.Y.Z"
1349
+ ("settings.json", ["_omg", "_version"]),
1350
+ (".claude-plugin/plugin.json", ["version"]),
1351
+ (".claude-plugin/marketplace.json", ["version"]),
1352
+ ("plugins/core/plugin.json", ["version"]),
1353
+ ("plugins/advanced/plugin.json", ["version"]),
1354
+ ("CHANGELOG.md", None), # Special case: check for version in header
1355
+ ]
1356
+
1357
+ for file_path, json_path in files_to_check:
1358
+ full_path = root / file_path
1359
+ if not full_path.exists():
1360
+ blockers.append(f"version_drift: missing file {file_path}")
1361
+ continue
1362
+
1363
+ found_version = None
1364
+
1365
+ try:
1366
+ if file_path == "pyproject.toml":
1367
+ # Extract from version = "X.Y.Z"
1368
+ content = full_path.read_text(encoding="utf-8")
1369
+ for line in content.split("\n"):
1370
+ if line.startswith("version = "):
1371
+ found_version = line.split('"')[1]
1372
+ break
1373
+ elif file_path == "CHANGELOG.md":
1374
+ # Extract from "## X.Y.Z -" header (skip "Unreleased" section)
1375
+ content = full_path.read_text(encoding="utf-8")
1376
+ for line in content.split("\n"):
1377
+ if line.startswith("## ") and " - " in line:
1378
+ version_str = line.split(" - ")[0].replace("## ", "").strip()
1379
+ if version_str.lower() != "unreleased":
1380
+ found_version = version_str
1381
+ break
1382
+ else:
1383
+ # JSON file: use json_path to navigate
1384
+ data = _load_json(full_path)
1385
+ current = data
1386
+ if json_path:
1387
+ for key in json_path:
1388
+ current = current.get(key)
1389
+ if current is None:
1390
+ break
1391
+ found_version = current
1392
+ except Exception as e:
1393
+ blockers.append(f"version_drift: failed to parse {file_path}: {e}")
1394
+ continue
1395
+
1396
+ if found_version is None:
1397
+ blockers.append(f"version_drift: could not extract version from {file_path}")
1398
+ elif str(found_version) != canonical_version:
1399
+ blockers.append(
1400
+ f"version_drift: {file_path} has version {found_version}, expected {canonical_version}"
1401
+ )
1402
+ drift_details[file_path] = str(found_version)
1403
+ else:
1404
+ drift_details[file_path] = str(found_version)
1405
+
1406
+ return {
1407
+ "status": "ok" if not blockers else "error",
1408
+ "canonical_version": canonical_version,
1409
+ "blockers": blockers,
1410
+ "drift_details": drift_details,
1411
+ }
1412
+
1413
+
1414
+ def _check_doctor_output(output_root: Path) -> dict[str, Any]:
1415
+ evidence_dir = output_root / ".omg" / "evidence"
1416
+ doctor_path = evidence_dir / "doctor.json"
1417
+ if not doctor_path.exists():
1418
+ return {
1419
+ "status": "error",
1420
+ "path": "",
1421
+ "doctor": {},
1422
+ "blockers": ["doctor_check_missing: missing .omg/evidence/doctor.json"],
1423
+ }
1424
+ try:
1425
+ payload = _load_json(doctor_path)
1426
+ except Exception as exc:
1427
+ return {
1428
+ "status": "error",
1429
+ "path": str(doctor_path.relative_to(output_root)),
1430
+ "doctor": {},
1431
+ "blockers": [f"doctor_check_missing: invalid doctor output ({exc})"],
1432
+ }
1433
+
1434
+ blockers: list[str] = []
1435
+ if payload.get("schema") != "DoctorResult":
1436
+ blockers.append("doctor_check_missing: doctor evidence schema mismatch")
1437
+ if payload.get("status") != "pass":
1438
+ blockers.append("doctor_check_missing: doctor status is not pass")
1439
+ checks = payload.get("checks", [])
1440
+ if not isinstance(checks, list) or not checks:
1441
+ blockers.append("doctor_check_missing: doctor checks missing")
1442
+
1443
+ return {
1444
+ "status": "ok" if not blockers else "error",
1445
+ "path": str(doctor_path.relative_to(output_root)),
1446
+ "doctor": payload,
1447
+ "blockers": blockers,
1448
+ }
1449
+
1450
+
1451
+ def _check_proof_surface(root: Path) -> dict[str, Any]:
1452
+ proof_path = root / "docs" / "proof.md"
1453
+ if not proof_path.exists():
1454
+ return {
1455
+ "status": "error",
1456
+ "path": "docs/proof.md",
1457
+ "blockers": ["prose_only_proof: docs/proof.md missing"],
1458
+ }
1459
+
1460
+ content = proof_path.read_text(encoding="utf-8")
1461
+ lowered = content.lower()
1462
+ hardcoded_counts = bool(
1463
+ re.search(r"\b\d+\s*/\s*\d+\b", lowered)
1464
+ or re.search(r"\b\d+\s+(tests?|checks?|providers?)\s+(passed|pass|green|successful)\b", lowered)
1465
+ or re.search(r"\ball\s+tests?\s+passed\b", lowered)
1466
+ )
1467
+ artifact_refs = (
1468
+ ".omg/evidence/",
1469
+ ".omg/tracebank/",
1470
+ ".omg/evals/",
1471
+ ".omg/lineage/",
1472
+ )
1473
+ has_artifact_refs = any(token in content for token in artifact_refs)
1474
+
1475
+ blockers: list[str] = []
1476
+ if hardcoded_counts and not has_artifact_refs:
1477
+ blockers.append("prose_only_proof: hardcoded proof counts without machine artifact references")
1478
+
1479
+ return {
1480
+ "status": "ok" if not blockers else "error",
1481
+ "path": str(proof_path.relative_to(root)),
1482
+ "hardcoded_counts": hardcoded_counts,
1483
+ "has_artifact_refs": has_artifact_refs,
1484
+ "blockers": blockers,
1485
+ }
1486
+
1487
+
1488
+ def _is_loopback_hostname(hostname: str) -> bool:
1489
+ lowered = hostname.strip().lower()
1490
+ return lowered in {"localhost", "127.0.0.1", "::1"}
1491
+
1492
+
1493
+ def _collect_http_urls(line: str) -> list[str]:
1494
+ return re.findall(r"https?://[^\s)\]>'\"]+", line)
1495
+
1496
+
1497
+ def _check_same_machine_scope(root: Path, output_root: Path) -> dict[str, Any]:
1498
+ blockers: list[str] = []
1499
+ scanned: list[str] = []
1500
+
1501
+ for rel_path in ("README.md", "docs/proof.md", "OMG_COMPAT_CONTRACT.md"):
1502
+ path = root / rel_path
1503
+ if not path.exists():
1504
+ continue
1505
+ scanned.append(rel_path)
1506
+ for line in path.read_text(encoding="utf-8").splitlines():
1507
+ if "production" not in line.lower():
1508
+ continue
1509
+ for url in _collect_http_urls(line):
1510
+ parsed = urlparse(url)
1511
+ if parsed.scheme != "http":
1512
+ continue
1513
+ host = parsed.hostname or ""
1514
+ if host and not _is_loopback_hostname(host):
1515
+ blockers.append(
1516
+ f"same_machine_scope_violation: {rel_path} claims production over non-loopback HTTP ({url})"
1517
+ )
1518
+
1519
+ mcp_path = output_root / ".mcp.json"
1520
+ if mcp_path.exists():
1521
+ scanned.append(str(mcp_path.relative_to(output_root)))
1522
+ mcp_payload = _load_json(mcp_path)
1523
+ servers = mcp_payload.get("mcpServers", {})
1524
+ if isinstance(servers, dict):
1525
+ for server_name, server_cfg in servers.items():
1526
+ if not isinstance(server_cfg, dict):
1527
+ continue
1528
+ for key in ("url", "httpUrl"):
1529
+ raw_url = str(server_cfg.get(key, "")).strip()
1530
+ if not raw_url:
1531
+ continue
1532
+ parsed = urlparse(raw_url)
1533
+ if parsed.scheme != "http":
1534
+ continue
1535
+ host = parsed.hostname or ""
1536
+ if host and not _is_loopback_hostname(host):
1537
+ blockers.append(
1538
+ "same_machine_scope_violation: "
1539
+ f".mcp.json server '{server_name}' uses non-loopback HTTP endpoint ({raw_url})"
1540
+ )
1541
+
1542
+ return {
1543
+ "status": "ok" if not blockers else "error",
1544
+ "scanned": scanned,
1545
+ "blockers": blockers,
1546
+ }
1547
+
1548
+
1549
+ def _check_provider_host_parity(output_root: Path, providers: dict[str, dict[str, Any]]) -> dict[str, Any]:
1550
+ blockers: list[str] = []
1551
+ required_for_provider = {
1552
+ "claude": (
1553
+ output_root / "settings.json",
1554
+ output_root / ".claude-plugin" / "plugin.json",
1555
+ ),
1556
+ "codex": (
1557
+ output_root / ".agents" / "skills" / "omg" / "AGENTS.fragment.md",
1558
+ output_root / ".agents" / "skills" / "omg" / "codex-mcp.toml",
1559
+ ),
1560
+ }
1561
+ for provider, status in providers.items():
1562
+ if not status.get("ready"):
1563
+ continue
1564
+ for required_path in required_for_provider.get(provider, ()):
1565
+ if not required_path.exists():
1566
+ blockers.append(
1567
+ "provider_host_parity: "
1568
+ f"provider '{provider}' ready but host artifact missing {required_path.relative_to(output_root)}"
1569
+ )
1570
+ return {
1571
+ "status": "ok" if not blockers else "error",
1572
+ "blockers": blockers,
1573
+ }
1574
+
1575
+
1576
+ def _has_waiver(risk: dict[str, Any]) -> bool:
1577
+ return bool(
1578
+ risk.get("waived")
1579
+ or risk.get("waiver")
1580
+ or risk.get("waiver_id")
1581
+ or risk.get("waiver_evidence")
1582
+ )
1583
+
1584
+
1585
+ def _check_high_risk_security_waivers(payload: dict[str, Any]) -> list[str]:
1586
+ blockers: list[str] = []
1587
+ unresolved = payload.get("unresolved_risks", [])
1588
+ if isinstance(unresolved, list):
1589
+ for item in unresolved:
1590
+ if isinstance(item, dict):
1591
+ severity = str(item.get("severity") or item.get("risk_level") or "").lower()
1592
+ if severity in {"high", "critical"} and not _has_waiver(item):
1593
+ blockers.append("security_blocker_unwaived: unresolved high-risk item without waiver evidence")
1594
+ break
1595
+ elif isinstance(item, str):
1596
+ lowered = item.lower()
1597
+ is_high = "high" in lowered or "critical" in lowered
1598
+ waived = "waiv" in lowered
1599
+ if is_high and not waived:
1600
+ blockers.append("security_blocker_unwaived: unresolved high-risk item without waiver evidence")
1601
+ break
1602
+
1603
+ scans = payload.get("security_scans", [])
1604
+ if isinstance(scans, list):
1605
+ for scan in scans:
1606
+ if not isinstance(scan, dict):
1607
+ continue
1608
+ findings = scan.get("findings", [])
1609
+ if not isinstance(findings, list):
1610
+ continue
1611
+ for finding in findings:
1612
+ if not isinstance(finding, dict):
1613
+ continue
1614
+ severity = str(finding.get("severity", "")).lower()
1615
+ if severity in {"high", "critical"} and not _has_waiver(finding):
1616
+ blockers.append("security_blocker_unwaived: high-risk security finding without waiver evidence")
1617
+ return blockers
1618
+ return blockers
1619
+
1620
+
1621
+ def build_release_readiness(
1622
+ *,
1623
+ root_dir: str | Path | None = None,
1624
+ output_root: str | Path | None = None,
1625
+ channel: str = "dual",
1626
+ ) -> dict[str, Any]:
1627
+ root = _resolve_root(root_dir)
1628
+ output = _resolve_output_root(root, output_root)
1629
+ blockers: list[str] = []
1630
+ checks: dict[str, Any] = {}
1631
+
1632
+ validation = validate_contract_registry(root)
1633
+ checks["contract_validation"] = validation
1634
+ if validation["status"] != "ok":
1635
+ blockers.extend(validation["errors"])
1636
+
1637
+ required_channels = ["public", "enterprise"] if channel == "dual" else [channel]
1638
+ for required_channel in required_channels:
1639
+ dist_root = output / "dist" / required_channel
1640
+ manifest_path = dist_root / "manifest.json"
1641
+ if not manifest_path.exists():
1642
+ blockers.append(f"missing compiled manifest: dist/{required_channel}/manifest.json")
1643
+ continue
1644
+ manifest = _load_json(manifest_path)
1645
+ manifest_errors: list[str] = []
1646
+ for artifact in manifest.get("artifacts", []):
1647
+ if not isinstance(artifact, dict):
1648
+ continue
1649
+ rel_path = str(artifact.get("path", ""))
1650
+ expected_sha = str(artifact.get("sha256", ""))
1651
+ artifact_path = dist_root / rel_path
1652
+ if not artifact_path.exists():
1653
+ manifest_errors.append(f"{required_channel}: missing bundled artifact {rel_path}")
1654
+ continue
1655
+ if _sha256_file(artifact_path) != expected_sha:
1656
+ manifest_errors.append(f"{required_channel}: sha mismatch for {rel_path}")
1657
+ manifest_paths = {str(a.get("path", "")) for a in manifest.get("artifacts", []) if isinstance(a, dict)}
1658
+ for req_path in REQUIRED_ADVANCED_PLUGIN_ARTIFACTS:
1659
+ if req_path not in manifest_paths:
1660
+ manifest_errors.append(f"{required_channel}: advanced_plugin_missing {req_path}")
1661
+ if manifest_errors:
1662
+ blockers.extend(manifest_errors)
1663
+ manifest["integrity_errors"] = manifest_errors
1664
+ checks[f"dist_{required_channel}"] = manifest
1665
+
1666
+ required_outputs = [
1667
+ output / ".claude-plugin" / "plugin.json",
1668
+ output / ".claude-plugin" / "marketplace.json",
1669
+ output / ".mcp.json",
1670
+ output / "settings.json",
1671
+ output / ".agents" / "skills" / "omg" / "control-plane" / "SKILL.md",
1672
+ output / ".agents" / "skills" / "omg" / "control-plane" / "openai.yaml",
1673
+ ]
1674
+ missing_outputs = [str(path.relative_to(output)) for path in required_outputs if not path.exists()]
1675
+ if missing_outputs:
1676
+ blockers.append(f"missing compiled outputs: {', '.join(missing_outputs)}")
1677
+ checks["compiled_outputs"] = {"missing": missing_outputs}
1678
+
1679
+ required_bundle_outputs: list[Path] = []
1680
+ for bundle_id in DEFAULT_REQUIRED_BUNDLES:
1681
+ required_bundle_outputs.extend(
1682
+ [
1683
+ output / ".agents" / "skills" / "omg" / bundle_id / "SKILL.md",
1684
+ output / ".agents" / "skills" / "omg" / bundle_id / "openai.yaml",
1685
+ ]
1686
+ )
1687
+ missing_bundle_outputs = [str(path.relative_to(output)) for path in required_bundle_outputs if not path.exists()]
1688
+ if missing_bundle_outputs:
1689
+ blockers.append(f"missing bundle outputs: {', '.join(missing_bundle_outputs)}")
1690
+ checks["bundle_outputs"] = {"missing": missing_bundle_outputs}
1691
+
1692
+ evidence_check = _check_recent_evidence(output)
1693
+ checks["evidence"] = evidence_check
1694
+ blockers.extend(evidence_check.get("blockers", []))
1695
+
1696
+ doctor_check = _check_doctor_output(output)
1697
+ checks["doctor"] = doctor_check
1698
+ blockers.extend(doctor_check.get("blockers", []))
1699
+
1700
+ eval_check = _check_eval_gate(output)
1701
+ checks["eval_gate"] = eval_check
1702
+ blockers.extend(eval_check.get("blockers", []))
1703
+
1704
+ proof_chain_check = _check_proof_chain(output)
1705
+ checks["proof_chain"] = proof_chain_check
1706
+ blockers.extend(proof_chain_check.get("blockers", []))
1707
+
1708
+ security_blockers = [
1709
+ blocker
1710
+ for blocker in evidence_check.get("blockers", [])
1711
+ if isinstance(blocker, str) and blocker.startswith("security_blocker_unwaived:")
1712
+ ]
1713
+ checks["security_blocker_unwaived"] = {
1714
+ "status": "ok" if not security_blockers else "error",
1715
+ "blockers": security_blockers,
1716
+ }
1717
+
1718
+ proof_surface_check = _check_proof_surface(root)
1719
+ checks["proof_surface"] = proof_surface_check
1720
+ blockers.extend(proof_surface_check.get("blockers", []))
1721
+
1722
+ same_machine_scope = _check_same_machine_scope(root, output)
1723
+ checks["same_machine_scope"] = same_machine_scope
1724
+ blockers.extend(same_machine_scope.get("blockers", []))
1725
+
1726
+ package_check = _check_packaged_install_smoke(root)
1727
+ checks["package_smoke"] = package_check
1728
+ blockers.extend(package_check.get("blockers", []))
1729
+
1730
+ version_drift_check = _check_version_identity_drift(root)
1731
+ checks["version_identity_drift"] = version_drift_check
1732
+ blockers.extend(version_drift_check.get("blockers", []))
1733
+
1734
+ if channel == "dual":
1735
+ bundle_promotion_parity = _check_bundle_promotion_parity(root, output)
1736
+ checks["bundle_promotion_parity"] = bundle_promotion_parity
1737
+ blockers.extend(bundle_promotion_parity.get("blockers", []))
1738
+
1739
+ providers = _provider_statuses()
1740
+ checks["providers"] = providers
1741
+ for provider_name, status in providers.items():
1742
+ if not status.get("ready"):
1743
+ blockers.append(f"provider not ready: {provider_name}")
1744
+
1745
+ provider_parity = _check_provider_host_parity(output, providers)
1746
+ checks["provider_host_parity"] = provider_parity
1747
+ blockers.extend(provider_parity.get("blockers", []))
1748
+
1749
+ worktree_ready = shutil.which("git") is not None and (root / ".git").exists()
1750
+ checks["worktree"] = {"ready": worktree_ready}
1751
+ if not worktree_ready:
1752
+ blockers.append("git worktree support not available")
1753
+
1754
+ mcp_status = _check_mcp_fabric()
1755
+ checks["mcp_fabric"] = mcp_status
1756
+ if not mcp_status.get("ready"):
1757
+ blockers.append("mcp fabric incomplete")
1758
+
1759
+ return {
1760
+ "schema": "OmgReleaseReadinessResult",
1761
+ "status": "ok" if not blockers else "error",
1762
+ "channel": channel,
1763
+ "blockers": blockers,
1764
+ "checks": checks,
1765
+ }
1766
+
1767
+
1768
+ def _check_recent_evidence(output_root: Path) -> dict[str, Any]:
1769
+ evidence_dir = output_root / ".omg" / "evidence"
1770
+ if not evidence_dir.exists():
1771
+ return {"status": "missing", "blockers": []}
1772
+
1773
+ evidence_files = sorted(path for path in evidence_dir.glob("*.json") if path.is_file())
1774
+ if not evidence_files:
1775
+ return {"status": "missing", "blockers": []}
1776
+
1777
+ evidence_payloads: list[tuple[Path, dict[str, Any]]] = []
1778
+ for path in evidence_files:
1779
+ try:
1780
+ payload = _load_json(path)
1781
+ except Exception:
1782
+ continue
1783
+ if payload.get("schema") == "EvidencePack":
1784
+ evidence_payloads.append((path, payload))
1785
+
1786
+ if not evidence_payloads:
1787
+ return {"status": "missing", "blockers": []}
1788
+
1789
+ evidence_path, payload = evidence_payloads[-1]
1790
+ blockers: list[str] = []
1791
+ if not payload.get("security_scans"):
1792
+ blockers.append("cosmetic evidence: security_scans is empty")
1793
+ if not payload.get("provenance"):
1794
+ blockers.append("cosmetic evidence: provenance is empty")
1795
+ if not payload.get("timestamp") and not payload.get("created_at"):
1796
+ blockers.append("missing_attribution: evidence missing timestamp")
1797
+ if not payload.get("executor"):
1798
+ blockers.append("missing_attribution: evidence missing executor")
1799
+ if not payload.get("environment"):
1800
+ blockers.append("missing_attribution: evidence missing environment")
1801
+ if not payload.get("trace_ids"):
1802
+ blockers.append("missing trace ids in evidence")
1803
+ if not payload.get("trace_id") and not payload.get("trace_ids"):
1804
+ blockers.append("missing trace_id in evidence")
1805
+ if not payload.get("lineage"):
1806
+ blockers.append("missing lineage in evidence")
1807
+ tests = payload.get("tests", [])
1808
+ if isinstance(tests, list):
1809
+ for item in tests:
1810
+ if isinstance(item, dict) and item.get("name") == "worker_implementation" and not item.get("passed", False):
1811
+ blockers.append("simulated worker evidence detected")
1812
+ break
1813
+ blockers.extend(_check_test_intent_claims(payload))
1814
+ blockers.extend(_check_high_risk_security_waivers(payload))
1815
+ return {
1816
+ "status": "ok" if not blockers else "error",
1817
+ "evidence_file": str(evidence_path.relative_to(output_root)),
1818
+ "blockers": blockers,
1819
+ }
1820
+
1821
+
1822
+ def _check_test_intent_claims(payload: dict[str, Any]) -> list[str]:
1823
+ test_delta = payload.get("test_delta")
1824
+ claims = payload.get("claims", [])
1825
+ if not isinstance(claims, list):
1826
+ return []
1827
+
1828
+ from runtime.test_intent_lock import evaluate_test_delta
1829
+
1830
+ blockers: list[str] = []
1831
+ guarded_claims = {"tests passed", "tests_passed", "bug fixed", "bug_fixed"}
1832
+ for claim in claims:
1833
+ if not isinstance(claim, dict):
1834
+ continue
1835
+ claim_type = str(claim.get("claim_type", "")).strip().lower()
1836
+ if claim_type not in guarded_claims:
1837
+ continue
1838
+ delta = claim.get("test_delta")
1839
+ if not isinstance(delta, dict):
1840
+ delta = test_delta if isinstance(test_delta, dict) else None
1841
+ if not isinstance(delta, dict):
1842
+ blockers.append(f"test_intent_lock_missing_delta: claim '{claim_type}' requires test_delta evidence")
1843
+ continue
1844
+ result = evaluate_test_delta(delta)
1845
+ if result.get("verdict") != "pass":
1846
+ reasons = result.get("reasons", [])
1847
+ reason_text = "; ".join(str(item) for item in reasons if str(item).strip())
1848
+ suffix = f": {reason_text}" if reason_text else ""
1849
+ blockers.append(f"test_intent_lock_blocked: claim '{claim_type}'{suffix}")
1850
+ return blockers
1851
+
1852
+
1853
+ def _check_eval_gate(output_root: Path) -> dict[str, Any]:
1854
+ latest_path = output_root / ".omg" / "evals" / "latest.json"
1855
+ if not latest_path.exists():
1856
+ return {"status": "missing", "blockers": []}
1857
+ payload = _load_json(latest_path)
1858
+ blockers: list[str] = []
1859
+ if payload.get("status") != "ok" or bool(payload.get("summary", {}).get("regressed")):
1860
+ blockers.append("eval regression detected")
1861
+ return {
1862
+ "status": "ok" if not blockers else "error",
1863
+ "path": str(latest_path.relative_to(output_root)),
1864
+ "blockers": blockers,
1865
+ }
1866
+
1867
+
1868
+ def _check_proof_chain(output_root: Path) -> dict[str, Any]:
1869
+ chain_module = importlib.import_module("runtime.proof_chain")
1870
+ gate_module = importlib.import_module("runtime.proof_gate")
1871
+
1872
+ gate_input = chain_module.build_proof_gate_input(str(output_root))
1873
+ chain = gate_input.get("proof_chain", {}) if isinstance(gate_input, dict) else {}
1874
+ chain_status = str(chain.get("status", "error"))
1875
+ raw_blockers = chain.get("blockers", [])
1876
+ blockers = [f"proof_chain_linkage: {item}" for item in raw_blockers] if isinstance(raw_blockers, list) else ["proof_chain_linkage: invalid blockers"]
1877
+ if chain_status == "ok":
1878
+ blockers = []
1879
+
1880
+ proof_gate = gate_module.evaluate_proof_gate(gate_input if isinstance(gate_input, dict) else {})
1881
+ if str(proof_gate.get("verdict", "fail")) != "pass":
1882
+ gate_blockers = proof_gate.get("blockers", [])
1883
+ if isinstance(gate_blockers, list) and gate_blockers:
1884
+ blockers.extend(f"proof_gate_blocked: {item}" for item in gate_blockers)
1885
+ else:
1886
+ blockers.append("proof_gate_blocked: verdict_fail")
1887
+
1888
+ return {
1889
+ "status": "ok" if not blockers else "error",
1890
+ "proof_chain": chain,
1891
+ "proof_gate": proof_gate,
1892
+ "blockers": blockers,
1893
+ }
1894
+
1895
+
1896
+ def _check_bundle_promotion_parity(root: Path, output_root: Path) -> dict[str, Any]:
1897
+ missing_settings_required_bundles: list[str] = []
1898
+ missing_dist_public: list[str] = []
1899
+ missing_dist_enterprise: list[str] = []
1900
+ missing_pyproject_data_files: list[str] = []
1901
+
1902
+ settings_path = output_root / "settings.json"
1903
+ if settings_path.exists():
1904
+ settings = _load_json(settings_path)
1905
+ required_bundles = settings.get("_omg", {}).get("generated", {}).get("required_bundles", [])
1906
+ if not isinstance(required_bundles, list):
1907
+ required_bundles = []
1908
+ required_bundle_set = {str(item) for item in required_bundles}
1909
+ missing_settings_required_bundles = [
1910
+ bundle_id for bundle_id in TRUTH_COUNCIL_BUNDLES if bundle_id not in required_bundle_set
1911
+ ]
1912
+ else:
1913
+ missing_settings_required_bundles = list(TRUTH_COUNCIL_BUNDLES)
1914
+
1915
+ for bundle_id in TRUTH_COUNCIL_BUNDLES:
1916
+ public_skill = output_root / "dist" / "public" / "bundle" / ".agents" / "skills" / "omg" / bundle_id / "SKILL.md"
1917
+ if not public_skill.exists():
1918
+ missing_dist_public.append(str(public_skill.relative_to(output_root)))
1919
+
1920
+ enterprise_skill = output_root / "dist" / "enterprise" / "bundle" / ".agents" / "skills" / "omg" / bundle_id / "SKILL.md"
1921
+ if not enterprise_skill.exists():
1922
+ missing_dist_enterprise.append(str(enterprise_skill.relative_to(output_root)))
1923
+
1924
+ pyproject_path = root / "pyproject.toml"
1925
+ if pyproject_path.exists():
1926
+ pyproject_content = pyproject_path.read_text(encoding="utf-8")
1927
+ for bundle_id in TRUTH_COUNCIL_BUNDLES:
1928
+ data_file_key = f'".agents/skills/omg/{bundle_id}" = '
1929
+ if data_file_key not in pyproject_content:
1930
+ missing_pyproject_data_files.append(bundle_id)
1931
+ else:
1932
+ missing_pyproject_data_files = list(TRUTH_COUNCIL_BUNDLES)
1933
+
1934
+ failed = any(
1935
+ (
1936
+ missing_settings_required_bundles,
1937
+ missing_dist_public,
1938
+ missing_dist_enterprise,
1939
+ missing_pyproject_data_files,
1940
+ )
1941
+ )
1942
+ return {
1943
+ "status": "ok" if not failed else "error",
1944
+ "blockers": ["bundle_promotion_parity"] if failed else [],
1945
+ "missing_settings_required_bundles": missing_settings_required_bundles,
1946
+ "missing_dist_public": missing_dist_public,
1947
+ "missing_dist_enterprise": missing_dist_enterprise,
1948
+ "missing_pyproject_data_files": missing_pyproject_data_files,
1949
+ }
1950
+
1951
+
1952
+ def _check_packaged_install_smoke(root: Path) -> dict[str, Any]:
1953
+ blockers: list[str] = []
1954
+ with tempfile.TemporaryDirectory(prefix="omg-wheel-") as tmp_dir:
1955
+ proc = subprocess.run(
1956
+ [sys.executable, "-m", "pip", "wheel", ".", "--no-deps", "-w", tmp_dir],
1957
+ cwd=str(root),
1958
+ capture_output=True,
1959
+ text=True,
1960
+ check=False,
1961
+ timeout=120,
1962
+ )
1963
+ if proc.returncode != 0:
1964
+ return {
1965
+ "status": "error",
1966
+ "blockers": ["package smoke failed to build wheel"],
1967
+ "stdout": proc.stdout,
1968
+ "stderr": proc.stderr,
1969
+ }
1970
+ wheels = sorted(Path(tmp_dir).glob("*.whl"))
1971
+ if not wheels:
1972
+ return {"status": "error", "blockers": ["package smoke did not produce a wheel"]}
1973
+ with zipfile.ZipFile(wheels[-1]) as archive:
1974
+ names = set(archive.namelist())
1975
+ required_suffixes = (
1976
+ "control_plane/service.py",
1977
+ "registry/verify_artifact.py",
1978
+ "plugins/dephealth/cve_scanner.py",
1979
+ "OMG_COMPAT_CONTRACT.md",
1980
+ ".agents/skills/omg/security-check/SKILL.md",
1981
+ ".agents/skills/omg/plan-council/SKILL.md",
1982
+ ".agents/skills/omg/claim-judge/SKILL.md",
1983
+ ".agents/skills/omg/test-intent-lock/SKILL.md",
1984
+ ".agents/skills/omg/proof-gate/SKILL.md",
1985
+ )
1986
+ for suffix in required_suffixes:
1987
+ if not any(name.endswith(suffix) for name in names):
1988
+ blockers.append(f"package parity missing {suffix}")
1989
+ return {"status": "ok" if not blockers else "error", "blockers": blockers}