@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,259 @@
1
+ """Tests for the skill-power layer.
2
+
3
+ Covers:
4
+ * Bridge from $OMEGA_HOME/Agentik_AI/.../skills/ → ~/.claude/skills/
5
+ (the symlink layer in ClaudeCodeAdapter.link_to_user_claude)
6
+ * WORKFLOWS catalog presence + shape
7
+ * Richness invariants on the role→skill map (no regressions in coverage)
8
+ """
9
+ from __future__ import annotations
10
+
11
+ import os
12
+ import sys
13
+ import tempfile
14
+ import unittest
15
+ from pathlib import Path
16
+
17
+
18
+ HERE = Path(__file__).resolve().parent
19
+ sys.path.insert(0, str(HERE.parent))
20
+
21
+ from omega_engine import skill_routing as SR # noqa: E402
22
+ from omega_engine.sync import ClaudeCodeAdapter # noqa: E402
23
+
24
+
25
+ # ---------------------------------------------------------------------------
26
+ # Bridge: provider tree → ~/.claude/skills/
27
+ # ---------------------------------------------------------------------------
28
+
29
+
30
+ def _make_ssot(home: Path, skill_ids: list[str]) -> None:
31
+ """Create a minimal SSOT tree with `skill_ids` skills."""
32
+ skills = home / "Agentik_SSOT" / "skills"
33
+ skills.mkdir(parents=True)
34
+ for sid in skill_ids:
35
+ d = skills / sid
36
+ d.mkdir()
37
+ (d / "SKILL.md").write_text(
38
+ f"---\nname: {sid}\ndescription: test skill {sid}\n"
39
+ f"allowed-tools: Bash Read\n---\n# {sid}\n"
40
+ )
41
+
42
+
43
+ class TestLinkToUserClaude(unittest.TestCase):
44
+ def test_link_creates_symlinks_in_user_claude(self):
45
+ with tempfile.TemporaryDirectory() as tmp:
46
+ home = Path(tmp) / "Omega"
47
+ user_claude = Path(tmp) / ".claude"
48
+ _make_ssot(home, ["pursue", "codeaudit", "debugaudit"])
49
+ adapter = ClaudeCodeAdapter()
50
+ adapter.project(home) # populates the provider tree
51
+ info = adapter.link_to_user_claude(home, user_claude=user_claude)
52
+ self.assertEqual(info["linked_skills"], 3)
53
+ for sid in ("pursue", "codeaudit", "debugaudit"):
54
+ link = user_claude / "skills" / sid
55
+ self.assertTrue(link.is_symlink(),
56
+ f"{sid} should be a symlink")
57
+ # Resolves to a path inside the provider tree
58
+ self.assertTrue(
59
+ str(link.resolve()).startswith(str(home)),
60
+ f"{sid} should resolve inside $OMEGA_HOME"
61
+ )
62
+ self.assertTrue(
63
+ (link / "SKILL.md").exists(),
64
+ f"{sid}/SKILL.md should be reachable via the symlink"
65
+ )
66
+
67
+ def test_link_is_idempotent(self):
68
+ with tempfile.TemporaryDirectory() as tmp:
69
+ home = Path(tmp) / "Omega"
70
+ user_claude = Path(tmp) / ".claude"
71
+ _make_ssot(home, ["pursue"])
72
+ adapter = ClaudeCodeAdapter()
73
+ adapter.project(home)
74
+ a = adapter.link_to_user_claude(home, user_claude=user_claude)
75
+ b = adapter.link_to_user_claude(home, user_claude=user_claude)
76
+ # Same count both times — no duplicates, no errors.
77
+ self.assertEqual(a["linked_skills"], 1)
78
+ self.assertEqual(b["linked_skills"], 1)
79
+ self.assertEqual(
80
+ len(list((user_claude / "skills").iterdir())), 1
81
+ )
82
+
83
+ def test_link_removes_stale_symlinks_for_deleted_ssot_skills(self):
84
+ with tempfile.TemporaryDirectory() as tmp:
85
+ home = Path(tmp) / "Omega"
86
+ user_claude = Path(tmp) / ".claude"
87
+ _make_ssot(home, ["a", "b", "c"])
88
+ adapter = ClaudeCodeAdapter()
89
+ adapter.project(home)
90
+ adapter.link_to_user_claude(home, user_claude=user_claude)
91
+ # Remove skill 'b' from SSOT + the provider tree, re-sync.
92
+ import shutil
93
+ shutil.rmtree(home / "Agentik_SSOT" / "skills" / "b")
94
+ shutil.rmtree(
95
+ home / "Agentik_AI" / "providers" / "claude-code"
96
+ / ".claude" / "skills" / "b"
97
+ )
98
+ info = adapter.link_to_user_claude(home, user_claude=user_claude)
99
+ self.assertEqual(info["linked_skills"], 2)
100
+ self.assertIn(
101
+ str(user_claude / "skills" / "b"), info["removed"]
102
+ )
103
+ self.assertFalse((user_claude / "skills" / "b").exists())
104
+
105
+ def test_link_preserves_user_owned_dirs(self):
106
+ """A real dir the user created (not a symlink) must NEVER be touched."""
107
+ with tempfile.TemporaryDirectory() as tmp:
108
+ home = Path(tmp) / "Omega"
109
+ user_claude = Path(tmp) / ".claude"
110
+ _make_ssot(home, ["pursue"])
111
+ (user_claude / "skills" / "myhandwritten").mkdir(parents=True)
112
+ (user_claude / "skills" / "myhandwritten" / "SKILL.md").write_text(
113
+ "---\nname: myhandwritten\n---\n# mine\n"
114
+ )
115
+ adapter = ClaudeCodeAdapter()
116
+ adapter.project(home)
117
+ adapter.link_to_user_claude(home, user_claude=user_claude)
118
+ # User's skill is still a real dir with the original content.
119
+ self.assertTrue(
120
+ (user_claude / "skills" / "myhandwritten").is_dir()
121
+ )
122
+ self.assertFalse(
123
+ (user_claude / "skills" / "myhandwritten").is_symlink()
124
+ )
125
+ content = (
126
+ user_claude / "skills" / "myhandwritten" / "SKILL.md"
127
+ ).read_text()
128
+ self.assertIn("name: myhandwritten", content)
129
+
130
+ def test_project_auto_links_by_default(self):
131
+ """project() should also bridge by default unless OMEGA_SYNC_NO_LINK=1."""
132
+ with tempfile.TemporaryDirectory() as tmp:
133
+ home = Path(tmp) / "Omega"
134
+ user_claude = Path(tmp) / ".claude"
135
+ _make_ssot(home, ["pursue"])
136
+ # Force HOME so the auto-link inside project() targets our tmp.
137
+ old_home = os.environ.get("HOME")
138
+ try:
139
+ os.environ["HOME"] = str(user_claude.parent)
140
+ adapter = ClaudeCodeAdapter()
141
+ result = adapter.project(home)
142
+ finally:
143
+ if old_home is not None:
144
+ os.environ["HOME"] = old_home
145
+ self.assertIn("linked_to_user_claude", result)
146
+ self.assertEqual(
147
+ result["linked_to_user_claude"].get("linked_skills"), 1
148
+ )
149
+
150
+ def test_project_skips_link_when_env_var_set(self):
151
+ with tempfile.TemporaryDirectory() as tmp:
152
+ home = Path(tmp) / "Omega"
153
+ _make_ssot(home, ["pursue"])
154
+ os.environ["OMEGA_SYNC_NO_LINK"] = "1"
155
+ try:
156
+ adapter = ClaudeCodeAdapter()
157
+ result = adapter.project(home)
158
+ finally:
159
+ del os.environ["OMEGA_SYNC_NO_LINK"]
160
+ self.assertEqual(result["linked_to_user_claude"], {})
161
+
162
+
163
+ # ---------------------------------------------------------------------------
164
+ # WORKFLOWS catalog
165
+ # ---------------------------------------------------------------------------
166
+
167
+
168
+ class TestWorkflows(unittest.TestCase):
169
+ def test_workflows_exist(self):
170
+ self.assertIn("ship-feature", SR.WORKFLOWS)
171
+ self.assertIn("self-audit-loop", SR.WORKFLOWS)
172
+ self.assertIn("ux-redesign", SR.WORKFLOWS)
173
+ self.assertIn("linear-fix-batch", SR.WORKFLOWS)
174
+ self.assertIn("scheduled-quality", SR.WORKFLOWS)
175
+
176
+ def test_every_workflow_mentions_at_least_two_skills(self):
177
+ # Each canonical workflow must compose multiple skills — otherwise
178
+ # it's not a "workflow", it's a single-skill invocation.
179
+ for name, body in SR.WORKFLOWS.items():
180
+ slash_count = body.count("/dispatch") + body.count("/pursue") \
181
+ + body.count("/codeaudit") + body.count("/debugaudit") \
182
+ + body.count("/uiuxaudit") + body.count("/secaudit") \
183
+ + body.count("/perfaudit") + body.count("/cadence") \
184
+ + body.count("/refontaudit") + body.count("/a11yaudit")
185
+ self.assertGreaterEqual(
186
+ slash_count, 2,
187
+ f"workflow '{name}' must compose at least 2 skills"
188
+ )
189
+
190
+ def test_workflows_reference_real_ssot_skills(self):
191
+ # The canonical workflows shouldn't reference skills that don't exist
192
+ # in the SSOT catalog. We don't enforce this strictly (the SSOT may
193
+ # ship without some optional skills) — but if dispatch/pursue/codeaudit
194
+ # exist they should be reachable.
195
+ from pathlib import Path as _P
196
+ repo = _P(__file__).resolve().parents[3]
197
+ ssot = repo / "omega" / "Agentik_SSOT" / "skills"
198
+ if not ssot.is_dir():
199
+ self.skipTest("SSOT not in repo")
200
+ present = {d.name for d in ssot.iterdir() if d.is_dir()}
201
+ for must in ("dispatch", "pursue", "codeaudit"):
202
+ self.assertIn(must, present,
203
+ f"workflow assumes /{must} exists in SSOT")
204
+
205
+
206
+ # ---------------------------------------------------------------------------
207
+ # Role-skill map richness invariants
208
+ # ---------------------------------------------------------------------------
209
+
210
+
211
+ class TestRoleMapRichness(unittest.TestCase):
212
+ def test_oracle_has_dispatch_and_pursue(self):
213
+ recs = SR.recommend("oracle")
214
+ self.assertIn("dispatch", recs)
215
+ self.assertIn("pursue", recs)
216
+
217
+ def test_worker_has_at_least_8_audits(self):
218
+ """The worker is the busiest role — give it real self-audit power."""
219
+ recs = SR.recommend("worker")
220
+ self.assertGreaterEqual(len(recs), 8,
221
+ "worker should have ≥ 8 skills so self-audit covers most domains")
222
+
223
+ def test_seraph_has_widest_palette(self):
224
+ """Seraph is the senior verifier — it should see EVERY audit domain."""
225
+ recs = SR.recommend("seraph")
226
+ self.assertGreaterEqual(len(recs), 10,
227
+ "seraph should have the widest audit palette of any role")
228
+
229
+ def test_specialised_workers_exist(self):
230
+ """Domain-specialist workers must exist + each has its primary audit."""
231
+ for role, primary in [
232
+ ("worker_ui", "uiuxaudit"),
233
+ ("worker_perf", "perfaudit"),
234
+ ("worker_sec", "secaudit"),
235
+ ("worker_api", "apiaudit"),
236
+ ("worker_data", "dataaudit"),
237
+ ("worker_seo", "seoaudit"),
238
+ ("worker_ops", "automationaudit"),
239
+ ("worker_growth", "retentionaudit"),
240
+ ]:
241
+ recs = SR.recommend(role)
242
+ self.assertIn("pursue", recs,
243
+ f"specialised role {role} must include /pursue")
244
+ self.assertIn(primary, recs,
245
+ f"specialised role {role} must include its primary audit /{primary}")
246
+
247
+ def test_classifier_is_minimal(self):
248
+ # Triage roles deliberately have zero skills — fast haiku pass.
249
+ self.assertEqual(SR.recommend("classifier"), [])
250
+ self.assertEqual(SR.recommend("triage"), [])
251
+
252
+ def test_total_role_count(self):
253
+ """Sanity floor: at least 20 roles. If someone deletes the
254
+ specialised workers this test catches it."""
255
+ self.assertGreaterEqual(len(SR._ROLE_SKILLS), 20)
256
+
257
+
258
+ if __name__ == "__main__":
259
+ unittest.main()
@@ -0,0 +1,189 @@
1
+ """Tests for omega_engine.skill_routing — role → skills resolution + the
2
+ system-prompt skill block.
3
+
4
+ The routing module is pure (no I/O for the role map, single Read for the
5
+ description extraction) so these tests stay fast: ~30 ms total.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import sys
10
+ import tempfile
11
+ import unittest
12
+ from pathlib import Path
13
+
14
+
15
+ HERE = Path(__file__).resolve().parent
16
+ sys.path.insert(0, str(HERE.parent))
17
+
18
+ from omega_engine import skill_routing as SR # noqa: E402
19
+ from omega_engine import worker as W # noqa: E402
20
+
21
+
22
+ class TestRoleDefaults(unittest.TestCase):
23
+ def test_worker_includes_pursue_and_audits(self):
24
+ recs = SR.recommend("worker")
25
+ self.assertIn("pursue", recs)
26
+ self.assertIn("codeaudit", recs)
27
+ self.assertIn("debugaudit", recs)
28
+
29
+ def test_oracle_includes_dispatch(self):
30
+ self.assertIn("dispatch", SR.recommend("oracle"))
31
+
32
+ def test_classifier_is_empty(self):
33
+ self.assertEqual(SR.recommend("classifier"), [])
34
+
35
+ def test_unknown_role_returns_empty_list(self):
36
+ self.assertEqual(SR.recommend("does-not-exist"), [])
37
+
38
+ def test_recommend_returns_copy(self):
39
+ # Mutating the return value must not pollute the global map.
40
+ a = SR.recommend("worker")
41
+ a.append("garbage")
42
+ self.assertNotIn("garbage", SR.recommend("worker"))
43
+
44
+ def test_power_skills_listed(self):
45
+ # The constant exists, includes the obvious ones, has stable ordering.
46
+ self.assertIn("dispatch", SR.POWER_SKILLS)
47
+ self.assertIn("pursue", SR.POWER_SKILLS)
48
+ self.assertIn("codeaudit", SR.POWER_SKILLS)
49
+
50
+
51
+ class TestResolution(unittest.TestCase):
52
+ def test_explicit_wins(self):
53
+ out = SR.skills_for("worker", explicit=["only-this"])
54
+ self.assertEqual(out, ["only-this"])
55
+
56
+ def test_topology_wins_over_role_default(self):
57
+ out = SR.skills_for("worker", topology_skills=["mission-skill"])
58
+ self.assertEqual(out, ["mission-skill"])
59
+
60
+ def test_explicit_wins_over_topology(self):
61
+ out = SR.skills_for("worker", explicit=["a"], topology_skills=["b"])
62
+ self.assertEqual(out, ["a"])
63
+
64
+ def test_falls_back_to_role_default(self):
65
+ out = SR.skills_for("oracle")
66
+ self.assertIn("dispatch", out)
67
+
68
+
69
+ class TestCatalog(unittest.TestCase):
70
+ def test_empty_home_returns_empty(self):
71
+ with tempfile.TemporaryDirectory() as tmp:
72
+ self.assertEqual(SR.catalog_for_home(tmp), [])
73
+
74
+ def test_lists_skill_dirs_and_files(self):
75
+ with tempfile.TemporaryDirectory() as tmp:
76
+ root = Path(tmp) / "Agentik_SSOT" / "skills"
77
+ (root / "pursue").mkdir(parents=True)
78
+ (root / "pursue" / "SKILL.md").write_text("---\nname: pursue\n---")
79
+ (root / "codeaudit").mkdir()
80
+ (root / "codeaudit" / "SKILL.md").write_text("---\nname: codeaudit\n---")
81
+ (root / "no-skillmd").mkdir() # not a real skill, must be skipped
82
+ (root / "rag-route.md").write_text("---\nname: rag-route\n---")
83
+ out = SR.catalog_for_home(tmp)
84
+ self.assertIn("pursue", out)
85
+ self.assertIn("codeaudit", out)
86
+ self.assertIn("rag-route", out)
87
+ self.assertNotIn("no-skillmd", out)
88
+
89
+
90
+ class TestSkillBlock(unittest.TestCase):
91
+ def test_empty_returns_empty(self):
92
+ self.assertEqual(SR.format_skill_block([]), "")
93
+
94
+ def test_block_lists_skill_ids_and_header(self):
95
+ block = SR.format_skill_block(["pursue", "codeaudit"])
96
+ self.assertIn("## Skills available", block)
97
+ self.assertIn("/pursue", block)
98
+ self.assertIn("/codeaudit", block)
99
+ self.assertIn("invoke them as slash", block)
100
+
101
+ def test_block_includes_descriptions_when_skillmd_present(self):
102
+ with tempfile.TemporaryDirectory() as tmp:
103
+ root = Path(tmp) / "Agentik_SSOT" / "skills"
104
+ (root / "pursue").mkdir(parents=True)
105
+ (root / "pursue" / "SKILL.md").write_text(
106
+ "---\nname: pursue\n"
107
+ "description: Goal-driven loop until verify exits 0.\n"
108
+ "---\n# pursue\n"
109
+ )
110
+ block = SR.format_skill_block(["pursue"], home=tmp)
111
+ self.assertIn("Goal-driven loop", block)
112
+
113
+ def test_description_too_long_is_truncated(self):
114
+ with tempfile.TemporaryDirectory() as tmp:
115
+ root = Path(tmp) / "Agentik_SSOT" / "skills"
116
+ (root / "huge").mkdir(parents=True)
117
+ long_desc = "x" * 200
118
+ (root / "huge" / "SKILL.md").write_text(
119
+ f"---\nname: huge\ndescription: {long_desc}\n---"
120
+ )
121
+ block = SR.format_skill_block(["huge"], home=tmp)
122
+ self.assertIn("...", block)
123
+
124
+
125
+ class TestWorkerBriefSkills(unittest.TestCase):
126
+ def test_default_role_resolves_to_role_skills(self):
127
+ b = W.WorkerBrief(task_id="t1", role="worker", intent="x")
128
+ skills = b.resolved_skills()
129
+ self.assertIn("pursue", skills)
130
+
131
+ def test_explicit_skills_override(self):
132
+ b = W.WorkerBrief(task_id="t1", role="worker", intent="x",
133
+ skills=["only-this"])
134
+ self.assertEqual(b.resolved_skills(), ["only-this"])
135
+
136
+ def test_classifier_role_empty_by_default(self):
137
+ b = W.WorkerBrief(task_id="t1", role="classifier", intent="x")
138
+ self.assertEqual(b.resolved_skills(), [])
139
+
140
+ def test_json_round_trip_preserves_skills(self):
141
+ import json
142
+ b = W.WorkerBrief(task_id="t1", role="worker", intent="x",
143
+ skills=["pursue", "codeaudit"])
144
+ loaded = W.WorkerBrief.from_dict(json.loads(b.to_json()))
145
+ self.assertEqual(loaded.skills, ["pursue", "codeaudit"])
146
+
147
+
148
+ class TestRunBriefEmbedsSkillBlock(unittest.TestCase):
149
+ """When the brief carries skills, the system_prompt sent to claude
150
+ contains the skill block."""
151
+
152
+ def test_system_prompt_includes_skill_section(self):
153
+ import json as _json
154
+ from unittest import mock
155
+ with tempfile.TemporaryDirectory() as tmp:
156
+ home = Path(tmp)
157
+ brief = W.WorkerBrief(
158
+ task_id="t-sk", role="worker", intent="x",
159
+ skills=["pursue", "codeaudit"],
160
+ )
161
+ W.write_brief(home, brief)
162
+ captured = {}
163
+
164
+ def fake_run(cmd, **kw):
165
+ captured["cmd"] = cmd
166
+ import subprocess
167
+ return subprocess.CompletedProcess(
168
+ args=cmd, returncode=0,
169
+ stdout=_json.dumps({
170
+ "result": "ok", "session_id": "s",
171
+ "usage": {}, "total_cost_usd": 0.0,
172
+ }),
173
+ stderr="",
174
+ )
175
+
176
+ with mock.patch.object(W.subprocess, "run", side_effect=fake_run):
177
+ W.run_brief(home, "t-sk")
178
+ cmd = captured["cmd"]
179
+ # --append-system-prompt is present
180
+ self.assertIn("--append-system-prompt", cmd)
181
+ idx = cmd.index("--append-system-prompt")
182
+ block = cmd[idx + 1]
183
+ self.assertIn("## Skills available", block)
184
+ self.assertIn("/pursue", block)
185
+ self.assertIn("/codeaudit", block)
186
+
187
+
188
+ if __name__ == "__main__":
189
+ unittest.main()
@@ -0,0 +1,172 @@
1
+ """Snapshotting (bounded reduction) + PARTIAL policy (per-topology join handling).
2
+
3
+ Standalone: python3 tests/test_snapshot_partial.py
4
+ """
5
+ import os
6
+ import sys
7
+ import tempfile
8
+ from pathlib import Path
9
+
10
+ sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
11
+
12
+ from omega_engine.audit import AuditGate # noqa: E402
13
+ from omega_engine.bus import EventBus # noqa: E402
14
+ from omega_engine.events import Event, EventType # noqa: E402
15
+ from omega_engine.executor import Executor # noqa: E402
16
+ from omega_engine.provider import AgentRequest, AgentResult # noqa: E402
17
+ from omega_engine.reducer import reduce_task, reduce_task_fast # noqa: E402
18
+ from omega_engine.router import ModelRouter # noqa: E402
19
+ from omega_engine.store import SQLiteStore # noqa: E402
20
+ from omega_engine.task import Kind, TaskState # noqa: E402
21
+
22
+
23
+ # ----- snapshotting ---------------------------------------------------------
24
+
25
+ def test_snapshot_round_trip():
26
+ """A snapshot captures the reduced state; latest_snapshot returns it."""
27
+ db = tempfile.mktemp(suffix=".db")
28
+ store = SQLiteStore(db)
29
+ for et in (EventType.CREATED, EventType.DISPATCHED, EventType.STARTED):
30
+ store.append(Event(task_id="t1", type=et))
31
+ snap = store.snapshot("t1")
32
+ assert snap is not None
33
+ assert snap["state"] is TaskState.RUNNING
34
+
35
+ again = store.latest_snapshot("t1")
36
+ assert again is not None and again["state"] is TaskState.RUNNING
37
+ store.close()
38
+ os.remove(db)
39
+
40
+
41
+ def test_snapshot_makes_reduce_correct_and_short():
42
+ """reduce_task_fast skips events covered by the snapshot."""
43
+ db = tempfile.mktemp(suffix=".db")
44
+ store = SQLiteStore(db)
45
+ seq = [EventType.CREATED, EventType.DISPATCHED, EventType.STARTED]
46
+ for et in seq:
47
+ store.append(Event(task_id="t1", type=et))
48
+ store.snapshot("t1") # state == RUNNING, captured at the 3rd event
49
+
50
+ # 0 events after the snapshot -> fast path returns the snapshot state
51
+ assert reduce_task_fast(store, "t1") is TaskState.RUNNING
52
+
53
+ # add more events; fast == full
54
+ for et in (EventType.CLAIMED_DONE, EventType.VERIFYING, EventType.VERIFIED,
55
+ EventType.COMPLETED):
56
+ store.append(Event(task_id="t1", type=et))
57
+
58
+ full = reduce_task(store.events_for("t1"))
59
+ fast = reduce_task_fast(store, "t1")
60
+ assert full is TaskState.COMPLETED
61
+ assert fast is TaskState.COMPLETED
62
+ # only events AFTER the snapshot should be folded by the fast path
63
+ assert len(store.events_since_snapshot("t1")) == 4
64
+ store.close()
65
+ os.remove(db)
66
+
67
+
68
+ def test_snapshot_on_unknown_task_returns_none():
69
+ db = tempfile.mktemp(suffix=".db")
70
+ store = SQLiteStore(db)
71
+ assert store.snapshot("ghost") is None
72
+ assert store.latest_snapshot("ghost") is None
73
+ store.close()
74
+ os.remove(db)
75
+
76
+
77
+ # ----- PARTIAL policy -------------------------------------------------------
78
+
79
+ class _PartialProvider:
80
+ """3-worker plan; selected indices fail their runtime audit (verify_cmd=false)."""
81
+ id = "test-partial"
82
+
83
+ def __init__(self, fail_indices) -> None:
84
+ self._fail = set(fail_indices)
85
+
86
+ def run(self, req: AgentRequest) -> AgentResult:
87
+ if req.role in ("oracle", "manager", "aisb"):
88
+ plan = []
89
+ for i in range(3):
90
+ cmd = "false" if i in self._fail else "true"
91
+ plan.append({"role": "worker",
92
+ "spec": {"task": f"t{i}", "verify_cmd": cmd}})
93
+ return AgentResult(text="planned", claimed_done=True, plan=plan)
94
+ if req.role == "worker":
95
+ return AgentResult(
96
+ text="done", claimed_done=True,
97
+ artifacts={"files": ["x.py"], "summary": "done"},
98
+ )
99
+ if req.role in ("verifier", "audit"):
100
+ return AgentResult(
101
+ text="ok", claimed_done=True,
102
+ artifacts={"verdict": {"score": 95, "verified": True,
103
+ "confidence": "high",
104
+ "summary": "ok",
105
+ "findings": [], "fix_plan": []}})
106
+ return AgentResult(text="ok", claimed_done=True)
107
+
108
+
109
+ def _engine(provider, partial_policy="fail_up"):
110
+ db = tempfile.mktemp(suffix=".db")
111
+ store = SQLiteStore(db)
112
+ bus = EventBus(store)
113
+ router = ModelRouter.single(provider)
114
+ executor = Executor(store, bus, router, AuditGate(),
115
+ partial_policy=partial_policy)
116
+ return store, executor, db
117
+
118
+
119
+ def test_partial_fail_up_default():
120
+ """Default policy: a PARTIAL scope fails the dispatcher."""
121
+ store, ex, db = _engine(_PartialProvider(fail_indices=[1]))
122
+ result = ex.run_mission("partial mission")
123
+ assert result.final_state is TaskState.FAILED, result.final_state
124
+ store.close(); os.remove(db)
125
+
126
+
127
+ def test_partial_accept_partial():
128
+ """accept_partial: the dispatcher completes despite a failed child."""
129
+ store, ex, db = _engine(_PartialProvider(fail_indices=[1]),
130
+ partial_policy="accept_partial")
131
+ result = ex.run_mission("partial mission")
132
+ assert result.final_state is TaskState.COMPLETED, result.final_state
133
+ store.close(); os.remove(db)
134
+
135
+
136
+ def test_partial_retry_failed_spawns_extra_children():
137
+ """retry_failed: a replacement task is spawned for each failed child."""
138
+ store, ex, db = _engine(_PartialProvider(fail_indices=[1]),
139
+ partial_policy="retry_failed")
140
+ result = ex.run_mission("partial mission")
141
+ workers = [t for t in result.tasks.values() if t.kind is Kind.EXECUTOR]
142
+ # original 3 + 1 retry replacement = 4 worker tasks (the failing index
143
+ # was retried once; under this provider it fails again, so the final
144
+ # state is FAILED — but the retry attempt is observable)
145
+ assert len(workers) == 4, f"retry did not spawn a replacement: {len(workers)}"
146
+ assert result.final_state is TaskState.FAILED # retry exhausted -> fail_up
147
+ store.close(); os.remove(db)
148
+
149
+
150
+ def test_unknown_partial_policy_raises():
151
+ raised = False
152
+ try:
153
+ _engine(_PartialProvider([]), partial_policy="ignore")
154
+ except ValueError:
155
+ raised = True
156
+ assert raised
157
+
158
+
159
+ def _run_all() -> bool:
160
+ tests = [v for k, v in sorted(globals().items())
161
+ if k.startswith("test_") and callable(v)]
162
+ passed = 0
163
+ for t in tests:
164
+ t()
165
+ print(f" PASS {t.__name__}")
166
+ passed += 1
167
+ print(f"\n{passed}/{len(tests)} snapshot+partial tests passed")
168
+ return passed == len(tests)
169
+
170
+
171
+ if __name__ == "__main__":
172
+ sys.exit(0 if _run_all() else 1)