@agentikos/omega-os 0.2.0 → 0.19.6

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 (376) hide show
  1. package/README.md +33 -3
  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 +790 -21
  10. package/bootstrap/manifest.example.yaml +87 -1
  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/GAP-ANALYSIS.md +214 -0
  48. package/docs/INSTALL.md +47 -9
  49. package/docs/MCP-AND-PLUGINS.md +31 -4
  50. package/docs/SIMULATION.md +171 -0
  51. package/docs/simulate.sh +211 -0
  52. package/install.sh +164 -17
  53. package/omega/Agentik_Engine/README.md +4 -2
  54. package/omega/Agentik_Engine/omega_engine/__init__.py +147 -1
  55. package/omega/Agentik_Engine/omega_engine/__pycache__/__init__.cpython-313.pyc +0 -0
  56. package/omega/Agentik_Engine/omega_engine/__pycache__/account.cpython-313.pyc +0 -0
  57. package/omega/Agentik_Engine/omega_engine/__pycache__/agent_messages.cpython-313.pyc +0 -0
  58. package/omega/Agentik_Engine/omega_engine/__pycache__/aisb_chat.cpython-313.pyc +0 -0
  59. package/omega/Agentik_Engine/omega_engine/__pycache__/audit.cpython-313.pyc +0 -0
  60. package/omega/Agentik_Engine/omega_engine/__pycache__/audit_arsenal.cpython-313.pyc +0 -0
  61. package/omega/Agentik_Engine/omega_engine/__pycache__/audit_diff.cpython-313.pyc +0 -0
  62. package/omega/Agentik_Engine/omega_engine/__pycache__/audit_gate.cpython-313.pyc +0 -0
  63. package/omega/Agentik_Engine/omega_engine/__pycache__/auto_update.cpython-313.pyc +0 -0
  64. package/omega/Agentik_Engine/omega_engine/__pycache__/autonomous.cpython-313.pyc +0 -0
  65. package/omega/Agentik_Engine/omega_engine/__pycache__/backup.cpython-313.pyc +0 -0
  66. package/omega/Agentik_Engine/omega_engine/__pycache__/barrier.cpython-313.pyc +0 -0
  67. package/omega/Agentik_Engine/omega_engine/__pycache__/bus.cpython-313.pyc +0 -0
  68. package/omega/Agentik_Engine/omega_engine/__pycache__/cadence.cpython-313.pyc +0 -0
  69. package/omega/Agentik_Engine/omega_engine/__pycache__/classifier.cpython-313.pyc +0 -0
  70. package/omega/Agentik_Engine/omega_engine/__pycache__/cleanup.cpython-313.pyc +0 -0
  71. package/omega/Agentik_Engine/omega_engine/__pycache__/cli.cpython-313.pyc +0 -0
  72. package/omega/Agentik_Engine/omega_engine/__pycache__/completions.cpython-313.pyc +0 -0
  73. package/omega/Agentik_Engine/omega_engine/__pycache__/costs.cpython-313.pyc +0 -0
  74. package/omega/Agentik_Engine/omega_engine/__pycache__/done_signal.cpython-313.pyc +0 -0
  75. package/omega/Agentik_Engine/omega_engine/__pycache__/envelope.cpython-313.pyc +0 -0
  76. package/omega/Agentik_Engine/omega_engine/__pycache__/events.cpython-313.pyc +0 -0
  77. package/omega/Agentik_Engine/omega_engine/__pycache__/executor.cpython-313.pyc +0 -0
  78. package/omega/Agentik_Engine/omega_engine/__pycache__/handoff.cpython-313.pyc +0 -0
  79. package/omega/Agentik_Engine/omega_engine/__pycache__/hermes.cpython-313.pyc +0 -0
  80. package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_bootstrap.cpython-313.pyc +0 -0
  81. package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_desktop.cpython-313.pyc +0 -0
  82. package/omega/Agentik_Engine/omega_engine/__pycache__/learning.cpython-313.pyc +0 -0
  83. package/omega/Agentik_Engine/omega_engine/__pycache__/managed_agent.cpython-313.pyc +0 -0
  84. package/omega/Agentik_Engine/omega_engine/__pycache__/memory.cpython-313.pyc +0 -0
  85. package/omega/Agentik_Engine/omega_engine/__pycache__/menu.cpython-313.pyc +0 -0
  86. package/omega/Agentik_Engine/omega_engine/__pycache__/mission.cpython-313.pyc +0 -0
  87. package/omega/Agentik_Engine/omega_engine/__pycache__/plan.cpython-313.pyc +0 -0
  88. package/omega/Agentik_Engine/omega_engine/__pycache__/progress.cpython-313.pyc +0 -0
  89. package/omega/Agentik_Engine/omega_engine/__pycache__/project.cpython-313.pyc +0 -0
  90. package/omega/Agentik_Engine/omega_engine/__pycache__/prompts.cpython-313.pyc +0 -0
  91. package/omega/Agentik_Engine/omega_engine/__pycache__/provider.cpython-313.pyc +0 -0
  92. package/omega/Agentik_Engine/omega_engine/__pycache__/prune.cpython-313.pyc +0 -0
  93. package/omega/Agentik_Engine/omega_engine/__pycache__/pursue.cpython-313.pyc +0 -0
  94. package/omega/Agentik_Engine/omega_engine/__pycache__/reducer.cpython-313.pyc +0 -0
  95. package/omega/Agentik_Engine/omega_engine/__pycache__/report.cpython-313.pyc +0 -0
  96. package/omega/Agentik_Engine/omega_engine/__pycache__/router.cpython-313.pyc +0 -0
  97. package/omega/Agentik_Engine/omega_engine/__pycache__/skill_routing.cpython-313.pyc +0 -0
  98. package/omega/Agentik_Engine/omega_engine/__pycache__/smoke.cpython-313.pyc +0 -0
  99. package/omega/Agentik_Engine/omega_engine/__pycache__/store.cpython-313.pyc +0 -0
  100. package/omega/Agentik_Engine/omega_engine/__pycache__/supervisor.cpython-313.pyc +0 -0
  101. package/omega/Agentik_Engine/omega_engine/__pycache__/sync.cpython-313.pyc +0 -0
  102. package/omega/Agentik_Engine/omega_engine/__pycache__/task.cpython-313.pyc +0 -0
  103. package/omega/Agentik_Engine/omega_engine/__pycache__/telegram.cpython-313.pyc +0 -0
  104. package/omega/Agentik_Engine/omega_engine/__pycache__/telegram_history.cpython-313.pyc +0 -0
  105. package/omega/Agentik_Engine/omega_engine/__pycache__/tmux.cpython-313.pyc +0 -0
  106. package/omega/Agentik_Engine/omega_engine/__pycache__/tools.cpython-313.pyc +0 -0
  107. package/omega/Agentik_Engine/omega_engine/__pycache__/understand_anything.cpython-313.pyc +0 -0
  108. package/omega/Agentik_Engine/omega_engine/__pycache__/updater.cpython-313.pyc +0 -0
  109. package/omega/Agentik_Engine/omega_engine/__pycache__/validate.cpython-313.pyc +0 -0
  110. package/omega/Agentik_Engine/omega_engine/__pycache__/vault.cpython-313.pyc +0 -0
  111. package/omega/Agentik_Engine/omega_engine/__pycache__/webhooks.cpython-313.pyc +0 -0
  112. package/omega/Agentik_Engine/omega_engine/__pycache__/worker.cpython-313.pyc +0 -0
  113. package/omega/Agentik_Engine/omega_engine/account.py +28 -31
  114. package/omega/Agentik_Engine/omega_engine/agent_messages.py +167 -0
  115. package/omega/Agentik_Engine/omega_engine/aisb_chat.py +128 -0
  116. package/omega/Agentik_Engine/omega_engine/audit_diff.py +99 -0
  117. package/omega/Agentik_Engine/omega_engine/audit_gate.py +149 -0
  118. package/omega/Agentik_Engine/omega_engine/audits/__init__.py +60 -0
  119. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/__init__.cpython-313.pyc +0 -0
  120. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/batcher.cpython-313.pyc +0 -0
  121. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/dispatcher.cpython-313.pyc +0 -0
  122. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/generator.cpython-313.pyc +0 -0
  123. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/history.cpython-313.pyc +0 -0
  124. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/pipeline.cpython-313.pyc +0 -0
  125. package/omega/Agentik_Engine/omega_engine/audits/batcher.py +218 -0
  126. package/omega/Agentik_Engine/omega_engine/audits/dispatcher.py +92 -0
  127. package/omega/Agentik_Engine/omega_engine/audits/generator.py +234 -0
  128. package/omega/Agentik_Engine/omega_engine/audits/history.py +168 -0
  129. package/omega/Agentik_Engine/omega_engine/audits/pipeline.py +198 -0
  130. package/omega/Agentik_Engine/omega_engine/auto_update.py +339 -0
  131. package/omega/Agentik_Engine/omega_engine/backup.py +215 -0
  132. package/omega/Agentik_Engine/omega_engine/cadence.py +158 -0
  133. package/omega/Agentik_Engine/omega_engine/classifier.py +215 -0
  134. package/omega/Agentik_Engine/omega_engine/cleanup.py +673 -0
  135. package/omega/Agentik_Engine/omega_engine/cli.py +4156 -86
  136. package/omega/Agentik_Engine/omega_engine/completions.py +260 -0
  137. package/omega/Agentik_Engine/omega_engine/costs.py +100 -0
  138. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/__init__.cpython-313.pyc +0 -0
  139. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/autonomous.cpython-313.pyc +0 -0
  140. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/engine.cpython-313.pyc +0 -0
  141. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/telegram.cpython-313.pyc +0 -0
  142. package/omega/Agentik_Engine/omega_engine/daemons/engine.py +53 -4
  143. package/omega/Agentik_Engine/omega_engine/daemons/telegram.py +101 -17
  144. package/omega/Agentik_Engine/omega_engine/done_signal.py +154 -0
  145. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/__init__.cpython-313.pyc +0 -0
  146. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/artifact.cpython-313.pyc +0 -0
  147. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/automation.cpython-313.pyc +0 -0
  148. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/base.cpython-313.pyc +0 -0
  149. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/claudecode.cpython-313.pyc +0 -0
  150. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/connection.cpython-313.pyc +0 -0
  151. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/coworker.cpython-313.pyc +0 -0
  152. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/loop.cpython-313.pyc +0 -0
  153. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/prompt.cpython-313.pyc +0 -0
  154. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/skill.cpython-313.pyc +0 -0
  155. package/omega/Agentik_Engine/omega_engine/envelope.py +219 -0
  156. package/omega/Agentik_Engine/omega_engine/executor.py +149 -10
  157. package/omega/Agentik_Engine/omega_engine/genesis/__init__.py +134 -0
  158. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/__init__.cpython-313.pyc +0 -0
  159. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/orchestrator.cpython-313.pyc +0 -0
  160. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/phases.cpython-313.pyc +0 -0
  161. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/stack.cpython-313.pyc +0 -0
  162. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/state.cpython-313.pyc +0 -0
  163. package/omega/Agentik_Engine/omega_engine/genesis/orchestrator.py +262 -0
  164. package/omega/Agentik_Engine/omega_engine/genesis/phases.py +950 -0
  165. package/omega/Agentik_Engine/omega_engine/genesis/stack.py +324 -0
  166. package/omega/Agentik_Engine/omega_engine/genesis/state.py +353 -0
  167. package/omega/Agentik_Engine/omega_engine/handoff.py +459 -0
  168. package/omega/Agentik_Engine/omega_engine/hermes.py +426 -0
  169. package/omega/Agentik_Engine/omega_engine/hermes_bootstrap.py +382 -0
  170. package/omega/Agentik_Engine/omega_engine/hermes_desktop.py +469 -0
  171. package/omega/Agentik_Engine/omega_engine/integrations/__init__.py +30 -0
  172. package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/__init__.cpython-313.pyc +0 -0
  173. package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/graphify.cpython-313.pyc +0 -0
  174. package/omega/Agentik_Engine/omega_engine/integrations/graphify.py +234 -0
  175. package/omega/Agentik_Engine/omega_engine/learning.py +268 -0
  176. package/omega/Agentik_Engine/omega_engine/managed_agent.py +467 -0
  177. package/omega/Agentik_Engine/omega_engine/memory.py +271 -0
  178. package/omega/Agentik_Engine/omega_engine/menu.py +1065 -0
  179. package/omega/Agentik_Engine/omega_engine/migrations/__init__.py +144 -0
  180. package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/__init__.cpython-313.pyc +0 -0
  181. package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/v0_14_0.cpython-313.pyc +0 -0
  182. package/omega/Agentik_Engine/omega_engine/migrations/v0_14_0.py +29 -0
  183. package/omega/Agentik_Engine/omega_engine/mission.py +16 -13
  184. package/omega/Agentik_Engine/omega_engine/plan.py +846 -0
  185. package/omega/Agentik_Engine/omega_engine/prompts.py +158 -0
  186. package/omega/Agentik_Engine/omega_engine/provider.py +161 -12
  187. package/omega/Agentik_Engine/omega_engine/prune.py +151 -0
  188. package/omega/Agentik_Engine/omega_engine/pursue.py +205 -0
  189. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/__init__.cpython-313.pyc +0 -0
  190. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/agentic.cpython-313.pyc +0 -0
  191. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/base.cpython-313.pyc +0 -0
  192. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/corrective.cpython-313.pyc +0 -0
  193. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/graph.cpython-313.pyc +0 -0
  194. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/hybrid.cpython-313.pyc +0 -0
  195. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/multimodal.cpython-313.pyc +0 -0
  196. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/router.cpython-313.pyc +0 -0
  197. package/omega/Agentik_Engine/omega_engine/router.py +28 -0
  198. package/omega/Agentik_Engine/omega_engine/skill_discovery/__init__.py +48 -0
  199. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/__init__.cpython-313.pyc +0 -0
  200. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/auditor.cpython-313.pyc +0 -0
  201. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/finder.cpython-313.pyc +0 -0
  202. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/installer.cpython-313.pyc +0 -0
  203. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/marketplaces.cpython-313.pyc +0 -0
  204. package/omega/Agentik_Engine/omega_engine/skill_discovery/auditor.py +232 -0
  205. package/omega/Agentik_Engine/omega_engine/skill_discovery/finder.py +94 -0
  206. package/omega/Agentik_Engine/omega_engine/skill_discovery/installer.py +129 -0
  207. package/omega/Agentik_Engine/omega_engine/skill_discovery/marketplaces.py +80 -0
  208. package/omega/Agentik_Engine/omega_engine/skill_routing.py +388 -0
  209. package/omega/Agentik_Engine/omega_engine/smoke.py +81 -0
  210. package/omega/Agentik_Engine/omega_engine/store.py +88 -41
  211. package/omega/Agentik_Engine/omega_engine/sync.py +142 -1
  212. package/omega/Agentik_Engine/omega_engine/telegram_history.py +260 -0
  213. package/omega/Agentik_Engine/omega_engine/tmux.py +526 -0
  214. package/omega/Agentik_Engine/omega_engine/understand_anything.py +275 -0
  215. package/omega/Agentik_Engine/omega_engine/updater.py +70 -0
  216. package/omega/Agentik_Engine/omega_engine/validate.py +186 -0
  217. package/omega/Agentik_Engine/omega_engine/vault.py +342 -0
  218. package/omega/Agentik_Engine/omega_engine/webhooks.py +262 -0
  219. package/omega/Agentik_Engine/omega_engine/worker.py +526 -0
  220. package/omega/Agentik_Engine/pyproject.toml +1 -1
  221. package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313-pytest-8.4.2.pyc +0 -0
  222. package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313.pyc +0 -0
  223. package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313-pytest-8.4.2.pyc +0 -0
  224. package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313.pyc +0 -0
  225. package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313-pytest-8.4.2.pyc +0 -0
  226. package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313.pyc +0 -0
  227. package/omega/Agentik_Engine/tests/__pycache__/test_audit_arsenal.cpython-313-pytest-8.4.2.pyc +0 -0
  228. package/omega/Agentik_Engine/tests/__pycache__/test_audit_arsenal.cpython-313.pyc +0 -0
  229. package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313-pytest-8.4.2.pyc +0 -0
  230. package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313.pyc +0 -0
  231. package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313-pytest-8.4.2.pyc +0 -0
  232. package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313.pyc +0 -0
  233. package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313-pytest-8.4.2.pyc +0 -0
  234. package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313.pyc +0 -0
  235. package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313-pytest-8.4.2.pyc +0 -0
  236. package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313.pyc +0 -0
  237. package/omega/Agentik_Engine/tests/__pycache__/test_executor.cpython-313-pytest-8.4.2.pyc +0 -0
  238. package/omega/Agentik_Engine/tests/__pycache__/test_executor.cpython-313.pyc +0 -0
  239. package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313-pytest-8.4.2.pyc +0 -0
  240. package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313.pyc +0 -0
  241. package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313-pytest-8.4.2.pyc +0 -0
  242. package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313.pyc +0 -0
  243. package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313-pytest-8.4.2.pyc +0 -0
  244. package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313.pyc +0 -0
  245. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313-pytest-8.4.2.pyc +0 -0
  246. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313.pyc +0 -0
  247. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313-pytest-8.4.2.pyc +0 -0
  248. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313.pyc +0 -0
  249. package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313-pytest-8.4.2.pyc +0 -0
  250. package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313.pyc +0 -0
  251. package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313-pytest-8.4.2.pyc +0 -0
  252. package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313.pyc +0 -0
  253. package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313-pytest-8.4.2.pyc +0 -0
  254. package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313.pyc +0 -0
  255. package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313-pytest-8.4.2.pyc +0 -0
  256. package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313.pyc +0 -0
  257. package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313-pytest-8.4.2.pyc +0 -0
  258. package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313.pyc +0 -0
  259. package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313-pytest-8.4.2.pyc +0 -0
  260. package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313.pyc +0 -0
  261. package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313-pytest-8.4.2.pyc +0 -0
  262. package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313.pyc +0 -0
  263. package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313-pytest-8.4.2.pyc +0 -0
  264. package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313.pyc +0 -0
  265. package/omega/Agentik_Engine/tests/__pycache__/test_mission.cpython-313-pytest-8.4.2.pyc +0 -0
  266. package/omega/Agentik_Engine/tests/__pycache__/test_mission.cpython-313.pyc +0 -0
  267. package/omega/Agentik_Engine/tests/__pycache__/test_progress.cpython-313-pytest-8.4.2.pyc +0 -0
  268. package/omega/Agentik_Engine/tests/__pycache__/test_progress.cpython-313.pyc +0 -0
  269. package/omega/Agentik_Engine/tests/__pycache__/test_project.cpython-313-pytest-8.4.2.pyc +0 -0
  270. package/omega/Agentik_Engine/tests/__pycache__/test_project.cpython-313.pyc +0 -0
  271. package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313-pytest-8.4.2.pyc +0 -0
  272. package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313.pyc +0 -0
  273. package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313-pytest-8.4.2.pyc +0 -0
  274. package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313.pyc +0 -0
  275. package/omega/Agentik_Engine/tests/__pycache__/test_reducer.cpython-313-pytest-8.4.2.pyc +0 -0
  276. package/omega/Agentik_Engine/tests/__pycache__/test_reducer.cpython-313.pyc +0 -0
  277. package/omega/Agentik_Engine/tests/__pycache__/test_report.cpython-313-pytest-8.4.2.pyc +0 -0
  278. package/omega/Agentik_Engine/tests/__pycache__/test_report.cpython-313.pyc +0 -0
  279. package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313-pytest-8.4.2.pyc +0 -0
  280. package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313.pyc +0 -0
  281. package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313-pytest-8.4.2.pyc +0 -0
  282. package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313.pyc +0 -0
  283. package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313-pytest-8.4.2.pyc +0 -0
  284. package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313.pyc +0 -0
  285. package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313-pytest-8.4.2.pyc +0 -0
  286. package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313.pyc +0 -0
  287. package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313-pytest-8.4.2.pyc +0 -0
  288. package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313.pyc +0 -0
  289. package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313-pytest-8.4.2.pyc +0 -0
  290. package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313.pyc +0 -0
  291. package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313-pytest-8.4.2.pyc +0 -0
  292. package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313.pyc +0 -0
  293. package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313-pytest-8.4.2.pyc +0 -0
  294. package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313.pyc +0 -0
  295. package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313-pytest-8.4.2.pyc +0 -0
  296. package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313.pyc +0 -0
  297. package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313-pytest-8.4.2.pyc +0 -0
  298. package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313.pyc +0 -0
  299. package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313-pytest-8.4.2.pyc +0 -0
  300. package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313.pyc +0 -0
  301. package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313-pytest-8.4.2.pyc +0 -0
  302. package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313.pyc +0 -0
  303. package/omega/Agentik_Engine/tests/test_account.py +8 -3
  304. package/omega/Agentik_Engine/tests/test_adversarial.py +351 -0
  305. package/omega/Agentik_Engine/tests/test_agents_envelope.py +274 -0
  306. package/omega/Agentik_Engine/tests/test_audits_pipeline.py +348 -0
  307. package/omega/Agentik_Engine/tests/test_auto_update_and_migrations.py +394 -0
  308. package/omega/Agentik_Engine/tests/test_genesis_and_plan.py +573 -0
  309. package/omega/Agentik_Engine/tests/test_graphify.py +190 -0
  310. package/omega/Agentik_Engine/tests/test_handoff.py +311 -0
  311. package/omega/Agentik_Engine/tests/test_hermes_and_ua.py +387 -0
  312. package/omega/Agentik_Engine/tests/test_hermes_bootstrap_and_desktop.py +358 -0
  313. package/omega/Agentik_Engine/tests/test_install_steps.py +359 -0
  314. package/omega/Agentik_Engine/tests/test_install_ux.py +151 -0
  315. package/omega/Agentik_Engine/tests/test_installer_wiring.py +496 -0
  316. package/omega/Agentik_Engine/tests/test_intelligence.py +285 -0
  317. package/omega/Agentik_Engine/tests/test_llm_clis_and_uninstall.py +228 -0
  318. package/omega/Agentik_Engine/tests/test_managed_agent.py +363 -0
  319. package/omega/Agentik_Engine/tests/test_max_provider_and_menu.py +231 -0
  320. package/omega/Agentik_Engine/tests/test_menu_coverage.py +72 -0
  321. package/omega/Agentik_Engine/tests/test_pursue_cadence.py +217 -0
  322. package/omega/Agentik_Engine/tests/test_role_aliases_and_ssot.py +207 -0
  323. package/omega/Agentik_Engine/tests/test_skill_discovery_and_gate.py +337 -0
  324. package/omega/Agentik_Engine/tests/test_skill_power.py +259 -0
  325. package/omega/Agentik_Engine/tests/test_skill_routing.py +189 -0
  326. package/omega/Agentik_Engine/tests/test_telegram_history.py +209 -0
  327. package/omega/Agentik_Engine/tests/test_tmux_and_aisb_chat.py +223 -0
  328. package/omega/Agentik_Engine/tests/test_v06_features.py +370 -0
  329. package/omega/Agentik_Engine/tests/test_vault.py +173 -0
  330. package/omega/Agentik_Engine/tests/test_webhooks_and_readiness.py +277 -0
  331. package/omega/Agentik_Engine/tests/test_worker_and_cleanup.py +541 -0
  332. package/omega/Agentik_Extra/etc/secrets/.vault-key +3 -0
  333. package/omega/Agentik_Extra/etc/secrets/.vault-pub +1 -0
  334. package/omega/Agentik_Runtime/audits.db +0 -0
  335. package/omega/Agentik_SSOT/VERSION +1 -1
  336. package/omega/Agentik_SSOT/claude-plugins/claude-plugins.yaml +100 -0
  337. package/omega/Agentik_SSOT/docs/LAYERS.md +90 -0
  338. package/omega/Agentik_SSOT/docs/USER-JOURNEY.md +283 -0
  339. package/omega/Agentik_SSOT/docs/quality-arsenal/ARSENAL-INTERCONNECTIONS.md +283 -0
  340. package/omega/Agentik_SSOT/docs/quality-arsenal/ARSENAL-ORCHESTRATION-PLAYBOOK.md +364 -0
  341. package/omega/Agentik_SSOT/docs/quality-arsenal/AUDIT-VERIFICATION-CONTRACT.md +272 -0
  342. package/omega/Agentik_SSOT/docs/quality-arsenal/QUALITY-ARSENAL-PREAMBLE.md +462 -0
  343. package/omega/Agentik_SSOT/marketplaces/design-discipline.yaml +86 -0
  344. package/omega/Agentik_SSOT/skills/a11yaudit/SKILL.md +161 -0
  345. package/omega/Agentik_SSOT/skills/apiaudit/SKILL.md +157 -0
  346. package/omega/Agentik_SSOT/skills/audit-orchestrator.md +212 -0
  347. package/omega/Agentik_SSOT/skills/audit-pilot.md +466 -0
  348. package/omega/Agentik_SSOT/skills/audit-tracker.md +147 -0
  349. package/omega/Agentik_SSOT/skills/automationaudit/SKILL.md +161 -0
  350. package/omega/Agentik_SSOT/skills/cadence/SKILL.md +76 -0
  351. package/omega/Agentik_SSOT/skills/codeaudit/SKILL.md +153 -0
  352. package/omega/Agentik_SSOT/skills/copyaudit/SKILL.md +161 -0
  353. package/omega/Agentik_SSOT/skills/dataaudit/SKILL.md +157 -0
  354. package/omega/Agentik_SSOT/skills/debugaudit/SKILL.md +161 -0
  355. package/omega/Agentik_SSOT/skills/dispatch/SKILL.md +79 -0
  356. package/omega/Agentik_SSOT/skills/dxaudit/SKILL.md +161 -0
  357. package/omega/Agentik_SSOT/skills/featureaudit/SKILL.md +161 -0
  358. package/omega/Agentik_SSOT/skills/flowaudit/SKILL.md +165 -0
  359. package/omega/Agentik_SSOT/skills/genesis/SKILL.md +116 -0
  360. package/omega/Agentik_SSOT/skills/handoff/SKILL.md +117 -0
  361. package/omega/Agentik_SSOT/skills/logicaudit/SKILL.md +165 -0
  362. package/omega/Agentik_SSOT/skills/motionaudit/SKILL.md +165 -0
  363. package/omega/Agentik_SSOT/skills/newcmd.md +300 -0
  364. package/omega/Agentik_SSOT/skills/perfaudit/SKILL.md +161 -0
  365. package/omega/Agentik_SSOT/skills/plan/SKILL.md +127 -0
  366. package/omega/Agentik_SSOT/skills/pursue/SKILL.md +68 -0
  367. package/omega/Agentik_SSOT/skills/quality-arsenal.md +180 -0
  368. package/omega/Agentik_SSOT/skills/rag-route.md +9 -0
  369. package/omega/Agentik_SSOT/skills/refontaudit/SKILL.md +165 -0
  370. package/omega/Agentik_SSOT/skills/retentionaudit/SKILL.md +165 -0
  371. package/omega/Agentik_SSOT/skills/secaudit/SKILL.md +157 -0
  372. package/omega/Agentik_SSOT/skills/seoaudit/SKILL.md +161 -0
  373. package/omega/Agentik_SSOT/skills/skill-auditor/SKILL.md +83 -0
  374. package/omega/Agentik_SSOT/skills/skill-finder/SKILL.md +116 -0
  375. package/omega/Agentik_SSOT/skills/uiuxaudit/SKILL.md +165 -0
  376. package/package.json +2 -2
@@ -0,0 +1,573 @@
1
+ """Tests for the Genesis pipeline + Plan v7 FSM-enforced executor.
2
+
3
+ The two modules are tightly coupled (Genesis writes plan/DAG.json;
4
+ Plan ingests it) — same suite to keep the contract honest.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import json
9
+ import os
10
+ import sys
11
+ import tempfile
12
+ import unittest
13
+ from pathlib import Path
14
+
15
+
16
+ HERE = Path(__file__).resolve().parent
17
+ sys.path.insert(0, str(HERE.parent))
18
+
19
+ from omega_engine.genesis import ( # noqa: E402
20
+ PHASES,
21
+ GenesisOrchestrator,
22
+ GenesisState,
23
+ StackConfig,
24
+ init_project,
25
+ load_state,
26
+ pick_stack,
27
+ project_root,
28
+ stack_questions,
29
+ )
30
+ from omega_engine.genesis.state import delete_project # noqa: E402
31
+ from omega_engine import plan as P # noqa: E402
32
+
33
+
34
+ # ---------------------------------------------------------------------------
35
+ # Stack picker
36
+ # ---------------------------------------------------------------------------
37
+
38
+
39
+ class TestStackPicker(unittest.TestCase):
40
+ def test_default_is_omegaos_canonical(self):
41
+ cfg = pick_stack(accept_defaults=True)
42
+ self.assertEqual(cfg.type, "web")
43
+ self.assertEqual(cfg.frontend, "nextjs")
44
+ self.assertEqual(cfg.backend, "convex")
45
+ self.assertEqual(cfg.deploy, "vercel")
46
+ self.assertEqual(cfg.payments, "stripe")
47
+ self.assertEqual(cfg.ui_kit, "shadcn")
48
+ self.assertEqual(cfg.auth, "clerk")
49
+
50
+ def test_questions_cover_five_essentials(self):
51
+ keys = {q.key for q in stack_questions()}
52
+ self.assertEqual(
53
+ keys, {"type", "backend", "frontend", "auth", "payments"}
54
+ )
55
+
56
+ def test_iphone_forces_swiftui_and_none_deploy(self):
57
+ cfg = pick_stack(answers={"type": "iphone"})
58
+ self.assertEqual(cfg.mobile, "swiftui")
59
+ self.assertEqual(cfg.deploy, "none")
60
+ self.assertEqual(cfg.ui_kit, "custom")
61
+
62
+ def test_mobile_expo_couples_eas(self):
63
+ cfg = pick_stack(answers={"type": "mobile", "frontend": "expo"})
64
+ self.assertEqual(cfg.mobile, "expo")
65
+ self.assertEqual(cfg.deploy, "eas")
66
+
67
+ def test_supabase_couples_auth(self):
68
+ cfg = pick_stack(answers={"backend": "supabase"})
69
+ self.assertEqual(cfg.auth, "supabase-auth")
70
+
71
+ def test_supabase_with_explicit_auth_keeps_it(self):
72
+ cfg = pick_stack(answers={"backend": "supabase", "auth": "clerk"})
73
+ self.assertEqual(cfg.auth, "clerk")
74
+
75
+ def test_library_strips_payments_and_deploy(self):
76
+ cfg = pick_stack(answers={"type": "library"})
77
+ self.assertEqual(cfg.deploy, "none")
78
+ self.assertEqual(cfg.payments, "none")
79
+ self.assertEqual(cfg.ui_kit, "tailwind-only")
80
+
81
+ def test_rejects_unknown_key(self):
82
+ with self.assertRaises(ValueError):
83
+ pick_stack(answers={"not_a_key": "bogus"})
84
+
85
+ def test_rejects_invalid_value(self):
86
+ with self.assertRaises(ValueError):
87
+ pick_stack(answers={"backend": "neo4j"})
88
+
89
+
90
+ # ---------------------------------------------------------------------------
91
+ # State machine (PROJECT.yaml)
92
+ # ---------------------------------------------------------------------------
93
+
94
+
95
+ class TestState(unittest.TestCase):
96
+ def test_init_creates_canonical_tree(self):
97
+ with tempfile.TemporaryDirectory() as tmp:
98
+ home = Path(tmp)
99
+ state = init_project("acme", omega_home=home)
100
+ root = project_root("acme", omega_home=home)
101
+ self.assertTrue((root / "PROJECT.yaml").exists())
102
+ for sub in ("docs/10-market", "docs/20-brand",
103
+ "docs/30-prd", "docs/40-features", "plan"):
104
+ self.assertTrue((root / sub).is_dir(), sub)
105
+ self.assertEqual(state.phase, "stack")
106
+ self.assertEqual(state.completed_phases, [])
107
+
108
+ def test_init_refuses_duplicate_without_force(self):
109
+ with tempfile.TemporaryDirectory() as tmp:
110
+ home = Path(tmp)
111
+ init_project("acme", omega_home=home)
112
+ with self.assertRaises(FileExistsError):
113
+ init_project("acme", omega_home=home)
114
+
115
+ def test_init_force_overwrites(self):
116
+ with tempfile.TemporaryDirectory() as tmp:
117
+ home = Path(tmp)
118
+ init_project("acme", name="First", omega_home=home)
119
+ init_project("acme", name="Second", force=True, omega_home=home)
120
+ self.assertEqual(load_state("acme", omega_home=home).name,
121
+ "Second")
122
+
123
+ def test_load_state_round_trip(self):
124
+ with tempfile.TemporaryDirectory() as tmp:
125
+ home = Path(tmp)
126
+ init_project("acme", intent="X", omega_home=home)
127
+ state = load_state("acme", omega_home=home)
128
+ self.assertEqual(state.intent, "X")
129
+ self.assertEqual(state.slug, "acme")
130
+
131
+ def test_invalid_slug_rejected(self):
132
+ with self.assertRaises(ValueError):
133
+ project_root("../etc/passwd")
134
+ with self.assertRaises(ValueError):
135
+ project_root("with spaces")
136
+
137
+ def test_mark_phase_done_advances_pointer(self):
138
+ with tempfile.TemporaryDirectory() as tmp:
139
+ home = Path(tmp)
140
+ init_project("acme", omega_home=home)
141
+ state = load_state("acme", omega_home=home)
142
+ state.mark_phase_done("stack")
143
+ self.assertIn("stack", state.completed_phases)
144
+ self.assertEqual(state.phase, "vision")
145
+
146
+ def test_next_phase_walks_through_all(self):
147
+ with tempfile.TemporaryDirectory() as tmp:
148
+ home = Path(tmp)
149
+ init_project("acme", omega_home=home)
150
+ state = load_state("acme", omega_home=home)
151
+ order: list[str] = []
152
+ while True:
153
+ nxt = state.next_phase()
154
+ if nxt is None:
155
+ break
156
+ order.append(nxt)
157
+ state.mark_phase_done(nxt)
158
+ self.assertEqual(tuple(order), PHASES)
159
+
160
+
161
+ class TestDeleteProject(unittest.TestCase):
162
+ def test_delete_returns_true_when_present(self):
163
+ with tempfile.TemporaryDirectory() as tmp:
164
+ home = Path(tmp)
165
+ init_project("acme", omega_home=home)
166
+ self.assertTrue(delete_project("acme", omega_home=home))
167
+ self.assertFalse(project_root("acme", omega_home=home).exists())
168
+
169
+ def test_delete_returns_false_when_absent(self):
170
+ with tempfile.TemporaryDirectory() as tmp:
171
+ home = Path(tmp)
172
+ self.assertFalse(delete_project("nope", omega_home=home))
173
+
174
+
175
+ # ---------------------------------------------------------------------------
176
+ # Orchestrator — walks every phase, writes files, flips state
177
+ # ---------------------------------------------------------------------------
178
+
179
+
180
+ class TestOrchestrator(unittest.TestCase):
181
+ def test_run_all_walks_every_phase(self):
182
+ with tempfile.TemporaryDirectory() as tmp:
183
+ home = Path(tmp)
184
+ init_project("acme", intent="A test SaaS", omega_home=home)
185
+ orch = GenesisOrchestrator("acme", omega_home=home)
186
+ results = orch.run_all()
187
+ phases_run = [r.phase for r in results]
188
+ self.assertEqual(tuple(phases_run), PHASES)
189
+ for r in results:
190
+ self.assertTrue(r.ok, f"{r.phase} failed: {r.error}")
191
+
192
+ def test_files_land_in_correct_subdirs(self):
193
+ with tempfile.TemporaryDirectory() as tmp:
194
+ home = Path(tmp)
195
+ init_project("acme", omega_home=home)
196
+ GenesisOrchestrator("acme", omega_home=home).run_all()
197
+ root = project_root("acme", omega_home=home)
198
+ # Vision: one file at the top of docs/
199
+ self.assertTrue((root / "docs" / "00-VISION.md").exists())
200
+ # Market: 5 files
201
+ market = list((root / "docs" / "10-market").glob("*.md"))
202
+ self.assertEqual(len(market), 5)
203
+ # Branding: 3 files
204
+ brand = list((root / "docs" / "20-brand").glob("*.md"))
205
+ self.assertEqual(len(brand), 3)
206
+ # PRD: 9 files
207
+ prd = list((root / "docs" / "30-prd").glob("*.md"))
208
+ self.assertEqual(len(prd), 9)
209
+ # Features: at least 6 starter + TEMPLATE
210
+ features = sorted((root / "docs" / "40-features").glob("*.md"))
211
+ self.assertGreaterEqual(len(features), 7)
212
+ # DAG.json is valid JSON with the right shape
213
+ dag = json.loads((root / "plan" / "DAG.json").read_text())
214
+ self.assertIn("features", dag)
215
+ self.assertGreaterEqual(len(dag["features"]), 6)
216
+ self.assertEqual(dag["slug"], "acme")
217
+
218
+ def test_resume_is_idempotent(self):
219
+ with tempfile.TemporaryDirectory() as tmp:
220
+ home = Path(tmp)
221
+ init_project("acme", omega_home=home)
222
+ orch = GenesisOrchestrator("acme", omega_home=home)
223
+ # Run halfway
224
+ r1 = orch.run()
225
+ self.assertEqual(r1.phase, "stack")
226
+ r2 = orch.run()
227
+ self.assertEqual(r2.phase, "vision")
228
+ # Status reflects that
229
+ st = orch.status()
230
+ self.assertIn("vision", st["completed_phases"])
231
+ # Resume — picks up at market
232
+ r3 = orch.run()
233
+ self.assertEqual(r3.phase, "market")
234
+
235
+ def test_only_runs_specific_phase(self):
236
+ with tempfile.TemporaryDirectory() as tmp:
237
+ home = Path(tmp)
238
+ init_project("acme", omega_home=home)
239
+ orch = GenesisOrchestrator("acme", omega_home=home)
240
+ # Force PRD phase even though we haven't done vision
241
+ r = orch.run(only="prd")
242
+ self.assertEqual(r.phase, "prd")
243
+ self.assertTrue(r.ok)
244
+
245
+ def test_status_reports_remaining(self):
246
+ with tempfile.TemporaryDirectory() as tmp:
247
+ home = Path(tmp)
248
+ init_project("acme", omega_home=home)
249
+ orch = GenesisOrchestrator("acme", omega_home=home)
250
+ orch.run() # stack
251
+ orch.run() # vision
252
+ st = orch.status()
253
+ self.assertEqual(st["phase"], "market")
254
+ self.assertIn("market", st["remaining_phases"])
255
+
256
+ def test_per_project_isolation(self):
257
+ """Genesis on slug-a writes nothing under slug-b's tree."""
258
+ with tempfile.TemporaryDirectory() as tmp:
259
+ home = Path(tmp)
260
+ init_project("alpha", omega_home=home)
261
+ init_project("beta", omega_home=home)
262
+ GenesisOrchestrator("alpha", omega_home=home).run_all()
263
+ beta_root = project_root("beta", omega_home=home)
264
+ # Beta should still be empty except for the init skeleton
265
+ self.assertFalse((beta_root / "docs" / "00-VISION.md").exists())
266
+ self.assertFalse((beta_root / "plan" / "DAG.json").exists())
267
+
268
+
269
+ # ---------------------------------------------------------------------------
270
+ # Plan v7 — FSM enforcement (the bug fix)
271
+ # ---------------------------------------------------------------------------
272
+
273
+
274
+ def _bootstrap_plan(home: Path, slug: str = "demo") -> None:
275
+ """Helper: init + run genesis + build the plan store."""
276
+ init_project(slug, omega_home=home)
277
+ GenesisOrchestrator(slug, omega_home=home).run_all()
278
+ P.build_plan(slug, omega_home=home)
279
+
280
+
281
+ class TestPlanBuild(unittest.TestCase):
282
+ def test_build_inserts_features_from_dag(self):
283
+ with tempfile.TemporaryDirectory() as tmp:
284
+ home = Path(tmp)
285
+ _bootstrap_plan(home)
286
+ res = P.build_plan("demo", omega_home=home)
287
+ # idempotent: second call updates, not re-inserts
288
+ self.assertEqual(res["inserted"], 0)
289
+ self.assertGreaterEqual(res["updated"], 6)
290
+ self.assertGreaterEqual(res["total"], 6)
291
+
292
+ def test_build_validates_dag(self):
293
+ with tempfile.TemporaryDirectory() as tmp:
294
+ home = Path(tmp)
295
+ init_project("demo", omega_home=home)
296
+ GenesisOrchestrator("demo", omega_home=home).run_all()
297
+ # Corrupt the DAG: feature pointing at unknown dep
298
+ dag_p = project_root("demo", omega_home=home) / "plan" / "DAG.json"
299
+ dag = json.loads(dag_p.read_text())
300
+ dag["features"].append({
301
+ "id": "F-999", "title": "bad",
302
+ "depends_on": ["F-XYZ"], "wave": 1,
303
+ "estimated_minutes": 10, "files_owned": [],
304
+ "verify_cmd": "true", "skill": "",
305
+ })
306
+ dag_p.write_text(json.dumps(dag))
307
+ with self.assertRaises(P.PlanError):
308
+ P.build_plan("demo", omega_home=home)
309
+
310
+ def test_build_detects_cycle(self):
311
+ with tempfile.TemporaryDirectory() as tmp:
312
+ home = Path(tmp)
313
+ init_project("demo", omega_home=home)
314
+ GenesisOrchestrator("demo", omega_home=home).run_all()
315
+ dag_p = project_root("demo", omega_home=home) / "plan" / "DAG.json"
316
+ dag_p.write_text(json.dumps({
317
+ "slug": "demo",
318
+ "features": [
319
+ {"id": "A", "title": "a", "depends_on": ["B"], "wave": 1,
320
+ "estimated_minutes": 1, "files_owned": [],
321
+ "verify_cmd": "true", "skill": ""},
322
+ {"id": "B", "title": "b", "depends_on": ["A"], "wave": 1,
323
+ "estimated_minutes": 1, "files_owned": [],
324
+ "verify_cmd": "true", "skill": ""},
325
+ ],
326
+ }))
327
+ with self.assertRaises(P.PlanError):
328
+ P.build_plan("demo", omega_home=home)
329
+
330
+
331
+ class TestPlanFSM(unittest.TestCase):
332
+ """The core bug-fix proofs — every adversarial path is rejected."""
333
+
334
+ def test_next_eligible_is_root_task(self):
335
+ with tempfile.TemporaryDirectory() as tmp:
336
+ home = Path(tmp)
337
+ _bootstrap_plan(home)
338
+ t = P.next_eligible("demo", omega_home=home)
339
+ self.assertEqual(t.id, "F-001") # the root
340
+ self.assertEqual(t.depends_on, [])
341
+
342
+ def test_cannot_jump_past_dependencies(self):
343
+ """The original v6 bug: agent skipping T-050 to T-090.
344
+ Here: F-006 depends on F-001 + F-003. Must reject."""
345
+ with tempfile.TemporaryDirectory() as tmp:
346
+ home = Path(tmp)
347
+ _bootstrap_plan(home)
348
+ with self.assertRaises(P.PlanError) as ctx:
349
+ P.mark_in_progress("demo", "F-006", omega_home=home)
350
+ self.assertIn("unverified deps", str(ctx.exception))
351
+
352
+ def test_cannot_skip_state_pending_to_verified(self):
353
+ with tempfile.TemporaryDirectory() as tmp:
354
+ home = Path(tmp)
355
+ _bootstrap_plan(home)
356
+ with self.assertRaises(P.PlanError):
357
+ P.mark_done("demo", "F-001", omega_home=home, verify=False)
358
+
359
+ def test_cannot_skip_in_progress_to_verified(self):
360
+ """Even after in_progress, must go through claimed_done."""
361
+ with tempfile.TemporaryDirectory() as tmp:
362
+ home = Path(tmp)
363
+ _bootstrap_plan(home)
364
+ P.mark_in_progress("demo", "F-001", omega_home=home)
365
+ # Direct in_progress → verified is illegal
366
+ # mark_done auto-bridges via claimed_done when verify=False,
367
+ # but the underlying _transition would reject it. Use the
368
+ # explicit funnel:
369
+ from omega_engine.plan import _transition, VERIFIED
370
+ with self.assertRaises(P.PlanError):
371
+ _transition("demo", "F-001", VERIFIED, omega_home=home)
372
+
373
+ def test_normal_flow_advances(self):
374
+ with tempfile.TemporaryDirectory() as tmp:
375
+ home = Path(tmp)
376
+ _bootstrap_plan(home)
377
+ P.mark_in_progress("demo", "F-001", omega_home=home)
378
+ P.mark_claimed_done("demo", "F-001", omega_home=home)
379
+ t = P.mark_done("demo", "F-001", verify=False, omega_home=home)
380
+ self.assertEqual(t.state, P.VERIFIED)
381
+
382
+ def test_completed_dep_unlocks_next(self):
383
+ with tempfile.TemporaryDirectory() as tmp:
384
+ home = Path(tmp)
385
+ _bootstrap_plan(home)
386
+ # Walk F-001 to VERIFIED
387
+ P.mark_in_progress("demo", "F-001", omega_home=home)
388
+ P.mark_claimed_done("demo", "F-001", omega_home=home)
389
+ P.mark_done("demo", "F-001", verify=False, omega_home=home)
390
+ # Now F-002 (deps F-001) should be eligible
391
+ t = P.next_eligible("demo", omega_home=home)
392
+ self.assertEqual(t.id, "F-002")
393
+ # F-006 still blocked (also needs F-003)
394
+ with self.assertRaises(P.PlanError):
395
+ P.mark_in_progress("demo", "F-006", omega_home=home)
396
+
397
+ def test_verify_failure_routes_to_failed(self):
398
+ with tempfile.TemporaryDirectory() as tmp:
399
+ home = Path(tmp)
400
+ _bootstrap_plan(home)
401
+ P.mark_in_progress("demo", "F-001", omega_home=home)
402
+ P.mark_claimed_done("demo", "F-001", omega_home=home)
403
+ # Override the verify_cmd to a guaranteed failure
404
+ import sqlite3
405
+ with sqlite3.connect(str(P.db_path("demo", omega_home=home))) as conn:
406
+ conn.execute(
407
+ "UPDATE tasks SET verify_cmd=? WHERE slug=? AND id=?",
408
+ ("exit 1", "demo", "F-001"),
409
+ )
410
+ conn.commit()
411
+ t = P.mark_done("demo", "F-001", verify=True, omega_home=home)
412
+ self.assertEqual(t.state, P.FAILED)
413
+ self.assertIn("rc=", t.last_error)
414
+ # And the failed task does NOT unlock F-002
415
+ t2 = P.next_eligible("demo", omega_home=home)
416
+ # F-002 needs F-001 verified — should NOT be eligible.
417
+ # next_eligible returns None or a different non-dependent task.
418
+ # In our seed F-001 has no dependent at wave 1 other than F-002,
419
+ # F-003. F-004 depends on F-002 → blocked too. So nothing
420
+ # eligible.
421
+ self.assertIsNone(t2)
422
+
423
+ def test_retry_resets_failed_to_pending(self):
424
+ with tempfile.TemporaryDirectory() as tmp:
425
+ home = Path(tmp)
426
+ _bootstrap_plan(home)
427
+ P.mark_in_progress("demo", "F-001", omega_home=home)
428
+ P.mark_failed("demo", "F-001", reason="explicit",
429
+ omega_home=home)
430
+ t = P.retry("demo", "F-001", omega_home=home)
431
+ self.assertEqual(t.state, P.PENDING)
432
+ self.assertEqual(t.last_error, "")
433
+
434
+ def test_status_reports_completion(self):
435
+ with tempfile.TemporaryDirectory() as tmp:
436
+ home = Path(tmp)
437
+ _bootstrap_plan(home)
438
+ # Verify F-001
439
+ P.mark_in_progress("demo", "F-001", omega_home=home)
440
+ P.mark_claimed_done("demo", "F-001", omega_home=home)
441
+ P.mark_done("demo", "F-001", verify=False, omega_home=home)
442
+ st = P.status("demo", omega_home=home)
443
+ self.assertEqual(st["counts"]["verified"], 1)
444
+ self.assertGreater(st["completion_pct"], 0)
445
+ self.assertLess(st["completion_pct"], 100)
446
+
447
+ def test_list_filters_by_state(self):
448
+ with tempfile.TemporaryDirectory() as tmp:
449
+ home = Path(tmp)
450
+ _bootstrap_plan(home)
451
+ pending = P.list_tasks("demo", state=P.PENDING, omega_home=home)
452
+ self.assertEqual(len(pending), 6)
453
+ self.assertEqual(P.list_tasks("demo", state=P.VERIFIED,
454
+ omega_home=home), [])
455
+
456
+
457
+ class TestPlanRun(unittest.TestCase):
458
+ """The multi-day autonomous loop — the closing piece for the user's
459
+ 'agents qui travaillent plusieurs jours' requirement."""
460
+
461
+ def test_run_dry_mode_walks_root_only_when_verify_passes(self):
462
+ """With no dispatch + no spawn, verify_cmd runs as-is. Only tasks
463
+ whose verify_cmd exits 0 advance."""
464
+ with tempfile.TemporaryDirectory() as tmp:
465
+ home = Path(tmp)
466
+ _bootstrap_plan(home)
467
+ # Override every task's verify_cmd to `true` so they all pass
468
+ import sqlite3
469
+ conn = sqlite3.connect(str(P.db_path("demo", omega_home=home)))
470
+ conn.execute("UPDATE tasks SET verify_cmd='true' WHERE slug='demo'")
471
+ conn.commit(); conn.close()
472
+ # No dispatch → loop just walks the FSM
473
+ result = P.run("demo", omega_home=home, max_iterations=10)
474
+ self.assertEqual(result.iterations, 6) # 6 starter features
475
+ self.assertEqual(len(result.verified), 6)
476
+ self.assertEqual(len(result.failed), 0)
477
+ st = P.status("demo", omega_home=home)
478
+ self.assertEqual(st["completion_pct"], 100.0)
479
+
480
+ def test_run_respects_dependency_chain(self):
481
+ """Force the verify_cmd of F-003 (auth-flow) to fail. Dependants
482
+ (F-005 dashboard-shell, F-006 billing) must NOT be touched."""
483
+ with tempfile.TemporaryDirectory() as tmp:
484
+ home = Path(tmp)
485
+ _bootstrap_plan(home)
486
+ import sqlite3
487
+ conn = sqlite3.connect(str(P.db_path("demo", omega_home=home)))
488
+ conn.execute("UPDATE tasks SET verify_cmd='true' WHERE slug='demo'")
489
+ conn.execute(
490
+ "UPDATE tasks SET verify_cmd='exit 1' "
491
+ "WHERE slug='demo' AND id='F-003'"
492
+ )
493
+ conn.commit(); conn.close()
494
+ result = P.run("demo", omega_home=home, max_iterations=10)
495
+ # F-003 fails → blocks F-005 + F-006
496
+ self.assertIn("F-003", result.failed)
497
+ tasks = {t.id: t for t in P.list_tasks("demo", omega_home=home)}
498
+ self.assertEqual(tasks["F-003"].state, P.FAILED)
499
+ self.assertEqual(tasks["F-005"].state, P.PENDING) # NEVER touched
500
+ self.assertEqual(tasks["F-006"].state, P.PENDING) # NEVER touched
501
+ # Independent branches (F-001, F-002, F-004) still verify
502
+ self.assertEqual(tasks["F-001"].state, P.VERIFIED)
503
+ self.assertEqual(tasks["F-002"].state, P.VERIFIED)
504
+ self.assertEqual(tasks["F-004"].state, P.VERIFIED)
505
+
506
+ def test_run_max_iterations_caps_loop(self):
507
+ with tempfile.TemporaryDirectory() as tmp:
508
+ home = Path(tmp)
509
+ _bootstrap_plan(home)
510
+ import sqlite3
511
+ conn = sqlite3.connect(str(P.db_path("demo", omega_home=home)))
512
+ conn.execute("UPDATE tasks SET verify_cmd='true' WHERE slug='demo'")
513
+ conn.commit(); conn.close()
514
+ result = P.run("demo", omega_home=home, max_iterations=2)
515
+ self.assertEqual(result.iterations, 2)
516
+ self.assertEqual(len(result.verified), 2)
517
+
518
+ def test_run_dispatch_callback_invoked_per_task(self):
519
+ """The custom dispatch callable replaces the spawn_cmd path."""
520
+ with tempfile.TemporaryDirectory() as tmp:
521
+ home = Path(tmp)
522
+ _bootstrap_plan(home)
523
+ import sqlite3
524
+ conn = sqlite3.connect(str(P.db_path("demo", omega_home=home)))
525
+ conn.execute("UPDATE tasks SET verify_cmd='true' WHERE slug='demo'")
526
+ conn.commit(); conn.close()
527
+ dispatched: list[str] = []
528
+ def fake_dispatch(task):
529
+ dispatched.append(task.id)
530
+ P.run("demo", omega_home=home, max_iterations=3,
531
+ dispatch=fake_dispatch)
532
+ self.assertEqual(dispatched, ["F-001", "F-002", "F-003"])
533
+
534
+ def test_run_on_iteration_hook_fires(self):
535
+ with tempfile.TemporaryDirectory() as tmp:
536
+ home = Path(tmp)
537
+ _bootstrap_plan(home)
538
+ import sqlite3
539
+ conn = sqlite3.connect(str(P.db_path("demo", omega_home=home)))
540
+ conn.execute("UPDATE tasks SET verify_cmd='true' WHERE slug='demo'")
541
+ conn.commit(); conn.close()
542
+ events: list[tuple[str, str]] = []
543
+ P.run("demo", omega_home=home, max_iterations=2,
544
+ on_iteration=lambda t, r: events.append((t.id, r)))
545
+ self.assertEqual(len(events), 2)
546
+ self.assertEqual(events[0][1], "verified")
547
+
548
+
549
+ class TestPlanIsolation(unittest.TestCase):
550
+ """Two projects must not share state or DB."""
551
+
552
+ def test_two_projects_each_have_own_db(self):
553
+ with tempfile.TemporaryDirectory() as tmp:
554
+ home = Path(tmp)
555
+ _bootstrap_plan(home, "alpha")
556
+ _bootstrap_plan(home, "beta")
557
+ # Advance alpha only
558
+ P.mark_in_progress("alpha", "F-001", omega_home=home)
559
+ P.mark_claimed_done("alpha", "F-001", omega_home=home)
560
+ P.mark_done("alpha", "F-001", verify=False, omega_home=home)
561
+ # Beta untouched
562
+ st_b = P.status("beta", omega_home=home)
563
+ self.assertEqual(st_b["counts"]["verified"], 0)
564
+ self.assertEqual(st_b["counts"]["pending"], 6)
565
+ # And the file paths are different
566
+ self.assertNotEqual(
567
+ str(P.db_path("alpha", omega_home=home)),
568
+ str(P.db_path("beta", omega_home=home)),
569
+ )
570
+
571
+
572
+ if __name__ == "__main__":
573
+ unittest.main()