@agentikos/omega-os 0.1.0 → 0.19.5

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 (379) hide show
  1. package/README.md +56 -14
  2. package/bootstrap/lib/__pycache__/claude-code-settings.cpython-313.pyc +0 -0
  3. package/bootstrap/lib/__pycache__/llm-clis.cpython-313.pyc +0 -0
  4. package/bootstrap/lib/__pycache__/manifest-helpers.cpython-313.pyc +0 -0
  5. package/bootstrap/lib/claude-code-settings.py +176 -0
  6. package/bootstrap/lib/common.sh +457 -1
  7. package/bootstrap/lib/llm-clis.py +341 -0
  8. package/bootstrap/lib/manifest-helpers.py +384 -0
  9. package/bootstrap/lib/steps.sh +1000 -26
  10. package/bootstrap/manifest.example.yaml +93 -2
  11. package/bootstrap/templates/aisb/CLAUDE.md +305 -0
  12. package/bootstrap/templates/aisb/architect.md +204 -0
  13. package/bootstrap/templates/aisb/checkers/CLAUDE.md +9 -0
  14. package/bootstrap/templates/aisb/checkers/checker-architect.md +151 -0
  15. package/bootstrap/templates/aisb/checkers/checker-common.md +171 -0
  16. package/bootstrap/templates/aisb/checkers/checker-construct.md +129 -0
  17. package/bootstrap/templates/aisb/checkers/checker-keymaker.md +204 -0
  18. package/bootstrap/templates/aisb/checkers/checker-link.md +205 -0
  19. package/bootstrap/templates/aisb/checkers/checker-merovingian.md +219 -0
  20. package/bootstrap/templates/aisb/checkers/checker-morpheus.md +211 -0
  21. package/bootstrap/templates/aisb/checkers/checker-neo.md +177 -0
  22. package/bootstrap/templates/aisb/checkers/checker-niobe.md +156 -0
  23. package/bootstrap/templates/aisb/checkers/checker-oracle.md +164 -0
  24. package/bootstrap/templates/aisb/checkers/checker-seraph.md +187 -0
  25. package/bootstrap/templates/aisb/checkers/checker-smith.md +195 -0
  26. package/bootstrap/templates/aisb/checkers/checker-zion.md +113 -0
  27. package/bootstrap/templates/aisb/construct.md +135 -0
  28. package/bootstrap/templates/aisb/keymaker.md +227 -0
  29. package/bootstrap/templates/aisb/link.md +170 -0
  30. package/bootstrap/templates/aisb/lmc-protocol.md +57 -0
  31. package/bootstrap/templates/aisb/merovingian.md +159 -0
  32. package/bootstrap/templates/aisb/morpheus.md +243 -0
  33. package/bootstrap/templates/aisb/neo.md +147 -0
  34. package/bootstrap/templates/aisb/niobe.md +197 -0
  35. package/bootstrap/templates/aisb/oracle.md +244 -0
  36. package/bootstrap/templates/aisb/protocols/handoff-templates.md +204 -0
  37. package/bootstrap/templates/aisb/protocols/shared-protocol.md +248 -0
  38. package/bootstrap/templates/aisb/pythia.md +153 -0
  39. package/bootstrap/templates/aisb/seraph.md +315 -0
  40. package/bootstrap/templates/aisb/smith.md +202 -0
  41. package/bootstrap/templates/aisb/zion.md +172 -0
  42. package/bootstrap/templates/autonomous/audit-patrol.yaml +41 -0
  43. package/bootstrap/templates/autonomous/smith-reflect.yaml +43 -0
  44. package/bootstrap/templates/autonomous/ssh-key-rotate.yaml +46 -0
  45. package/bootstrap/templates/autonomous/support-agent.yaml +38 -0
  46. package/docs/AUDITS.md +85 -0
  47. package/docs/COMPLETION-PLAN.md +48 -0
  48. package/docs/GAP-ANALYSIS.md +214 -0
  49. package/docs/INSTALL.md +47 -9
  50. package/docs/MCP-AND-PLUGINS.md +31 -4
  51. package/docs/SIMULATION.md +171 -0
  52. package/docs/simulate.sh +211 -0
  53. package/install.sh +164 -17
  54. package/omega/Agentik_Engine/README.md +27 -10
  55. package/omega/Agentik_Engine/omega_engine/__init__.py +212 -2
  56. package/omega/Agentik_Engine/omega_engine/__pycache__/__init__.cpython-313.pyc +0 -0
  57. package/omega/Agentik_Engine/omega_engine/__pycache__/account.cpython-313.pyc +0 -0
  58. package/omega/Agentik_Engine/omega_engine/__pycache__/agent_messages.cpython-313.pyc +0 -0
  59. package/omega/Agentik_Engine/omega_engine/__pycache__/aisb_chat.cpython-313.pyc +0 -0
  60. package/omega/Agentik_Engine/omega_engine/__pycache__/audit_diff.cpython-313.pyc +0 -0
  61. package/omega/Agentik_Engine/omega_engine/__pycache__/audit_gate.cpython-313.pyc +0 -0
  62. package/omega/Agentik_Engine/omega_engine/__pycache__/auto_update.cpython-313.pyc +0 -0
  63. package/omega/Agentik_Engine/omega_engine/__pycache__/autonomous.cpython-313.pyc +0 -0
  64. package/omega/Agentik_Engine/omega_engine/__pycache__/backup.cpython-313.pyc +0 -0
  65. package/omega/Agentik_Engine/omega_engine/__pycache__/cadence.cpython-313.pyc +0 -0
  66. package/omega/Agentik_Engine/omega_engine/__pycache__/classifier.cpython-313.pyc +0 -0
  67. package/omega/Agentik_Engine/omega_engine/__pycache__/cleanup.cpython-313.pyc +0 -0
  68. package/omega/Agentik_Engine/omega_engine/__pycache__/cli.cpython-313.pyc +0 -0
  69. package/omega/Agentik_Engine/omega_engine/__pycache__/completions.cpython-313.pyc +0 -0
  70. package/omega/Agentik_Engine/omega_engine/__pycache__/costs.cpython-313.pyc +0 -0
  71. package/omega/Agentik_Engine/omega_engine/__pycache__/done_signal.cpython-313.pyc +0 -0
  72. package/omega/Agentik_Engine/omega_engine/__pycache__/envelope.cpython-313.pyc +0 -0
  73. package/omega/Agentik_Engine/omega_engine/__pycache__/executor.cpython-313.pyc +0 -0
  74. package/omega/Agentik_Engine/omega_engine/__pycache__/handoff.cpython-313.pyc +0 -0
  75. package/omega/Agentik_Engine/omega_engine/__pycache__/hermes.cpython-313.pyc +0 -0
  76. package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_bootstrap.cpython-313.pyc +0 -0
  77. package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_desktop.cpython-313.pyc +0 -0
  78. package/omega/Agentik_Engine/omega_engine/__pycache__/learning.cpython-313.pyc +0 -0
  79. package/omega/Agentik_Engine/omega_engine/__pycache__/managed_agent.cpython-313.pyc +0 -0
  80. package/omega/Agentik_Engine/omega_engine/__pycache__/memory.cpython-313.pyc +0 -0
  81. package/omega/Agentik_Engine/omega_engine/__pycache__/menu.cpython-313.pyc +0 -0
  82. package/omega/Agentik_Engine/omega_engine/__pycache__/mission.cpython-313.pyc +0 -0
  83. package/omega/Agentik_Engine/omega_engine/__pycache__/plan.cpython-313.pyc +0 -0
  84. package/omega/Agentik_Engine/omega_engine/__pycache__/project.cpython-313.pyc +0 -0
  85. package/omega/Agentik_Engine/omega_engine/__pycache__/prompts.cpython-313.pyc +0 -0
  86. package/omega/Agentik_Engine/omega_engine/__pycache__/provider.cpython-313.pyc +0 -0
  87. package/omega/Agentik_Engine/omega_engine/__pycache__/prune.cpython-313.pyc +0 -0
  88. package/omega/Agentik_Engine/omega_engine/__pycache__/pursue.cpython-313.pyc +0 -0
  89. package/omega/Agentik_Engine/omega_engine/__pycache__/reducer.cpython-313.pyc +0 -0
  90. package/omega/Agentik_Engine/omega_engine/__pycache__/router.cpython-313.pyc +0 -0
  91. package/omega/Agentik_Engine/omega_engine/__pycache__/skill_routing.cpython-313.pyc +0 -0
  92. package/omega/Agentik_Engine/omega_engine/__pycache__/smoke.cpython-313.pyc +0 -0
  93. package/omega/Agentik_Engine/omega_engine/__pycache__/store.cpython-313.pyc +0 -0
  94. package/omega/Agentik_Engine/omega_engine/__pycache__/sync.cpython-313.pyc +0 -0
  95. package/omega/Agentik_Engine/omega_engine/__pycache__/telegram_history.cpython-313.pyc +0 -0
  96. package/omega/Agentik_Engine/omega_engine/__pycache__/tmux.cpython-313.pyc +0 -0
  97. package/omega/Agentik_Engine/omega_engine/__pycache__/tools.cpython-313.pyc +0 -0
  98. package/omega/Agentik_Engine/omega_engine/__pycache__/understand_anything.cpython-313.pyc +0 -0
  99. package/omega/Agentik_Engine/omega_engine/__pycache__/updater.cpython-313.pyc +0 -0
  100. package/omega/Agentik_Engine/omega_engine/__pycache__/validate.cpython-313.pyc +0 -0
  101. package/omega/Agentik_Engine/omega_engine/__pycache__/vault.cpython-313.pyc +0 -0
  102. package/omega/Agentik_Engine/omega_engine/__pycache__/webhooks.cpython-313.pyc +0 -0
  103. package/omega/Agentik_Engine/omega_engine/__pycache__/worker.cpython-313.pyc +0 -0
  104. package/omega/Agentik_Engine/omega_engine/account.py +502 -0
  105. package/omega/Agentik_Engine/omega_engine/agent_messages.py +167 -0
  106. package/omega/Agentik_Engine/omega_engine/aisb_chat.py +128 -0
  107. package/omega/Agentik_Engine/omega_engine/audit_diff.py +99 -0
  108. package/omega/Agentik_Engine/omega_engine/audit_gate.py +149 -0
  109. package/omega/Agentik_Engine/omega_engine/audits/__init__.py +60 -0
  110. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/__init__.cpython-313.pyc +0 -0
  111. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/batcher.cpython-313.pyc +0 -0
  112. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/dispatcher.cpython-313.pyc +0 -0
  113. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/generator.cpython-313.pyc +0 -0
  114. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/history.cpython-313.pyc +0 -0
  115. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/pipeline.cpython-313.pyc +0 -0
  116. package/omega/Agentik_Engine/omega_engine/audits/batcher.py +218 -0
  117. package/omega/Agentik_Engine/omega_engine/audits/dispatcher.py +92 -0
  118. package/omega/Agentik_Engine/omega_engine/audits/generator.py +234 -0
  119. package/omega/Agentik_Engine/omega_engine/audits/history.py +168 -0
  120. package/omega/Agentik_Engine/omega_engine/audits/pipeline.py +198 -0
  121. package/omega/Agentik_Engine/omega_engine/auto_update.py +339 -0
  122. package/omega/Agentik_Engine/omega_engine/autonomous.py +538 -0
  123. package/omega/Agentik_Engine/omega_engine/backup.py +215 -0
  124. package/omega/Agentik_Engine/omega_engine/cadence.py +158 -0
  125. package/omega/Agentik_Engine/omega_engine/classifier.py +215 -0
  126. package/omega/Agentik_Engine/omega_engine/cleanup.py +673 -0
  127. package/omega/Agentik_Engine/omega_engine/cli.py +4564 -56
  128. package/omega/Agentik_Engine/omega_engine/completions.py +260 -0
  129. package/omega/Agentik_Engine/omega_engine/costs.py +100 -0
  130. package/omega/Agentik_Engine/omega_engine/daemons/__init__.py +14 -0
  131. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/__init__.cpython-313.pyc +0 -0
  132. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/autonomous.cpython-313.pyc +0 -0
  133. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/engine.cpython-313.pyc +0 -0
  134. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/telegram.cpython-313.pyc +0 -0
  135. package/omega/Agentik_Engine/omega_engine/daemons/autonomous.py +56 -0
  136. package/omega/Agentik_Engine/omega_engine/daemons/engine.py +236 -0
  137. package/omega/Agentik_Engine/omega_engine/daemons/telegram.py +315 -0
  138. package/omega/Agentik_Engine/omega_engine/done_signal.py +154 -0
  139. package/omega/Agentik_Engine/omega_engine/educators/__init__.py +51 -0
  140. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/__init__.cpython-313.pyc +0 -0
  141. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/artifact.cpython-313.pyc +0 -0
  142. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/automation.cpython-313.pyc +0 -0
  143. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/base.cpython-313.pyc +0 -0
  144. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/claudecode.cpython-313.pyc +0 -0
  145. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/connection.cpython-313.pyc +0 -0
  146. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/coworker.cpython-313.pyc +0 -0
  147. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/loop.cpython-313.pyc +0 -0
  148. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/prompt.cpython-313.pyc +0 -0
  149. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/skill.cpython-313.pyc +0 -0
  150. package/omega/Agentik_Engine/omega_engine/educators/artifact.py +65 -0
  151. package/omega/Agentik_Engine/omega_engine/educators/automation.py +76 -0
  152. package/omega/Agentik_Engine/omega_engine/educators/base.py +327 -0
  153. package/omega/Agentik_Engine/omega_engine/educators/claudecode.py +71 -0
  154. package/omega/Agentik_Engine/omega_engine/educators/connection.py +75 -0
  155. package/omega/Agentik_Engine/omega_engine/educators/coworker.py +68 -0
  156. package/omega/Agentik_Engine/omega_engine/educators/loop.py +82 -0
  157. package/omega/Agentik_Engine/omega_engine/educators/prompt.py +68 -0
  158. package/omega/Agentik_Engine/omega_engine/educators/skill.py +69 -0
  159. package/omega/Agentik_Engine/omega_engine/envelope.py +219 -0
  160. package/omega/Agentik_Engine/omega_engine/executor.py +195 -16
  161. package/omega/Agentik_Engine/omega_engine/genesis/__init__.py +134 -0
  162. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/__init__.cpython-313.pyc +0 -0
  163. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/orchestrator.cpython-313.pyc +0 -0
  164. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/phases.cpython-313.pyc +0 -0
  165. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/stack.cpython-313.pyc +0 -0
  166. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/state.cpython-313.pyc +0 -0
  167. package/omega/Agentik_Engine/omega_engine/genesis/orchestrator.py +262 -0
  168. package/omega/Agentik_Engine/omega_engine/genesis/phases.py +950 -0
  169. package/omega/Agentik_Engine/omega_engine/genesis/stack.py +324 -0
  170. package/omega/Agentik_Engine/omega_engine/genesis/state.py +353 -0
  171. package/omega/Agentik_Engine/omega_engine/handoff.py +459 -0
  172. package/omega/Agentik_Engine/omega_engine/hermes.py +426 -0
  173. package/omega/Agentik_Engine/omega_engine/hermes_bootstrap.py +382 -0
  174. package/omega/Agentik_Engine/omega_engine/hermes_desktop.py +469 -0
  175. package/omega/Agentik_Engine/omega_engine/integrations/__init__.py +30 -0
  176. package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/__init__.cpython-313.pyc +0 -0
  177. package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/graphify.cpython-313.pyc +0 -0
  178. package/omega/Agentik_Engine/omega_engine/integrations/graphify.py +234 -0
  179. package/omega/Agentik_Engine/omega_engine/learning.py +268 -0
  180. package/omega/Agentik_Engine/omega_engine/managed_agent.py +467 -0
  181. package/omega/Agentik_Engine/omega_engine/memory.py +271 -0
  182. package/omega/Agentik_Engine/omega_engine/menu.py +1065 -0
  183. package/omega/Agentik_Engine/omega_engine/migrations/__init__.py +144 -0
  184. package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/__init__.cpython-313.pyc +0 -0
  185. package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/v0_14_0.cpython-313.pyc +0 -0
  186. package/omega/Agentik_Engine/omega_engine/migrations/v0_14_0.py +29 -0
  187. package/omega/Agentik_Engine/omega_engine/mission.py +29 -14
  188. package/omega/Agentik_Engine/omega_engine/plan.py +846 -0
  189. package/omega/Agentik_Engine/omega_engine/prompts.py +158 -0
  190. package/omega/Agentik_Engine/omega_engine/provider.py +408 -13
  191. package/omega/Agentik_Engine/omega_engine/prune.py +151 -0
  192. package/omega/Agentik_Engine/omega_engine/pursue.py +205 -0
  193. package/omega/Agentik_Engine/omega_engine/rag/__init__.py +21 -0
  194. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/__init__.cpython-313.pyc +0 -0
  195. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/agentic.cpython-313.pyc +0 -0
  196. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/base.cpython-313.pyc +0 -0
  197. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/corrective.cpython-313.pyc +0 -0
  198. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/graph.cpython-313.pyc +0 -0
  199. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/hybrid.cpython-313.pyc +0 -0
  200. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/multimodal.cpython-313.pyc +0 -0
  201. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/router.cpython-313.pyc +0 -0
  202. package/omega/Agentik_Engine/omega_engine/rag/agentic.py +83 -0
  203. package/omega/Agentik_Engine/omega_engine/rag/base.py +42 -0
  204. package/omega/Agentik_Engine/omega_engine/rag/corrective.py +119 -0
  205. package/omega/Agentik_Engine/omega_engine/rag/graph.py +169 -0
  206. package/omega/Agentik_Engine/omega_engine/rag/hybrid.py +205 -0
  207. package/omega/Agentik_Engine/omega_engine/rag/multimodal.py +136 -0
  208. package/omega/Agentik_Engine/omega_engine/rag/router.py +110 -0
  209. package/omega/Agentik_Engine/omega_engine/reducer.py +21 -3
  210. package/omega/Agentik_Engine/omega_engine/router.py +28 -0
  211. package/omega/Agentik_Engine/omega_engine/skill_discovery/__init__.py +48 -0
  212. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/__init__.cpython-313.pyc +0 -0
  213. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/auditor.cpython-313.pyc +0 -0
  214. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/finder.cpython-313.pyc +0 -0
  215. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/installer.cpython-313.pyc +0 -0
  216. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/marketplaces.cpython-313.pyc +0 -0
  217. package/omega/Agentik_Engine/omega_engine/skill_discovery/auditor.py +232 -0
  218. package/omega/Agentik_Engine/omega_engine/skill_discovery/finder.py +94 -0
  219. package/omega/Agentik_Engine/omega_engine/skill_discovery/installer.py +129 -0
  220. package/omega/Agentik_Engine/omega_engine/skill_discovery/marketplaces.py +80 -0
  221. package/omega/Agentik_Engine/omega_engine/skill_routing.py +388 -0
  222. package/omega/Agentik_Engine/omega_engine/smoke.py +81 -0
  223. package/omega/Agentik_Engine/omega_engine/store.py +132 -25
  224. package/omega/Agentik_Engine/omega_engine/sync.py +445 -0
  225. package/omega/Agentik_Engine/omega_engine/telegram_history.py +260 -0
  226. package/omega/Agentik_Engine/omega_engine/tmux.py +526 -0
  227. package/omega/Agentik_Engine/omega_engine/tools.py +272 -0
  228. package/omega/Agentik_Engine/omega_engine/understand_anything.py +275 -0
  229. package/omega/Agentik_Engine/omega_engine/updater.py +70 -0
  230. package/omega/Agentik_Engine/omega_engine/validate.py +186 -0
  231. package/omega/Agentik_Engine/omega_engine/vault.py +342 -0
  232. package/omega/Agentik_Engine/omega_engine/webhooks.py +262 -0
  233. package/omega/Agentik_Engine/omega_engine/worker.py +526 -0
  234. package/omega/Agentik_Engine/pyproject.toml +1 -1
  235. package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313-pytest-8.4.2.pyc +0 -0
  236. package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313.pyc +0 -0
  237. package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313-pytest-8.4.2.pyc +0 -0
  238. package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313.pyc +0 -0
  239. package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313-pytest-8.4.2.pyc +0 -0
  240. package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313.pyc +0 -0
  241. package/omega/Agentik_Engine/tests/__pycache__/test_audit_arsenal.cpython-313-pytest-8.4.2.pyc +0 -0
  242. package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313-pytest-8.4.2.pyc +0 -0
  243. package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313.pyc +0 -0
  244. package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313-pytest-8.4.2.pyc +0 -0
  245. package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313.pyc +0 -0
  246. package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313-pytest-8.4.2.pyc +0 -0
  247. package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313.pyc +0 -0
  248. package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313-pytest-8.4.2.pyc +0 -0
  249. package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313.pyc +0 -0
  250. package/omega/Agentik_Engine/tests/__pycache__/test_executor.cpython-313-pytest-8.4.2.pyc +0 -0
  251. package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313-pytest-8.4.2.pyc +0 -0
  252. package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313.pyc +0 -0
  253. package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313-pytest-8.4.2.pyc +0 -0
  254. package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313.pyc +0 -0
  255. package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313-pytest-8.4.2.pyc +0 -0
  256. package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313.pyc +0 -0
  257. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313-pytest-8.4.2.pyc +0 -0
  258. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313.pyc +0 -0
  259. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313-pytest-8.4.2.pyc +0 -0
  260. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313.pyc +0 -0
  261. package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313-pytest-8.4.2.pyc +0 -0
  262. package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313.pyc +0 -0
  263. package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313-pytest-8.4.2.pyc +0 -0
  264. package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313.pyc +0 -0
  265. package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313-pytest-8.4.2.pyc +0 -0
  266. package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313.pyc +0 -0
  267. package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313-pytest-8.4.2.pyc +0 -0
  268. package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313.pyc +0 -0
  269. package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313-pytest-8.4.2.pyc +0 -0
  270. package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313.pyc +0 -0
  271. package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313-pytest-8.4.2.pyc +0 -0
  272. package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313.pyc +0 -0
  273. package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313-pytest-8.4.2.pyc +0 -0
  274. package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313.pyc +0 -0
  275. package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313-pytest-8.4.2.pyc +0 -0
  276. package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313.pyc +0 -0
  277. package/omega/Agentik_Engine/tests/__pycache__/test_mission.cpython-313-pytest-8.4.2.pyc +0 -0
  278. package/omega/Agentik_Engine/tests/__pycache__/test_progress.cpython-313-pytest-8.4.2.pyc +0 -0
  279. package/omega/Agentik_Engine/tests/__pycache__/test_project.cpython-313-pytest-8.4.2.pyc +0 -0
  280. package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313-pytest-8.4.2.pyc +0 -0
  281. package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313.pyc +0 -0
  282. package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313-pytest-8.4.2.pyc +0 -0
  283. package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313.pyc +0 -0
  284. package/omega/Agentik_Engine/tests/__pycache__/test_reducer.cpython-313-pytest-8.4.2.pyc +0 -0
  285. package/omega/Agentik_Engine/tests/__pycache__/test_report.cpython-313-pytest-8.4.2.pyc +0 -0
  286. package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313-pytest-8.4.2.pyc +0 -0
  287. package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313.pyc +0 -0
  288. package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313-pytest-8.4.2.pyc +0 -0
  289. package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313.pyc +0 -0
  290. package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313-pytest-8.4.2.pyc +0 -0
  291. package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313.pyc +0 -0
  292. package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313-pytest-8.4.2.pyc +0 -0
  293. package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313.pyc +0 -0
  294. package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313-pytest-8.4.2.pyc +0 -0
  295. package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313.pyc +0 -0
  296. package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313-pytest-8.4.2.pyc +0 -0
  297. package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313.pyc +0 -0
  298. package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313-pytest-8.4.2.pyc +0 -0
  299. package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313.pyc +0 -0
  300. package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313-pytest-8.4.2.pyc +0 -0
  301. package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313.pyc +0 -0
  302. package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313-pytest-8.4.2.pyc +0 -0
  303. package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313.pyc +0 -0
  304. package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313-pytest-8.4.2.pyc +0 -0
  305. package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313.pyc +0 -0
  306. package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313-pytest-8.4.2.pyc +0 -0
  307. package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313.pyc +0 -0
  308. package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313-pytest-8.4.2.pyc +0 -0
  309. package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313.pyc +0 -0
  310. package/omega/Agentik_Engine/tests/test_account.py +338 -0
  311. package/omega/Agentik_Engine/tests/test_adversarial.py +351 -0
  312. package/omega/Agentik_Engine/tests/test_agents_envelope.py +274 -0
  313. package/omega/Agentik_Engine/tests/test_audits_pipeline.py +348 -0
  314. package/omega/Agentik_Engine/tests/test_auto_update_and_migrations.py +394 -0
  315. package/omega/Agentik_Engine/tests/test_autonomous.py +361 -0
  316. package/omega/Agentik_Engine/tests/test_educators.py +233 -0
  317. package/omega/Agentik_Engine/tests/test_genesis_and_plan.py +573 -0
  318. package/omega/Agentik_Engine/tests/test_graphify.py +190 -0
  319. package/omega/Agentik_Engine/tests/test_handoff.py +311 -0
  320. package/omega/Agentik_Engine/tests/test_hermes_and_ua.py +387 -0
  321. package/omega/Agentik_Engine/tests/test_hermes_bootstrap_and_desktop.py +358 -0
  322. package/omega/Agentik_Engine/tests/test_install_steps.py +359 -0
  323. package/omega/Agentik_Engine/tests/test_install_ux.py +151 -0
  324. package/omega/Agentik_Engine/tests/test_installer_wiring.py +496 -0
  325. package/omega/Agentik_Engine/tests/test_intelligence.py +285 -0
  326. package/omega/Agentik_Engine/tests/test_llm_clis_and_uninstall.py +228 -0
  327. package/omega/Agentik_Engine/tests/test_managed_agent.py +363 -0
  328. package/omega/Agentik_Engine/tests/test_max_provider_and_menu.py +231 -0
  329. package/omega/Agentik_Engine/tests/test_menu_coverage.py +72 -0
  330. package/omega/Agentik_Engine/tests/test_pursue_cadence.py +217 -0
  331. package/omega/Agentik_Engine/tests/test_rag.py +287 -0
  332. package/omega/Agentik_Engine/tests/test_role_aliases_and_ssot.py +207 -0
  333. package/omega/Agentik_Engine/tests/test_skill_discovery_and_gate.py +337 -0
  334. package/omega/Agentik_Engine/tests/test_skill_power.py +259 -0
  335. package/omega/Agentik_Engine/tests/test_skill_routing.py +189 -0
  336. package/omega/Agentik_Engine/tests/test_snapshot_partial.py +172 -0
  337. package/omega/Agentik_Engine/tests/test_telegram_history.py +209 -0
  338. package/omega/Agentik_Engine/tests/test_tmux_and_aisb_chat.py +223 -0
  339. package/omega/Agentik_Engine/tests/test_tools_and_sync.py +312 -0
  340. package/omega/Agentik_Engine/tests/test_v06_features.py +370 -0
  341. package/omega/Agentik_Engine/tests/test_vault.py +173 -0
  342. package/omega/Agentik_Engine/tests/test_webhooks_and_readiness.py +277 -0
  343. package/omega/Agentik_Engine/tests/test_worker_and_cleanup.py +541 -0
  344. package/omega/Agentik_Extra/etc/secrets/.vault-key +3 -0
  345. package/omega/Agentik_Extra/etc/secrets/.vault-pub +1 -0
  346. package/omega/Agentik_Runtime/audits.db +0 -0
  347. package/omega/Agentik_SSOT/VERSION +1 -1
  348. package/omega/Agentik_SSOT/claude-plugins/claude-plugins.yaml +100 -0
  349. package/omega/Agentik_SSOT/docs/LAYERS.md +90 -0
  350. package/omega/Agentik_SSOT/docs/USER-JOURNEY.md +283 -0
  351. package/omega/Agentik_SSOT/marketplaces/design-discipline.yaml +86 -0
  352. package/omega/Agentik_SSOT/skills/a11yaudit/SKILL.md +161 -0
  353. package/omega/Agentik_SSOT/skills/apiaudit/SKILL.md +157 -0
  354. package/omega/Agentik_SSOT/skills/automationaudit/SKILL.md +161 -0
  355. package/omega/Agentik_SSOT/skills/cadence/SKILL.md +76 -0
  356. package/omega/Agentik_SSOT/skills/codeaudit/SKILL.md +153 -0
  357. package/omega/Agentik_SSOT/skills/copyaudit/SKILL.md +161 -0
  358. package/omega/Agentik_SSOT/skills/dataaudit/SKILL.md +157 -0
  359. package/omega/Agentik_SSOT/skills/debugaudit/SKILL.md +161 -0
  360. package/omega/Agentik_SSOT/skills/dispatch/SKILL.md +79 -0
  361. package/omega/Agentik_SSOT/skills/dxaudit/SKILL.md +161 -0
  362. package/omega/Agentik_SSOT/skills/featureaudit/SKILL.md +161 -0
  363. package/omega/Agentik_SSOT/skills/flowaudit/SKILL.md +165 -0
  364. package/omega/Agentik_SSOT/skills/genesis/SKILL.md +116 -0
  365. package/omega/Agentik_SSOT/skills/handoff/SKILL.md +117 -0
  366. package/omega/Agentik_SSOT/skills/logicaudit/SKILL.md +165 -0
  367. package/omega/Agentik_SSOT/skills/motionaudit/SKILL.md +165 -0
  368. package/omega/Agentik_SSOT/skills/perfaudit/SKILL.md +161 -0
  369. package/omega/Agentik_SSOT/skills/plan/SKILL.md +127 -0
  370. package/omega/Agentik_SSOT/skills/pursue/SKILL.md +68 -0
  371. package/omega/Agentik_SSOT/skills/rag-route.md +82 -0
  372. package/omega/Agentik_SSOT/skills/refontaudit/SKILL.md +165 -0
  373. package/omega/Agentik_SSOT/skills/retentionaudit/SKILL.md +165 -0
  374. package/omega/Agentik_SSOT/skills/secaudit/SKILL.md +157 -0
  375. package/omega/Agentik_SSOT/skills/seoaudit/SKILL.md +161 -0
  376. package/omega/Agentik_SSOT/skills/skill-auditor/SKILL.md +83 -0
  377. package/omega/Agentik_SSOT/skills/skill-finder/SKILL.md +116 -0
  378. package/omega/Agentik_SSOT/skills/uiuxaudit/SKILL.md +165 -0
  379. package/package.json +2 -2
@@ -0,0 +1,128 @@
1
+ """AISB chat-loop — talk to the AISB master agent like it was Telegram.
2
+
3
+ The user often runs OmegaOS in places where Telegram isn't connected
4
+ (fresh VPS, the operator on a different machine, etc.). The AISB chat
5
+ loop is the fallback: spawn `tmux new-session -s AISB-chat` running
6
+ this loop, attach, and you get a REPL-style conversation with the AISB
7
+ master agent — same envelope, same .done.json contract, but stdin /
8
+ stdout instead of Telegram.
9
+
10
+ Conversation history is persisted in
11
+ ``Agentik_Runtime/telegram-history.db`` under topic_id = -1 (a sentinel
12
+ "chat-loop" topic) so we share the same history layer the Telegram
13
+ daemon already uses. The user sees prior turns at the top of each new
14
+ session.
15
+ """
16
+ from __future__ import annotations
17
+
18
+ import os
19
+ import sys
20
+ import time
21
+ from pathlib import Path
22
+
23
+
24
+ CHAT_TOPIC = -1
25
+
26
+
27
+ def _omega_home() -> Path:
28
+ return Path(os.environ.get("OMEGA_HOME", str(Path.home() / "Omega")))
29
+
30
+
31
+ def _print_banner() -> None:
32
+ print("─" * 60)
33
+ print(" AISB chat — Telegram-equivalent fallback")
34
+ print(f" history persisted under topic_id={CHAT_TOPIC}")
35
+ print(" type /quit to exit, /history to show the last 10 turns,")
36
+ print(" /clear to wipe this session's history")
37
+ print("─" * 60)
38
+
39
+
40
+ def _print_history(home: Path, limit: int = 10) -> None:
41
+ from omega_engine.telegram_history import recent_messages
42
+ msgs = recent_messages(home, topic_id=CHAT_TOPIC, limit=limit)
43
+ if not msgs:
44
+ print(" (no history yet)")
45
+ return
46
+ for m in msgs:
47
+ print(f" {m.role}: {m.text[:300]}")
48
+
49
+
50
+ def _clear_history(home: Path) -> int:
51
+ from omega_engine.telegram_history import _connect
52
+ conn = _connect(home)
53
+ try:
54
+ cur = conn.execute(
55
+ "DELETE FROM messages WHERE topic_id = ?", (CHAT_TOPIC,),
56
+ )
57
+ conn.commit()
58
+ return int(cur.rowcount or 0)
59
+ finally:
60
+ conn.close()
61
+
62
+
63
+ def run_chat_loop() -> int:
64
+ """Block until /quit. Returns 0 on clean exit."""
65
+ home = _omega_home()
66
+ from omega_engine.envelope import EnvelopeContext, build_envelope
67
+ from omega_engine.provider import AgentRequest
68
+ from omega_engine.router import ModelRouter
69
+ from omega_engine.telegram_history import (
70
+ build_context_prompt, record_inbound, record_outbound,
71
+ )
72
+
73
+ _print_banner()
74
+ router = ModelRouter.auto()
75
+
76
+ while True:
77
+ try:
78
+ line = input("\nyou > ").strip()
79
+ except (EOFError, KeyboardInterrupt):
80
+ print("\n(exit)")
81
+ return 0
82
+ if not line:
83
+ continue
84
+ if line == "/quit":
85
+ print("(exit)")
86
+ return 0
87
+ if line == "/history":
88
+ _print_history(home)
89
+ continue
90
+ if line == "/clear":
91
+ n = _clear_history(home)
92
+ print(f"(cleared {n} message(s))")
93
+ continue
94
+
95
+ # Record the user's turn.
96
+ record_inbound(home, topic_id=CHAT_TOPIC, text=line)
97
+
98
+ # Build the AISB envelope — same one the engine uses everywhere.
99
+ enriched = build_context_prompt(
100
+ home, topic_id=CHAT_TOPIC, new_intent=line, limit=10,
101
+ )
102
+ ctx = EnvelopeContext(
103
+ role="aisb",
104
+ intent=enriched,
105
+ task_id=f"chat-{int(time.time())}",
106
+ )
107
+ env = build_envelope(home, ctx)
108
+ provider = router.resolve("aisb")
109
+ try:
110
+ result = provider.run(AgentRequest(
111
+ role="aisb", prompt=env["user"], context={},
112
+ system=env["system"],
113
+ ))
114
+ except Exception as exc: # noqa: BLE001
115
+ print(f"aisb (error): {exc}")
116
+ continue
117
+
118
+ reply = (result.text or "").strip() or "(empty reply)"
119
+ record_outbound(home, topic_id=CHAT_TOPIC, text=reply)
120
+ print(f"\naisb > {reply}")
121
+
122
+
123
+ def main(argv: list[str] | None = None) -> int:
124
+ return run_chat_loop()
125
+
126
+
127
+ if __name__ == "__main__":
128
+ sys.exit(main())
@@ -0,0 +1,99 @@
1
+ """`omega audit diff <run-id-1> <run-id-2>` — compare two forensic-audit runs.
2
+
3
+ Given two run ids (same audit usually, but different audits also work),
4
+ report:
5
+
6
+ * Score delta (run1 → run2)
7
+ * Findings that were FIXED (in run1, gone in run2)
8
+ * Findings that are NEW (in run2, weren't in run1)
9
+ * Findings that PERSIST (in both — the operator hasn't fixed them yet)
10
+ * Findings that REGRESSED (severity went UP in run2)
11
+
12
+ We dedupe by `(phase, location, message)` — same finding location is
13
+ considered "the same issue" across runs. This is a heuristic; for
14
+ findings without locations (architectural) we dedupe by phase+message.
15
+ """
16
+ from __future__ import annotations
17
+
18
+ from dataclasses import dataclass, field
19
+ from pathlib import Path
20
+ from typing import Any
21
+
22
+
23
+ @dataclass(frozen=True)
24
+ class FindingKey:
25
+ phase: str
26
+ location: str
27
+ message: str
28
+
29
+
30
+ @dataclass
31
+ class AuditDiff:
32
+ run1: str
33
+ run2: str
34
+ audit_id: str
35
+ score1: int
36
+ score2: int
37
+ fixed: list[dict[str, Any]] = field(default_factory=list)
38
+ new: list[dict[str, Any]] = field(default_factory=list)
39
+ persist: list[dict[str, Any]] = field(default_factory=list)
40
+ regressed: list[dict[str, Any]] = field(default_factory=list)
41
+
42
+ @property
43
+ def delta(self) -> int:
44
+ return self.score2 - self.score1
45
+
46
+
47
+ _SEVERITY_RANK = {"low": 0, "medium": 1, "med": 1,
48
+ "high": 2, "critical": 3, "crit": 3}
49
+
50
+
51
+ def _finding_key(f: dict) -> FindingKey:
52
+ return FindingKey(
53
+ phase=str(f.get("phase", "?")),
54
+ location=str(f.get("location", f.get("file", "?"))),
55
+ message=str(f.get("message", f.get("claim", "")))[:120],
56
+ )
57
+
58
+
59
+ def _by_key(findings: list[dict]) -> dict[FindingKey, dict]:
60
+ return {_finding_key(f): f for f in findings}
61
+
62
+
63
+ def diff_runs(
64
+ omega_home: str | Path, run1: str, run2: str,
65
+ ) -> AuditDiff:
66
+ """Load two audit runs from history and produce a structured diff."""
67
+ from omega_engine.audits.history import list_runs
68
+
69
+ runs = list_runs(omega_home, audit_id=None, limit=1000)
70
+ by_id = {r.run_id: r for r in runs}
71
+ r1 = by_id.get(run1)
72
+ r2 = by_id.get(run2)
73
+ if r1 is None:
74
+ raise KeyError(f"run not found: {run1}")
75
+ if r2 is None:
76
+ raise KeyError(f"run not found: {run2}")
77
+
78
+ findings1 = list(r1.verdict.get("findings") or [])
79
+ findings2 = list(r2.verdict.get("findings") or [])
80
+ map1 = _by_key(findings1)
81
+ map2 = _by_key(findings2)
82
+
83
+ fixed = [map1[k] for k in (map1.keys() - map2.keys())]
84
+ new = [map2[k] for k in (map2.keys() - map1.keys())]
85
+ persist_keys = map1.keys() & map2.keys()
86
+ persist = [map2[k] for k in persist_keys]
87
+ regressed = []
88
+ for k in persist_keys:
89
+ s1 = _SEVERITY_RANK.get(str(map1[k].get("severity", "medium")).lower(), 1)
90
+ s2 = _SEVERITY_RANK.get(str(map2[k].get("severity", "medium")).lower(), 1)
91
+ if s2 > s1:
92
+ regressed.append(map2[k])
93
+
94
+ return AuditDiff(
95
+ run1=run1, run2=run2,
96
+ audit_id=str(r2.audit_id),
97
+ score1=int(r1.score), score2=int(r2.score),
98
+ fixed=fixed, new=new, persist=persist, regressed=regressed,
99
+ )
@@ -0,0 +1,149 @@
1
+ """`omega audit gate` — the Claude Code Stop-hook gatekeeper.
2
+
3
+ When ``claude_code_settings.audit_gate: true`` is set in the install
4
+ manifest, the installer writes a ``Stop`` hook into
5
+ ``~/.claude/settings.json`` that calls this command. The hook fires
6
+ whenever Claude is about to say "I'm done" — and this command decides
7
+ whether the audit verdicts let it.
8
+
9
+ Flow:
10
+
11
+ 1. Claude finishes a turn.
12
+ 2. Claude Code triggers the ``Stop`` hook.
13
+ 3. ``omega audit gate`` reads the hook JSON from stdin
14
+ (``{session_id, cwd, ...}``).
15
+ 4. We look at the per-session ``.done.json`` and the audit history
16
+ for the same scope.
17
+ 5. If the most recent ``.done.json`` has ``status == "failed"`` OR
18
+ the latest audit run for the cwd has ``verified=False``, we
19
+ emit ``permissionDecision: deny`` with a clear reason. Claude
20
+ must keep working.
21
+ 6. Otherwise we exit 0 silently and the Stop proceeds.
22
+
23
+ This is the killer rule that closes the "Claude says done but isn't"
24
+ loophole — at the *editor* level, not just the engine.
25
+ """
26
+ from __future__ import annotations
27
+
28
+ import json
29
+ import os
30
+ import sys
31
+ from pathlib import Path
32
+ from typing import Any
33
+
34
+
35
+ def _omega_home() -> Path:
36
+ return Path(os.environ.get("OMEGA_HOME", str(Path.home() / "Omega")))
37
+
38
+
39
+ def _read_hook_input() -> dict[str, Any]:
40
+ """Best-effort JSON read from stdin; an empty dict on failure."""
41
+ try:
42
+ raw = sys.stdin.read()
43
+ except Exception: # noqa: BLE001
44
+ return {}
45
+ if not raw.strip():
46
+ return {}
47
+ try:
48
+ return json.loads(raw)
49
+ except json.JSONDecodeError:
50
+ return {}
51
+
52
+
53
+ def _latest_done(home: Path, session_id: str) -> dict[str, Any] | None:
54
+ """Return the latest .done.json content for the session, or None."""
55
+ if not session_id:
56
+ return None
57
+ sess_root = home / "Agentik_Runtime" / "sessions"
58
+ candidates = list(sess_root.glob(f"*{session_id}*/.done.json"))
59
+ if not candidates:
60
+ return None
61
+ # newest by mtime
62
+ latest = max(candidates, key=lambda p: p.stat().st_mtime)
63
+ try:
64
+ return json.loads(latest.read_text())
65
+ except (json.JSONDecodeError, OSError):
66
+ return None
67
+
68
+
69
+ def _latest_audit_failed(home: Path) -> tuple[bool, str]:
70
+ """Return (failed, message). True if the latest audit run was not verified."""
71
+ try:
72
+ from omega_engine.audits.history import list_runs
73
+ except ImportError:
74
+ return False, ""
75
+ runs = list_runs(home, audit_id=None, limit=1)
76
+ if not runs:
77
+ return False, ""
78
+ r = runs[0]
79
+ if r.verified:
80
+ return False, ""
81
+ return True, (
82
+ f"audit '{r.audit_id}' run {r.run_id} scored {r.score} "
83
+ f"(threshold not met). Fix the findings before declaring done."
84
+ )
85
+
86
+
87
+ def _deny(reason: str) -> None:
88
+ """Emit the hookSpecificOutput payload that denies the Stop."""
89
+ payload = {
90
+ "continue": False,
91
+ "stopReason": reason,
92
+ "systemMessage": f"omega audit gate: {reason}",
93
+ "hookSpecificOutput": {
94
+ "hookEventName": "Stop",
95
+ "permissionDecision": "deny",
96
+ "permissionDecisionReason": reason,
97
+ },
98
+ }
99
+ print(json.dumps(payload))
100
+
101
+
102
+ def gate(input_payload: dict[str, Any] | None = None) -> int:
103
+ """Decide whether to allow the Stop. Returns the exit code.
104
+
105
+ Exit 0 = allow (silent). Exit 2 + JSON on stdout = deny.
106
+ Other failures → exit 0 (we never break the editor on our own bugs).
107
+ """
108
+ home = _omega_home()
109
+ data = input_payload if input_payload is not None else _read_hook_input()
110
+
111
+ session_id = str(data.get("session_id") or "")
112
+
113
+ # 1. Did the worker explicitly write status=failed?
114
+ done = _latest_done(home, session_id)
115
+ if done and done.get("status") == "failed":
116
+ errs = ", ".join(done.get("errors") or [])[:300] or "no detail"
117
+ _deny(
118
+ f"worker reported status=failed in .done.json ({errs}). "
119
+ "Resume the task or revise."
120
+ )
121
+ return 2
122
+
123
+ # 2. Did the worker leave pending actions un-actioned?
124
+ if done and done.get("status") == "pending":
125
+ pa = done.get("pending_actions") or []
126
+ if pa:
127
+ _deny(
128
+ f"worker reported status=pending with {len(pa)} pending "
129
+ f"action(s): {pa[:3]}. Resolve or hand off explicitly."
130
+ )
131
+ return 2
132
+
133
+ # 3. Is the latest forensic audit verdict still failing?
134
+ failed, msg = _latest_audit_failed(home)
135
+ if failed:
136
+ _deny(msg)
137
+ return 2
138
+
139
+ # All clear.
140
+ return 0
141
+
142
+
143
+ def main(argv: list[str] | None = None) -> int:
144
+ """Entry point for the `omega audit gate` CLI."""
145
+ return gate()
146
+
147
+
148
+ if __name__ == "__main__":
149
+ sys.exit(main())
@@ -0,0 +1,60 @@
1
+ """Audits package — the 100% mega powerful Quality Arsenal layer.
2
+
3
+ What lives here:
4
+
5
+ * ``pipeline.AuditPipeline`` — gather + analyse + batch + dispatch +
6
+ re-audit + record, all in one call.
7
+ * ``batcher.batch_findings`` — cluster findings into ≤N disjoint
8
+ worker batches.
9
+ * ``dispatcher.dispatch_fixes`` — spawn a worker per batch via the
10
+ engine's executor.
11
+ * ``history.*`` — SQLite-backed score history per audit.
12
+ * ``generator.write_all`` — produce ``SKILL.md`` for every audit.
13
+
14
+ The existing forensic primitives (``Audit``, ``AuditRegistry``,
15
+ ``run_forensic_audit``, ``ArsenalGate``) stay in
16
+ ``omega_engine.audit_arsenal`` — this package builds the next layer on top.
17
+ """
18
+ from omega_engine.audits.batcher import (
19
+ Batch,
20
+ BatchPlan,
21
+ Finding,
22
+ batch_findings,
23
+ )
24
+ from omega_engine.audits.dispatcher import (
25
+ DispatchResult,
26
+ dispatch_fixes,
27
+ )
28
+ from omega_engine.audits.generator import (
29
+ AuditSkillFile,
30
+ generate_all,
31
+ generate_skill,
32
+ write_all,
33
+ )
34
+ from omega_engine.audits.history import (
35
+ AuditRun,
36
+ latest_score,
37
+ list_runs,
38
+ make_run_id,
39
+ record_run,
40
+ trend,
41
+ )
42
+ from omega_engine.audits.pipeline import (
43
+ AuditOutcome,
44
+ AuditPipeline,
45
+ )
46
+
47
+
48
+ __all__ = [
49
+ # pipeline
50
+ "AuditPipeline", "AuditOutcome",
51
+ # batcher
52
+ "Finding", "Batch", "BatchPlan", "batch_findings",
53
+ # dispatcher
54
+ "DispatchResult", "dispatch_fixes",
55
+ # history
56
+ "AuditRun", "record_run", "list_runs", "latest_score", "trend",
57
+ "make_run_id",
58
+ # generator
59
+ "AuditSkillFile", "generate_skill", "generate_all", "write_all",
60
+ ]
@@ -0,0 +1,218 @@
1
+ """Smart finding batcher — cluster audit findings into ≤N worker batches.
2
+
3
+ The user's hard constraint: fix the issues found, but DO NOT spawn one
4
+ worker per finding (that would explode parallelism and overwhelm the
5
+ system). Instead:
6
+
7
+ * Group findings by their file footprint.
8
+ * Pack groups into a small number of batches (default 3).
9
+ * Two batches MUST have disjoint file sets — never let two workers race
10
+ on the same file.
11
+ * Findings with no file location ("architectural") get their own batch.
12
+ * If total batches would exceed the cap, prefer the highest-severity
13
+ ones and emit a ``deferred`` list for the rest.
14
+
15
+ This module is pure logic — no I/O, no subprocess. The dispatcher
16
+ (``omega_engine.audits.dispatcher``) consumes the result and actually
17
+ spawns workers.
18
+ """
19
+ from __future__ import annotations
20
+
21
+ from collections import defaultdict
22
+ from dataclasses import dataclass, field
23
+ from typing import Any, Iterable
24
+
25
+
26
+ SEVERITY_WEIGHT = {
27
+ "critical": 100, "crit": 100,
28
+ "high": 30,
29
+ "medium": 10, "med": 10,
30
+ "low": 3,
31
+ }
32
+
33
+
34
+ def _severity_weight(severity: str) -> int:
35
+ return SEVERITY_WEIGHT.get(severity.lower().strip(), 5)
36
+
37
+
38
+ @dataclass(frozen=True)
39
+ class Finding:
40
+ """A normalised finding used by the batcher.
41
+
42
+ Constructed from either an ``ArsenalFinding`` (the structured form
43
+ emitted by the forensic gate) or a raw dict.
44
+ """
45
+ audit: str
46
+ phase: str
47
+ severity: str
48
+ file: str | None
49
+ line: int | None
50
+ message: str
51
+ fix_hint: str = ""
52
+
53
+ @staticmethod
54
+ def from_arsenal(f: Any) -> "Finding":
55
+ """Build from an `ArsenalFinding` (duck-typed for testability)."""
56
+ loc = getattr(f, "location", "?") or "?"
57
+ file, line = _parse_location(loc)
58
+ return Finding(
59
+ audit=getattr(f, "audit", "?"),
60
+ phase=getattr(f, "phase", "?"),
61
+ severity=getattr(f, "severity", "medium"),
62
+ file=file, line=line,
63
+ message=(
64
+ f"{getattr(f, 'claim', '')} → {getattr(f, 'reality', '')}".strip(" →")
65
+ or getattr(f, "message", "")
66
+ ),
67
+ )
68
+
69
+ @staticmethod
70
+ def from_dict(d: dict[str, Any]) -> "Finding":
71
+ loc = d.get("location") or d.get("file") or "?"
72
+ if isinstance(loc, str):
73
+ file, line = _parse_location(loc)
74
+ else:
75
+ file, line = None, None
76
+ return Finding(
77
+ audit=str(d.get("audit", "?")),
78
+ phase=str(d.get("phase", "?")),
79
+ severity=str(d.get("severity", "medium")),
80
+ file=file, line=line,
81
+ message=str(d.get("message", d.get("claim", "")))[:500],
82
+ fix_hint=str(d.get("fix", d.get("fix_hint", "")))[:500],
83
+ )
84
+
85
+
86
+ def _parse_location(loc: str) -> tuple[str | None, int | None]:
87
+ """Parse 'path/to/file.py:42' → ('path/to/file.py', 42). None if no file."""
88
+ if not loc or loc == "?":
89
+ return None, None
90
+ # Strip leading "./" and the like
91
+ s = loc.strip()
92
+ if ":" in s:
93
+ path, _, rest = s.partition(":")
94
+ try:
95
+ line = int(rest.partition(":")[0])
96
+ except ValueError:
97
+ line = None
98
+ return (path or None), line
99
+ return s, None
100
+
101
+
102
+ @dataclass
103
+ class Batch:
104
+ """A fixable batch — a set of findings sharing a disjoint file footprint.
105
+
106
+ The dispatcher turns each Batch into one worker dispatch.
107
+ """
108
+ id: str
109
+ findings: list[Finding] = field(default_factory=list)
110
+ files: list[str] = field(default_factory=list)
111
+ score: int = 0 # higher = more severe — used to prioritise
112
+
113
+ def to_intent(self, audit_id: str) -> str:
114
+ """Render as a natural-language worker task description."""
115
+ bullets = []
116
+ for f in self.findings:
117
+ loc = f.file or "(global)"
118
+ if f.line:
119
+ loc = f"{loc}:{f.line}"
120
+ bullets.append(f"- [{f.severity}] {loc} — {f.message}")
121
+ return (
122
+ f"Fix the following {audit_id} findings:\n"
123
+ + "\n".join(bullets)
124
+ + ("\n\nFiles you may edit: " + ", ".join(self.files)
125
+ if self.files else "")
126
+ )
127
+
128
+
129
+ @dataclass
130
+ class BatchPlan:
131
+ """Output of ``batch_findings`` — ready-to-dispatch batches + deferred."""
132
+ batches: list[Batch]
133
+ deferred: list[Finding] = field(default_factory=list)
134
+ audit_id: str = ""
135
+
136
+
137
+ def batch_findings(
138
+ findings: Iterable[Finding | Any],
139
+ *,
140
+ audit_id: str = "",
141
+ max_batches: int = 3,
142
+ max_files_per_batch: int = 10,
143
+ min_severity: str | None = None,
144
+ ) -> BatchPlan:
145
+ """Cluster findings into ≤``max_batches`` disjoint-file batches.
146
+
147
+ Algorithm:
148
+ 1. Normalise the iterable to ``Finding`` objects.
149
+ 2. Filter by ``min_severity`` if given (low|medium|high|critical).
150
+ 3. Group by file (no file → goes in the "(global)" bucket).
151
+ 4. Sort groups by aggregate severity (worst first).
152
+ 5. Greedily pack the top groups into ``max_batches`` batches,
153
+ each carrying up to ``max_files_per_batch`` files, never
154
+ overlapping files between batches (impossible by construction
155
+ here, since each file lands in exactly one batch).
156
+ 6. If we'd need more than ``max_batches`` batches, defer the
157
+ leftover groups and return them in ``deferred``.
158
+ """
159
+ norm: list[Finding] = []
160
+ for raw in findings:
161
+ if isinstance(raw, Finding):
162
+ norm.append(raw)
163
+ elif isinstance(raw, dict):
164
+ norm.append(Finding.from_dict(raw))
165
+ else:
166
+ norm.append(Finding.from_arsenal(raw))
167
+
168
+ if min_severity:
169
+ threshold = _severity_weight(min_severity)
170
+ norm = [f for f in norm if _severity_weight(f.severity) >= threshold]
171
+
172
+ by_file: dict[str, list[Finding]] = defaultdict(list)
173
+ for f in norm:
174
+ key = f.file or "(global)"
175
+ by_file[key].append(f)
176
+
177
+ # Sort files by aggregate severity weight, worst first.
178
+ file_score = {
179
+ key: sum(_severity_weight(f.severity) for f in fs)
180
+ for key, fs in by_file.items()
181
+ }
182
+ files_ranked = sorted(by_file.keys(), key=lambda k: -file_score[k])
183
+
184
+ # Greedy pack into max_batches: pick the batch with the smallest
185
+ # current finding count (tie-broken by lowest aggregate score).
186
+ batches: list[Batch] = [
187
+ Batch(id=f"b{i + 1}") for i in range(max(1, max_batches))
188
+ ]
189
+
190
+ deferred: list[Finding] = []
191
+ for file_key in files_ranked:
192
+ if file_key == "(global)":
193
+ # Global findings get their own slot — the LAST batch.
194
+ target_batch = batches[-1]
195
+ else:
196
+ # Smallest batch that still has file capacity.
197
+ candidates = [
198
+ b for b in batches
199
+ if len(b.files) < max_files_per_batch
200
+ and file_key not in b.files
201
+ ]
202
+ if not candidates:
203
+ deferred.extend(by_file[file_key])
204
+ continue
205
+ target_batch = min(
206
+ candidates, key=lambda b: (len(b.findings), b.score)
207
+ )
208
+ target_batch.findings.extend(by_file[file_key])
209
+ if file_key != "(global)":
210
+ target_batch.files.append(file_key)
211
+ target_batch.score += file_score[file_key]
212
+
213
+ # Drop empty batches.
214
+ batches = [b for b in batches if b.findings]
215
+ # Re-id sequentially.
216
+ for i, b in enumerate(batches, start=1):
217
+ b.id = f"b{i}"
218
+ return BatchPlan(batches=batches, deferred=deferred, audit_id=audit_id)