@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.
- package/README.md +56 -14
- package/bootstrap/lib/__pycache__/claude-code-settings.cpython-313.pyc +0 -0
- package/bootstrap/lib/__pycache__/llm-clis.cpython-313.pyc +0 -0
- package/bootstrap/lib/__pycache__/manifest-helpers.cpython-313.pyc +0 -0
- package/bootstrap/lib/claude-code-settings.py +176 -0
- package/bootstrap/lib/common.sh +457 -1
- package/bootstrap/lib/llm-clis.py +341 -0
- package/bootstrap/lib/manifest-helpers.py +384 -0
- package/bootstrap/lib/steps.sh +1000 -26
- package/bootstrap/manifest.example.yaml +93 -2
- package/bootstrap/templates/aisb/CLAUDE.md +305 -0
- package/bootstrap/templates/aisb/architect.md +204 -0
- package/bootstrap/templates/aisb/checkers/CLAUDE.md +9 -0
- package/bootstrap/templates/aisb/checkers/checker-architect.md +151 -0
- package/bootstrap/templates/aisb/checkers/checker-common.md +171 -0
- package/bootstrap/templates/aisb/checkers/checker-construct.md +129 -0
- package/bootstrap/templates/aisb/checkers/checker-keymaker.md +204 -0
- package/bootstrap/templates/aisb/checkers/checker-link.md +205 -0
- package/bootstrap/templates/aisb/checkers/checker-merovingian.md +219 -0
- package/bootstrap/templates/aisb/checkers/checker-morpheus.md +211 -0
- package/bootstrap/templates/aisb/checkers/checker-neo.md +177 -0
- package/bootstrap/templates/aisb/checkers/checker-niobe.md +156 -0
- package/bootstrap/templates/aisb/checkers/checker-oracle.md +164 -0
- package/bootstrap/templates/aisb/checkers/checker-seraph.md +187 -0
- package/bootstrap/templates/aisb/checkers/checker-smith.md +195 -0
- package/bootstrap/templates/aisb/checkers/checker-zion.md +113 -0
- package/bootstrap/templates/aisb/construct.md +135 -0
- package/bootstrap/templates/aisb/keymaker.md +227 -0
- package/bootstrap/templates/aisb/link.md +170 -0
- package/bootstrap/templates/aisb/lmc-protocol.md +57 -0
- package/bootstrap/templates/aisb/merovingian.md +159 -0
- package/bootstrap/templates/aisb/morpheus.md +243 -0
- package/bootstrap/templates/aisb/neo.md +147 -0
- package/bootstrap/templates/aisb/niobe.md +197 -0
- package/bootstrap/templates/aisb/oracle.md +244 -0
- package/bootstrap/templates/aisb/protocols/handoff-templates.md +204 -0
- package/bootstrap/templates/aisb/protocols/shared-protocol.md +248 -0
- package/bootstrap/templates/aisb/pythia.md +153 -0
- package/bootstrap/templates/aisb/seraph.md +315 -0
- package/bootstrap/templates/aisb/smith.md +202 -0
- package/bootstrap/templates/aisb/zion.md +172 -0
- package/bootstrap/templates/autonomous/audit-patrol.yaml +41 -0
- package/bootstrap/templates/autonomous/smith-reflect.yaml +43 -0
- package/bootstrap/templates/autonomous/ssh-key-rotate.yaml +46 -0
- package/bootstrap/templates/autonomous/support-agent.yaml +38 -0
- package/docs/AUDITS.md +85 -0
- package/docs/COMPLETION-PLAN.md +48 -0
- package/docs/GAP-ANALYSIS.md +214 -0
- package/docs/INSTALL.md +47 -9
- package/docs/MCP-AND-PLUGINS.md +31 -4
- package/docs/SIMULATION.md +171 -0
- package/docs/simulate.sh +211 -0
- package/install.sh +164 -17
- package/omega/Agentik_Engine/README.md +27 -10
- package/omega/Agentik_Engine/omega_engine/__init__.py +212 -2
- package/omega/Agentik_Engine/omega_engine/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/account.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/agent_messages.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/aisb_chat.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/audit_diff.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/audit_gate.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/auto_update.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/autonomous.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/backup.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/cadence.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/classifier.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/cleanup.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/cli.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/completions.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/costs.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/done_signal.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/envelope.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/executor.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/handoff.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/hermes.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_bootstrap.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_desktop.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/learning.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/managed_agent.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/memory.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/menu.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/mission.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/plan.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/project.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/prompts.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/provider.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/prune.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/pursue.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/reducer.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/router.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/skill_routing.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/smoke.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/store.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/sync.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/telegram_history.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/tmux.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/tools.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/understand_anything.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/updater.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/validate.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/vault.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/webhooks.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/worker.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/account.py +502 -0
- package/omega/Agentik_Engine/omega_engine/agent_messages.py +167 -0
- package/omega/Agentik_Engine/omega_engine/aisb_chat.py +128 -0
- package/omega/Agentik_Engine/omega_engine/audit_diff.py +99 -0
- package/omega/Agentik_Engine/omega_engine/audit_gate.py +149 -0
- package/omega/Agentik_Engine/omega_engine/audits/__init__.py +60 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/batcher.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/dispatcher.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/generator.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/history.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/pipeline.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/batcher.py +218 -0
- package/omega/Agentik_Engine/omega_engine/audits/dispatcher.py +92 -0
- package/omega/Agentik_Engine/omega_engine/audits/generator.py +234 -0
- package/omega/Agentik_Engine/omega_engine/audits/history.py +168 -0
- package/omega/Agentik_Engine/omega_engine/audits/pipeline.py +198 -0
- package/omega/Agentik_Engine/omega_engine/auto_update.py +339 -0
- package/omega/Agentik_Engine/omega_engine/autonomous.py +538 -0
- package/omega/Agentik_Engine/omega_engine/backup.py +215 -0
- package/omega/Agentik_Engine/omega_engine/cadence.py +158 -0
- package/omega/Agentik_Engine/omega_engine/classifier.py +215 -0
- package/omega/Agentik_Engine/omega_engine/cleanup.py +673 -0
- package/omega/Agentik_Engine/omega_engine/cli.py +4564 -56
- package/omega/Agentik_Engine/omega_engine/completions.py +260 -0
- package/omega/Agentik_Engine/omega_engine/costs.py +100 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__init__.py +14 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/autonomous.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/engine.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/telegram.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/autonomous.py +56 -0
- package/omega/Agentik_Engine/omega_engine/daemons/engine.py +236 -0
- package/omega/Agentik_Engine/omega_engine/daemons/telegram.py +315 -0
- package/omega/Agentik_Engine/omega_engine/done_signal.py +154 -0
- package/omega/Agentik_Engine/omega_engine/educators/__init__.py +51 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/artifact.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/automation.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/base.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/claudecode.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/connection.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/coworker.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/loop.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/prompt.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/skill.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/artifact.py +65 -0
- package/omega/Agentik_Engine/omega_engine/educators/automation.py +76 -0
- package/omega/Agentik_Engine/omega_engine/educators/base.py +327 -0
- package/omega/Agentik_Engine/omega_engine/educators/claudecode.py +71 -0
- package/omega/Agentik_Engine/omega_engine/educators/connection.py +75 -0
- package/omega/Agentik_Engine/omega_engine/educators/coworker.py +68 -0
- package/omega/Agentik_Engine/omega_engine/educators/loop.py +82 -0
- package/omega/Agentik_Engine/omega_engine/educators/prompt.py +68 -0
- package/omega/Agentik_Engine/omega_engine/educators/skill.py +69 -0
- package/omega/Agentik_Engine/omega_engine/envelope.py +219 -0
- package/omega/Agentik_Engine/omega_engine/executor.py +195 -16
- package/omega/Agentik_Engine/omega_engine/genesis/__init__.py +134 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/orchestrator.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/phases.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/stack.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/state.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/orchestrator.py +262 -0
- package/omega/Agentik_Engine/omega_engine/genesis/phases.py +950 -0
- package/omega/Agentik_Engine/omega_engine/genesis/stack.py +324 -0
- package/omega/Agentik_Engine/omega_engine/genesis/state.py +353 -0
- package/omega/Agentik_Engine/omega_engine/handoff.py +459 -0
- package/omega/Agentik_Engine/omega_engine/hermes.py +426 -0
- package/omega/Agentik_Engine/omega_engine/hermes_bootstrap.py +382 -0
- package/omega/Agentik_Engine/omega_engine/hermes_desktop.py +469 -0
- package/omega/Agentik_Engine/omega_engine/integrations/__init__.py +30 -0
- package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/graphify.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/integrations/graphify.py +234 -0
- package/omega/Agentik_Engine/omega_engine/learning.py +268 -0
- package/omega/Agentik_Engine/omega_engine/managed_agent.py +467 -0
- package/omega/Agentik_Engine/omega_engine/memory.py +271 -0
- package/omega/Agentik_Engine/omega_engine/menu.py +1065 -0
- package/omega/Agentik_Engine/omega_engine/migrations/__init__.py +144 -0
- package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/v0_14_0.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/migrations/v0_14_0.py +29 -0
- package/omega/Agentik_Engine/omega_engine/mission.py +29 -14
- package/omega/Agentik_Engine/omega_engine/plan.py +846 -0
- package/omega/Agentik_Engine/omega_engine/prompts.py +158 -0
- package/omega/Agentik_Engine/omega_engine/provider.py +408 -13
- package/omega/Agentik_Engine/omega_engine/prune.py +151 -0
- package/omega/Agentik_Engine/omega_engine/pursue.py +205 -0
- package/omega/Agentik_Engine/omega_engine/rag/__init__.py +21 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/agentic.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/base.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/corrective.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/graph.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/hybrid.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/multimodal.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/router.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/agentic.py +83 -0
- package/omega/Agentik_Engine/omega_engine/rag/base.py +42 -0
- package/omega/Agentik_Engine/omega_engine/rag/corrective.py +119 -0
- package/omega/Agentik_Engine/omega_engine/rag/graph.py +169 -0
- package/omega/Agentik_Engine/omega_engine/rag/hybrid.py +205 -0
- package/omega/Agentik_Engine/omega_engine/rag/multimodal.py +136 -0
- package/omega/Agentik_Engine/omega_engine/rag/router.py +110 -0
- package/omega/Agentik_Engine/omega_engine/reducer.py +21 -3
- package/omega/Agentik_Engine/omega_engine/router.py +28 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__init__.py +48 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/auditor.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/finder.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/installer.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/marketplaces.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/auditor.py +232 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/finder.py +94 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/installer.py +129 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/marketplaces.py +80 -0
- package/omega/Agentik_Engine/omega_engine/skill_routing.py +388 -0
- package/omega/Agentik_Engine/omega_engine/smoke.py +81 -0
- package/omega/Agentik_Engine/omega_engine/store.py +132 -25
- package/omega/Agentik_Engine/omega_engine/sync.py +445 -0
- package/omega/Agentik_Engine/omega_engine/telegram_history.py +260 -0
- package/omega/Agentik_Engine/omega_engine/tmux.py +526 -0
- package/omega/Agentik_Engine/omega_engine/tools.py +272 -0
- package/omega/Agentik_Engine/omega_engine/understand_anything.py +275 -0
- package/omega/Agentik_Engine/omega_engine/updater.py +70 -0
- package/omega/Agentik_Engine/omega_engine/validate.py +186 -0
- package/omega/Agentik_Engine/omega_engine/vault.py +342 -0
- package/omega/Agentik_Engine/omega_engine/webhooks.py +262 -0
- package/omega/Agentik_Engine/omega_engine/worker.py +526 -0
- package/omega/Agentik_Engine/pyproject.toml +1 -1
- package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_audit_arsenal.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_executor.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_mission.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_progress.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_project.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_reducer.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_report.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/test_account.py +338 -0
- package/omega/Agentik_Engine/tests/test_adversarial.py +351 -0
- package/omega/Agentik_Engine/tests/test_agents_envelope.py +274 -0
- package/omega/Agentik_Engine/tests/test_audits_pipeline.py +348 -0
- package/omega/Agentik_Engine/tests/test_auto_update_and_migrations.py +394 -0
- package/omega/Agentik_Engine/tests/test_autonomous.py +361 -0
- package/omega/Agentik_Engine/tests/test_educators.py +233 -0
- package/omega/Agentik_Engine/tests/test_genesis_and_plan.py +573 -0
- package/omega/Agentik_Engine/tests/test_graphify.py +190 -0
- package/omega/Agentik_Engine/tests/test_handoff.py +311 -0
- package/omega/Agentik_Engine/tests/test_hermes_and_ua.py +387 -0
- package/omega/Agentik_Engine/tests/test_hermes_bootstrap_and_desktop.py +358 -0
- package/omega/Agentik_Engine/tests/test_install_steps.py +359 -0
- package/omega/Agentik_Engine/tests/test_install_ux.py +151 -0
- package/omega/Agentik_Engine/tests/test_installer_wiring.py +496 -0
- package/omega/Agentik_Engine/tests/test_intelligence.py +285 -0
- package/omega/Agentik_Engine/tests/test_llm_clis_and_uninstall.py +228 -0
- package/omega/Agentik_Engine/tests/test_managed_agent.py +363 -0
- package/omega/Agentik_Engine/tests/test_max_provider_and_menu.py +231 -0
- package/omega/Agentik_Engine/tests/test_menu_coverage.py +72 -0
- package/omega/Agentik_Engine/tests/test_pursue_cadence.py +217 -0
- package/omega/Agentik_Engine/tests/test_rag.py +287 -0
- package/omega/Agentik_Engine/tests/test_role_aliases_and_ssot.py +207 -0
- package/omega/Agentik_Engine/tests/test_skill_discovery_and_gate.py +337 -0
- package/omega/Agentik_Engine/tests/test_skill_power.py +259 -0
- package/omega/Agentik_Engine/tests/test_skill_routing.py +189 -0
- package/omega/Agentik_Engine/tests/test_snapshot_partial.py +172 -0
- package/omega/Agentik_Engine/tests/test_telegram_history.py +209 -0
- package/omega/Agentik_Engine/tests/test_tmux_and_aisb_chat.py +223 -0
- package/omega/Agentik_Engine/tests/test_tools_and_sync.py +312 -0
- package/omega/Agentik_Engine/tests/test_v06_features.py +370 -0
- package/omega/Agentik_Engine/tests/test_vault.py +173 -0
- package/omega/Agentik_Engine/tests/test_webhooks_and_readiness.py +277 -0
- package/omega/Agentik_Engine/tests/test_worker_and_cleanup.py +541 -0
- package/omega/Agentik_Extra/etc/secrets/.vault-key +3 -0
- package/omega/Agentik_Extra/etc/secrets/.vault-pub +1 -0
- package/omega/Agentik_Runtime/audits.db +0 -0
- package/omega/Agentik_SSOT/VERSION +1 -1
- package/omega/Agentik_SSOT/claude-plugins/claude-plugins.yaml +100 -0
- package/omega/Agentik_SSOT/docs/LAYERS.md +90 -0
- package/omega/Agentik_SSOT/docs/USER-JOURNEY.md +283 -0
- package/omega/Agentik_SSOT/marketplaces/design-discipline.yaml +86 -0
- package/omega/Agentik_SSOT/skills/a11yaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/apiaudit/SKILL.md +157 -0
- package/omega/Agentik_SSOT/skills/automationaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/cadence/SKILL.md +76 -0
- package/omega/Agentik_SSOT/skills/codeaudit/SKILL.md +153 -0
- package/omega/Agentik_SSOT/skills/copyaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/dataaudit/SKILL.md +157 -0
- package/omega/Agentik_SSOT/skills/debugaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/dispatch/SKILL.md +79 -0
- package/omega/Agentik_SSOT/skills/dxaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/featureaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/flowaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/genesis/SKILL.md +116 -0
- package/omega/Agentik_SSOT/skills/handoff/SKILL.md +117 -0
- package/omega/Agentik_SSOT/skills/logicaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/motionaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/perfaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/plan/SKILL.md +127 -0
- package/omega/Agentik_SSOT/skills/pursue/SKILL.md +68 -0
- package/omega/Agentik_SSOT/skills/rag-route.md +82 -0
- package/omega/Agentik_SSOT/skills/refontaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/retentionaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/secaudit/SKILL.md +157 -0
- package/omega/Agentik_SSOT/skills/seoaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/skill-auditor/SKILL.md +83 -0
- package/omega/Agentik_SSOT/skills/skill-finder/SKILL.md +116 -0
- package/omega/Agentik_SSOT/skills/uiuxaudit/SKILL.md +165 -0
- package/package.json +2 -2
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
"""Adversarial test suite — proves the fixes for the bugs caught during
|
|
2
|
+
the 'inverse audit' pass:
|
|
3
|
+
|
|
4
|
+
C1. Command injection via task_id in spawn_worker (CRITICAL)
|
|
5
|
+
H1. SQLiteStore breaks when used from multiple threads (HIGH)
|
|
6
|
+
H2. .done.json + brief.json non-atomic writes (HIGH)
|
|
7
|
+
H4. Empty mission intent accepted silently (HIGH)
|
|
8
|
+
M1. Webhook replay window absent (MEDIUM)
|
|
9
|
+
|
|
10
|
+
Each test FIRST proves the bug existed in the spirit of the failure and
|
|
11
|
+
THEN proves the fix holds.
|
|
12
|
+
"""
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import json
|
|
16
|
+
import os
|
|
17
|
+
import subprocess
|
|
18
|
+
import sys
|
|
19
|
+
import tempfile
|
|
20
|
+
import threading
|
|
21
|
+
import time
|
|
22
|
+
import unittest
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
from unittest import mock
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
HERE = Path(__file__).resolve().parent
|
|
28
|
+
sys.path.insert(0, str(HERE.parent))
|
|
29
|
+
|
|
30
|
+
from omega_engine import worker as W # noqa: E402
|
|
31
|
+
from omega_engine.done_signal import ( # noqa: E402
|
|
32
|
+
DoneSignal, done_path, read_done, write_done,
|
|
33
|
+
)
|
|
34
|
+
from omega_engine.store import SQLiteStore # noqa: E402
|
|
35
|
+
from omega_engine.events import Event, EventType # noqa: E402
|
|
36
|
+
from omega_engine import webhooks as WH # noqa: E402
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# ---------------------------------------------------------------------------
|
|
40
|
+
# C1 — Command injection in spawn_worker(task_id=...)
|
|
41
|
+
# ---------------------------------------------------------------------------
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class TestTaskIdInjectionGuard(unittest.TestCase):
|
|
45
|
+
def test_validate_accepts_normal_ids(self):
|
|
46
|
+
for ok in ("t-1", "t_abc.42", "task-2026-05-23-7f3a", "x" * 128):
|
|
47
|
+
self.assertEqual(W._validate_task_id(ok), ok)
|
|
48
|
+
|
|
49
|
+
def test_validate_rejects_semicolon_injection(self):
|
|
50
|
+
with self.assertRaises(ValueError):
|
|
51
|
+
W._validate_task_id("t; touch /tmp/PWNED")
|
|
52
|
+
|
|
53
|
+
def test_validate_rejects_command_substitution(self):
|
|
54
|
+
with self.assertRaises(ValueError):
|
|
55
|
+
W._validate_task_id("t$(rm -rf /)")
|
|
56
|
+
|
|
57
|
+
def test_validate_rejects_pipe(self):
|
|
58
|
+
with self.assertRaises(ValueError):
|
|
59
|
+
W._validate_task_id("t|rm -rf /")
|
|
60
|
+
|
|
61
|
+
def test_validate_rejects_backtick(self):
|
|
62
|
+
with self.assertRaises(ValueError):
|
|
63
|
+
W._validate_task_id("t`whoami`")
|
|
64
|
+
|
|
65
|
+
def test_validate_rejects_space(self):
|
|
66
|
+
with self.assertRaises(ValueError):
|
|
67
|
+
W._validate_task_id("t and more")
|
|
68
|
+
|
|
69
|
+
def test_validate_rejects_path_traversal(self):
|
|
70
|
+
with self.assertRaises(ValueError):
|
|
71
|
+
W._validate_task_id("../../etc/passwd")
|
|
72
|
+
|
|
73
|
+
def test_validate_rejects_empty(self):
|
|
74
|
+
with self.assertRaises(ValueError):
|
|
75
|
+
W._validate_task_id("")
|
|
76
|
+
|
|
77
|
+
def test_validate_rejects_too_long(self):
|
|
78
|
+
with self.assertRaises(ValueError):
|
|
79
|
+
W._validate_task_id("x" * 129)
|
|
80
|
+
|
|
81
|
+
def test_spawn_refuses_injection(self):
|
|
82
|
+
"""The real attack vector — spawn_worker must reject before tmux."""
|
|
83
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
84
|
+
brief = W.WorkerBrief(
|
|
85
|
+
task_id="t; touch /tmp/SHOULD_NEVER_HAPPEN",
|
|
86
|
+
role="worker", intent="x",
|
|
87
|
+
)
|
|
88
|
+
with self.assertRaises(ValueError):
|
|
89
|
+
W.spawn_worker(brief, home=Path(tmp))
|
|
90
|
+
|
|
91
|
+
def test_write_brief_refuses_injection(self):
|
|
92
|
+
"""write_brief is the second line of defence (defence-in-depth)."""
|
|
93
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
94
|
+
# Construct via __init__ (no validator on the dataclass itself)
|
|
95
|
+
brief = W.WorkerBrief(
|
|
96
|
+
task_id="t$(id)", role="worker", intent="x",
|
|
97
|
+
)
|
|
98
|
+
with self.assertRaises(ValueError):
|
|
99
|
+
W.write_brief(Path(tmp), brief)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
# ---------------------------------------------------------------------------
|
|
103
|
+
# H1 — SQLiteStore concurrent access
|
|
104
|
+
# ---------------------------------------------------------------------------
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class TestStoreThreadSafety(unittest.TestCase):
|
|
108
|
+
def test_5_threads_append_without_error(self):
|
|
109
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
110
|
+
s = SQLiteStore(str(Path(tmp) / "concurrent.db"))
|
|
111
|
+
errors: list[str] = []
|
|
112
|
+
|
|
113
|
+
def worker(n: int) -> None:
|
|
114
|
+
try:
|
|
115
|
+
for i in range(10):
|
|
116
|
+
s.append(Event(
|
|
117
|
+
id=f"e-{n}-{i}-{time.time_ns()}",
|
|
118
|
+
task_id=f"t-{n}",
|
|
119
|
+
type=EventType.HEARTBEAT,
|
|
120
|
+
ts=time.time(),
|
|
121
|
+
payload={"n": n, "i": i},
|
|
122
|
+
))
|
|
123
|
+
except Exception as exc: # noqa: BLE001
|
|
124
|
+
errors.append(f"{n}: {type(exc).__name__}: {exc}")
|
|
125
|
+
|
|
126
|
+
threads = [threading.Thread(target=worker, args=(n,))
|
|
127
|
+
for n in range(5)]
|
|
128
|
+
for t in threads:
|
|
129
|
+
t.start()
|
|
130
|
+
for t in threads:
|
|
131
|
+
t.join()
|
|
132
|
+
self.assertEqual(errors, [], f"unexpected errors: {errors}")
|
|
133
|
+
# 5 threads × 10 events each = 50 events
|
|
134
|
+
count = sum(1 for _ in s.all_events())
|
|
135
|
+
self.assertEqual(count, 50)
|
|
136
|
+
s.close()
|
|
137
|
+
|
|
138
|
+
def test_close_is_safe_to_call_twice(self):
|
|
139
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
140
|
+
s = SQLiteStore(str(Path(tmp) / "db.db"))
|
|
141
|
+
s.close()
|
|
142
|
+
# Second close MUST not raise — best-effort.
|
|
143
|
+
s.close()
|
|
144
|
+
|
|
145
|
+
def test_reads_under_concurrent_writes(self):
|
|
146
|
+
"""Reader threads must not see a malformed or torn row."""
|
|
147
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
148
|
+
s = SQLiteStore(str(Path(tmp) / "readwrite.db"))
|
|
149
|
+
stop = threading.Event()
|
|
150
|
+
|
|
151
|
+
def writer():
|
|
152
|
+
i = 0
|
|
153
|
+
while not stop.is_set():
|
|
154
|
+
try:
|
|
155
|
+
s.append(Event(
|
|
156
|
+
id=f"w-{i}-{time.time_ns()}",
|
|
157
|
+
task_id="t-shared",
|
|
158
|
+
type=EventType.HEARTBEAT,
|
|
159
|
+
ts=time.time(), payload={"i": i},
|
|
160
|
+
))
|
|
161
|
+
except Exception: # noqa: BLE001
|
|
162
|
+
pass
|
|
163
|
+
i += 1
|
|
164
|
+
|
|
165
|
+
errors: list[str] = []
|
|
166
|
+
|
|
167
|
+
def reader():
|
|
168
|
+
try:
|
|
169
|
+
for _ in range(20):
|
|
170
|
+
s.events_for("t-shared")
|
|
171
|
+
except Exception as exc: # noqa: BLE001
|
|
172
|
+
errors.append(f"{type(exc).__name__}: {exc}")
|
|
173
|
+
|
|
174
|
+
wt = threading.Thread(target=writer)
|
|
175
|
+
rts = [threading.Thread(target=reader) for _ in range(3)]
|
|
176
|
+
wt.start()
|
|
177
|
+
for rt in rts:
|
|
178
|
+
rt.start()
|
|
179
|
+
for rt in rts:
|
|
180
|
+
rt.join()
|
|
181
|
+
stop.set()
|
|
182
|
+
wt.join()
|
|
183
|
+
self.assertEqual(errors, [])
|
|
184
|
+
s.close()
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
# ---------------------------------------------------------------------------
|
|
188
|
+
# H2 — Atomic writes for .done.json + brief.json
|
|
189
|
+
# ---------------------------------------------------------------------------
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
class TestAtomicWrites(unittest.TestCase):
|
|
193
|
+
def test_done_json_writes_atomically(self):
|
|
194
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
195
|
+
sig = DoneSignal(status="done_clean", summary="ok",
|
|
196
|
+
files_changed=["a.py"])
|
|
197
|
+
p = write_done(Path(tmp), "t-atom", sig)
|
|
198
|
+
# The temp file used during the write must not linger.
|
|
199
|
+
self.assertFalse(p.with_suffix(p.suffix + ".tmp").exists())
|
|
200
|
+
loaded = read_done(Path(tmp), "t-atom")
|
|
201
|
+
self.assertEqual(loaded.status, "done_clean")
|
|
202
|
+
|
|
203
|
+
def test_brief_json_writes_atomically(self):
|
|
204
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
205
|
+
brief = W.WorkerBrief(task_id="t-atom", role="worker", intent="x")
|
|
206
|
+
p = W.write_brief(Path(tmp), brief)
|
|
207
|
+
self.assertFalse(p.with_suffix(p.suffix + ".tmp").exists())
|
|
208
|
+
self.assertEqual(
|
|
209
|
+
W.read_brief(Path(tmp), "t-atom").task_id, "t-atom"
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
def test_done_json_round_trip_no_torn_read_under_overwrite(self):
|
|
213
|
+
"""Repeatedly overwrite while a parallel reader polls. With the
|
|
214
|
+
atomic write, the reader either sees the old JSON or the new JSON
|
|
215
|
+
— never a half-blob that would raise JSONDecodeError."""
|
|
216
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
217
|
+
sig1 = DoneSignal(status="done_clean", summary="v1")
|
|
218
|
+
write_done(Path(tmp), "t-loop", sig1)
|
|
219
|
+
errors: list[str] = []
|
|
220
|
+
stop = threading.Event()
|
|
221
|
+
|
|
222
|
+
def writer():
|
|
223
|
+
for i in range(50):
|
|
224
|
+
write_done(Path(tmp), "t-loop",
|
|
225
|
+
DoneSignal(status="done_clean",
|
|
226
|
+
summary=f"v{i}"))
|
|
227
|
+
|
|
228
|
+
def reader():
|
|
229
|
+
while not stop.is_set():
|
|
230
|
+
try:
|
|
231
|
+
read_done(Path(tmp), "t-loop")
|
|
232
|
+
except Exception as exc: # noqa: BLE001
|
|
233
|
+
errors.append(f"{type(exc).__name__}: {exc}")
|
|
234
|
+
|
|
235
|
+
rts = [threading.Thread(target=reader) for _ in range(3)]
|
|
236
|
+
for rt in rts:
|
|
237
|
+
rt.start()
|
|
238
|
+
wt = threading.Thread(target=writer)
|
|
239
|
+
wt.start()
|
|
240
|
+
wt.join()
|
|
241
|
+
stop.set()
|
|
242
|
+
for rt in rts:
|
|
243
|
+
rt.join()
|
|
244
|
+
self.assertEqual(errors, [], f"torn-read errors: {errors[:3]}")
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
# ---------------------------------------------------------------------------
|
|
248
|
+
# H4 — Empty intent rejected at CLI level
|
|
249
|
+
# ---------------------------------------------------------------------------
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
class TestEmptyIntentRejected(unittest.TestCase):
|
|
253
|
+
def test_cli_run_empty_intent_returns_nonzero(self):
|
|
254
|
+
# Invoke the CLI through subprocess so we exercise argparse + cmd_run
|
|
255
|
+
# in a real shell — no MockProvider gymnastics.
|
|
256
|
+
repo = Path(__file__).resolve().parents[1]
|
|
257
|
+
env = {**os.environ, "OMEGA_HOME": "/tmp/omega-empty-test"}
|
|
258
|
+
Path("/tmp/omega-empty-test").mkdir(exist_ok=True)
|
|
259
|
+
proc = subprocess.run(
|
|
260
|
+
[sys.executable, "-m", "omega_engine.cli", "run", ""],
|
|
261
|
+
cwd=str(repo), env=env, capture_output=True, text=True,
|
|
262
|
+
timeout=20,
|
|
263
|
+
)
|
|
264
|
+
self.assertNotEqual(proc.returncode, 0,
|
|
265
|
+
f"empty intent should be rejected: {proc.stdout!r} {proc.stderr!r}")
|
|
266
|
+
self.assertIn("empty", (proc.stdout + proc.stderr).lower())
|
|
267
|
+
|
|
268
|
+
def test_cli_run_whitespace_intent_returns_nonzero(self):
|
|
269
|
+
repo = Path(__file__).resolve().parents[1]
|
|
270
|
+
env = {**os.environ, "OMEGA_HOME": "/tmp/omega-empty-test"}
|
|
271
|
+
Path("/tmp/omega-empty-test").mkdir(exist_ok=True)
|
|
272
|
+
proc = subprocess.run(
|
|
273
|
+
[sys.executable, "-m", "omega_engine.cli", "run", " "],
|
|
274
|
+
cwd=str(repo), env=env, capture_output=True, text=True,
|
|
275
|
+
timeout=20,
|
|
276
|
+
)
|
|
277
|
+
self.assertNotEqual(proc.returncode, 0)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
# ---------------------------------------------------------------------------
|
|
281
|
+
# M1 — Webhook replay protection
|
|
282
|
+
# ---------------------------------------------------------------------------
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
class TestWebhookReplayProtection(unittest.TestCase):
|
|
286
|
+
def setUp(self):
|
|
287
|
+
self.secret = "test-secret-deadbeef"
|
|
288
|
+
self.body = b'{"event":"push","ref":"main"}'
|
|
289
|
+
self.sig = WH.generate_test_signature(
|
|
290
|
+
"generic", self.body, self.secret,
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
def test_no_timestamp_still_accepts_valid_sig_backwards_compat(self):
|
|
294
|
+
"""v0.5 contract: HMAC alone is enough."""
|
|
295
|
+
ok, reason = WH.verify_signature(
|
|
296
|
+
"generic", self.body, self.sig, self.secret,
|
|
297
|
+
)
|
|
298
|
+
self.assertTrue(ok, reason)
|
|
299
|
+
|
|
300
|
+
def test_fresh_timestamp_within_window_passes(self):
|
|
301
|
+
ts = str(int(time.time()))
|
|
302
|
+
ok, reason = WH.verify_signature(
|
|
303
|
+
"generic", self.body, self.sig, self.secret,
|
|
304
|
+
timestamp_header_value=ts,
|
|
305
|
+
)
|
|
306
|
+
self.assertTrue(ok, reason)
|
|
307
|
+
|
|
308
|
+
def test_old_timestamp_rejected_replay(self):
|
|
309
|
+
old_ts = str(int(time.time() - 600)) # 10 min ago
|
|
310
|
+
ok, reason = WH.verify_signature(
|
|
311
|
+
"generic", self.body, self.sig, self.secret,
|
|
312
|
+
timestamp_header_value=old_ts,
|
|
313
|
+
)
|
|
314
|
+
self.assertFalse(ok)
|
|
315
|
+
self.assertIn("replay window", reason)
|
|
316
|
+
|
|
317
|
+
def test_future_timestamp_rejected(self):
|
|
318
|
+
future_ts = str(int(time.time() + 600))
|
|
319
|
+
ok, reason = WH.verify_signature(
|
|
320
|
+
"generic", self.body, self.sig, self.secret,
|
|
321
|
+
timestamp_header_value=future_ts,
|
|
322
|
+
)
|
|
323
|
+
self.assertFalse(ok)
|
|
324
|
+
self.assertIn("replay window", reason)
|
|
325
|
+
|
|
326
|
+
def test_garbage_timestamp_rejected(self):
|
|
327
|
+
ok, reason = WH.verify_signature(
|
|
328
|
+
"generic", self.body, self.sig, self.secret,
|
|
329
|
+
timestamp_header_value="not-a-number",
|
|
330
|
+
)
|
|
331
|
+
self.assertFalse(ok)
|
|
332
|
+
self.assertIn("numeric", reason)
|
|
333
|
+
|
|
334
|
+
def test_configurable_window(self):
|
|
335
|
+
old_ts = str(int(time.time() - 60)) # 60s ago
|
|
336
|
+
# Default 300s window → ok
|
|
337
|
+
ok, _ = WH.verify_signature(
|
|
338
|
+
"generic", self.body, self.sig, self.secret,
|
|
339
|
+
timestamp_header_value=old_ts,
|
|
340
|
+
)
|
|
341
|
+
self.assertTrue(ok)
|
|
342
|
+
# Tighter 30s window → rejected
|
|
343
|
+
ok, reason = WH.verify_signature(
|
|
344
|
+
"generic", self.body, self.sig, self.secret,
|
|
345
|
+
timestamp_header_value=old_ts, replay_window_s=30,
|
|
346
|
+
)
|
|
347
|
+
self.assertFalse(ok)
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
if __name__ == "__main__":
|
|
351
|
+
unittest.main()
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
"""Tests for the AISB agent suite plumbing.
|
|
2
|
+
|
|
3
|
+
Three things to exercise:
|
|
4
|
+
|
|
5
|
+
1. ``omega_engine.prompts.load_agent_prompt`` reads the right file, strips
|
|
6
|
+
YAML frontmatter, and appends LMC + shared protocols when present.
|
|
7
|
+
2. ``omega_engine.envelope.build_envelope`` produces a ``{system, user}``
|
|
8
|
+
pair: the system holds the agent prompt + the right orchestration
|
|
9
|
+
contract; the user holds the verbatim intent + structured context.
|
|
10
|
+
3. ``omega_engine.done_signal`` round-trips a worker's completion JSON,
|
|
11
|
+
rejects invalid statuses, and lets the verifier attach an audit.
|
|
12
|
+
"""
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import json
|
|
16
|
+
import sys
|
|
17
|
+
import tempfile
|
|
18
|
+
import unittest
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
HERE = Path(__file__).resolve().parent
|
|
23
|
+
sys.path.insert(0, str(HERE.parent))
|
|
24
|
+
|
|
25
|
+
from omega_engine.done_signal import ( # noqa: E402
|
|
26
|
+
DoneSignal,
|
|
27
|
+
DoneSignalError,
|
|
28
|
+
attach_audit_to_done,
|
|
29
|
+
read_done,
|
|
30
|
+
write_done,
|
|
31
|
+
)
|
|
32
|
+
from omega_engine.envelope import ( # noqa: E402
|
|
33
|
+
DISPATCHER_ROLES,
|
|
34
|
+
EXECUTOR_ROLES,
|
|
35
|
+
EnvelopeContext,
|
|
36
|
+
VERIFIER_ROLES,
|
|
37
|
+
build_envelope,
|
|
38
|
+
)
|
|
39
|
+
from omega_engine.prompts import ( # noqa: E402
|
|
40
|
+
clear_cache,
|
|
41
|
+
find_agent_file,
|
|
42
|
+
list_available_agents,
|
|
43
|
+
load_agent_prompt,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _seed_aisb(home: Path, role: str, body: str, *,
|
|
48
|
+
with_lmc: bool = False) -> None:
|
|
49
|
+
suite = home / "Agentik_SSOT" / "agents" / "aisb"
|
|
50
|
+
suite.mkdir(parents=True, exist_ok=True)
|
|
51
|
+
(suite / f"{role}.md").write_text(body)
|
|
52
|
+
if with_lmc:
|
|
53
|
+
(suite / "lmc-protocol.md").write_text(
|
|
54
|
+
"## LMC PROTOCOL\n\nLead → Manager → Checker."
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class TestPrompts(unittest.TestCase):
|
|
59
|
+
def setUp(self):
|
|
60
|
+
clear_cache()
|
|
61
|
+
|
|
62
|
+
def test_load_returns_none_when_no_file(self):
|
|
63
|
+
with tempfile.TemporaryDirectory() as td:
|
|
64
|
+
self.assertIsNone(load_agent_prompt(td, "oracle"))
|
|
65
|
+
|
|
66
|
+
def test_load_strips_yaml_frontmatter(self):
|
|
67
|
+
with tempfile.TemporaryDirectory() as td:
|
|
68
|
+
home = Path(td)
|
|
69
|
+
_seed_aisb(home, "oracle",
|
|
70
|
+
"---\nname: oracle\n---\n# ORACLE\n\nI orchestrate.")
|
|
71
|
+
text = load_agent_prompt(home, "oracle")
|
|
72
|
+
self.assertIsNotNone(text)
|
|
73
|
+
self.assertNotIn("---", text)
|
|
74
|
+
self.assertIn("# ORACLE", text)
|
|
75
|
+
|
|
76
|
+
def test_load_appends_lmc(self):
|
|
77
|
+
with tempfile.TemporaryDirectory() as td:
|
|
78
|
+
home = Path(td)
|
|
79
|
+
_seed_aisb(home, "architect", "# ARCHITECT", with_lmc=True)
|
|
80
|
+
text = load_agent_prompt(home, "architect")
|
|
81
|
+
self.assertIn("# ARCHITECT", text)
|
|
82
|
+
self.assertIn("LMC PROTOCOL", text)
|
|
83
|
+
|
|
84
|
+
def test_find_file_aisb_takes_priority(self):
|
|
85
|
+
with tempfile.TemporaryDirectory() as td:
|
|
86
|
+
home = Path(td)
|
|
87
|
+
_seed_aisb(home, "oracle", "# AISB-ORACLE")
|
|
88
|
+
other = home / "Agentik_SSOT" / "agents" / "custom"
|
|
89
|
+
other.mkdir(parents=True)
|
|
90
|
+
(other / "oracle.md").write_text("# CUSTOM-ORACLE")
|
|
91
|
+
path = find_agent_file(home, "oracle")
|
|
92
|
+
self.assertIn("aisb", str(path))
|
|
93
|
+
|
|
94
|
+
def test_list_available_agents(self):
|
|
95
|
+
with tempfile.TemporaryDirectory() as td:
|
|
96
|
+
home = Path(td)
|
|
97
|
+
for r in ("oracle", "architect", "keymaker"):
|
|
98
|
+
_seed_aisb(home, r, f"# {r.upper()}")
|
|
99
|
+
# Also a non-role-looking file that should be excluded.
|
|
100
|
+
(home / "Agentik_SSOT" / "agents" / "aisb" / "CLAUDE.md").write_text("x")
|
|
101
|
+
(home / "Agentik_SSOT" / "agents" / "aisb" / "checker-oracle.md").write_text("x")
|
|
102
|
+
agents = list_available_agents(home)
|
|
103
|
+
self.assertIn("aisb", agents)
|
|
104
|
+
self.assertIn("oracle", agents["aisb"])
|
|
105
|
+
self.assertIn("architect", agents["aisb"])
|
|
106
|
+
self.assertNotIn("CLAUDE", agents["aisb"])
|
|
107
|
+
self.assertNotIn("checker-oracle", agents["aisb"])
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class TestEnvelope(unittest.TestCase):
|
|
111
|
+
def setUp(self):
|
|
112
|
+
clear_cache()
|
|
113
|
+
|
|
114
|
+
def test_envelope_loads_agent_and_dispatcher_contract(self):
|
|
115
|
+
with tempfile.TemporaryDirectory() as td:
|
|
116
|
+
home = Path(td)
|
|
117
|
+
_seed_aisb(home, "oracle", "# ORACLE — I orchestrate.")
|
|
118
|
+
ctx = EnvelopeContext(
|
|
119
|
+
role="oracle",
|
|
120
|
+
intent="Fix the login bug",
|
|
121
|
+
task_id="t-1",
|
|
122
|
+
mission_id="m-1",
|
|
123
|
+
)
|
|
124
|
+
env = build_envelope(home, ctx)
|
|
125
|
+
self.assertIn("ORACLE", env["system"])
|
|
126
|
+
self.assertIn("ORCHESTRATION CONTRACT (dispatcher)", env["system"])
|
|
127
|
+
self.assertIn("Fix the login bug", env["user"])
|
|
128
|
+
|
|
129
|
+
def test_envelope_worker_gets_done_json_contract(self):
|
|
130
|
+
with tempfile.TemporaryDirectory() as td:
|
|
131
|
+
home = Path(td)
|
|
132
|
+
_seed_aisb(home, "worker", "# WORKER")
|
|
133
|
+
ctx = EnvelopeContext(
|
|
134
|
+
role="worker", intent="Implement X",
|
|
135
|
+
done_json_path="/tmp/foo/.done.json",
|
|
136
|
+
verify_cmd="pytest tests/test_foo.py",
|
|
137
|
+
)
|
|
138
|
+
env = build_envelope(home, ctx)
|
|
139
|
+
self.assertIn("ORCHESTRATION CONTRACT (executor / worker)", env["system"])
|
|
140
|
+
self.assertIn("/tmp/foo/.done.json", env["system"])
|
|
141
|
+
self.assertIn("Implement X", env["user"])
|
|
142
|
+
self.assertIn("pytest tests/test_foo.py", env["user"])
|
|
143
|
+
|
|
144
|
+
def test_envelope_verifier_gets_verifier_contract(self):
|
|
145
|
+
with tempfile.TemporaryDirectory() as td:
|
|
146
|
+
home = Path(td)
|
|
147
|
+
_seed_aisb(home, "seraph", "# SERAPH")
|
|
148
|
+
ctx = EnvelopeContext(role="seraph", intent="Verify X")
|
|
149
|
+
env = build_envelope(home, ctx)
|
|
150
|
+
self.assertIn("ORCHESTRATION CONTRACT (verifier)", env["system"])
|
|
151
|
+
|
|
152
|
+
def test_envelope_includes_parent_context(self):
|
|
153
|
+
with tempfile.TemporaryDirectory() as td:
|
|
154
|
+
home = Path(td)
|
|
155
|
+
_seed_aisb(home, "worker", "# WORKER")
|
|
156
|
+
ctx = EnvelopeContext(
|
|
157
|
+
role="worker", intent="Subtask 1",
|
|
158
|
+
parent_role="oracle",
|
|
159
|
+
parent_intent="Fix the cart bug",
|
|
160
|
+
plan_so_far=[{"role": "worker", "spec": {"task": "1"}}],
|
|
161
|
+
)
|
|
162
|
+
env = build_envelope(home, ctx)
|
|
163
|
+
self.assertIn("Fix the cart bug", env["user"])
|
|
164
|
+
self.assertIn("Plan so far", env["user"])
|
|
165
|
+
|
|
166
|
+
def test_role_constants_cover_aisb_agents(self):
|
|
167
|
+
# All canonical AISB roles must fit in exactly one bucket.
|
|
168
|
+
for r in ("aisb", "oracle", "manager", "architect", "keymaker", "morpheus"):
|
|
169
|
+
self.assertIn(r, DISPATCHER_ROLES)
|
|
170
|
+
for r in ("worker", "construct", "link"):
|
|
171
|
+
self.assertIn(r, EXECUTOR_ROLES)
|
|
172
|
+
for r in ("seraph", "audit", "verifier"):
|
|
173
|
+
self.assertIn(r, VERIFIER_ROLES)
|
|
174
|
+
|
|
175
|
+
def test_envelope_falls_back_when_no_agent_file(self):
|
|
176
|
+
with tempfile.TemporaryDirectory() as td:
|
|
177
|
+
home = Path(td) # no agent files seeded
|
|
178
|
+
ctx = EnvelopeContext(role="oracle", intent="X")
|
|
179
|
+
env = build_envelope(home, ctx)
|
|
180
|
+
# Generic identity line is the floor; contract is still appended.
|
|
181
|
+
self.assertIn("ORACLE", env["system"].upper())
|
|
182
|
+
self.assertIn("ORCHESTRATION CONTRACT", env["system"])
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class TestDoneSignal(unittest.TestCase):
|
|
186
|
+
def test_round_trip(self):
|
|
187
|
+
with tempfile.TemporaryDirectory() as td:
|
|
188
|
+
sig = DoneSignal(
|
|
189
|
+
status="done_clean",
|
|
190
|
+
summary="implemented X",
|
|
191
|
+
files_changed=["a.py", "b.py"],
|
|
192
|
+
artifacts={"key": "value"},
|
|
193
|
+
)
|
|
194
|
+
path = write_done(td, "t-42", sig)
|
|
195
|
+
self.assertTrue(path.exists())
|
|
196
|
+
got = read_done(td, "t-42")
|
|
197
|
+
self.assertEqual(got.status, "done_clean")
|
|
198
|
+
self.assertEqual(got.files_changed, ["a.py", "b.py"])
|
|
199
|
+
self.assertEqual(got.artifacts["key"], "value")
|
|
200
|
+
|
|
201
|
+
def test_rejects_invalid_status_on_write(self):
|
|
202
|
+
with tempfile.TemporaryDirectory() as td:
|
|
203
|
+
sig = DoneSignal(status="all_good")
|
|
204
|
+
with self.assertRaises(DoneSignalError):
|
|
205
|
+
write_done(td, "t-1", sig)
|
|
206
|
+
|
|
207
|
+
def test_rejects_invalid_status_on_read(self):
|
|
208
|
+
with tempfile.TemporaryDirectory() as td:
|
|
209
|
+
from omega_engine.done_signal import session_dir
|
|
210
|
+
d = session_dir(td, "t-9")
|
|
211
|
+
(d / ".done.json").write_text(json.dumps({"status": "BAD"}))
|
|
212
|
+
with self.assertRaises(DoneSignalError):
|
|
213
|
+
read_done(td, "t-9")
|
|
214
|
+
|
|
215
|
+
def test_attach_audit_preserves_existing_fields(self):
|
|
216
|
+
with tempfile.TemporaryDirectory() as td:
|
|
217
|
+
sig = DoneSignal(status="pending", summary="halfway",
|
|
218
|
+
files_changed=["x.py"])
|
|
219
|
+
write_done(td, "t-7", sig)
|
|
220
|
+
attach_audit_to_done(td, "t-7", {"verified": True, "score": 95})
|
|
221
|
+
got = read_done(td, "t-7")
|
|
222
|
+
self.assertEqual(got.status, "pending") # unchanged
|
|
223
|
+
self.assertEqual(got.files_changed, ["x.py"])
|
|
224
|
+
self.assertEqual(got.audit["score"], 95)
|
|
225
|
+
self.assertTrue(got.audit["verified"])
|
|
226
|
+
|
|
227
|
+
def test_read_returns_none_when_missing(self):
|
|
228
|
+
with tempfile.TemporaryDirectory() as td:
|
|
229
|
+
self.assertIsNone(read_done(td, "t-missing"))
|
|
230
|
+
|
|
231
|
+
def test_file_mode_is_600(self):
|
|
232
|
+
with tempfile.TemporaryDirectory() as td:
|
|
233
|
+
path = write_done(td, "t-mode", DoneSignal(status="failed"))
|
|
234
|
+
self.assertEqual(path.stat().st_mode & 0o777, 0o600)
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
class TestProjectVault(unittest.TestCase):
|
|
238
|
+
def test_project_vault_isolation(self):
|
|
239
|
+
from omega_engine.vault import (
|
|
240
|
+
list_project_vaults, vault_read, vault_write,
|
|
241
|
+
)
|
|
242
|
+
import shutil as _sh
|
|
243
|
+
|
|
244
|
+
if not (_sh.which("age") and _sh.which("age-keygen")):
|
|
245
|
+
# Plain mode is the test we can run universally.
|
|
246
|
+
pass
|
|
247
|
+
|
|
248
|
+
with tempfile.TemporaryDirectory() as td:
|
|
249
|
+
# Write a secret in the global vault and one in project "alpha".
|
|
250
|
+
vault_write(td, "GLOBAL_X", "global-value")
|
|
251
|
+
vault_write(td, "ALPHA_X", "alpha-value", project="alpha")
|
|
252
|
+
vault_write(td, "BETA_X", "beta-value", project="beta")
|
|
253
|
+
|
|
254
|
+
# Project vaults don't see each other or the global one.
|
|
255
|
+
self.assertEqual(vault_read(td, "ALPHA_X", project="alpha"),
|
|
256
|
+
"alpha-value")
|
|
257
|
+
self.assertIsNone(vault_read(td, "ALPHA_X")) # not in global
|
|
258
|
+
self.assertIsNone(vault_read(td, "ALPHA_X", project="beta"))
|
|
259
|
+
self.assertEqual(vault_read(td, "GLOBAL_X"), "global-value")
|
|
260
|
+
|
|
261
|
+
vaults = list_project_vaults(td)
|
|
262
|
+
slugs = {v["project"] for v in vaults}
|
|
263
|
+
self.assertEqual(slugs, {"alpha", "beta"})
|
|
264
|
+
|
|
265
|
+
def test_project_vault_rejects_traversal(self):
|
|
266
|
+
from omega_engine.vault import vault_write
|
|
267
|
+
with tempfile.TemporaryDirectory() as td:
|
|
268
|
+
for bad in ("../escape", "a/b", "..", ".hidden"):
|
|
269
|
+
with self.assertRaises(ValueError):
|
|
270
|
+
vault_write(td, "X", "v", project=bad)
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
if __name__ == "__main__":
|
|
274
|
+
unittest.main(verbosity=2)
|