@trac3er/oh-my-god 2.1.1 → 2.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (351) hide show
  1. package/.agents/skills/omg/AGENTS.fragment.md +2 -2
  2. package/.agents/skills/omg/algorithms/SKILL.md +1 -1
  3. package/.agents/skills/omg/algorithms/openai.yaml +1 -1
  4. package/.agents/skills/omg/api-twin/SKILL.md +1 -1
  5. package/.agents/skills/omg/api-twin/openai.yaml +1 -1
  6. package/.agents/skills/omg/claim-judge/SKILL.md +1 -1
  7. package/.agents/skills/omg/claim-judge/openai.yaml +1 -1
  8. package/.agents/skills/omg/codex-rules.md +1 -1
  9. package/.agents/skills/omg/control-plane/SKILL.md +1 -1
  10. package/.agents/skills/omg/control-plane/openai.yaml +1 -1
  11. package/.agents/skills/omg/data-lineage/SKILL.md +1 -1
  12. package/.agents/skills/omg/data-lineage/openai.yaml +1 -1
  13. package/.agents/skills/omg/delta-classifier/SKILL.md +1 -1
  14. package/.agents/skills/omg/delta-classifier/openai.yaml +1 -1
  15. package/.agents/skills/omg/eval-gate/SKILL.md +1 -1
  16. package/.agents/skills/omg/eval-gate/openai.yaml +1 -1
  17. package/.agents/skills/omg/health/SKILL.md +1 -1
  18. package/.agents/skills/omg/health/openai.yaml +1 -1
  19. package/.agents/skills/omg/hook-governor/SKILL.md +1 -1
  20. package/.agents/skills/omg/hook-governor/openai.yaml +1 -1
  21. package/.agents/skills/omg/incident-replay/SKILL.md +1 -1
  22. package/.agents/skills/omg/incident-replay/openai.yaml +1 -1
  23. package/.agents/skills/omg/lsp-pack/SKILL.md +1 -1
  24. package/.agents/skills/omg/lsp-pack/openai.yaml +1 -1
  25. package/.agents/skills/omg/mcp-fabric/SKILL.md +1 -1
  26. package/.agents/skills/omg/mcp-fabric/openai.yaml +1 -1
  27. package/.agents/skills/omg/plan-council/SKILL.md +1 -1
  28. package/.agents/skills/omg/plan-council/openai.yaml +1 -1
  29. package/.agents/skills/omg/preflight/SKILL.md +1 -1
  30. package/.agents/skills/omg/preflight/openai.yaml +1 -1
  31. package/.agents/skills/omg/proof-gate/SKILL.md +1 -1
  32. package/.agents/skills/omg/proof-gate/openai.yaml +1 -1
  33. package/.agents/skills/omg/remote-supervisor/SKILL.md +1 -1
  34. package/.agents/skills/omg/remote-supervisor/openai.yaml +1 -1
  35. package/.agents/skills/omg/robotics/SKILL.md +1 -1
  36. package/.agents/skills/omg/robotics/openai.yaml +1 -1
  37. package/.agents/skills/omg/secure-worktree-pipeline/SKILL.md +1 -1
  38. package/.agents/skills/omg/secure-worktree-pipeline/openai.yaml +1 -1
  39. package/.agents/skills/omg/security-check/SKILL.md +1 -1
  40. package/.agents/skills/omg/security-check/openai.yaml +1 -1
  41. package/.agents/skills/omg/test-intent-lock/SKILL.md +1 -1
  42. package/.agents/skills/omg/test-intent-lock/openai.yaml +1 -1
  43. package/.agents/skills/omg/tracebank/SKILL.md +1 -1
  44. package/.agents/skills/omg/tracebank/openai.yaml +1 -1
  45. package/.agents/skills/omg/vision/SKILL.md +1 -1
  46. package/.agents/skills/omg/vision/openai.yaml +1 -1
  47. package/.claude-plugin/marketplace.json +3 -3
  48. package/.claude-plugin/plugin.json +1 -1
  49. package/CHANGELOG.md +5 -0
  50. package/CLI-ADAPTER-MAP.md +3 -3
  51. package/OMG-setup.sh +114 -1
  52. package/OMG_COMPAT_CONTRACT.md +1 -1
  53. package/README.md +2 -1
  54. package/artifacts/release/.claude-plugin/marketplace.json +3 -3
  55. package/artifacts/release/.claude-plugin/plugin.json +1 -1
  56. package/artifacts/release/OMG_COMPAT_CONTRACT.md +1 -1
  57. package/artifacts/release/dist/enterprise/bundle/.claude-plugin/marketplace.json +3 -3
  58. package/artifacts/release/dist/enterprise/bundle/.claude-plugin/plugin.json +1 -1
  59. package/artifacts/release/dist/enterprise/bundle/OMG_COMPAT_CONTRACT.md +1 -1
  60. package/artifacts/release/dist/enterprise/bundle/plugins/advanced/plugin.json +26 -9
  61. package/artifacts/release/dist/enterprise/bundle/registry/bundles/algorithms.yaml +1 -1
  62. package/artifacts/release/dist/enterprise/bundle/registry/bundles/api-twin.yaml +1 -1
  63. package/artifacts/release/dist/enterprise/bundle/registry/bundles/claim-judge.yaml +1 -1
  64. package/artifacts/release/dist/enterprise/bundle/registry/bundles/control-plane.yaml +1 -1
  65. package/artifacts/release/dist/enterprise/bundle/registry/bundles/data-lineage.yaml +1 -1
  66. package/artifacts/release/dist/enterprise/bundle/registry/bundles/delta-classifier.yaml +1 -1
  67. package/artifacts/release/dist/enterprise/bundle/registry/bundles/eval-gate.yaml +1 -1
  68. package/artifacts/release/dist/enterprise/bundle/registry/bundles/health.yaml +1 -1
  69. package/artifacts/release/dist/enterprise/bundle/registry/bundles/hook-governor.yaml +1 -1
  70. package/artifacts/release/dist/enterprise/bundle/registry/bundles/incident-replay.yaml +1 -1
  71. package/artifacts/release/dist/enterprise/bundle/registry/bundles/lsp-pack.yaml +1 -1
  72. package/artifacts/release/dist/enterprise/bundle/registry/bundles/mcp-fabric.yaml +1 -1
  73. package/artifacts/release/dist/enterprise/bundle/registry/bundles/plan-council.yaml +1 -1
  74. package/artifacts/release/dist/enterprise/bundle/registry/bundles/preflight.yaml +1 -1
  75. package/artifacts/release/dist/enterprise/bundle/registry/bundles/proof-gate.yaml +1 -1
  76. package/artifacts/release/dist/enterprise/bundle/registry/bundles/remote-supervisor.yaml +1 -1
  77. package/artifacts/release/dist/enterprise/bundle/registry/bundles/robotics.yaml +1 -1
  78. package/artifacts/release/dist/enterprise/bundle/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  79. package/artifacts/release/dist/enterprise/bundle/registry/bundles/security-check.yaml +1 -1
  80. package/artifacts/release/dist/enterprise/bundle/registry/bundles/test-intent-lock.yaml +1 -1
  81. package/artifacts/release/dist/enterprise/bundle/registry/bundles/tracebank.yaml +1 -1
  82. package/artifacts/release/dist/enterprise/bundle/registry/bundles/vision.yaml +1 -1
  83. package/artifacts/release/dist/enterprise/bundle/registry/omg-capability.schema.json +1 -1
  84. package/artifacts/release/dist/enterprise/bundle/settings.json +3 -3
  85. package/artifacts/release/dist/enterprise/manifest.json +30 -40
  86. package/artifacts/release/dist/public/bundle/.claude-plugin/marketplace.json +3 -3
  87. package/artifacts/release/dist/public/bundle/.claude-plugin/plugin.json +1 -1
  88. package/artifacts/release/dist/public/bundle/OMG_COMPAT_CONTRACT.md +1 -1
  89. package/artifacts/release/dist/public/bundle/plugins/advanced/plugin.json +26 -9
  90. package/artifacts/release/dist/public/bundle/registry/bundles/algorithms.yaml +1 -1
  91. package/artifacts/release/dist/public/bundle/registry/bundles/api-twin.yaml +1 -1
  92. package/artifacts/release/dist/public/bundle/registry/bundles/claim-judge.yaml +1 -1
  93. package/artifacts/release/dist/public/bundle/registry/bundles/control-plane.yaml +1 -1
  94. package/artifacts/release/dist/public/bundle/registry/bundles/data-lineage.yaml +1 -1
  95. package/artifacts/release/dist/public/bundle/registry/bundles/delta-classifier.yaml +1 -1
  96. package/artifacts/release/dist/public/bundle/registry/bundles/eval-gate.yaml +1 -1
  97. package/artifacts/release/dist/public/bundle/registry/bundles/health.yaml +1 -1
  98. package/artifacts/release/dist/public/bundle/registry/bundles/hook-governor.yaml +1 -1
  99. package/artifacts/release/dist/public/bundle/registry/bundles/incident-replay.yaml +1 -1
  100. package/artifacts/release/dist/public/bundle/registry/bundles/lsp-pack.yaml +1 -1
  101. package/artifacts/release/dist/public/bundle/registry/bundles/mcp-fabric.yaml +1 -1
  102. package/artifacts/release/dist/public/bundle/registry/bundles/plan-council.yaml +1 -1
  103. package/artifacts/release/dist/public/bundle/registry/bundles/preflight.yaml +1 -1
  104. package/artifacts/release/dist/public/bundle/registry/bundles/proof-gate.yaml +1 -1
  105. package/artifacts/release/dist/public/bundle/registry/bundles/remote-supervisor.yaml +1 -1
  106. package/artifacts/release/dist/public/bundle/registry/bundles/robotics.yaml +1 -1
  107. package/artifacts/release/dist/public/bundle/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  108. package/artifacts/release/dist/public/bundle/registry/bundles/security-check.yaml +1 -1
  109. package/artifacts/release/dist/public/bundle/registry/bundles/test-intent-lock.yaml +1 -1
  110. package/artifacts/release/dist/public/bundle/registry/bundles/tracebank.yaml +1 -1
  111. package/artifacts/release/dist/public/bundle/registry/bundles/vision.yaml +1 -1
  112. package/artifacts/release/dist/public/bundle/registry/omg-capability.schema.json +1 -1
  113. package/artifacts/release/dist/public/bundle/settings.json +3 -3
  114. package/artifacts/release/dist/public/manifest.json +30 -40
  115. package/artifacts/release/plugins/advanced/plugin.json +26 -9
  116. package/artifacts/release/registry/bundles/algorithms.yaml +1 -1
  117. package/artifacts/release/registry/bundles/api-twin.yaml +1 -1
  118. package/artifacts/release/registry/bundles/claim-judge.yaml +1 -1
  119. package/artifacts/release/registry/bundles/control-plane.yaml +1 -1
  120. package/artifacts/release/registry/bundles/data-lineage.yaml +1 -1
  121. package/artifacts/release/registry/bundles/delta-classifier.yaml +1 -1
  122. package/artifacts/release/registry/bundles/eval-gate.yaml +1 -1
  123. package/artifacts/release/registry/bundles/health.yaml +1 -1
  124. package/artifacts/release/registry/bundles/hook-governor.yaml +1 -1
  125. package/artifacts/release/registry/bundles/incident-replay.yaml +1 -1
  126. package/artifacts/release/registry/bundles/lsp-pack.yaml +1 -1
  127. package/artifacts/release/registry/bundles/mcp-fabric.yaml +1 -1
  128. package/artifacts/release/registry/bundles/plan-council.yaml +1 -1
  129. package/artifacts/release/registry/bundles/preflight.yaml +1 -1
  130. package/artifacts/release/registry/bundles/proof-gate.yaml +1 -1
  131. package/artifacts/release/registry/bundles/remote-supervisor.yaml +1 -1
  132. package/artifacts/release/registry/bundles/robotics.yaml +1 -1
  133. package/artifacts/release/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  134. package/artifacts/release/registry/bundles/security-check.yaml +1 -1
  135. package/artifacts/release/registry/bundles/test-intent-lock.yaml +1 -1
  136. package/artifacts/release/registry/bundles/tracebank.yaml +1 -1
  137. package/artifacts/release/registry/bundles/vision.yaml +1 -1
  138. package/artifacts/release/registry/omg-capability.schema.json +1 -1
  139. package/artifacts/release/settings.json +3 -3
  140. package/build/lib/commands/OMG:profile-review.md +43 -0
  141. package/build/lib/commands/OMG:validate.md +59 -0
  142. package/build/lib/hooks/_agent_registry.py +2 -0
  143. package/build/lib/hooks/firewall.py +146 -2
  144. package/build/lib/hooks/intentgate-keyword-detector.py +15 -3
  145. package/build/lib/hooks/policy_engine.py +77 -0
  146. package/build/lib/hooks/prompt-enhancer.py +146 -0
  147. package/build/lib/hooks/session-end-capture.py +374 -6
  148. package/build/lib/hooks/session-start.py +13 -35
  149. package/build/lib/hooks/setup_wizard.py +333 -1
  150. package/build/lib/plugins/advanced/plugin.json +26 -9
  151. package/build/lib/plugins/core/plugin.json +44 -11
  152. package/build/lib/registry/bundles/algorithms.yaml +1 -1
  153. package/build/lib/registry/bundles/api-twin.yaml +1 -1
  154. package/build/lib/registry/bundles/claim-judge.yaml +1 -1
  155. package/build/lib/registry/bundles/control-plane.yaml +1 -1
  156. package/build/lib/registry/bundles/data-lineage.yaml +1 -1
  157. package/build/lib/registry/bundles/delta-classifier.yaml +1 -1
  158. package/build/lib/registry/bundles/eval-gate.yaml +1 -1
  159. package/build/lib/registry/bundles/health.yaml +1 -1
  160. package/build/lib/registry/bundles/hook-governor.yaml +1 -1
  161. package/build/lib/registry/bundles/incident-replay.yaml +1 -1
  162. package/build/lib/registry/bundles/lsp-pack.yaml +1 -1
  163. package/build/lib/registry/bundles/mcp-fabric.yaml +1 -1
  164. package/build/lib/registry/bundles/plan-council.yaml +1 -1
  165. package/build/lib/registry/bundles/preflight.yaml +1 -1
  166. package/build/lib/registry/bundles/proof-gate.yaml +1 -1
  167. package/build/lib/registry/bundles/remote-supervisor.yaml +1 -1
  168. package/build/lib/registry/bundles/robotics.yaml +1 -1
  169. package/build/lib/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  170. package/build/lib/registry/bundles/security-check.yaml +1 -1
  171. package/build/lib/registry/bundles/test-intent-lock.yaml +1 -1
  172. package/build/lib/registry/bundles/tracebank.yaml +1 -1
  173. package/build/lib/registry/bundles/vision.yaml +1 -1
  174. package/build/lib/registry/omg-capability.schema.json +1 -1
  175. package/build/lib/runtime/adoption.py +1 -1
  176. package/build/lib/runtime/background_verification.py +62 -0
  177. package/build/lib/runtime/claim_judge.py +79 -9
  178. package/build/lib/runtime/compat.py +15 -1
  179. package/build/lib/runtime/context_engine.py +242 -0
  180. package/build/lib/runtime/contract_compiler.py +133 -78
  181. package/build/lib/runtime/defense_state.py +79 -8
  182. package/build/lib/runtime/delta_classifier.py +80 -2
  183. package/build/lib/runtime/evidence_query.py +56 -4
  184. package/build/lib/runtime/evidence_registry.py +16 -0
  185. package/build/lib/runtime/evidence_requirements.py +47 -0
  186. package/build/lib/runtime/forge_agents.py +163 -25
  187. package/build/lib/runtime/forge_contracts.py +164 -2
  188. package/build/lib/runtime/memory_store.py +134 -1
  189. package/build/lib/runtime/omg_compat_contract_snapshot.json +2 -2
  190. package/build/lib/runtime/preflight.py +14 -0
  191. package/build/lib/runtime/profile_io.py +294 -0
  192. package/build/lib/runtime/proof_gate.py +43 -7
  193. package/build/lib/runtime/release_surfaces.py +243 -0
  194. package/build/lib/runtime/runtime_contracts.py +90 -0
  195. package/build/lib/runtime/security_check.py +16 -0
  196. package/build/lib/runtime/session_health.py +49 -16
  197. package/build/lib/runtime/team_router.py +65 -6
  198. package/build/lib/runtime/tool_plan_gate.py +114 -6
  199. package/build/lib/runtime/validate.py +194 -0
  200. package/build/lib/runtime/verification_controller.py +52 -2
  201. package/commands/OMG:diagnose-plugins.md +33 -0
  202. package/commands/OMG:profile-review.md +43 -0
  203. package/commands/OMG:setup.md +4 -1
  204. package/commands/OMG:validate.md +59 -0
  205. package/dist/enterprise/bundle/.claude-plugin/marketplace.json +3 -3
  206. package/dist/enterprise/bundle/.claude-plugin/plugin.json +1 -1
  207. package/dist/enterprise/bundle/OMG_COMPAT_CONTRACT.md +1 -1
  208. package/dist/enterprise/bundle/plugins/advanced/plugin.json +26 -9
  209. package/dist/enterprise/bundle/registry/bundles/algorithms.yaml +1 -1
  210. package/dist/enterprise/bundle/registry/bundles/api-twin.yaml +1 -1
  211. package/dist/enterprise/bundle/registry/bundles/claim-judge.yaml +1 -1
  212. package/dist/enterprise/bundle/registry/bundles/control-plane.yaml +1 -1
  213. package/dist/enterprise/bundle/registry/bundles/data-lineage.yaml +1 -1
  214. package/dist/enterprise/bundle/registry/bundles/delta-classifier.yaml +1 -1
  215. package/dist/enterprise/bundle/registry/bundles/eval-gate.yaml +1 -1
  216. package/dist/enterprise/bundle/registry/bundles/health.yaml +1 -1
  217. package/dist/enterprise/bundle/registry/bundles/hook-governor.yaml +1 -1
  218. package/dist/enterprise/bundle/registry/bundles/incident-replay.yaml +1 -1
  219. package/dist/enterprise/bundle/registry/bundles/lsp-pack.yaml +1 -1
  220. package/dist/enterprise/bundle/registry/bundles/mcp-fabric.yaml +1 -1
  221. package/dist/enterprise/bundle/registry/bundles/plan-council.yaml +1 -1
  222. package/dist/enterprise/bundle/registry/bundles/preflight.yaml +1 -1
  223. package/dist/enterprise/bundle/registry/bundles/proof-gate.yaml +1 -1
  224. package/dist/enterprise/bundle/registry/bundles/remote-supervisor.yaml +1 -1
  225. package/dist/enterprise/bundle/registry/bundles/robotics.yaml +1 -1
  226. package/dist/enterprise/bundle/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  227. package/dist/enterprise/bundle/registry/bundles/security-check.yaml +1 -1
  228. package/dist/enterprise/bundle/registry/bundles/test-intent-lock.yaml +1 -1
  229. package/dist/enterprise/bundle/registry/bundles/tracebank.yaml +1 -1
  230. package/dist/enterprise/bundle/registry/bundles/vision.yaml +1 -1
  231. package/dist/enterprise/bundle/registry/omg-capability.schema.json +1 -1
  232. package/dist/enterprise/bundle/settings.json +3 -3
  233. package/dist/enterprise/manifest.json +30 -40
  234. package/dist/oh_my_god-2.1.4-py3-none-any.whl +0 -0
  235. package/dist/oh_my_god-2.1.4.tar.gz +0 -0
  236. package/dist/public/bundle/.claude-plugin/marketplace.json +3 -3
  237. package/dist/public/bundle/.claude-plugin/plugin.json +1 -1
  238. package/dist/public/bundle/OMG_COMPAT_CONTRACT.md +1 -1
  239. package/dist/public/bundle/plugins/advanced/plugin.json +26 -9
  240. package/dist/public/bundle/registry/bundles/algorithms.yaml +1 -1
  241. package/dist/public/bundle/registry/bundles/api-twin.yaml +1 -1
  242. package/dist/public/bundle/registry/bundles/claim-judge.yaml +1 -1
  243. package/dist/public/bundle/registry/bundles/control-plane.yaml +1 -1
  244. package/dist/public/bundle/registry/bundles/data-lineage.yaml +1 -1
  245. package/dist/public/bundle/registry/bundles/delta-classifier.yaml +1 -1
  246. package/dist/public/bundle/registry/bundles/eval-gate.yaml +1 -1
  247. package/dist/public/bundle/registry/bundles/health.yaml +1 -1
  248. package/dist/public/bundle/registry/bundles/hook-governor.yaml +1 -1
  249. package/dist/public/bundle/registry/bundles/incident-replay.yaml +1 -1
  250. package/dist/public/bundle/registry/bundles/lsp-pack.yaml +1 -1
  251. package/dist/public/bundle/registry/bundles/mcp-fabric.yaml +1 -1
  252. package/dist/public/bundle/registry/bundles/plan-council.yaml +1 -1
  253. package/dist/public/bundle/registry/bundles/preflight.yaml +1 -1
  254. package/dist/public/bundle/registry/bundles/proof-gate.yaml +1 -1
  255. package/dist/public/bundle/registry/bundles/remote-supervisor.yaml +1 -1
  256. package/dist/public/bundle/registry/bundles/robotics.yaml +1 -1
  257. package/dist/public/bundle/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  258. package/dist/public/bundle/registry/bundles/security-check.yaml +1 -1
  259. package/dist/public/bundle/registry/bundles/test-intent-lock.yaml +1 -1
  260. package/dist/public/bundle/registry/bundles/tracebank.yaml +1 -1
  261. package/dist/public/bundle/registry/bundles/vision.yaml +1 -1
  262. package/dist/public/bundle/registry/omg-capability.schema.json +1 -1
  263. package/dist/public/bundle/settings.json +3 -3
  264. package/dist/public/manifest.json +30 -40
  265. package/docs/install/opencode.md +30 -0
  266. package/docs/proof.md +3 -0
  267. package/docs/release-checklist.md +6 -1
  268. package/hooks/_agent_registry.py +2 -0
  269. package/hooks/firewall.py +146 -2
  270. package/hooks/intentgate-keyword-detector.py +15 -3
  271. package/hooks/policy_engine.py +77 -0
  272. package/hooks/prompt-enhancer.py +146 -0
  273. package/hooks/session-end-capture.py +374 -6
  274. package/hooks/session-start.py +13 -35
  275. package/hooks/setup_wizard.py +342 -2
  276. package/hud/omg-hud.mjs +16 -3
  277. package/lab/pipeline.py +195 -26
  278. package/package.json +1 -1
  279. package/plugins/advanced/plugin.json +26 -9
  280. package/plugins/core/plugin.json +51 -12
  281. package/pyproject.toml +10 -2
  282. package/registry/bundles/algorithms.yaml +1 -1
  283. package/registry/bundles/api-twin.yaml +1 -1
  284. package/registry/bundles/claim-judge.yaml +1 -1
  285. package/registry/bundles/control-plane.yaml +1 -1
  286. package/registry/bundles/data-lineage.yaml +1 -1
  287. package/registry/bundles/delta-classifier.yaml +1 -1
  288. package/registry/bundles/eval-gate.yaml +1 -1
  289. package/registry/bundles/health.yaml +1 -1
  290. package/registry/bundles/hook-governor.yaml +1 -1
  291. package/registry/bundles/incident-replay.yaml +1 -1
  292. package/registry/bundles/lsp-pack.yaml +1 -1
  293. package/registry/bundles/mcp-fabric.yaml +1 -1
  294. package/registry/bundles/plan-council.yaml +1 -1
  295. package/registry/bundles/preflight.yaml +1 -1
  296. package/registry/bundles/proof-gate.yaml +1 -1
  297. package/registry/bundles/remote-supervisor.yaml +1 -1
  298. package/registry/bundles/robotics.yaml +1 -1
  299. package/registry/bundles/secure-worktree-pipeline.yaml +1 -1
  300. package/registry/bundles/security-check.yaml +1 -1
  301. package/registry/bundles/test-intent-lock.yaml +1 -1
  302. package/registry/bundles/tracebank.yaml +1 -1
  303. package/registry/bundles/vision.yaml +1 -1
  304. package/registry/omg-capability.schema.json +1 -1
  305. package/runtime/adoption.py +7 -5
  306. package/runtime/background_verification.py +62 -0
  307. package/runtime/claim_judge.py +79 -9
  308. package/runtime/compat.py +48 -1
  309. package/runtime/context_engine.py +242 -0
  310. package/runtime/contract_compiler.py +133 -78
  311. package/runtime/defense_state.py +79 -8
  312. package/runtime/delta_classifier.py +80 -2
  313. package/runtime/evidence_query.py +56 -4
  314. package/runtime/evidence_registry.py +16 -0
  315. package/runtime/evidence_requirements.py +47 -0
  316. package/runtime/forge_agents.py +163 -25
  317. package/runtime/forge_contracts.py +164 -2
  318. package/runtime/hook_governor.py +19 -1
  319. package/runtime/memory_store.py +134 -1
  320. package/runtime/omg_compat_contract_snapshot.json +2 -2
  321. package/runtime/plugin_diagnostics.py +248 -0
  322. package/runtime/plugin_interop.py +1007 -0
  323. package/runtime/preflight.py +14 -0
  324. package/runtime/profile_io.py +294 -0
  325. package/runtime/proof_gate.py +43 -7
  326. package/runtime/providers/opencode_provider.py +94 -0
  327. package/runtime/release_surfaces.py +243 -0
  328. package/runtime/runtime_contracts.py +90 -0
  329. package/runtime/security_check.py +16 -0
  330. package/runtime/session_health.py +49 -16
  331. package/runtime/team_router.py +65 -6
  332. package/runtime/tool_plan_gate.py +82 -0
  333. package/runtime/validate.py +289 -0
  334. package/runtime/verification_controller.py +52 -2
  335. package/scripts/omg.py +262 -1
  336. package/scripts/prepare-release-proof-fixtures.py +89 -0
  337. package/scripts/print-canonical-version.py +80 -0
  338. package/scripts/sync-release-identity.py +476 -0
  339. package/scripts/validate-release-identity.py +246 -0
  340. package/scripts/verify-standalone.sh +3 -0
  341. package/settings.json +3 -3
  342. package/templates/plugins-allowlist.yaml +19 -0
  343. package/artifacts/release/dist/enterprise/bundle/.gemini/settings.json +0 -11
  344. package/artifacts/release/dist/enterprise/bundle/.kimi/mcp.json +0 -11
  345. package/artifacts/release/dist/public/bundle/.gemini/settings.json +0 -11
  346. package/artifacts/release/dist/public/bundle/.kimi/mcp.json +0 -11
  347. package/build/lib/yaml.py +0 -321
  348. package/dist/enterprise/bundle/.gemini/settings.json +0 -11
  349. package/dist/enterprise/bundle/.kimi/mcp.json +0 -11
  350. package/dist/public/bundle/.gemini/settings.json +0 -11
  351. package/dist/public/bundle/.kimi/mcp.json +0 -11
@@ -8,6 +8,7 @@ import json
8
8
  import os
9
9
  import sys
10
10
  from pathlib import Path
11
+ from typing import Any
11
12
 
12
13
  HOOKS_DIR = os.path.dirname(__file__)
13
14
  PROJECT_ROOT = os.path.dirname(HOOKS_DIR)
@@ -21,7 +22,9 @@ from _common import setup_crash_handler, json_input, deny_decision, is_bypass_mo
21
22
  setup_crash_handler("firewall", fail_closed=True)
22
23
 
23
24
  try:
24
- from policy_engine import evaluate_bash_command, to_pretool_hook_output # pyright: ignore[reportImplicitRelativeImport]
25
+ from policy_engine import evaluate_bash_command, to_pretool_hook_output, scan_mutation_command, ask, deny # pyright: ignore[reportImplicitRelativeImport]
26
+ from runtime.defense_state import DefenseState
27
+ from runtime.session_health import compute_session_health
25
28
  from runtime.mutation_gate import check_mutation_allowed
26
29
  from runtime.tool_plan_gate import journal_mutation_bash
27
30
  except Exception as _import_err:
@@ -67,6 +70,16 @@ def _resolve_run_id(payload: dict[str, object]) -> str:
67
70
  return env_run_id.strip()
68
71
 
69
72
 
73
+ def _resolve_active_run_id(project_dir: str) -> str:
74
+ active_run_path = Path(project_dir) / ".omg" / "shadow" / "active-run"
75
+ if not active_run_path.exists():
76
+ return ""
77
+ try:
78
+ return active_run_path.read_text(encoding="utf-8").strip()
79
+ except OSError:
80
+ return ""
81
+
82
+
70
83
  def _read_defense_risk(project_dir: str) -> str:
71
84
  path = Path(project_dir) / ".omg" / "state" / "defense_state" / "current.json"
72
85
  if not path.exists():
@@ -106,6 +119,122 @@ def _read_council_signal(project_dir: str, run_id: str) -> str:
106
119
  return ""
107
120
  return f"council evidence={verdict} findings={findings_count}"
108
121
 
122
+
123
+ def _read_clarification_state(project_dir: str, run_id: str) -> dict[str, object]:
124
+ if not run_id:
125
+ return {
126
+ "requires_clarification": False,
127
+ "intent_class": "",
128
+ "clarification_prompt": "",
129
+ "confidence": 0.0,
130
+ }
131
+ path = Path(project_dir) / ".omg" / "state" / "intent_gate" / f"{run_id}.json"
132
+ if not path.exists():
133
+ return {
134
+ "requires_clarification": False,
135
+ "intent_class": "",
136
+ "clarification_prompt": "",
137
+ "confidence": 0.0,
138
+ }
139
+ try:
140
+ payload = json.loads(path.read_text(encoding="utf-8"))
141
+ except (OSError, json.JSONDecodeError):
142
+ return {
143
+ "requires_clarification": False,
144
+ "intent_class": "",
145
+ "clarification_prompt": "",
146
+ "confidence": 0.0,
147
+ }
148
+ if not isinstance(payload, dict):
149
+ return {
150
+ "requires_clarification": False,
151
+ "intent_class": "",
152
+ "clarification_prompt": "",
153
+ "confidence": 0.0,
154
+ }
155
+ prompt = " ".join(str(payload.get("clarification_prompt", "")).split())
156
+ try:
157
+ confidence = float(payload.get("confidence", 0.0))
158
+ except (TypeError, ValueError):
159
+ confidence = 0.0
160
+ return {
161
+ "requires_clarification": bool(payload.get("requires_clarification") is True),
162
+ "intent_class": str(payload.get("intent_class", "")).strip(),
163
+ "clarification_prompt": prompt,
164
+ "confidence": round(max(0.0, min(1.0, confidence)), 2),
165
+ }
166
+
167
+
168
+ def _clarification_reason(clarification_prompt: str) -> str:
169
+ prompt = " ".join(str(clarification_prompt or "").split())
170
+ if prompt:
171
+ return f"Clarification required before mutation: {prompt}"
172
+ return "Clarification required before mutation: provide the missing intent details."
173
+
174
+
175
+ def _to_float(value: Any, default: float) -> float:
176
+ try:
177
+ return float(value)
178
+ except (TypeError, ValueError):
179
+ return default
180
+
181
+
182
+ def _mutating_defense_decision(
183
+ *,
184
+ project_dir: str,
185
+ cmd: str,
186
+ run_id: str,
187
+ ):
188
+ scan = scan_mutation_command(cmd)
189
+ defense_state = DefenseState(project_dir).update(
190
+ injection_hits=int(_to_float(scan.get("injection_hits"), 0.0)),
191
+ contamination_score=_to_float(scan.get("contamination_score"), 0.0),
192
+ overthinking_score=_to_float(scan.get("overthinking_score"), 0.0),
193
+ premature_fixer_score=_to_float(scan.get("premature_fixer_score"), 0.0),
194
+ )
195
+
196
+ resolved_run_id = run_id.strip() or _resolve_active_run_id(project_dir) or "default"
197
+ session_health = compute_session_health(project_dir, run_id=resolved_run_id)
198
+
199
+ contamination = _to_float(session_health.get("contamination_risk"), _to_float(defense_state.get("contamination_score"), 0.0))
200
+ overthinking = _to_float(session_health.get("overthinking_score"), _to_float(defense_state.get("overthinking_score"), 0.0))
201
+ premature_fixer = _to_float(defense_state.get("premature_fixer_score"), 0.0)
202
+ health_action = str(session_health.get("recommended_action", "continue"))
203
+ thresholds = session_health.get("thresholds") if isinstance(session_health, dict) else {}
204
+ contamination_thresholds = thresholds.get("contamination_risk") if isinstance(thresholds, dict) else {}
205
+ overthinking_thresholds = thresholds.get("overthinking_score") if isinstance(thresholds, dict) else {}
206
+ reflect_contamination = _to_float(contamination_thresholds.get("reflect") if isinstance(contamination_thresholds, dict) else None, 0.05)
207
+ reflect_overthinking = _to_float(overthinking_thresholds.get("reflect") if isinstance(overthinking_thresholds, dict) else None, 0.15)
208
+ reflect_triggers = session_health.get("reflect_triggers") if isinstance(session_health, dict) else {}
209
+ contamination_trigger = bool(reflect_triggers.get("contamination")) if isinstance(reflect_triggers, dict) else contamination > reflect_contamination
210
+ overthinking_trigger = bool(reflect_triggers.get("overthinking")) if isinstance(reflect_triggers, dict) else overthinking > reflect_overthinking
211
+ pause_required = bool(session_health.get("defense_pause_required") is True) if isinstance(session_health, dict) else (contamination_trigger or overthinking_trigger)
212
+ signal_text = ", ".join(str(item) for item in scan.get("signals", []) if str(item)) or "none"
213
+ context = (
214
+ f"defense hits={int(_to_float(defense_state.get('injection_hits'), 0.0))} "
215
+ f"contamination={contamination:.4f} overthinking={overthinking:.4f} "
216
+ f"premature_fixer={premature_fixer:.4f} "
217
+ f"session_health={health_action} signals={signal_text}"
218
+ )
219
+
220
+ if health_action == "block":
221
+ return deny(
222
+ f"Blocked: mutation denied by defense/session-health reducer [{context}]",
223
+ "high",
224
+ ["defense-reducer", "session-health"],
225
+ )
226
+
227
+ if pause_required or contamination_trigger or overthinking_trigger:
228
+ return ask(
229
+ "Pause: mutation requires reflection before execution "
230
+ f"[{context}; thresholds contamination>{reflect_contamination:.2f} "
231
+ f"overthinking>{reflect_overthinking:.2f}]",
232
+ "high",
233
+ ["reflect", "defense-reducer", "session-health"],
234
+ )
235
+
236
+ return None
237
+
109
238
  data = json_input()
110
239
 
111
240
  tool = data.get("tool_name", "")
@@ -117,7 +246,6 @@ if not cmd:
117
246
  sys.exit(0)
118
247
 
119
248
  decision = evaluate_bash_command(cmd)
120
- decision = _enrich_risk_context(decision, data)
121
249
 
122
250
  tool_input = data.get("tool_input")
123
251
  metadata = tool_input.get("metadata") if isinstance(tool_input, dict) else None
@@ -136,10 +264,26 @@ gate_result = check_mutation_allowed(
136
264
  metadata=metadata if isinstance(metadata, dict) else None,
137
265
  )
138
266
  is_mutation_capable = str(gate_result.get("reason", "")) != "tool is read-only for mutation gate"
267
+ clarification_state = _read_clarification_state(get_project_dir(), run_id)
268
+ if is_mutation_capable:
269
+ defense_decision = _mutating_defense_decision(
270
+ project_dir=get_project_dir(),
271
+ cmd=cmd,
272
+ run_id=run_id,
273
+ )
274
+ if defense_decision is not None:
275
+ decision = defense_decision
276
+
277
+ if clarification_state.get("requires_clarification") is True and is_mutation_capable:
278
+ deny_decision(_clarification_reason(str(clarification_state.get("clarification_prompt", ""))))
279
+ sys.exit(0)
280
+
139
281
  if is_mutation_capable and gate_result.get("status") == "blocked":
140
282
  deny_decision(str(gate_result.get("reason", "mutation denied by test intent lock gate")))
141
283
  sys.exit(0)
142
284
 
285
+ decision = _enrich_risk_context(decision, data)
286
+
143
287
  # In bypass-permission mode, only enforce hard denials (critical safety).
144
288
  # Skip "ask" decisions so the user is not prompted for confirmation.
145
289
  if is_bypass_mode(data) and decision.action != "deny":
@@ -38,7 +38,7 @@ try:
38
38
  get_feature_flag,
39
39
  _resolve_project_dir,
40
40
  check_performance_budget,
41
- PRE_TOOL_INJECT_MAX_MS,
41
+ PRE_TOOL_INJECT_MAX_MS as pre_tool_inject_max_ms,
42
42
  )
43
43
  except ImportError:
44
44
  import importlib
@@ -48,7 +48,7 @@ except ImportError:
48
48
  get_feature_flag = _common.get_feature_flag
49
49
  _resolve_project_dir = _common._resolve_project_dir
50
50
  check_performance_budget = _common.check_performance_budget
51
- PRE_TOOL_INJECT_MAX_MS = _common.PRE_TOOL_INJECT_MAX_MS
51
+ pre_tool_inject_max_ms = _common.PRE_TOOL_INJECT_MAX_MS
52
52
 
53
53
  setup_crash_handler("intentgate-keyword-detector", fail_closed=False)
54
54
 
@@ -64,6 +64,18 @@ KEYWORD_INTENT_MAP = {
64
64
  "search": "INTENT_SEARCH",
65
65
  "stop": "INTENT_STOP",
66
66
  "crazy": "INTENT_CRAZY",
67
+ "auth": "INTENT_AUTH_SETUP",
68
+ "login": "INTENT_AUTH_SETUP",
69
+ "credentials": "INTENT_AUTH_SETUP",
70
+ "setup my credentials": "INTENT_AUTH_SETUP",
71
+ "setup credentials": "INTENT_AUTH_SETUP",
72
+ "remember my settings": "INTENT_PREFERENCE_MEMORY",
73
+ "remember settings": "INTENT_PREFERENCE_MEMORY",
74
+ "preferences": "INTENT_PREFERENCE_MEMORY",
75
+ "memory style": "INTENT_PREFERENCE_MEMORY",
76
+ "setup preferences": "INTENT_AMBIGUOUS_CONFIG",
77
+ "configure preferences": "INTENT_AMBIGUOUS_CONFIG",
78
+ "remember setup": "INTENT_AMBIGUOUS_CONFIG",
67
79
  }
68
80
 
69
81
 
@@ -179,7 +191,7 @@ if detected_intents:
179
191
  # PERFORMANCE BUDGET CHECK
180
192
  # ═══════════════════════════════════════════════════════════
181
193
  elapsed_ms = (time.time() - start_time) * 1000
182
- check_performance_budget("intentgate-keyword-detector", elapsed_ms, PRE_TOOL_INJECT_MAX_MS)
194
+ check_performance_budget("intentgate-keyword-detector", elapsed_ms, pre_tool_inject_max_ms)
183
195
 
184
196
  # ═══════════════════════════════════════════════════════════
185
197
  # OUTPUT
@@ -126,6 +126,33 @@ UNTRUSTED_MUTATION_PATTERNS = [
126
126
  TRUSTED_CONTENT_TIERS = frozenset({"local", "balanced"})
127
127
  UNTRUSTED_EXTERNAL_TIERS = frozenset({"research", "browser"})
128
128
 
129
+ INJECTION_MARKER_PATTERNS: tuple[tuple[re.Pattern[str], float, str], ...] = (
130
+ (re.compile(r"\bIGNORE\s+(?:ALL\s+)?PREVIOUS(?:\s+INSTRUCTIONS?)?\b", re.IGNORECASE), 0.03, "ignore-previous-instructions"),
131
+ (re.compile(r"<\|im_start\|>", re.IGNORECASE), 0.03, "im-start-token"),
132
+ (re.compile(r"<\|im_end\|>", re.IGNORECASE), 0.03, "im-end-token"),
133
+ (re.compile(r"\[INST\]", re.IGNORECASE), 0.03, "inst-token"),
134
+ (re.compile(r"\[/INST\]", re.IGNORECASE), 0.03, "inst-close-token"),
135
+ )
136
+
137
+ HIDDEN_INSTRUCTION_PATTERNS: tuple[tuple[re.Pattern[str], float, str], ...] = (
138
+ (re.compile(r"(?:^|\s)SYSTEM\s*:", re.IGNORECASE), 0.02, "system-role-token"),
139
+ (re.compile(r"(?:^|\s)ASSISTANT\s*:", re.IGNORECASE), 0.02, "assistant-role-token"),
140
+ (re.compile(r"(?:(?:#|//|/\*|<!--).{0,80})\b(?:ignore|override|jailbreak|bypass)\b", re.IGNORECASE), 0.01, "comment-hidden-instruction"),
141
+ (re.compile(r"\bbase64\s+(?:-d|--decode)\b", re.IGNORECASE), 0.01, "base64-decoder-token"),
142
+ (re.compile(r"\b[A-Za-z0-9+/]{48,}={0,2}\b"), 0.01, "opaque-base64-payload"),
143
+ )
144
+
145
+ CACHE_POISONING_PATTERNS: tuple[tuple[re.Pattern[str], float, str], ...] = (
146
+ (re.compile(r"(?:>|>>|tee\b|cp\b|mv\b|rm\b|sed\s+-i\b).{0,120}/\.omg/state/", re.IGNORECASE), 0.04, "state-path-overwrite-attempt"),
147
+ (re.compile(r"(?:>|>>|tee\b|cp\b|mv\b|rm\b|sed\s+-i\b).{0,120}/\.omg/shadow/active-run", re.IGNORECASE), 0.04, "active-run-overwrite-attempt"),
148
+ (re.compile(r"\b(?:cache|state)\s*(?:poison|override|overwrite|tamper)\b", re.IGNORECASE), 0.02, "cache-poisoning-language"),
149
+ )
150
+
151
+ CLARIFICATION_AMBIGUITY_PATTERNS: tuple[tuple[re.Pattern[str], float, str], ...] = (
152
+ (re.compile(r"\b(?:without\s+asking|no\s+questions\s+asked|skip\s+clarif(?:y|ication))\b", re.IGNORECASE), 0.08, "clarification-bypass-language"),
153
+ (re.compile(r"\b(?:just\s+fix\s+it|fix\s+everything|do\s+whatever\s+it\s+takes)\b", re.IGNORECASE), 0.08, "ambiguous-mutation-intent"),
154
+ )
155
+
129
156
 
130
157
  def _project_dir() -> str:
131
158
  return os.environ.get("CLAUDE_PROJECT_DIR", os.getcwd())
@@ -211,6 +238,56 @@ def _is_untrusted_content_mode_active() -> bool:
211
238
  return False
212
239
 
213
240
 
241
+ def scan_mutation_command(cmd: str) -> dict[str, Any]:
242
+ text = str(cmd or "")
243
+ if not text.strip():
244
+ return {
245
+ "injection_hits": 0,
246
+ "contamination_score": 0.0,
247
+ "overthinking_score": 0.0,
248
+ "premature_fixer_score": 0.0,
249
+ "signals": [],
250
+ }
251
+
252
+ contamination_score = 0.0
253
+ overthinking_score = 0.0
254
+ premature_fixer_score = 0.0
255
+ injection_hits = 0
256
+ signals: list[str] = []
257
+
258
+ for pattern, weight, label in INJECTION_MARKER_PATTERNS:
259
+ if pattern.search(text):
260
+ injection_hits += 1
261
+ contamination_score += weight
262
+ signals.append(label)
263
+
264
+ for pattern, weight, label in HIDDEN_INSTRUCTION_PATTERNS:
265
+ if pattern.search(text):
266
+ injection_hits += 1
267
+ contamination_score += weight
268
+ signals.append(label)
269
+
270
+ for pattern, weight, label in CACHE_POISONING_PATTERNS:
271
+ if pattern.search(text):
272
+ injection_hits += 1
273
+ contamination_score += weight
274
+ signals.append(label)
275
+
276
+ for pattern, weight, label in CLARIFICATION_AMBIGUITY_PATTERNS:
277
+ if pattern.search(text):
278
+ overthinking_score += weight
279
+ premature_fixer_score += weight
280
+ signals.append(label)
281
+
282
+ return {
283
+ "injection_hits": max(0, injection_hits),
284
+ "contamination_score": round(max(0.0, min(1.0, contamination_score)), 4),
285
+ "overthinking_score": round(max(0.0, min(1.0, overthinking_score)), 4),
286
+ "premature_fixer_score": round(max(0.0, min(1.0, premature_fixer_score)), 4),
287
+ "signals": signals,
288
+ }
289
+
290
+
214
291
  def evaluate_bash_command(cmd: str) -> PolicyDecision:
215
292
  if not cmd:
216
293
  return allow("empty command")
@@ -14,7 +14,9 @@ Inspired by earlier OMG routing experiments. Key upgrades:
14
14
 
15
15
  No dependency on CLAUDE.md or AGENTS.md.
16
16
  """
17
+ import hashlib
17
18
  import json, sys, os, re, time
19
+ from datetime import datetime, timezone
18
20
  import importlib
19
21
 
20
22
  HOOKS_DIR = os.path.dirname(__file__)
@@ -77,6 +79,48 @@ def signal_matches_text(signal, text):
77
79
  return signal in text
78
80
  return re.search(r'\b' + re.escape(signal) + r'\b', text, re.IGNORECASE) is not None
79
81
 
82
+
83
+ def _hash_prompt(value):
84
+ return hashlib.sha256(value.encode("utf-8")).hexdigest()
85
+
86
+
87
+ def _single_line(text, max_chars=220):
88
+ line = " ".join(str(text).replace("\r", " ").replace("\n", " ").split())
89
+ if len(line) > max_chars:
90
+ return line[: max_chars - 3] + "..."
91
+ return line
92
+
93
+
94
+ def _resolve_run_id(payload, prompt_hash):
95
+ if isinstance(payload, dict):
96
+ run_id = payload.get("run_id")
97
+ if isinstance(run_id, str) and run_id.strip():
98
+ return run_id.strip()
99
+ tool_input = payload.get("tool_input")
100
+ if isinstance(tool_input, dict):
101
+ metadata = tool_input.get("metadata")
102
+ if isinstance(metadata, dict):
103
+ metadata_run_id = metadata.get("run_id")
104
+ if isinstance(metadata_run_id, str) and metadata_run_id.strip():
105
+ return metadata_run_id.strip()
106
+ env_run_id = os.environ.get("OMG_RUN_ID", "").strip()
107
+ if env_run_id:
108
+ return env_run_id
109
+ return prompt_hash[:24]
110
+
111
+
112
+ def _count_signals(signals, text):
113
+ return sum(1 for sig in signals if signal_matches_text(sig, text))
114
+
115
+
116
+ def _write_intent_gate_artifact(state_root, run_id, artifact):
117
+ state_path = os.path.join(state_root, "intent_gate", f"{run_id}.json")
118
+ os.makedirs(os.path.dirname(state_path), exist_ok=True)
119
+ tmp_path = f"{state_path}.tmp"
120
+ with open(tmp_path, "w", encoding="utf-8") as tmp_file:
121
+ json.dump(artifact, tmp_file, indent=2, ensure_ascii=True)
122
+ os.replace(tmp_path, state_path)
123
+
80
124
  # ── Zero-injection optimization ──
81
125
  # Simple prompts (≤10 words, no coding/mode/routing signals) get zero overhead
82
126
  _word_count_early = len(prompt_lower.split())
@@ -88,6 +132,8 @@ _has_any_signal = any([
88
132
  "codex","gemini","ccg","screenshot","screen",
89
133
  "security","warning","hook error","resume","handoff",
90
134
  "continue","domain","scaffold","debug","deploy",
135
+ "setup","credential","credentials","preference",
136
+ "preferences","remember","settings","memory",
91
137
  "수정","구현","버그","에러","고쳐","스크린샷","보안"]),
92
138
  _word_count_early > 10,
93
139
  ])
@@ -127,14 +173,109 @@ INTENT_MAP = {
127
173
  "구현", "빌드", "생성", "만들", "추가", "기능", "개발"],
128
174
  "directive": "IMPLEMENT — Plan → code → test → verify. Follow existing patterns"
129
175
  },
176
+ "auth_setup": {
177
+ "signals": ["auth", "login", "credential", "credentials", "oauth", "token", "setup auth",
178
+ "setup credential", "set up credential", "인증", "로그인", "자격 증명", "토큰"],
179
+ "directive": "AUTH_SETUP — Clarify auth target and credential source before changes"
180
+ },
181
+ "preference_memory": {
182
+ "signals": ["remember my settings", "remember settings", "preference", "preferences", "settings",
183
+ "memory style", "save my setup", "기억", "설정", "선호"],
184
+ "directive": "PREFERENCE_MEMORY — Clarify scope and persistence policy before changes"
185
+ },
186
+ "ambiguous_config": {
187
+ "signals": ["setup", "configure", "config", "remember", "save", "setup my", "set up",
188
+ "설정해", "구성", "저장"],
189
+ "directive": "AMBIGUOUS_CONFIG — Ask one-line clarification before any implementation"
190
+ },
130
191
  }
131
192
 
193
+ IMPLEMENTATION_ACTION_SIGNALS = [
194
+ "implement", "build", "create", "add", "fix", "refactor", "update", "write", "code",
195
+ "debug", "test", "migrate", "deploy", "patch", "change", "구현", "추가", "수정", "개발",
196
+ ]
197
+ AUTH_PROVIDER_SIGNALS = [
198
+ "codex", "claude", "gemini", "github", "google", "openai", "provider", "service", "cli",
199
+ ]
200
+ AUTH_SOURCE_SIGNALS = [
201
+ "env", "token", "key", "secret", "credential", "password", "vault", "profile", "yaml",
202
+ ]
203
+ PREFERENCE_SCOPE_SIGNALS = ["session", "project", "global", "default", "always", "workspace", "local"]
204
+
205
+
206
+ def _build_intent_gate_state(prompt_text, payload):
207
+ has_auth = _count_signals(INTENT_MAP["auth_setup"]["signals"], prompt_text) > 0
208
+ has_pref = _count_signals(INTENT_MAP["preference_memory"]["signals"], prompt_text) > 0
209
+ has_ambiguous_config = _count_signals(INTENT_MAP["ambiguous_config"]["signals"], prompt_text) > 0
210
+ if not (has_auth or has_pref or has_ambiguous_config):
211
+ return None
212
+
213
+ has_specific_action = any(signal_matches_text(sig, prompt_text) for sig in IMPLEMENTATION_ACTION_SIGNALS)
214
+
215
+ if has_auth and has_pref:
216
+ intent_class = "ambiguous_config"
217
+ elif has_auth and has_ambiguous_config and not has_specific_action:
218
+ intent_class = "ambiguous_config"
219
+ elif has_auth:
220
+ intent_class = "auth_setup"
221
+ elif has_pref:
222
+ intent_class = "preference_memory"
223
+ else:
224
+ intent_class = "ambiguous_config"
225
+
226
+ missing_slots = []
227
+ if intent_class in ("auth_setup", "ambiguous_config"):
228
+ if not any(signal_matches_text(sig, prompt_text) for sig in AUTH_PROVIDER_SIGNALS):
229
+ missing_slots.append("provider")
230
+ if not any(signal_matches_text(sig, prompt_text) for sig in AUTH_SOURCE_SIGNALS):
231
+ missing_slots.append("credential_source")
232
+ if intent_class in ("preference_memory", "ambiguous_config"):
233
+ if not any(signal_matches_text(sig, prompt_text) for sig in PREFERENCE_SCOPE_SIGNALS):
234
+ missing_slots.append("scope")
235
+ if not has_specific_action:
236
+ missing_slots.append("desired_action")
237
+
238
+ requires_clarification = intent_class == "ambiguous_config" or bool(missing_slots)
239
+ clarification_prompt = ""
240
+ if requires_clarification:
241
+ prompt_map = {
242
+ "auth_setup": "Clarify auth setup in one line: target service, credential source, and exact action to run.",
243
+ "preference_memory": "Clarify preference memory in one line: settings to save, scope, and when to apply them.",
244
+ "ambiguous_config": "Clarify in one line whether this is auth setup or preference memory, plus the exact action to execute.",
245
+ }
246
+ clarification_prompt = _single_line(prompt_map[intent_class])
247
+
248
+ source_prompt_hash = _hash_prompt(prompt_text)
249
+ run_id = _resolve_run_id(payload, source_prompt_hash)
250
+ signal_hits = _count_signals(INTENT_MAP[intent_class]["signals"], prompt_text)
251
+ confidence = min(0.99, 0.76 + (signal_hits * 0.07) + (0.06 if intent_class == "ambiguous_config" else 0.0))
252
+
253
+ return {
254
+ "schema": "IntentGateClarificationState",
255
+ "schema_version": "1.0.0",
256
+ "run_id": run_id,
257
+ "intent_class": intent_class,
258
+ "confidence": round(confidence, 2),
259
+ "requires_clarification": requires_clarification,
260
+ "missing_slots": missing_slots,
261
+ "clarification_prompt": clarification_prompt,
262
+ "source_prompt_hash": source_prompt_hash,
263
+ "updated_at": datetime.now(timezone.utc).isoformat(),
264
+ }
265
+
132
266
  detected_intent = None
133
267
  for intent_key, intent_data in INTENT_MAP.items():
134
268
  if any(signal_matches_text(sig, prompt) for sig in intent_data["signals"]):
135
269
  detected_intent = intent_key
136
270
  break
137
271
 
272
+ intent_gate_state = _build_intent_gate_state(prompt, data)
273
+ if intent_gate_state is not None:
274
+ try:
275
+ _write_intent_gate_artifact(state_dir, intent_gate_state["run_id"], intent_gate_state)
276
+ except Exception:
277
+ pass
278
+
138
279
  # ═══════════════════════════════════════════════════════════
139
280
  # 2. DISCIPLINE SYSTEM (Sisyphus-grade)
140
281
  # ═══════════════════════════════════════════════════════════
@@ -143,6 +284,11 @@ parts = []
143
284
  if detected_intent:
144
285
  parts.append(f"@intent: {INTENT_MAP[detected_intent]['directive']}")
145
286
 
287
+ if intent_gate_state and intent_gate_state.get("requires_clarification"):
288
+ clarification_line = _single_line(intent_gate_state.get("clarification_prompt", ""))
289
+ if clarification_line:
290
+ parts.append(f"@intent-clarify: {clarification_line}")
291
+
146
292
  parts.append(
147
293
  "@discipline: Senior-eng mode. Clean minimal code. "
148
294
  "VERIFY changes. NEVER claim done unverified. "