@trac3er/oh-my-god 2.0.7 → 2.0.9

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 (400) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.claude-plugin/scripts/uninstall.sh +1 -1
  4. package/.gemini/settings.json +11 -0
  5. package/.kimi/mcp.json +11 -0
  6. package/CHANGELOG.md +17 -0
  7. package/OMG-setup.sh +1 -1
  8. package/OMG_COMPAT_CONTRACT.md +14 -1
  9. package/README.md +2 -1
  10. package/artifacts/release/.agents/skills/omg/AGENTS.fragment.md +7 -1
  11. package/artifacts/release/.agents/skills/omg/claim-judge/SKILL.md +11 -0
  12. package/artifacts/release/.agents/skills/omg/claim-judge/openai.yaml +13 -0
  13. package/artifacts/release/.agents/skills/omg/codex-rules.md +4 -0
  14. package/artifacts/release/.agents/skills/omg/plan-council/SKILL.md +11 -0
  15. package/artifacts/release/.agents/skills/omg/plan-council/openai.yaml +12 -0
  16. package/artifacts/release/.agents/skills/omg/proof-gate/SKILL.md +11 -0
  17. package/artifacts/release/.agents/skills/omg/proof-gate/openai.yaml +13 -0
  18. package/artifacts/release/.agents/skills/omg/test-intent-lock/SKILL.md +11 -0
  19. package/artifacts/release/.agents/skills/omg/test-intent-lock/openai.yaml +13 -0
  20. package/artifacts/release/.claude-plugin/marketplace.json +3 -3
  21. package/artifacts/release/.claude-plugin/plugin.json +1 -1
  22. package/artifacts/release/.mcp.json +0 -22
  23. package/artifacts/release/OMG_COMPAT_CONTRACT.md +8 -1
  24. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/AGENTS.fragment.md +7 -1
  25. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/claim-judge/SKILL.md +11 -0
  26. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/claim-judge/openai.yaml +13 -0
  27. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/codex-rules.md +4 -0
  28. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/plan-council/SKILL.md +11 -0
  29. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/plan-council/openai.yaml +12 -0
  30. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/proof-gate/SKILL.md +11 -0
  31. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/proof-gate/openai.yaml +13 -0
  32. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/test-intent-lock/SKILL.md +11 -0
  33. package/artifacts/release/dist/enterprise/bundle/.agents/skills/omg/test-intent-lock/openai.yaml +13 -0
  34. package/artifacts/release/dist/enterprise/bundle/.claude-plugin/marketplace.json +36 -0
  35. package/artifacts/release/dist/enterprise/bundle/.claude-plugin/plugin.json +23 -0
  36. package/artifacts/release/dist/enterprise/bundle/.mcp.json +18 -0
  37. package/artifacts/release/dist/enterprise/bundle/OMG_COMPAT_CONTRACT.md +8 -1
  38. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/commands/OMG:code-review.md +114 -0
  39. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/commands/OMG:deep-plan.md +266 -0
  40. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/commands/OMG:handoff.md +115 -0
  41. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/commands/OMG:learn.md +110 -0
  42. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/commands/OMG:maintainer.md +31 -0
  43. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/commands/OMG:ralph-start.md +43 -0
  44. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/commands/OMG:ralph-stop.md +23 -0
  45. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/commands/OMG:security-review.md +16 -0
  46. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/commands/OMG:sequential-thinking.md +20 -0
  47. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/commands/OMG:ship.md +46 -0
  48. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/plugin.json +87 -0
  49. package/artifacts/release/dist/enterprise/bundle/registry/bundles/algorithms.yaml +1 -1
  50. package/artifacts/release/dist/enterprise/bundle/registry/bundles/api-twin.yaml +1 -1
  51. package/artifacts/release/dist/enterprise/bundle/registry/bundles/claim-judge.yaml +49 -0
  52. package/artifacts/release/dist/enterprise/bundle/registry/bundles/control-plane.yaml +1 -1
  53. package/artifacts/release/dist/enterprise/bundle/registry/bundles/data-lineage.yaml +1 -1
  54. package/artifacts/release/dist/enterprise/bundle/registry/bundles/delta-classifier.yaml +1 -1
  55. package/artifacts/release/dist/enterprise/bundle/registry/bundles/eval-gate.yaml +1 -1
  56. package/artifacts/release/dist/enterprise/bundle/registry/bundles/health.yaml +1 -1
  57. package/artifacts/release/dist/enterprise/bundle/registry/bundles/hook-governor.yaml +1 -1
  58. package/artifacts/release/dist/enterprise/bundle/registry/bundles/incident-replay.yaml +1 -1
  59. package/artifacts/release/dist/enterprise/bundle/registry/bundles/lsp-pack.yaml +1 -1
  60. package/artifacts/release/dist/enterprise/bundle/registry/bundles/mcp-fabric.yaml +1 -1
  61. package/artifacts/release/dist/enterprise/bundle/registry/bundles/plan-council.yaml +51 -0
  62. package/artifacts/release/dist/enterprise/bundle/registry/bundles/preflight.yaml +1 -1
  63. package/artifacts/release/dist/enterprise/bundle/registry/bundles/proof-gate.yaml +49 -0
  64. package/artifacts/release/dist/enterprise/bundle/registry/bundles/remote-supervisor.yaml +1 -1
  65. package/artifacts/release/dist/enterprise/bundle/registry/bundles/robotics.yaml +1 -1
  66. package/artifacts/release/dist/enterprise/bundle/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  67. package/artifacts/release/dist/enterprise/bundle/registry/bundles/security-check.yaml +1 -1
  68. package/artifacts/release/dist/enterprise/bundle/registry/bundles/test-intent-lock.yaml +49 -0
  69. package/artifacts/release/dist/enterprise/bundle/registry/bundles/tracebank.yaml +1 -1
  70. package/artifacts/release/dist/enterprise/bundle/registry/bundles/vision.yaml +1 -1
  71. package/artifacts/release/dist/enterprise/bundle/registry/omg-capability.schema.json +1 -1
  72. package/artifacts/release/dist/enterprise/bundle/settings.json +598 -0
  73. package/artifacts/release/dist/enterprise/manifest.json +131 -23
  74. package/artifacts/release/dist/public/bundle/.agents/skills/omg/AGENTS.fragment.md +55 -4
  75. package/artifacts/release/dist/public/bundle/.agents/skills/omg/claim-judge/SKILL.md +11 -0
  76. package/artifacts/release/dist/public/bundle/.agents/skills/omg/claim-judge/openai.yaml +13 -0
  77. package/artifacts/release/dist/public/bundle/.agents/skills/omg/codex-rules.md +33 -0
  78. package/artifacts/release/dist/public/bundle/.agents/skills/omg/plan-council/SKILL.md +11 -0
  79. package/artifacts/release/dist/public/bundle/.agents/skills/omg/plan-council/openai.yaml +12 -0
  80. package/artifacts/release/dist/public/bundle/.agents/skills/omg/proof-gate/SKILL.md +11 -0
  81. package/artifacts/release/dist/public/bundle/.agents/skills/omg/proof-gate/openai.yaml +13 -0
  82. package/artifacts/release/dist/public/bundle/.agents/skills/omg/test-intent-lock/SKILL.md +11 -0
  83. package/artifacts/release/dist/public/bundle/.agents/skills/omg/test-intent-lock/openai.yaml +13 -0
  84. package/artifacts/release/dist/public/bundle/.claude-plugin/marketplace.json +3 -3
  85. package/artifacts/release/dist/public/bundle/.claude-plugin/plugin.json +1 -1
  86. package/artifacts/release/dist/public/bundle/.mcp.json +0 -22
  87. package/artifacts/release/dist/public/bundle/OMG_COMPAT_CONTRACT.md +8 -1
  88. package/artifacts/release/dist/public/bundle/plugins/advanced/commands/OMG:code-review.md +114 -0
  89. package/artifacts/release/dist/public/bundle/plugins/advanced/commands/OMG:deep-plan.md +266 -0
  90. package/artifacts/release/dist/public/bundle/plugins/advanced/commands/OMG:handoff.md +115 -0
  91. package/artifacts/release/dist/public/bundle/plugins/advanced/commands/OMG:learn.md +110 -0
  92. package/artifacts/release/dist/public/bundle/plugins/advanced/commands/OMG:maintainer.md +31 -0
  93. package/artifacts/release/dist/public/bundle/plugins/advanced/commands/OMG:ralph-start.md +43 -0
  94. package/artifacts/release/dist/public/bundle/plugins/advanced/commands/OMG:ralph-stop.md +23 -0
  95. package/artifacts/release/dist/public/bundle/plugins/advanced/commands/OMG:security-review.md +16 -0
  96. package/artifacts/release/dist/public/bundle/plugins/advanced/commands/OMG:sequential-thinking.md +20 -0
  97. package/artifacts/release/dist/public/bundle/plugins/advanced/commands/OMG:ship.md +46 -0
  98. package/artifacts/release/dist/public/bundle/plugins/advanced/plugin.json +87 -0
  99. package/artifacts/release/dist/public/bundle/registry/bundles/algorithms.yaml +1 -1
  100. package/artifacts/release/dist/public/bundle/registry/bundles/api-twin.yaml +1 -1
  101. package/artifacts/release/dist/public/bundle/registry/bundles/claim-judge.yaml +49 -0
  102. package/artifacts/release/dist/public/bundle/registry/bundles/control-plane.yaml +1 -1
  103. package/artifacts/release/dist/public/bundle/registry/bundles/data-lineage.yaml +1 -1
  104. package/artifacts/release/dist/public/bundle/registry/bundles/delta-classifier.yaml +1 -1
  105. package/artifacts/release/dist/public/bundle/registry/bundles/eval-gate.yaml +1 -1
  106. package/artifacts/release/dist/public/bundle/registry/bundles/health.yaml +1 -1
  107. package/artifacts/release/dist/public/bundle/registry/bundles/hook-governor.yaml +1 -1
  108. package/artifacts/release/dist/public/bundle/registry/bundles/incident-replay.yaml +1 -1
  109. package/artifacts/release/dist/public/bundle/registry/bundles/lsp-pack.yaml +1 -1
  110. package/artifacts/release/dist/public/bundle/registry/bundles/mcp-fabric.yaml +1 -1
  111. package/artifacts/release/dist/public/bundle/registry/bundles/plan-council.yaml +51 -0
  112. package/artifacts/release/dist/public/bundle/registry/bundles/preflight.yaml +1 -1
  113. package/artifacts/release/dist/public/bundle/registry/bundles/proof-gate.yaml +49 -0
  114. package/artifacts/release/dist/public/bundle/registry/bundles/remote-supervisor.yaml +1 -1
  115. package/artifacts/release/dist/public/bundle/registry/bundles/robotics.yaml +1 -1
  116. package/artifacts/release/dist/public/bundle/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  117. package/artifacts/release/dist/public/bundle/registry/bundles/security-check.yaml +1 -1
  118. package/artifacts/release/dist/public/bundle/registry/bundles/test-intent-lock.yaml +49 -0
  119. package/artifacts/release/dist/public/bundle/registry/bundles/tracebank.yaml +1 -1
  120. package/artifacts/release/dist/public/bundle/registry/bundles/vision.yaml +1 -1
  121. package/artifacts/release/dist/public/bundle/registry/omg-capability.schema.json +1 -1
  122. package/artifacts/release/dist/public/bundle/settings.json +76 -4
  123. package/artifacts/release/dist/public/manifest.json +122 -26
  124. package/artifacts/release/plugins/advanced/commands/OMG:code-review.md +114 -0
  125. package/artifacts/release/plugins/advanced/commands/OMG:deep-plan.md +266 -0
  126. package/artifacts/release/plugins/advanced/commands/OMG:handoff.md +115 -0
  127. package/artifacts/release/plugins/advanced/commands/OMG:learn.md +110 -0
  128. package/artifacts/release/plugins/advanced/commands/OMG:maintainer.md +31 -0
  129. package/artifacts/release/plugins/advanced/commands/OMG:ralph-start.md +43 -0
  130. package/artifacts/release/plugins/advanced/commands/OMG:ralph-stop.md +23 -0
  131. package/artifacts/release/plugins/advanced/commands/OMG:security-review.md +16 -0
  132. package/artifacts/release/plugins/advanced/commands/OMG:sequential-thinking.md +20 -0
  133. package/artifacts/release/plugins/advanced/commands/OMG:ship.md +46 -0
  134. package/artifacts/release/plugins/advanced/plugin.json +87 -0
  135. package/artifacts/release/registry/bundles/algorithms.yaml +1 -1
  136. package/artifacts/release/registry/bundles/api-twin.yaml +1 -1
  137. package/artifacts/release/registry/bundles/claim-judge.yaml +49 -0
  138. package/artifacts/release/registry/bundles/control-plane.yaml +1 -1
  139. package/artifacts/release/registry/bundles/data-lineage.yaml +1 -1
  140. package/artifacts/release/registry/bundles/delta-classifier.yaml +1 -1
  141. package/artifacts/release/registry/bundles/eval-gate.yaml +1 -1
  142. package/artifacts/release/registry/bundles/health.yaml +1 -1
  143. package/artifacts/release/registry/bundles/hook-governor.yaml +1 -1
  144. package/artifacts/release/registry/bundles/incident-replay.yaml +1 -1
  145. package/artifacts/release/registry/bundles/lsp-pack.yaml +1 -1
  146. package/artifacts/release/registry/bundles/mcp-fabric.yaml +1 -1
  147. package/artifacts/release/registry/bundles/plan-council.yaml +51 -0
  148. package/artifacts/release/registry/bundles/preflight.yaml +1 -1
  149. package/artifacts/release/registry/bundles/proof-gate.yaml +49 -0
  150. package/artifacts/release/registry/bundles/remote-supervisor.yaml +1 -1
  151. package/artifacts/release/registry/bundles/robotics.yaml +1 -1
  152. package/artifacts/release/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  153. package/artifacts/release/registry/bundles/security-check.yaml +1 -1
  154. package/artifacts/release/registry/bundles/test-intent-lock.yaml +49 -0
  155. package/artifacts/release/registry/bundles/tracebank.yaml +1 -1
  156. package/artifacts/release/registry/bundles/vision.yaml +1 -1
  157. package/artifacts/release/registry/omg-capability.schema.json +1 -1
  158. package/artifacts/release/settings.json +7 -3
  159. package/build/lib/commands/OMG:forge.md +92 -0
  160. package/build/lib/commands/OMG:mode.md +13 -13
  161. package/build/lib/commands/OMG:session-branch.md +17 -1
  162. package/build/lib/commands/OMG:session-fork.md +5 -1
  163. package/build/lib/commands/OMG:session-merge.md +5 -1
  164. package/build/lib/control_plane/openapi.yaml +1 -1
  165. package/build/lib/control_plane/server.py +4 -0
  166. package/build/lib/control_plane/service.py +55 -0
  167. package/build/lib/hooks/setup_wizard.py +21 -1
  168. package/build/lib/hooks/shadow_manager.py +25 -2
  169. package/build/lib/hooks/state_migration.py +3 -0
  170. package/build/lib/plugins/README.md +1 -1
  171. package/build/lib/plugins/advanced/commands/OMG:deep-plan.md +2 -1
  172. package/build/lib/plugins/advanced/plugin.json +1 -1
  173. package/build/lib/plugins/core/plugin.json +1 -1
  174. package/build/lib/plugins/dephealth/cve_scanner.py +91 -0
  175. package/build/lib/plugins/dephealth/vuln_analyzer.py +7 -0
  176. package/build/lib/registry/bundles/algorithms.yaml +1 -1
  177. package/build/lib/registry/bundles/api-twin.yaml +1 -1
  178. package/build/lib/registry/bundles/claim-judge.yaml +1 -1
  179. package/build/lib/registry/bundles/control-plane.yaml +1 -1
  180. package/build/lib/registry/bundles/data-lineage.yaml +1 -1
  181. package/build/lib/registry/bundles/delta-classifier.yaml +1 -1
  182. package/build/lib/registry/bundles/eval-gate.yaml +1 -1
  183. package/build/lib/registry/bundles/health.yaml +1 -1
  184. package/build/lib/registry/bundles/hook-governor.yaml +1 -1
  185. package/build/lib/registry/bundles/incident-replay.yaml +1 -1
  186. package/build/lib/registry/bundles/lsp-pack.yaml +1 -1
  187. package/build/lib/registry/bundles/mcp-fabric.yaml +1 -1
  188. package/build/lib/registry/bundles/plan-council.yaml +2 -2
  189. package/build/lib/registry/bundles/preflight.yaml +1 -1
  190. package/build/lib/registry/bundles/proof-gate.yaml +1 -1
  191. package/build/lib/registry/bundles/remote-supervisor.yaml +1 -1
  192. package/build/lib/registry/bundles/robotics.yaml +1 -1
  193. package/build/lib/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  194. package/build/lib/registry/bundles/security-check.yaml +1 -1
  195. package/build/lib/registry/bundles/test-intent-lock.yaml +1 -1
  196. package/build/lib/registry/bundles/tracebank.yaml +1 -1
  197. package/build/lib/registry/bundles/vision.yaml +1 -1
  198. package/build/lib/registry/omg-capability.schema.json +84 -2
  199. package/build/lib/runtime/adoption.py +13 -5
  200. package/build/lib/runtime/api_twin.py +4 -4
  201. package/build/lib/runtime/artifact_parsers.py +161 -0
  202. package/build/lib/runtime/background_verification.py +48 -0
  203. package/build/lib/runtime/claim_judge.py +184 -7
  204. package/build/lib/runtime/contract_compiler.py +189 -9
  205. package/build/lib/runtime/ecosystem.py +1 -1
  206. package/build/lib/runtime/evidence_query.py +203 -0
  207. package/build/lib/runtime/mcp_memory_server.py +1 -1
  208. package/build/lib/runtime/omg_compat_contract_snapshot.json +2 -2
  209. package/build/lib/runtime/omg_contract_snapshot.json +2 -2
  210. package/build/lib/runtime/omg_mcp_server.py +19 -0
  211. package/build/lib/runtime/playwright_adapter.py +39 -0
  212. package/build/lib/runtime/proof_chain.py +136 -8
  213. package/build/lib/runtime/proof_gate.py +102 -0
  214. package/build/lib/runtime/providers/gemini_provider.py +7 -0
  215. package/build/lib/runtime/providers/kimi_provider.py +7 -0
  216. package/build/lib/runtime/repro_pack.py +292 -0
  217. package/build/lib/runtime/runtime_profile.py +87 -15
  218. package/build/lib/runtime/security_check.py +86 -3
  219. package/build/lib/runtime/test_intent_lock.py +47 -0
  220. package/build/lib/runtime/tracebank.py +33 -3
  221. package/build/lib/runtime/verification_loop.py +73 -0
  222. package/commands/OMG:forge.md +92 -0
  223. package/commands/OMG:mode.md +13 -13
  224. package/commands/OMG:session-branch.md +17 -1
  225. package/commands/OMG:session-fork.md +5 -1
  226. package/commands/OMG:session-merge.md +5 -1
  227. package/control_plane/openapi.yaml +1 -1
  228. package/control_plane/server.py +4 -0
  229. package/control_plane/service.py +55 -0
  230. package/dist/enterprise/bundle/.agents/skills/omg/AGENTS.fragment.md +7 -1
  231. package/dist/enterprise/bundle/.agents/skills/omg/claim-judge/SKILL.md +11 -0
  232. package/dist/enterprise/bundle/.agents/skills/omg/claim-judge/openai.yaml +13 -0
  233. package/dist/enterprise/bundle/.agents/skills/omg/codex-rules.md +4 -0
  234. package/dist/enterprise/bundle/.agents/skills/omg/plan-council/SKILL.md +11 -0
  235. package/dist/enterprise/bundle/.agents/skills/omg/plan-council/openai.yaml +12 -0
  236. package/dist/enterprise/bundle/.agents/skills/omg/proof-gate/SKILL.md +11 -0
  237. package/dist/enterprise/bundle/.agents/skills/omg/proof-gate/openai.yaml +13 -0
  238. package/dist/enterprise/bundle/.agents/skills/omg/test-intent-lock/SKILL.md +11 -0
  239. package/dist/enterprise/bundle/.agents/skills/omg/test-intent-lock/openai.yaml +13 -0
  240. package/dist/enterprise/bundle/.claude-plugin/marketplace.json +3 -3
  241. package/dist/enterprise/bundle/.claude-plugin/plugin.json +1 -1
  242. package/dist/enterprise/bundle/.gemini/settings.json +11 -0
  243. package/dist/enterprise/bundle/.kimi/mcp.json +11 -0
  244. package/dist/enterprise/bundle/.mcp.json +0 -22
  245. package/dist/enterprise/bundle/OMG_COMPAT_CONTRACT.md +14 -1
  246. package/dist/enterprise/bundle/plugins/advanced/commands/OMG:deep-plan.md +51 -6
  247. package/dist/enterprise/bundle/plugins/advanced/commands/OMG:ship.md +1 -1
  248. package/dist/enterprise/bundle/plugins/advanced/plugin.json +1 -1
  249. package/dist/enterprise/bundle/registry/bundles/algorithms.yaml +1 -1
  250. package/dist/enterprise/bundle/registry/bundles/api-twin.yaml +1 -1
  251. package/dist/enterprise/bundle/registry/bundles/claim-judge.yaml +49 -0
  252. package/dist/enterprise/bundle/registry/bundles/control-plane.yaml +1 -1
  253. package/dist/enterprise/bundle/registry/bundles/data-lineage.yaml +1 -1
  254. package/dist/enterprise/bundle/registry/bundles/delta-classifier.yaml +1 -1
  255. package/dist/enterprise/bundle/registry/bundles/eval-gate.yaml +1 -1
  256. package/dist/enterprise/bundle/registry/bundles/health.yaml +1 -1
  257. package/dist/enterprise/bundle/registry/bundles/hook-governor.yaml +1 -1
  258. package/dist/enterprise/bundle/registry/bundles/incident-replay.yaml +1 -1
  259. package/dist/enterprise/bundle/registry/bundles/lsp-pack.yaml +1 -1
  260. package/dist/enterprise/bundle/registry/bundles/mcp-fabric.yaml +1 -1
  261. package/dist/enterprise/bundle/registry/bundles/plan-council.yaml +51 -0
  262. package/dist/enterprise/bundle/registry/bundles/preflight.yaml +1 -1
  263. package/dist/enterprise/bundle/registry/bundles/proof-gate.yaml +49 -0
  264. package/dist/enterprise/bundle/registry/bundles/remote-supervisor.yaml +1 -1
  265. package/dist/enterprise/bundle/registry/bundles/robotics.yaml +1 -1
  266. package/dist/enterprise/bundle/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  267. package/dist/enterprise/bundle/registry/bundles/security-check.yaml +1 -1
  268. package/dist/enterprise/bundle/registry/bundles/test-intent-lock.yaml +49 -0
  269. package/dist/enterprise/bundle/registry/bundles/tracebank.yaml +1 -1
  270. package/dist/enterprise/bundle/registry/bundles/vision.yaml +1 -1
  271. package/dist/enterprise/bundle/registry/omg-capability.schema.json +84 -2
  272. package/dist/enterprise/bundle/settings.json +8 -3
  273. package/dist/enterprise/manifest.json +92 -30
  274. package/dist/public/bundle/.agents/skills/omg/AGENTS.fragment.md +7 -1
  275. package/dist/public/bundle/.agents/skills/omg/claim-judge/SKILL.md +11 -0
  276. package/dist/public/bundle/.agents/skills/omg/claim-judge/openai.yaml +13 -0
  277. package/dist/public/bundle/.agents/skills/omg/codex-rules.md +4 -0
  278. package/dist/public/bundle/.agents/skills/omg/incident-replay/SKILL.md +1 -1
  279. package/dist/public/bundle/.agents/skills/omg/incident-replay/openai.yaml +1 -1
  280. package/dist/public/bundle/.agents/skills/omg/lsp-pack/SKILL.md +1 -1
  281. package/dist/public/bundle/.agents/skills/omg/lsp-pack/openai.yaml +1 -1
  282. package/dist/public/bundle/.agents/skills/omg/mcp-fabric/SKILL.md +1 -1
  283. package/dist/public/bundle/.agents/skills/omg/mcp-fabric/openai.yaml +1 -1
  284. package/dist/public/bundle/.agents/skills/omg/plan-council/SKILL.md +11 -0
  285. package/dist/public/bundle/.agents/skills/omg/plan-council/openai.yaml +12 -0
  286. package/dist/public/bundle/.agents/skills/omg/preflight/SKILL.md +1 -1
  287. package/dist/public/bundle/.agents/skills/omg/preflight/openai.yaml +1 -1
  288. package/dist/public/bundle/.agents/skills/omg/proof-gate/SKILL.md +11 -0
  289. package/dist/public/bundle/.agents/skills/omg/proof-gate/openai.yaml +13 -0
  290. package/dist/public/bundle/.agents/skills/omg/remote-supervisor/SKILL.md +1 -1
  291. package/dist/public/bundle/.agents/skills/omg/remote-supervisor/openai.yaml +1 -1
  292. package/dist/public/bundle/.agents/skills/omg/robotics/SKILL.md +1 -1
  293. package/dist/public/bundle/.agents/skills/omg/robotics/openai.yaml +1 -1
  294. package/dist/public/bundle/.agents/skills/omg/secure-worktree-pipeline/SKILL.md +1 -1
  295. package/dist/public/bundle/.agents/skills/omg/secure-worktree-pipeline/openai.yaml +1 -1
  296. package/dist/public/bundle/.agents/skills/omg/security-check/SKILL.md +1 -1
  297. package/dist/public/bundle/.agents/skills/omg/security-check/openai.yaml +1 -1
  298. package/dist/public/bundle/.agents/skills/omg/test-intent-lock/SKILL.md +11 -0
  299. package/dist/public/bundle/.agents/skills/omg/test-intent-lock/openai.yaml +13 -0
  300. package/dist/public/bundle/.agents/skills/omg/tracebank/SKILL.md +1 -1
  301. package/dist/public/bundle/.agents/skills/omg/tracebank/openai.yaml +1 -1
  302. package/dist/public/bundle/.agents/skills/omg/vision/SKILL.md +1 -1
  303. package/dist/public/bundle/.agents/skills/omg/vision/openai.yaml +1 -1
  304. package/dist/public/bundle/.claude-plugin/marketplace.json +3 -3
  305. package/dist/public/bundle/.claude-plugin/plugin.json +1 -1
  306. package/dist/public/bundle/.gemini/settings.json +11 -0
  307. package/dist/public/bundle/.kimi/mcp.json +11 -0
  308. package/dist/public/bundle/.mcp.json +0 -22
  309. package/dist/public/bundle/OMG_COMPAT_CONTRACT.md +14 -1
  310. package/dist/public/bundle/plugins/advanced/commands/OMG:deep-plan.md +51 -6
  311. package/dist/public/bundle/plugins/advanced/commands/OMG:ship.md +1 -1
  312. package/dist/public/bundle/plugins/advanced/plugin.json +1 -1
  313. package/dist/public/bundle/registry/bundles/algorithms.yaml +1 -1
  314. package/dist/public/bundle/registry/bundles/api-twin.yaml +1 -1
  315. package/dist/public/bundle/registry/bundles/claim-judge.yaml +49 -0
  316. package/dist/public/bundle/registry/bundles/control-plane.yaml +1 -1
  317. package/dist/public/bundle/registry/bundles/data-lineage.yaml +1 -1
  318. package/dist/public/bundle/registry/bundles/delta-classifier.yaml +1 -1
  319. package/dist/public/bundle/registry/bundles/eval-gate.yaml +1 -1
  320. package/dist/public/bundle/registry/bundles/health.yaml +1 -1
  321. package/dist/public/bundle/registry/bundles/hook-governor.yaml +1 -1
  322. package/dist/public/bundle/registry/bundles/incident-replay.yaml +1 -1
  323. package/dist/public/bundle/registry/bundles/lsp-pack.yaml +1 -1
  324. package/dist/public/bundle/registry/bundles/mcp-fabric.yaml +1 -1
  325. package/dist/public/bundle/registry/bundles/plan-council.yaml +51 -0
  326. package/dist/public/bundle/registry/bundles/preflight.yaml +1 -1
  327. package/dist/public/bundle/registry/bundles/proof-gate.yaml +49 -0
  328. package/dist/public/bundle/registry/bundles/remote-supervisor.yaml +1 -1
  329. package/dist/public/bundle/registry/bundles/robotics.yaml +1 -1
  330. package/dist/public/bundle/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  331. package/dist/public/bundle/registry/bundles/security-check.yaml +1 -1
  332. package/dist/public/bundle/registry/bundles/test-intent-lock.yaml +49 -0
  333. package/dist/public/bundle/registry/bundles/tracebank.yaml +1 -1
  334. package/dist/public/bundle/registry/bundles/vision.yaml +1 -1
  335. package/dist/public/bundle/registry/omg-capability.schema.json +84 -2
  336. package/dist/public/bundle/settings.json +9 -4
  337. package/dist/public/manifest.json +112 -50
  338. package/docs/proof.md +7 -6
  339. package/hooks/setup_wizard.py +21 -1
  340. package/hooks/shadow_manager.py +25 -2
  341. package/hooks/state_migration.py +3 -0
  342. package/hud/omg-hud.mjs +66 -3
  343. package/package.json +1 -1
  344. package/plugins/README.md +1 -1
  345. package/plugins/advanced/commands/OMG:deep-plan.md +2 -1
  346. package/plugins/advanced/plugin.json +1 -1
  347. package/plugins/core/plugin.json +1 -1
  348. package/plugins/dephealth/cve_scanner.py +91 -0
  349. package/plugins/dephealth/vuln_analyzer.py +7 -0
  350. package/pyproject.toml +5 -1
  351. package/registry/bundles/algorithms.yaml +1 -1
  352. package/registry/bundles/api-twin.yaml +1 -1
  353. package/registry/bundles/claim-judge.yaml +1 -1
  354. package/registry/bundles/control-plane.yaml +1 -1
  355. package/registry/bundles/data-lineage.yaml +1 -1
  356. package/registry/bundles/delta-classifier.yaml +1 -1
  357. package/registry/bundles/eval-gate.yaml +1 -1
  358. package/registry/bundles/health.yaml +1 -1
  359. package/registry/bundles/hook-governor.yaml +1 -1
  360. package/registry/bundles/incident-replay.yaml +1 -1
  361. package/registry/bundles/lsp-pack.yaml +1 -1
  362. package/registry/bundles/mcp-fabric.yaml +1 -1
  363. package/registry/bundles/plan-council.yaml +2 -2
  364. package/registry/bundles/preflight.yaml +1 -1
  365. package/registry/bundles/proof-gate.yaml +1 -1
  366. package/registry/bundles/remote-supervisor.yaml +1 -1
  367. package/registry/bundles/robotics.yaml +1 -1
  368. package/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  369. package/registry/bundles/security-check.yaml +1 -1
  370. package/registry/bundles/test-intent-lock.yaml +1 -1
  371. package/registry/bundles/tracebank.yaml +1 -1
  372. package/registry/bundles/vision.yaml +1 -1
  373. package/registry/omg-capability.schema.json +84 -2
  374. package/runtime/adoption.py +13 -5
  375. package/runtime/api_twin.py +4 -4
  376. package/runtime/artifact_parsers.py +161 -0
  377. package/runtime/background_verification.py +48 -0
  378. package/runtime/claim_judge.py +184 -7
  379. package/runtime/contract_compiler.py +189 -9
  380. package/runtime/ecosystem.py +1 -1
  381. package/runtime/evidence_query.py +203 -0
  382. package/runtime/mcp_memory_server.py +1 -1
  383. package/runtime/omg_compat_contract_snapshot.json +2 -2
  384. package/runtime/omg_contract_snapshot.json +2 -2
  385. package/runtime/omg_mcp_server.py +19 -0
  386. package/runtime/playwright_adapter.py +39 -0
  387. package/runtime/proof_chain.py +136 -8
  388. package/runtime/proof_gate.py +102 -0
  389. package/runtime/providers/gemini_provider.py +7 -0
  390. package/runtime/providers/kimi_provider.py +7 -0
  391. package/runtime/repro_pack.py +292 -0
  392. package/runtime/runtime_profile.py +87 -15
  393. package/runtime/security_check.py +86 -3
  394. package/runtime/test_intent_lock.py +47 -0
  395. package/runtime/tracebank.py +33 -3
  396. package/runtime/verification_loop.py +73 -0
  397. package/scripts/omg.py +31 -4
  398. package/settings.json +8 -3
  399. package/tools/python_sandbox.py +9 -6
  400. package/tools/session_snapshot.py +146 -40
@@ -0,0 +1,161 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from pathlib import Path
5
+ from typing import Any
6
+ from xml.etree import ElementTree
7
+
8
+
9
+ def parse_junit(path: str) -> dict[str, Any]:
10
+ file_path = Path(path)
11
+ if not file_path.exists():
12
+ return {"valid": False, "summary": {}, "error": "file_not_found"}
13
+
14
+ try:
15
+ root = ElementTree.parse(file_path).getroot()
16
+ except (ElementTree.ParseError, OSError, ValueError) as exc:
17
+ return {"valid": False, "summary": {}, "error": f"junit_parse_error:{exc}"}
18
+
19
+ root_name = _local_name(root.tag)
20
+ if root_name not in {"testsuite", "testsuites"}:
21
+ return {
22
+ "valid": False,
23
+ "summary": {"root": root_name},
24
+ "error": "junit_invalid_root",
25
+ }
26
+
27
+ tests_value = root.attrib.get("tests", "")
28
+ return {
29
+ "valid": True,
30
+ "summary": {"root": root_name, "tests": str(tests_value).strip()},
31
+ "error": None,
32
+ }
33
+
34
+
35
+ def parse_sarif(path: str) -> dict[str, Any]:
36
+ payload, error = _load_json(Path(path))
37
+ if error:
38
+ return {"valid": False, "summary": {}, "error": error}
39
+
40
+ runs = payload.get("runs") if isinstance(payload, dict) else None
41
+ if not isinstance(runs, list):
42
+ return {"valid": False, "summary": {}, "error": "sarif_missing_runs"}
43
+
44
+ return {
45
+ "valid": True,
46
+ "summary": {"runs": len(runs), "version": str(payload.get("version", "")).strip()},
47
+ "error": None,
48
+ }
49
+
50
+
51
+ def parse_coverage(path: str) -> dict[str, Any]:
52
+ file_path = Path(path)
53
+ if not file_path.exists():
54
+ return {"valid": False, "summary": {}, "error": "file_not_found"}
55
+
56
+ xml_result = _parse_coverage_xml(file_path)
57
+ if xml_result["valid"]:
58
+ return xml_result
59
+
60
+ json_result = _parse_coverage_json(file_path)
61
+ if json_result["valid"]:
62
+ return json_result
63
+
64
+ return {
65
+ "valid": False,
66
+ "summary": {},
67
+ "error": xml_result.get("error") or json_result.get("error") or "coverage_missing_keys",
68
+ }
69
+
70
+
71
+ def parse_browser_trace(path: str) -> dict[str, Any]:
72
+ payload, error = _load_json(Path(path))
73
+ if error:
74
+ return {"valid": False, "summary": {}, "error": error}
75
+
76
+ if not isinstance(payload, dict):
77
+ return {"valid": False, "summary": {}, "error": "browser_trace_invalid_payload"}
78
+
79
+ has_trace = "trace" in payload
80
+ has_events = isinstance(payload.get("events"), list)
81
+ if not (has_trace or has_events):
82
+ return {
83
+ "valid": False,
84
+ "summary": {},
85
+ "error": "browser_trace_missing_trace_or_events",
86
+ }
87
+
88
+ return {
89
+ "valid": True,
90
+ "summary": {"has_trace": has_trace, "event_count": len(payload.get("events", [])) if has_events else 0},
91
+ "error": None,
92
+ }
93
+
94
+
95
+ def parse_diff_hunk(path: str) -> dict[str, Any]:
96
+ file_path = Path(path)
97
+ if not file_path.exists():
98
+ return {"valid": False, "summary": {}, "error": "file_not_found"}
99
+
100
+ try:
101
+ content = file_path.read_text(encoding="utf-8")
102
+ except (OSError, UnicodeDecodeError) as exc:
103
+ return {"valid": False, "summary": {}, "error": f"diff_read_error:{exc}"}
104
+
105
+ if "@@" not in content:
106
+ return {"valid": False, "summary": {}, "error": "diff_missing_hunk_marker"}
107
+
108
+ hunk_count = content.count("@@") // 2 if content.count("@@") >= 2 else 1
109
+ return {"valid": True, "summary": {"hunk_count": hunk_count}, "error": None}
110
+
111
+
112
+ def _parse_coverage_xml(file_path: Path) -> dict[str, Any]:
113
+ try:
114
+ root = ElementTree.parse(file_path).getroot()
115
+ except (ElementTree.ParseError, OSError, ValueError):
116
+ return {"valid": False, "summary": {}, "error": "coverage_xml_parse_error"}
117
+
118
+ if "line-rate" in root.attrib:
119
+ return {
120
+ "valid": True,
121
+ "summary": {"line-rate": str(root.attrib.get("line-rate", "")).strip()},
122
+ "error": None,
123
+ }
124
+
125
+ return {"valid": False, "summary": {}, "error": "coverage_missing_line_rate"}
126
+
127
+
128
+ def _parse_coverage_json(file_path: Path) -> dict[str, Any]:
129
+ payload, error = _load_json(file_path)
130
+ if error:
131
+ return {"valid": False, "summary": {}, "error": error}
132
+
133
+ if not isinstance(payload, dict):
134
+ return {"valid": False, "summary": {}, "error": "coverage_json_invalid_payload"}
135
+
136
+ if "coverage" not in payload:
137
+ return {"valid": False, "summary": {}, "error": "coverage_missing_coverage_key"}
138
+
139
+ return {
140
+ "valid": True,
141
+ "summary": {"coverage": payload.get("coverage")},
142
+ "error": None,
143
+ }
144
+
145
+
146
+ def _load_json(file_path: Path) -> tuple[Any, str | None]:
147
+ if not file_path.exists():
148
+ return {}, "file_not_found"
149
+
150
+ try:
151
+ payload = json.loads(file_path.read_text(encoding="utf-8"))
152
+ except (OSError, UnicodeDecodeError, json.JSONDecodeError) as exc:
153
+ return {}, f"json_parse_error:{exc}"
154
+
155
+ return payload, None
156
+
157
+
158
+ def _local_name(tag: str) -> str:
159
+ if "}" not in tag:
160
+ return tag
161
+ return tag.rsplit("}", 1)[-1]
@@ -0,0 +1,48 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from datetime import datetime, timezone
5
+ from pathlib import Path
6
+ from typing import Any
7
+
8
+ BACKGROUND_VERIFICATION_REL_PATH = Path(".omg") / "state" / "background-verification.json"
9
+
10
+ _VALID_STATUSES = frozenset({"running", "ok", "error", "blocked"})
11
+
12
+
13
+ def publish_verification_state(
14
+ project_dir: str,
15
+ run_id: str,
16
+ status: str,
17
+ blockers: list[str],
18
+ evidence_links: list[str],
19
+ progress: dict[str, Any],
20
+ ) -> str:
21
+ state = {
22
+ "schema": "BackgroundVerificationState",
23
+ "schema_version": 2,
24
+ "run_id": run_id,
25
+ "status": status if status in _VALID_STATUSES else "error",
26
+ "blockers": blockers,
27
+ "evidence_links": evidence_links,
28
+ "progress": progress,
29
+ "updated_at": datetime.now(timezone.utc).isoformat(),
30
+ }
31
+
32
+ path = Path(project_dir) / BACKGROUND_VERIFICATION_REL_PATH
33
+ path.parent.mkdir(parents=True, exist_ok=True)
34
+ path.write_text(json.dumps(state, indent=2, ensure_ascii=True), encoding="utf-8")
35
+ return str(path)
36
+
37
+
38
+ def read_verification_state(project_dir: str) -> dict[str, Any] | None:
39
+ path = Path(project_dir) / BACKGROUND_VERIFICATION_REL_PATH
40
+ if not path.exists():
41
+ return None
42
+ try:
43
+ payload = json.loads(path.read_text(encoding="utf-8"))
44
+ if isinstance(payload, dict) and payload.get("schema") == "BackgroundVerificationState":
45
+ return payload
46
+ except (json.JSONDecodeError, OSError):
47
+ pass
48
+ return None
@@ -1,15 +1,68 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import json
4
+ from pathlib import Path
3
5
  from typing import Any
4
6
 
7
+ from runtime import artifact_parsers
8
+ from runtime.evidence_query import get_evidence_pack
9
+
10
+
11
+ def judge_claims(project_dir: str, claims: list[dict[str, Any]]) -> dict[str, Any]:
12
+ root = Path(project_dir)
13
+ evidence_dir = root / ".omg" / "evidence"
14
+ evidence_dir.mkdir(parents=True, exist_ok=True)
15
+
16
+ results: list[dict[str, Any]] = []
17
+ aggregate_tokens: list[str] = []
18
+
19
+ for index, claim in enumerate(claims):
20
+ run_id = str(claim.get("run_id", "")).strip()
21
+ resolved_claim = dict(claim)
22
+
23
+ if run_id:
24
+ evidence_pack = get_evidence_pack(project_dir, run_id)
25
+ trace_ids: list[str] = []
26
+ if isinstance(evidence_pack, dict):
27
+ trace_ids = _as_non_empty_str_list(evidence_pack.get("trace_ids"))
28
+ resolved_claim = {
29
+ **claim,
30
+ "artifacts": [f".omg/evidence/{run_id}.json"],
31
+ "trace_ids": trace_ids,
32
+ }
33
+
34
+ result = judge_claim(resolved_claim)
35
+ result_with_run = {**result, "run_id": run_id}
36
+ results.append(result_with_run)
37
+ aggregate_tokens.append(str(result.get("verdict", "")).strip().lower())
38
+
39
+ artifact_run_id = run_id or f"unknown-{index + 1}"
40
+ artifact_path = evidence_dir / f"claim-judge-{_sanitize_run_id(artifact_run_id)}.json"
41
+ artifact_payload = {
42
+ "schema": "ClaimJudgeResult",
43
+ "run_id": run_id,
44
+ "claim": claim,
45
+ "result": result,
46
+ }
47
+ artifact_path.write_text(json.dumps(artifact_payload, indent=2, sort_keys=True), encoding="utf-8")
48
+
49
+ verdict = "pass"
50
+ if any(token == "fail" for token in aggregate_tokens):
51
+ verdict = "fail"
52
+ elif any(token == "block" for token in aggregate_tokens):
53
+ verdict = "insufficient"
54
+
55
+ return {"schema": "ClaimJudgeResults", "verdict": verdict, "results": results}
56
+
5
57
 
6
58
  def judge_claim(claim: dict[str, Any]) -> dict[str, Any]:
7
- claim_type = str(claim.get("claim_type", "")).strip()
8
- subject = str(claim.get("subject", "")).strip()
9
- artifacts = _as_non_empty_str_list(claim.get("artifacts"))
10
- trace_ids = _as_non_empty_str_list(claim.get("trace_ids"))
11
- security_scans = claim.get("security_scans")
12
- browser_evidence = claim.get("browser_evidence")
59
+ normalized_claim = _normalize_claim(claim)
60
+ claim_type = str(normalized_claim.get("claim_type", "")).strip()
61
+ subject = str(normalized_claim.get("subject", "")).strip()
62
+ artifacts = _as_non_empty_str_list(normalized_claim.get("artifacts"))
63
+ trace_ids = _as_non_empty_str_list(normalized_claim.get("trace_ids"))
64
+ security_scans = normalized_claim.get("security_scans")
65
+ browser_evidence = normalized_claim.get("browser_evidence")
13
66
 
14
67
  reasons: list[dict[str, Any]] = []
15
68
 
@@ -49,6 +102,22 @@ def judge_claim(claim: dict[str, Any]) -> dict[str, Any]:
49
102
  }
50
103
  )
51
104
 
105
+ raw_artifacts = _extract_artifact_dicts(claim)
106
+ project_dir = str(claim.get("project_dir", "."))
107
+ for artifact in raw_artifacts:
108
+ parse_result = parse_artifact_content(artifact=artifact, project_dir=project_dir)
109
+ if parse_result.get("parsed"):
110
+ continue
111
+ kind = str(parse_result.get("kind", "artifact")).strip().lower() or "artifact"
112
+ error = str(parse_result.get("error", "parse_error")).strip() or "parse_error"
113
+ reasons.append(
114
+ {
115
+ "code": f"artifact_parse_failed_{kind}",
116
+ "message": f"Artifact content parse failed for {kind}: {error}",
117
+ "field": "evidence.artifacts",
118
+ }
119
+ )
120
+
52
121
  hard_fail_codes = {"missing_artifacts", "missing_trace_ids"}
53
122
  if any(reason.get("code") in hard_fail_codes for reason in reasons):
54
123
  verdict = "fail"
@@ -66,19 +135,105 @@ def judge_claim(claim: dict[str, Any]) -> dict[str, Any]:
66
135
  "evidence": {
67
136
  "artifacts": artifacts,
68
137
  "trace_ids": trace_ids,
69
- "lineage": claim.get("lineage") if isinstance(claim.get("lineage"), dict) else {},
138
+ "lineage": normalized_claim.get("lineage") if isinstance(normalized_claim.get("lineage"), dict) else {},
70
139
  "security_scans": security_scans if isinstance(security_scans, list) else [],
71
140
  "browser_evidence": browser_evidence if isinstance(browser_evidence, list) else [],
72
141
  },
73
142
  }
74
143
 
75
144
 
145
+ def _normalize_claim(claim: dict[str, Any]) -> dict[str, Any]:
146
+ evidence = _as_dict(claim.get("evidence"))
147
+ artifact_refs = _as_non_empty_str_list(claim.get("artifacts"))
148
+ artifact_refs.extend(_normalize_artifact_records(evidence.get("artifacts")))
149
+
150
+ trace_ids = _as_non_empty_str_list(evidence.get("trace_ids"))
151
+ if not trace_ids:
152
+ trace_ids = _as_non_empty_str_list(claim.get("trace_ids"))
153
+
154
+ claim_lineage = claim.get("lineage")
155
+ lineage = claim_lineage if isinstance(claim_lineage, dict) else _as_dict(evidence.get("lineage"))
156
+
157
+ claim_security_scans = claim.get("security_scans")
158
+ security_scans = claim_security_scans if isinstance(claim_security_scans, list) else _as_non_empty_dict_list(evidence.get("security_scans"))
159
+
160
+ claim_browser_evidence = claim.get("browser_evidence")
161
+ browser_evidence = claim_browser_evidence if isinstance(claim_browser_evidence, list) else _as_non_empty_dict_list(evidence.get("browser_evidence"))
162
+
163
+ return {
164
+ "schema_version": claim.get("schema_version", 1),
165
+ "claim_type": claim.get("claim_type", ""),
166
+ "subject": claim.get("subject", ""),
167
+ "artifacts": artifact_refs,
168
+ "trace_ids": trace_ids,
169
+ "lineage": lineage,
170
+ "security_scans": security_scans,
171
+ "browser_evidence": browser_evidence,
172
+ }
173
+
174
+
175
+ def _normalize_artifact_records(value: Any) -> list[str]:
176
+ if not isinstance(value, list):
177
+ return []
178
+
179
+ refs: list[str] = []
180
+ for item in value:
181
+ if isinstance(item, str):
182
+ cleaned = item.strip()
183
+ if cleaned:
184
+ refs.append(cleaned)
185
+ continue
186
+ if not isinstance(item, dict):
187
+ continue
188
+ for field in ("kind", "path", "sha256", "parser", "summary", "trace_id"):
189
+ field_value = str(item.get(field, "")).strip()
190
+ if not field_value:
191
+ raise ValueError(f"claim_artifact_missing_{field}")
192
+ refs.append(str(item.get("path", "")).strip())
193
+ return refs
194
+
195
+
196
+ def parse_artifact_content(artifact: dict[str, Any], project_dir: str) -> dict[str, Any]:
197
+ kind = str(artifact.get("kind", "")).strip().lower()
198
+ path_value = str(artifact.get("path", "")).strip()
199
+ if not kind or not path_value:
200
+ return {"parsed": False, "kind": kind or "unknown", "summary": {}, "error": "missing_kind_or_path"}
201
+
202
+ parser = _PARSERS.get(kind)
203
+ if parser is None:
204
+ return {"parsed": False, "kind": kind, "summary": {}, "error": "unsupported_artifact_kind"}
205
+
206
+ file_path = Path(path_value)
207
+ if not file_path.is_absolute():
208
+ file_path = Path(project_dir) / file_path
209
+
210
+ parsed = parser(str(file_path))
211
+ return {
212
+ "parsed": bool(parsed.get("valid")),
213
+ "kind": kind,
214
+ "summary": parsed.get("summary", {}),
215
+ "error": parsed.get("error"),
216
+ }
217
+
218
+
76
219
  def _as_non_empty_str_list(value: Any) -> list[str]:
77
220
  if not isinstance(value, list):
78
221
  return []
79
222
  return [str(item).strip() for item in value if str(item).strip()]
80
223
 
81
224
 
225
+ def _as_non_empty_dict_list(value: Any) -> list[dict[str, Any]]:
226
+ if not isinstance(value, list):
227
+ return []
228
+ return [item for item in value if isinstance(item, dict)]
229
+
230
+
231
+ def _as_dict(value: Any) -> dict[str, Any]:
232
+ if not isinstance(value, dict):
233
+ return {}
234
+ return value
235
+
236
+
82
237
  def _has_failed_scan(value: Any) -> bool:
83
238
  if not isinstance(value, list):
84
239
  return False
@@ -93,3 +248,25 @@ def _has_failed_scan(value: Any) -> bool:
93
248
  if isinstance(unresolved_risks, list) and unresolved_risks:
94
249
  return True
95
250
  return False
251
+
252
+
253
+ def _extract_artifact_dicts(claim: dict[str, Any]) -> list[dict[str, Any]]:
254
+ evidence = _as_dict(claim.get("evidence"))
255
+ raw_artifacts = evidence.get("artifacts")
256
+ if not isinstance(raw_artifacts, list):
257
+ return []
258
+ return [item for item in raw_artifacts if isinstance(item, dict)]
259
+
260
+
261
+ _PARSERS: dict[str, Any] = {
262
+ "junit": artifact_parsers.parse_junit,
263
+ "sarif": artifact_parsers.parse_sarif,
264
+ "coverage": artifact_parsers.parse_coverage,
265
+ "browser_trace": artifact_parsers.parse_browser_trace,
266
+ "diff_hunk": artifact_parsers.parse_diff_hunk,
267
+ }
268
+
269
+
270
+ def _sanitize_run_id(value: str) -> str:
271
+ cleaned = "".join(ch if ch.isalnum() or ch in {"-", "_", "."} else "-" for ch in value.strip())
272
+ return cleaned or "unknown"