arkaos 4.7.1 → 4.9.0
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/VERSION +1 -1
- package/arka/skills/bootstrap-agent/SKILL.md +11 -7
- package/arka/skills/checkpoint/SKILL.md +10 -4
- package/arka/skills/comfyui/SKILL.md +11 -8
- package/arka/skills/conclave/SKILL.md +11 -3
- package/arka/skills/costs/SKILL.md +2 -3
- package/arka/skills/design-ops/SKILL.md +11 -5
- package/arka/skills/dreams/SKILL.md +10 -4
- package/arka/skills/forge/SKILL.md +6 -8
- package/arka/skills/fusion/SKILL.md +11 -7
- package/arka/skills/human-writing/SKILL.md +11 -13
- package/arka/skills/research/SKILL.md +9 -11
- package/config/claude-agents/affiliate-manager.md +50 -0
- package/config/claude-agents/ai-engineering-lead.md +52 -0
- package/config/claude-agents/architect.md +1 -1
- package/config/claude-agents/automation-engineer.md +50 -0
- package/config/claude-agents/brand-director.md +51 -0
- package/config/claude-agents/brand-strategist.md +50 -0
- package/config/claude-agents/business-model-designer.md +50 -0
- package/config/claude-agents/cfo.md +50 -0
- package/config/claude-agents/chief-of-staff.md +51 -0
- package/config/claude-agents/commerce-engineer.md +50 -0
- package/config/claude-agents/community-manager.md +50 -0
- package/config/claude-agents/community-strategist.md +50 -0
- package/config/claude-agents/content-marketer.md +50 -0
- package/config/claude-agents/content-strategist.md +50 -0
- package/config/claude-agents/conversion-strategist.md +50 -0
- package/config/claude-agents/coo.md +50 -0
- package/config/claude-agents/cs-manager.md +50 -0
- package/config/claude-agents/cto.md +51 -0
- package/config/claude-agents/culture-coach.md +50 -0
- package/config/claude-agents/data-collector.md +50 -0
- package/config/claude-agents/decision-quality.md +51 -0
- package/config/claude-agents/design-ops-lead.md +51 -0
- package/config/claude-agents/devops-eng.md +1 -1
- package/config/claude-agents/doc-writer.md +50 -0
- package/config/claude-agents/ecom-cro-specialist.md +50 -0
- package/config/claude-agents/ecom-director.md +50 -0
- package/config/claude-agents/engagement-designer.md +50 -0
- package/config/claude-agents/etl-eng.md +52 -0
- package/config/claude-agents/extraction-script-writer.md +51 -0
- package/config/claude-agents/financial-analyst.md +49 -0
- package/config/claude-agents/growth-engineer.md +50 -0
- package/config/claude-agents/hr-specialist.md +50 -0
- package/config/claude-agents/investment-strategist.md +50 -0
- package/config/claude-agents/knowledge-curator.md +51 -0
- package/config/claude-agents/knowledge-director.md +51 -0
- package/config/claude-agents/landing-cro-specialist.md +50 -0
- package/config/claude-agents/laravel-eng.md +52 -0
- package/config/claude-agents/leadership-director.md +50 -0
- package/config/claude-agents/market-analyst.md +50 -0
- package/config/claude-agents/marketing-director.md +50 -0
- package/config/claude-agents/metrics-analyst.md +50 -0
- package/config/claude-agents/node-ts-eng.md +52 -0
- package/config/claude-agents/okr-steward.md +51 -0
- package/config/claude-agents/ops-lead.md +50 -0
- package/config/claude-agents/org-designer.md +49 -0
- package/config/claude-agents/paid-specialist.md +50 -0
- package/config/claude-agents/people-ops.md +50 -0
- package/config/claude-agents/pm-director.md +52 -0
- package/config/claude-agents/product-owner.md +52 -0
- package/config/claude-agents/python-eng.md +52 -0
- package/config/claude-agents/repurpose-distributor.md +50 -0
- package/config/claude-agents/research-analyst.md +50 -0
- package/config/claude-agents/retention-manager.md +50 -0
- package/config/claude-agents/revops-lead.md +51 -0
- package/config/claude-agents/saas-strategist.md +50 -0
- package/config/claude-agents/sales-closer.md +50 -0
- package/config/claude-agents/sales-copywriter.md +51 -0
- package/config/claude-agents/sales-director.md +50 -0
- package/config/claude-agents/sales-ops.md +49 -0
- package/config/claude-agents/scriptwriter.md +50 -0
- package/config/claude-agents/scrum-master.md +50 -0
- package/config/claude-agents/sdr.md +51 -0
- package/config/claude-agents/security-eng.md +1 -1
- package/config/claude-agents/seo-specialist.md +50 -0
- package/config/claude-agents/shadcn-padronizer.md +51 -0
- package/config/claude-agents/strategic-pm.md +51 -0
- package/config/claude-agents/strategy-director.md +51 -0
- package/config/claude-agents/ux-designer.md +50 -0
- package/config/claude-agents/ux-researcher.md +51 -0
- package/config/claude-agents/ux-strategist.md +51 -0
- package/config/claude-agents/viral-engineer.md +50 -0
- package/config/claude-agents/visual-designer.md +50 -0
- package/config/claude-agents/wcag-auditor.md +51 -0
- package/config/disc-team-validator.sh +7 -7
- package/config/evals/dev.yaml +28 -0
- package/config/evals/finance.yaml +28 -0
- package/config/evals/kb.yaml +26 -0
- package/config/evals/marketing.yaml +28 -0
- package/config/evals/strategy.yaml +26 -0
- package/core/agents/__pycache__/behavioral_compiler.cpython-313.pyc +0 -0
- package/core/agents/__pycache__/registry_gen.cpython-313.pyc +0 -0
- package/core/agents/behavioral_compiler.py +66 -34
- package/core/agents/registry_gen.py +6 -4
- package/core/evals/__init__.py +19 -0
- package/core/evals/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/evals/__pycache__/schema.cpython-313.pyc +0 -0
- package/core/evals/__pycache__/verdict_labels.cpython-313.pyc +0 -0
- package/core/evals/schema.py +54 -0
- package/core/evals/verdict_labels.py +72 -0
- package/core/governance/__pycache__/compliance_telemetry_cli.cpython-313.pyc +0 -0
- package/core/governance/__pycache__/enforcement_telemetry_cli.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/claude_code.cpython-314.pyc +0 -0
- package/core/runtime/__pycache__/codex_cli.cpython-314.pyc +0 -0
- package/core/runtime/__pycache__/gemini_cli.cpython-314.pyc +0 -0
- package/core/runtime/__pycache__/llm_cost_telemetry.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/llm_cost_telemetry.cpython-314.pyc +0 -0
- package/core/runtime/__pycache__/subagent.cpython-313.pyc +0 -0
- package/core/runtime/llm_cost_telemetry.py +13 -1
- package/core/runtime/subagent.py +11 -170
- package/core/synapse/__pycache__/agent_experiences_layer.cpython-312.pyc +0 -0
- package/core/synapse/__pycache__/engine.cpython-312.pyc +0 -0
- package/core/synapse/__pycache__/engine.cpython-313.pyc +0 -0
- package/core/synapse/__pycache__/engine.cpython-314.pyc +0 -0
- package/core/synapse/__pycache__/layers.cpython-312.pyc +0 -0
- package/core/synapse/__pycache__/layers.cpython-313.pyc +0 -0
- package/core/synapse/__pycache__/layers.cpython-314.pyc +0 -0
- package/core/synapse/engine.py +6 -0
- package/core/synapse/layers.py +17 -0
- package/core/workflow/__init__.py +5 -3
- package/core/workflow/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/workflow/__pycache__/__init__.cpython-314.pyc +0 -0
- package/departments/brand/skills/archetype-finder/SKILL.md +7 -1
- package/departments/brand/skills/colors/SKILL.md +7 -1
- package/departments/brand/skills/design-system/SKILL.md +9 -2
- package/departments/brand/skills/identity-system/SKILL.md +8 -1
- package/departments/brand/skills/logo-brief/SKILL.md +7 -1
- package/departments/brand/skills/mockup-generate/SKILL.md +7 -1
- package/departments/brand/skills/naming-evaluate/SKILL.md +7 -1
- package/departments/brand/skills/positioning-statement/SKILL.md +8 -1
- package/departments/brand/skills/primal-audit/SKILL.md +7 -2
- package/departments/brand/skills/ux-audit/SKILL.md +8 -1
- package/departments/brand/skills/voice-guide/SKILL.md +8 -1
- package/departments/brand/skills/wireframe/SKILL.md +8 -1
- package/departments/community/skills/ai-community/SKILL.md +7 -1
- package/departments/community/skills/betting-setup/SKILL.md +7 -1
- package/departments/community/skills/business-model/SKILL.md +9 -2
- package/departments/community/skills/content-calendar/SKILL.md +8 -1
- package/departments/community/skills/events-plan/SKILL.md +7 -1
- package/departments/community/skills/gamification-design/SKILL.md +8 -1
- package/departments/community/skills/metrics-track/SKILL.md +8 -1
- package/departments/community/skills/moderation/SKILL.md +8 -1
- package/departments/community/skills/monetize-plan/SKILL.md +8 -1
- package/departments/community/skills/niche-setup/SKILL.md +9 -1
- package/departments/community/skills/onboarding-flow/SKILL.md +8 -1
- package/departments/community/skills/platform-select/SKILL.md +8 -1
- package/departments/community/skills/retention-system/SKILL.md +8 -2
- package/departments/content/skills/ai-workflow/SKILL.md +8 -1
- package/departments/content/skills/analytics/SKILL.md +8 -1
- package/departments/content/skills/calendar/SKILL.md +8 -1
- package/departments/content/skills/content-system/SKILL.md +8 -2
- package/departments/content/skills/hook-write/SKILL.md +8 -2
- package/departments/content/skills/monetization-plan/SKILL.md +8 -1
- package/departments/content/skills/newsletter-write/SKILL.md +7 -1
- package/departments/content/skills/platform-optimize/SKILL.md +9 -1
- package/departments/content/skills/repurpose-plan/SKILL.md +7 -1
- package/departments/content/skills/script-structure/SKILL.md +8 -1
- package/departments/content/skills/short-form/SKILL.md +8 -1
- package/departments/content/skills/thumbnail-package/SKILL.md +8 -1
- package/departments/content/skills/viral-design/SKILL.md +8 -2
- package/departments/content/skills/youtube-strategy/SKILL.md +9 -3
- package/departments/dev/skills/agent-design/SKILL.md +9 -2
- package/departments/dev/skills/agent-workflow/SKILL.md +9 -2
- package/departments/dev/skills/ai-assisted-dev/SKILL.md +7 -1
- package/departments/dev/skills/ai-security/SKILL.md +9 -2
- package/departments/dev/skills/api-design/SKILL.md +8 -2
- package/departments/dev/skills/app-test/SKILL.md +7 -3
- package/departments/dev/skills/architecture-design/SKILL.md +8 -2
- package/departments/dev/skills/changelog/SKILL.md +8 -1
- package/departments/dev/skills/ci-cd-pipeline/SKILL.md +7 -2
- package/departments/dev/skills/codebase-onboard/SKILL.md +8 -1
- package/departments/dev/skills/db-design/SKILL.md +8 -1
- package/departments/dev/skills/db-schema/SKILL.md +8 -2
- package/departments/dev/skills/ddd-model/SKILL.md +8 -1
- package/departments/dev/skills/demo-gif/SKILL.md +7 -3
- package/departments/dev/skills/dependency-audit/SKILL.md +8 -1
- package/departments/dev/skills/deploy/SKILL.md +8 -1
- package/departments/dev/skills/devops-pipeline/SKILL.md +8 -1
- package/departments/dev/skills/docs/SKILL.md +7 -1
- package/departments/dev/skills/env-secrets/SKILL.md +7 -1
- package/departments/dev/skills/incident/SKILL.md +8 -1
- package/departments/dev/skills/mcp/SKILL.md +8 -5
- package/departments/dev/skills/mcp-builder/SKILL.md +8 -2
- package/departments/dev/skills/observability/SKILL.md +8 -1
- package/departments/dev/skills/onboard/SKILL.md +8 -8
- package/departments/dev/skills/performance-audit/SKILL.md +8 -2
- package/departments/dev/skills/performance-profiler/SKILL.md +9 -2
- package/departments/dev/skills/rag-architect/SKILL.md +8 -2
- package/departments/dev/skills/red-team/SKILL.md +10 -1
- package/departments/dev/skills/refactor-plan/SKILL.md +8 -1
- package/departments/dev/skills/release/SKILL.md +8 -1
- package/departments/dev/skills/research/SKILL.md +3 -2
- package/departments/dev/skills/runbook/SKILL.md +8 -1
- package/departments/dev/skills/scaffold/SKILL.md +8 -5
- package/departments/dev/skills/security-audit/SKILL.md +9 -1
- package/departments/dev/skills/security-compliance/SKILL.md +8 -1
- package/departments/dev/skills/skill-audit/SKILL.md +9 -1
- package/departments/dev/skills/spec/SKILL.md +11 -14
- package/departments/dev/skills/stack-check/SKILL.md +8 -1
- package/departments/dev/skills/tdd-cycle/SKILL.md +8 -2
- package/departments/dev/skills/tech-debt/SKILL.md +8 -1
- package/departments/ecom/skills/analytics/SKILL.md +9 -1
- package/departments/ecom/skills/browse-competitor/SKILL.md +10 -3
- package/departments/ecom/skills/cart-recovery/SKILL.md +8 -1
- package/departments/ecom/skills/cro-optimize/SKILL.md +9 -2
- package/departments/ecom/skills/customer-journey/SKILL.md +8 -1
- package/departments/ecom/skills/ecommerce/SKILL.md +9 -8
- package/departments/ecom/skills/fulfillment-plan/SKILL.md +9 -1
- package/departments/ecom/skills/marketplace-manage/SKILL.md +9 -1
- package/departments/ecom/skills/pricing-strategy/SKILL.md +9 -1
- package/departments/ecom/skills/product-launch/SKILL.md +9 -3
- package/departments/ecom/skills/rfm-segment/SKILL.md +9 -2
- package/departments/ecom/skills/social-commerce/SKILL.md +8 -1
- package/departments/ecom/skills/store-audit/SKILL.md +9 -1
- package/departments/ecom/skills/subscription-model/SKILL.md +8 -1
- package/departments/finance/skills/budget-plan/SKILL.md +9 -1
- package/departments/finance/skills/cashflow-forecast/SKILL.md +9 -1
- package/departments/finance/skills/ciso-advisor/SKILL.md +9 -2
- package/departments/finance/skills/financial-model/SKILL.md +9 -2
- package/departments/finance/skills/pitch-deck/SKILL.md +9 -1
- package/departments/finance/skills/scenario-analysis/SKILL.md +8 -1
- package/departments/finance/skills/unit-economics/SKILL.md +9 -2
- package/departments/finance/skills/valuation-model/SKILL.md +9 -1
- package/departments/kb/skills/ai-research/SKILL.md +8 -1
- package/departments/kb/skills/competitive-intel/SKILL.md +8 -1
- package/departments/kb/skills/knowledge/SKILL.md +10 -9
- package/departments/kb/skills/knowledge-review/SKILL.md +7 -1
- package/departments/kb/skills/learn-content/SKILL.md +11 -1
- package/departments/kb/skills/moc-create/SKILL.md +7 -1
- package/departments/kb/skills/persona-build/SKILL.md +9 -4
- package/departments/kb/skills/research-plan/SKILL.md +9 -2
- package/departments/kb/skills/search-kb/SKILL.md +7 -1
- package/departments/kb/skills/source-evaluate/SKILL.md +8 -1
- package/departments/kb/skills/taxonomy-manage/SKILL.md +7 -1
- package/departments/kb/skills/write-as-persona/SKILL.md +8 -1
- package/departments/kb/skills/zettelkasten-process/SKILL.md +9 -2
- package/departments/landing/skills/ab-test/SKILL.md +7 -1
- package/departments/landing/skills/affiliate-bridge/SKILL.md +7 -1
- package/departments/landing/skills/awareness-diagnose/SKILL.md +8 -1
- package/departments/landing/skills/copy-framework/SKILL.md +7 -2
- package/departments/landing/skills/email-sequence/SKILL.md +7 -1
- package/departments/landing/skills/funnel-design/SKILL.md +8 -2
- package/departments/landing/skills/funnel-metrics/SKILL.md +7 -1
- package/departments/landing/skills/headline-write/SKILL.md +7 -1
- package/departments/landing/skills/landing-gen/SKILL.md +9 -3
- package/departments/landing/skills/launch-sequence/SKILL.md +7 -1
- package/departments/landing/skills/offer-create/SKILL.md +8 -2
- package/departments/landing/skills/optimize-page/SKILL.md +8 -1
- package/departments/landing/skills/page-architect/SKILL.md +7 -1
- package/departments/landing/skills/persuasion-apply/SKILL.md +9 -1
- package/departments/landing/skills/webinar-funnel/SKILL.md +8 -2
- package/departments/leadership/skills/change-manage/SKILL.md +8 -1
- package/departments/leadership/skills/conflict-resolve/SKILL.md +8 -1
- package/departments/leadership/skills/culture-audit/SKILL.md +7 -1
- package/departments/leadership/skills/delegation-matrix/SKILL.md +8 -1
- package/departments/leadership/skills/disc-assess/SKILL.md +8 -1
- package/departments/leadership/skills/feedback-give/SKILL.md +8 -1
- package/departments/leadership/skills/hiring-plan/SKILL.md +8 -1
- package/departments/leadership/skills/okr-define/SKILL.md +8 -2
- package/departments/leadership/skills/performance-review/SKILL.md +8 -1
- package/departments/leadership/skills/team-health/SKILL.md +8 -2
- package/departments/marketing/skills/ab-test/SKILL.md +7 -1
- package/departments/marketing/skills/analytics-report/SKILL.md +10 -1
- package/departments/marketing/skills/audience-segment/SKILL.md +8 -1
- package/departments/marketing/skills/calendar-plan/SKILL.md +8 -1
- package/departments/marketing/skills/cold-email/SKILL.md +8 -3
- package/departments/marketing/skills/competitor-analysis/SKILL.md +8 -1
- package/departments/marketing/skills/content-audit/SKILL.md +7 -1
- package/departments/marketing/skills/email-sequence/SKILL.md +9 -1
- package/departments/marketing/skills/marketing-automation/SKILL.md +7 -1
- package/departments/marketing/skills/paid-campaign/SKILL.md +8 -1
- package/departments/marketing/skills/programmatic-seo/SKILL.md +8 -3
- package/departments/marketing/skills/seo-audit/SKILL.md +8 -2
- package/departments/marketing/skills/social-strategy/SKILL.md +8 -1
- package/departments/ops/skills/bottleneck-find/SKILL.md +6 -2
- package/departments/ops/skills/dashboard-build/SKILL.md +7 -1
- package/departments/ops/skills/gdpr-compliance/SKILL.md +6 -1
- package/departments/ops/skills/gtd-setup/SKILL.md +6 -1
- package/departments/ops/skills/integration-design/SKILL.md +6 -1
- package/departments/ops/skills/iso27001/SKILL.md +7 -1
- package/departments/ops/skills/lean-audit/SKILL.md +6 -1
- package/departments/ops/skills/metrics-dashboard/SKILL.md +6 -1
- package/departments/ops/skills/n8n-flow/SKILL.md +6 -1
- package/departments/ops/skills/operations/SKILL.md +8 -8
- package/departments/ops/skills/quality-management/SKILL.md +6 -1
- package/departments/ops/skills/risk-management/SKILL.md +7 -1
- package/departments/ops/skills/soc2-compliance/SKILL.md +7 -1
- package/departments/ops/skills/sop-create/SKILL.md +6 -1
- package/departments/ops/skills/update/SKILL.md +8 -1
- package/departments/ops/skills/workflow-automate/SKILL.md +7 -2
- package/departments/ops/skills/zapier-flow/SKILL.md +6 -1
- package/departments/org/skills/compensation-plan/SKILL.md +7 -1
- package/departments/org/skills/culture-define/SKILL.md +8 -3
- package/departments/org/skills/decision-framework/SKILL.md +7 -1
- package/departments/org/skills/hiring-plan/SKILL.md +7 -1
- package/departments/org/skills/meeting-optimize/SKILL.md +7 -1
- package/departments/org/skills/okr-cadence/SKILL.md +7 -3
- package/departments/org/skills/onboarding-design/SKILL.md +7 -1
- package/departments/org/skills/org-design/SKILL.md +7 -1
- package/departments/org/skills/principles-audit/SKILL.md +8 -3
- package/departments/org/skills/remote-setup/SKILL.md +7 -1
- package/departments/org/skills/sop-process/SKILL.md +7 -1
- package/departments/org/skills/team-assess/SKILL.md +7 -1
- package/departments/pm/skills/agile-po/SKILL.md +10 -3
- package/departments/pm/skills/backlog-groom/SKILL.md +8 -1
- package/departments/pm/skills/discovery-plan/SKILL.md +10 -2
- package/departments/pm/skills/estimate-forecast/SKILL.md +9 -1
- package/departments/pm/skills/impact-map/SKILL.md +9 -1
- package/departments/pm/skills/kanban-setup/SKILL.md +7 -1
- package/departments/pm/skills/risk-register/SKILL.md +9 -1
- package/departments/pm/skills/roadmap-build/SKILL.md +10 -4
- package/departments/pm/skills/shape-pitch/SKILL.md +8 -2
- package/departments/pm/skills/sprint-plan/SKILL.md +8 -1
- package/departments/pm/skills/stakeholder-map/SKILL.md +7 -1
- package/departments/pm/skills/standup-run/SKILL.md +8 -1
- package/departments/pm/skills/story-write/SKILL.md +8 -1
- package/departments/saas/skills/benchmark-compare/SKILL.md +8 -1
- package/departments/saas/skills/churn-analysis/SKILL.md +8 -1
- package/departments/saas/skills/customer-success/SKILL.md +9 -1
- package/departments/saas/skills/gtm-strategy/SKILL.md +9 -3
- package/departments/saas/skills/launch-execute/SKILL.md +8 -1
- package/departments/saas/skills/leaky-bucket/SKILL.md +8 -3
- package/departments/saas/skills/metrics-dashboard/SKILL.md +8 -1
- package/departments/saas/skills/micro-saas-stack/SKILL.md +8 -1
- package/departments/saas/skills/mvp-build/SKILL.md +8 -1
- package/departments/saas/skills/onboarding-optimize/SKILL.md +9 -1
- package/departments/saas/skills/plg-setup/SKILL.md +9 -2
- package/departments/saas/skills/pricing-strategy/SKILL.md +9 -2
- package/departments/saas/skills/saas-scaffold/SKILL.md +8 -3
- package/departments/saas/skills/voc-loop/SKILL.md +10 -3
- package/departments/sales/skills/challenger-sell/SKILL.md +7 -1
- package/departments/sales/skills/deal-qualify/SKILL.md +7 -1
- package/departments/sales/skills/discovery-call/SKILL.md +6 -1
- package/departments/sales/skills/forecast-revenue/SKILL.md +7 -1
- package/departments/sales/skills/negotiate-plan/SKILL.md +7 -1
- package/departments/sales/skills/objection-handle/SKILL.md +7 -1
- package/departments/sales/skills/pipeline-manage/SKILL.md +7 -1
- package/departments/sales/skills/pricing-negotiate/SKILL.md +7 -1
- package/departments/sales/skills/proposal-write/SKILL.md +7 -2
- package/departments/sales/skills/spin-sell/SKILL.md +8 -2
- package/departments/strategy/skills/blue-ocean/SKILL.md +9 -2
- package/departments/strategy/skills/bmc/SKILL.md +8 -1
- package/departments/strategy/skills/board-advisor/SKILL.md +10 -2
- package/departments/strategy/skills/cto-advisor/SKILL.md +9 -2
- package/departments/strategy/skills/extract-data/SKILL.md +9 -3
- package/departments/strategy/skills/five-forces/SKILL.md +9 -2
- package/departments/strategy/skills/moat-analysis/SKILL.md +8 -1
- package/departments/strategy/skills/position/SKILL.md +10 -1
- package/departments/strategy/skills/premortem/SKILL.md +9 -3
- package/departments/strategy/skills/scenario-plan/SKILL.md +9 -1
- package/knowledge/commands-registry-v2.json +58 -108
- package/knowledge/commands-registry.json.bak +1 -1
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/scripts/tools/__pycache__/prompt_surface_benchmark.cpython-313.pyc +0 -0
- package/scripts/tools/prompt_surface_benchmark.py +144 -0
- package/core/workflow/announcer.py +0 -246
- package/core/workflow/engine.py +0 -260
- package/knowledge/agents-registry.json +0 -254
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
"""Phase announcement system for ArkaOS workflows.
|
|
2
|
-
|
|
3
|
-
Provides structured, visible announcements for workflow phases
|
|
4
|
-
enforcing the Constitution's "full visibility" rule.
|
|
5
|
-
|
|
6
|
-
Format: [PHASE] Starting: {name} | [PHASE] Completed: {name} ({duration}ms)
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
import time
|
|
10
|
-
from dataclasses import dataclass, field
|
|
11
|
-
from typing import Callable
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
@dataclass
|
|
15
|
-
class Announcement:
|
|
16
|
-
"""A single announcement record."""
|
|
17
|
-
|
|
18
|
-
phase_id: str
|
|
19
|
-
phase_name: str
|
|
20
|
-
event: str # "starting" | "completed" | "failed" | "blocked" | "skipped"
|
|
21
|
-
duration_ms: int = 0
|
|
22
|
-
metadata: dict = field(default_factory=dict)
|
|
23
|
-
at: float = field(default_factory=time.time)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class PhaseAnnouncer:
|
|
27
|
-
"""Manages phase announcements with structured output.
|
|
28
|
-
|
|
29
|
-
Integrates with WorkflowEngine via on_visibility callback.
|
|
30
|
-
Tracks all announcements for session summary generation.
|
|
31
|
-
"""
|
|
32
|
-
|
|
33
|
-
def __init__(self, on_announce: Callable[[str], None] | None = None):
|
|
34
|
-
"""Initialize announcer.
|
|
35
|
-
|
|
36
|
-
Args:
|
|
37
|
-
on_announce: Callback to output announcement. Defaults to print.
|
|
38
|
-
"""
|
|
39
|
-
self._on_announce = on_announce or print
|
|
40
|
-
self._announcements: list[Announcement] = []
|
|
41
|
-
self._phase_start_times: dict[str, float] = {}
|
|
42
|
-
|
|
43
|
-
def starting(self, phase_id: str, phase_name: str, **metadata: str) -> None:
|
|
44
|
-
"""Announce phase starting.
|
|
45
|
-
|
|
46
|
-
Args:
|
|
47
|
-
phase_id: Unique phase identifier
|
|
48
|
-
phase_name: Human-readable phase name
|
|
49
|
-
**metadata: Additional context (agents, department, etc.)
|
|
50
|
-
"""
|
|
51
|
-
self._phase_start_times[phase_id] = time.time()
|
|
52
|
-
announcement = Announcement(
|
|
53
|
-
phase_id=phase_id,
|
|
54
|
-
phase_name=phase_name,
|
|
55
|
-
event="starting",
|
|
56
|
-
metadata=metadata,
|
|
57
|
-
)
|
|
58
|
-
self._announcements.append(announcement)
|
|
59
|
-
self._emit(announcement)
|
|
60
|
-
|
|
61
|
-
def completed(self, phase_id: str, phase_name: str, output: str = "", **metadata: str) -> int:
|
|
62
|
-
"""Announce phase completed.
|
|
63
|
-
|
|
64
|
-
Args:
|
|
65
|
-
phase_id: Unique phase identifier
|
|
66
|
-
phase_name: Human-readable phase name
|
|
67
|
-
output: Phase result summary
|
|
68
|
-
**metadata: Additional context
|
|
69
|
-
|
|
70
|
-
Returns:
|
|
71
|
-
Duration in milliseconds
|
|
72
|
-
"""
|
|
73
|
-
start_time = self._phase_start_times.pop(phase_id, time.time())
|
|
74
|
-
duration_ms = int((time.time() - start_time) * 1000)
|
|
75
|
-
|
|
76
|
-
announcement = Announcement(
|
|
77
|
-
phase_id=phase_id,
|
|
78
|
-
phase_name=phase_name,
|
|
79
|
-
event="completed",
|
|
80
|
-
duration_ms=duration_ms,
|
|
81
|
-
metadata=metadata,
|
|
82
|
-
)
|
|
83
|
-
self._announcements.append(announcement)
|
|
84
|
-
self._emit(announcement)
|
|
85
|
-
return duration_ms
|
|
86
|
-
|
|
87
|
-
def failed(self, phase_id: str, phase_name: str, reason: str = "") -> None:
|
|
88
|
-
"""Announce phase failed.
|
|
89
|
-
|
|
90
|
-
Args:
|
|
91
|
-
phase_id: Unique phase identifier
|
|
92
|
-
phase_name: Human-readable phase name
|
|
93
|
-
reason: Failure reason
|
|
94
|
-
"""
|
|
95
|
-
announcement = Announcement(
|
|
96
|
-
phase_id=phase_id,
|
|
97
|
-
phase_name=phase_name,
|
|
98
|
-
event="failed",
|
|
99
|
-
metadata={"reason": reason} if reason else {},
|
|
100
|
-
)
|
|
101
|
-
self._announcements.append(announcement)
|
|
102
|
-
self._emit(announcement)
|
|
103
|
-
|
|
104
|
-
def blocked(self, phase_id: str, phase_name: str, reason: str = "") -> None:
|
|
105
|
-
"""Announce phase blocked.
|
|
106
|
-
|
|
107
|
-
Args:
|
|
108
|
-
phase_id: Unique phase identifier
|
|
109
|
-
phase_name: Human-readable phase name
|
|
110
|
-
reason: Block reason
|
|
111
|
-
"""
|
|
112
|
-
announcement = Announcement(
|
|
113
|
-
phase_id=phase_id,
|
|
114
|
-
phase_name=phase_name,
|
|
115
|
-
event="blocked",
|
|
116
|
-
metadata={"reason": reason} if reason else {},
|
|
117
|
-
)
|
|
118
|
-
self._announcements.append(announcement)
|
|
119
|
-
self._emit(announcement)
|
|
120
|
-
|
|
121
|
-
def skipped(self, phase_id: str, phase_name: str, reason: str = "") -> None:
|
|
122
|
-
"""Announce phase skipped.
|
|
123
|
-
|
|
124
|
-
Args:
|
|
125
|
-
phase_id: Unique phase identifier
|
|
126
|
-
phase_name: Human-readable phase name
|
|
127
|
-
reason: Skip reason
|
|
128
|
-
"""
|
|
129
|
-
announcement = Announcement(
|
|
130
|
-
phase_id=phase_id,
|
|
131
|
-
phase_name=phase_name,
|
|
132
|
-
event="skipped",
|
|
133
|
-
metadata={"reason": reason} if reason else {},
|
|
134
|
-
)
|
|
135
|
-
self._announcements.append(announcement)
|
|
136
|
-
self._emit(announcement)
|
|
137
|
-
|
|
138
|
-
def workflow_start(self, workflow_name: str, phase_count: int, tier: str) -> None:
|
|
139
|
-
"""Announce workflow starting.
|
|
140
|
-
|
|
141
|
-
Args:
|
|
142
|
-
workflow_name: Name of the workflow
|
|
143
|
-
phase_count: Number of phases
|
|
144
|
-
tier: Workflow tier
|
|
145
|
-
"""
|
|
146
|
-
msg = f"[WORKFLOW] Starting: {workflow_name} ({phase_count} phases, tier: {tier})"
|
|
147
|
-
self._on_announce(msg)
|
|
148
|
-
|
|
149
|
-
def workflow_complete(self, workflow_name: str, total_duration_ms: int) -> None:
|
|
150
|
-
"""Announce workflow completed.
|
|
151
|
-
|
|
152
|
-
Args:
|
|
153
|
-
workflow_name: Name of the workflow
|
|
154
|
-
total_duration_ms: Total execution time
|
|
155
|
-
"""
|
|
156
|
-
msg = f"[WORKFLOW] Completed: {workflow_name} (total: {total_duration_ms}ms)"
|
|
157
|
-
self._on_announce(msg)
|
|
158
|
-
|
|
159
|
-
def _emit(self, announcement: Announcement) -> None:
|
|
160
|
-
"""Format and emit an announcement."""
|
|
161
|
-
if announcement.event == "starting":
|
|
162
|
-
agents = announcement.metadata.get("agents", "")
|
|
163
|
-
msg = f"[PHASE] Starting: {announcement.phase_name}"
|
|
164
|
-
if agents:
|
|
165
|
-
msg += f" (agents: {agents})"
|
|
166
|
-
elif announcement.event == "completed":
|
|
167
|
-
msg = f"[PHASE] Completed: {announcement.phase_name} ({announcement.duration_ms}ms)"
|
|
168
|
-
elif announcement.event == "failed":
|
|
169
|
-
reason = announcement.metadata.get("reason", "")
|
|
170
|
-
msg = f"[PHASE] Failed: {announcement.phase_name}"
|
|
171
|
-
if reason:
|
|
172
|
-
msg += f" — {reason}"
|
|
173
|
-
elif announcement.event == "blocked":
|
|
174
|
-
reason = announcement.metadata.get("reason", "")
|
|
175
|
-
msg = f"[PHASE] Blocked: {announcement.phase_name}"
|
|
176
|
-
if reason:
|
|
177
|
-
msg += f" (waiting for: {reason})"
|
|
178
|
-
elif announcement.event == "skipped":
|
|
179
|
-
reason = announcement.metadata.get("reason", "")
|
|
180
|
-
msg = f"[PHASE] Skipped: {announcement.phase_name}"
|
|
181
|
-
if reason:
|
|
182
|
-
msg += f" ({reason})"
|
|
183
|
-
else:
|
|
184
|
-
msg = f"[PHASE] {announcement.phase_name} — {announcement.event.upper()}"
|
|
185
|
-
|
|
186
|
-
self._on_announce(msg)
|
|
187
|
-
|
|
188
|
-
@property
|
|
189
|
-
def announcements(self) -> list[Announcement]:
|
|
190
|
-
"""Get all announcements for this session."""
|
|
191
|
-
return self._announcements.copy()
|
|
192
|
-
|
|
193
|
-
def get_phase_announcements(
|
|
194
|
-
self, phase_id: str
|
|
195
|
-
) -> tuple[Announcement | None, Announcement | None]:
|
|
196
|
-
"""Get start and completion announcements for a phase.
|
|
197
|
-
|
|
198
|
-
Args:
|
|
199
|
-
phase_id: The phase identifier
|
|
200
|
-
|
|
201
|
-
Returns:
|
|
202
|
-
Tuple of (starting_announcement, completed_announcement) or (None, None)
|
|
203
|
-
"""
|
|
204
|
-
start_ann = None
|
|
205
|
-
complete_ann = None
|
|
206
|
-
for ann in self._announcements:
|
|
207
|
-
if ann.phase_id == phase_id:
|
|
208
|
-
if ann.event == "starting":
|
|
209
|
-
start_ann = ann
|
|
210
|
-
elif ann.event == "completed":
|
|
211
|
-
complete_ann = ann
|
|
212
|
-
return start_ann, complete_ann
|
|
213
|
-
|
|
214
|
-
def validate_phase_completion(self, phase_id: str) -> bool:
|
|
215
|
-
"""Check if a phase has both start and completion announcements.
|
|
216
|
-
|
|
217
|
-
Args:
|
|
218
|
-
phase_id: The phase to validate
|
|
219
|
-
|
|
220
|
-
Returns:
|
|
221
|
-
True if phase has both starting and completed announcements
|
|
222
|
-
"""
|
|
223
|
-
start_ann, complete_ann = self.get_phase_announcements(phase_id)
|
|
224
|
-
return start_ann is not None and complete_ann is not None
|
|
225
|
-
|
|
226
|
-
def get_total_duration_ms(self) -> int:
|
|
227
|
-
"""Calculate total duration across all completed phases.
|
|
228
|
-
|
|
229
|
-
Returns:
|
|
230
|
-
Total milliseconds
|
|
231
|
-
"""
|
|
232
|
-
return sum(ann.duration_ms for ann in self._announcements if ann.event == "completed")
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
def make_announcer(
|
|
236
|
-
on_announce: Callable[[str], None] | None = None,
|
|
237
|
-
) -> PhaseAnnouncer:
|
|
238
|
-
"""Factory to create a PhaseAnnouncer.
|
|
239
|
-
|
|
240
|
-
Args:
|
|
241
|
-
on_announce: Optional output callback
|
|
242
|
-
|
|
243
|
-
Returns:
|
|
244
|
-
Configured PhaseAnnouncer instance
|
|
245
|
-
"""
|
|
246
|
-
return PhaseAnnouncer(on_announce=on_announce)
|
package/core/workflow/engine.py
DELETED
|
@@ -1,260 +0,0 @@
|
|
|
1
|
-
"""Workflow execution engine.
|
|
2
|
-
|
|
3
|
-
Executes workflows phase by phase, respecting gates, conditions,
|
|
4
|
-
and agent assignments. Enforces the Constitution's sequential validation
|
|
5
|
-
and full visibility rules.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from dataclasses import dataclass, field
|
|
9
|
-
from typing import Optional, Callable, Any
|
|
10
|
-
|
|
11
|
-
from core.workflow.schema import (
|
|
12
|
-
Workflow, Phase, PhaseStatus, GateType, Gate,
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@dataclass
|
|
17
|
-
class PhaseResult:
|
|
18
|
-
"""Result of executing a single phase."""
|
|
19
|
-
phase_id: str
|
|
20
|
-
status: PhaseStatus
|
|
21
|
-
output: str = ""
|
|
22
|
-
agent_outputs: dict[str, str] = field(default_factory=dict)
|
|
23
|
-
duration_ms: int = 0
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@dataclass
|
|
27
|
-
class GateResult:
|
|
28
|
-
"""Result of evaluating a gate."""
|
|
29
|
-
passed: bool
|
|
30
|
-
gate_type: GateType
|
|
31
|
-
message: str = ""
|
|
32
|
-
verdict: str = ""
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class WorkflowEngine:
|
|
36
|
-
"""Executes YAML-defined workflows with phase gates and visibility.
|
|
37
|
-
|
|
38
|
-
The engine enforces:
|
|
39
|
-
1. Sequential validation — Phase N+1 only starts after N completes
|
|
40
|
-
2. Full visibility — Every phase announces what's starting and what resulted
|
|
41
|
-
3. Quality Gate — Mandatory review before delivery
|
|
42
|
-
4. Gate evaluation — User approval, quality checks, or conditions
|
|
43
|
-
"""
|
|
44
|
-
|
|
45
|
-
def __init__(
|
|
46
|
-
self,
|
|
47
|
-
on_phase_start: Optional[Callable[[Phase], None]] = None,
|
|
48
|
-
on_phase_complete: Optional[Callable[[Phase, PhaseResult], None]] = None,
|
|
49
|
-
on_gate_check: Optional[Callable[[Gate], GateResult]] = None,
|
|
50
|
-
on_visibility: Optional[Callable[[str], None]] = None,
|
|
51
|
-
budget_manager: Any = None,
|
|
52
|
-
obsidian_writer: Any = None,
|
|
53
|
-
):
|
|
54
|
-
"""Initialize the workflow engine.
|
|
55
|
-
|
|
56
|
-
Args:
|
|
57
|
-
on_phase_start: Called when a phase begins execution.
|
|
58
|
-
on_phase_complete: Called when a phase finishes.
|
|
59
|
-
on_gate_check: Called to evaluate a gate. Must return GateResult.
|
|
60
|
-
on_visibility: Called to announce status to the user.
|
|
61
|
-
"""
|
|
62
|
-
self._on_phase_start = on_phase_start
|
|
63
|
-
self._on_phase_complete = on_phase_complete
|
|
64
|
-
self._on_gate_check = on_gate_check
|
|
65
|
-
self._on_visibility = on_visibility
|
|
66
|
-
self._budget_manager = budget_manager
|
|
67
|
-
self._obsidian_writer = obsidian_writer
|
|
68
|
-
self._history: list[PhaseResult] = []
|
|
69
|
-
|
|
70
|
-
def announce(self, message: str) -> None:
|
|
71
|
-
"""Announce a status message (full visibility rule)."""
|
|
72
|
-
if self._on_visibility:
|
|
73
|
-
self._on_visibility(message)
|
|
74
|
-
|
|
75
|
-
def execute(self, workflow: Workflow) -> list[PhaseResult]:
|
|
76
|
-
"""Execute a workflow from start to finish.
|
|
77
|
-
|
|
78
|
-
Phases run sequentially. Each phase must complete and pass
|
|
79
|
-
its gate before the next phase starts.
|
|
80
|
-
|
|
81
|
-
Args:
|
|
82
|
-
workflow: The workflow definition to execute.
|
|
83
|
-
|
|
84
|
-
Returns:
|
|
85
|
-
List of PhaseResults for each executed phase.
|
|
86
|
-
"""
|
|
87
|
-
workflow.status = PhaseStatus.IN_PROGRESS
|
|
88
|
-
results: list[PhaseResult] = []
|
|
89
|
-
|
|
90
|
-
self.announce(
|
|
91
|
-
f"Starting workflow: {workflow.name} "
|
|
92
|
-
f"({len(workflow.phases)} phases, tier: {workflow.tier.value})"
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
for i, phase in enumerate(workflow.phases):
|
|
96
|
-
# Check skip condition
|
|
97
|
-
if phase.skip_if and self._evaluate_condition(phase.skip_if):
|
|
98
|
-
phase.status = PhaseStatus.SKIPPED
|
|
99
|
-
self.announce(f"Phase {i}: {phase.name} — SKIPPED (condition met)")
|
|
100
|
-
results.append(PhaseResult(
|
|
101
|
-
phase_id=phase.id,
|
|
102
|
-
status=PhaseStatus.SKIPPED,
|
|
103
|
-
output="Skipped: condition evaluated to true",
|
|
104
|
-
))
|
|
105
|
-
continue
|
|
106
|
-
|
|
107
|
-
# Check dependencies
|
|
108
|
-
if phase.depends_on:
|
|
109
|
-
unmet = [
|
|
110
|
-
dep for dep in phase.depends_on
|
|
111
|
-
if not self._is_phase_complete(workflow, dep)
|
|
112
|
-
]
|
|
113
|
-
if unmet:
|
|
114
|
-
phase.status = PhaseStatus.BLOCKED
|
|
115
|
-
self.announce(
|
|
116
|
-
f"Phase {i}: {phase.name} — BLOCKED "
|
|
117
|
-
f"(waiting for: {', '.join(unmet)})"
|
|
118
|
-
)
|
|
119
|
-
results.append(PhaseResult(
|
|
120
|
-
phase_id=phase.id,
|
|
121
|
-
status=PhaseStatus.BLOCKED,
|
|
122
|
-
output=f"Blocked by: {', '.join(unmet)}",
|
|
123
|
-
))
|
|
124
|
-
continue
|
|
125
|
-
|
|
126
|
-
# Execute phase
|
|
127
|
-
self.announce(
|
|
128
|
-
f"Phase {i}: {phase.name} — STARTING "
|
|
129
|
-
f"(agents: {', '.join(a.agent_id for a in phase.agents)})"
|
|
130
|
-
)
|
|
131
|
-
phase.status = PhaseStatus.IN_PROGRESS
|
|
132
|
-
|
|
133
|
-
if self._on_phase_start:
|
|
134
|
-
self._on_phase_start(phase)
|
|
135
|
-
|
|
136
|
-
result = self._execute_phase(phase)
|
|
137
|
-
results.append(result)
|
|
138
|
-
|
|
139
|
-
if result.status == PhaseStatus.FAILED:
|
|
140
|
-
phase.status = PhaseStatus.FAILED
|
|
141
|
-
workflow.status = PhaseStatus.FAILED
|
|
142
|
-
self.announce(f"Phase {i}: {phase.name} — FAILED: {result.output}")
|
|
143
|
-
break
|
|
144
|
-
|
|
145
|
-
phase.status = PhaseStatus.COMPLETED
|
|
146
|
-
phase.result = result.output
|
|
147
|
-
|
|
148
|
-
if self._on_phase_complete:
|
|
149
|
-
self._on_phase_complete(phase, result)
|
|
150
|
-
|
|
151
|
-
# Save outputs to Obsidian vault (NON-NEGOTIABLE: obsidian-output)
|
|
152
|
-
if self._obsidian_writer and hasattr(phase, "outputs"):
|
|
153
|
-
for output in getattr(phase, "outputs", []):
|
|
154
|
-
obsidian_path = getattr(output, "obsidian_path", "")
|
|
155
|
-
if obsidian_path and result.output:
|
|
156
|
-
try:
|
|
157
|
-
saved = self._obsidian_writer.save(
|
|
158
|
-
obsidian_path=obsidian_path,
|
|
159
|
-
content=result.output,
|
|
160
|
-
department=workflow.department,
|
|
161
|
-
workflow=workflow.id,
|
|
162
|
-
)
|
|
163
|
-
self.announce(f"Saved to vault: {saved.name}")
|
|
164
|
-
except Exception as e:
|
|
165
|
-
self.announce(f"Vault save failed: {e}")
|
|
166
|
-
|
|
167
|
-
self.announce(f"Phase {i}: {phase.name} — COMPLETED")
|
|
168
|
-
|
|
169
|
-
# Evaluate gate
|
|
170
|
-
gate_result = self._evaluate_gate(phase.gate)
|
|
171
|
-
if not gate_result.passed:
|
|
172
|
-
self.announce(
|
|
173
|
-
f"Gate after Phase {i} — REJECTED: {gate_result.message}"
|
|
174
|
-
)
|
|
175
|
-
# Loop back: reset phase to pending for retry
|
|
176
|
-
phase.status = PhaseStatus.PENDING
|
|
177
|
-
results.append(PhaseResult(
|
|
178
|
-
phase_id=f"{phase.id}_gate",
|
|
179
|
-
status=PhaseStatus.FAILED,
|
|
180
|
-
output=f"Gate rejected: {gate_result.message}",
|
|
181
|
-
))
|
|
182
|
-
workflow.status = PhaseStatus.FAILED
|
|
183
|
-
break
|
|
184
|
-
|
|
185
|
-
if workflow.all_phases_complete():
|
|
186
|
-
workflow.status = PhaseStatus.COMPLETED
|
|
187
|
-
self.announce(f"Workflow {workflow.name} — COMPLETED")
|
|
188
|
-
|
|
189
|
-
self._history.extend(results)
|
|
190
|
-
return results
|
|
191
|
-
|
|
192
|
-
def _execute_phase(self, phase: Phase) -> PhaseResult:
|
|
193
|
-
"""Execute a single phase.
|
|
194
|
-
|
|
195
|
-
In the real implementation, this dispatches to agents via
|
|
196
|
-
the runtime adapter. Here we return a placeholder result
|
|
197
|
-
that the calling code fills in.
|
|
198
|
-
"""
|
|
199
|
-
agent_ids = [a.agent_id for a in phase.agents]
|
|
200
|
-
return PhaseResult(
|
|
201
|
-
phase_id=phase.id,
|
|
202
|
-
status=PhaseStatus.COMPLETED,
|
|
203
|
-
output=f"Phase {phase.name} executed by {', '.join(agent_ids)}",
|
|
204
|
-
agent_outputs={a.agent_id: "completed" for a in phase.agents},
|
|
205
|
-
)
|
|
206
|
-
|
|
207
|
-
def _evaluate_gate(self, gate: Gate) -> GateResult:
|
|
208
|
-
"""Evaluate a phase gate."""
|
|
209
|
-
if gate.type == GateType.AUTO:
|
|
210
|
-
return GateResult(passed=True, gate_type=GateType.AUTO, message="Auto-pass")
|
|
211
|
-
|
|
212
|
-
if gate.type == GateType.BUDGET_CHECK and self._budget_manager:
|
|
213
|
-
return self._evaluate_budget_gate(gate)
|
|
214
|
-
|
|
215
|
-
if self._on_gate_check:
|
|
216
|
-
return self._on_gate_check(gate)
|
|
217
|
-
|
|
218
|
-
# Default: pass
|
|
219
|
-
return GateResult(passed=True, gate_type=gate.type, message="Default pass")
|
|
220
|
-
|
|
221
|
-
def _evaluate_budget_gate(self, gate: Gate) -> GateResult:
|
|
222
|
-
"""Evaluate a budget gate using the budget manager."""
|
|
223
|
-
# Default tier for budget checks (can be overridden via gate metadata)
|
|
224
|
-
tier = 2
|
|
225
|
-
estimated_tokens = 50_000 # Default estimate per phase
|
|
226
|
-
|
|
227
|
-
if self._budget_manager.check_budget(tier, estimated_tokens):
|
|
228
|
-
needs_approval = self._budget_manager.needs_approval(tier)
|
|
229
|
-
msg = "Budget OK"
|
|
230
|
-
if needs_approval:
|
|
231
|
-
msg = "Budget OK (>80% used — Tier 0 notified)"
|
|
232
|
-
self.announce(f"Budget warning: tier {tier} at >80% monthly usage")
|
|
233
|
-
return GateResult(passed=True, gate_type=GateType.BUDGET_CHECK, message=msg)
|
|
234
|
-
|
|
235
|
-
summary = self._budget_manager.get_summary(tier)
|
|
236
|
-
return GateResult(
|
|
237
|
-
passed=False,
|
|
238
|
-
gate_type=GateType.BUDGET_CHECK,
|
|
239
|
-
message=f"Budget exceeded: {summary.used}/{summary.allocated} tokens used ({summary.percent_used}%). Needs Tier 0 approval.",
|
|
240
|
-
)
|
|
241
|
-
|
|
242
|
-
def _evaluate_condition(self, condition: str) -> bool:
|
|
243
|
-
"""Evaluate a skip/branch condition.
|
|
244
|
-
|
|
245
|
-
For safety, only evaluates simple boolean expressions.
|
|
246
|
-
"""
|
|
247
|
-
# In production, this would evaluate against workflow context
|
|
248
|
-
return False
|
|
249
|
-
|
|
250
|
-
def _is_phase_complete(self, workflow: Workflow, phase_id: str) -> bool:
|
|
251
|
-
"""Check if a specific phase is complete."""
|
|
252
|
-
phase = workflow.get_phase_by_id(phase_id)
|
|
253
|
-
if phase is None:
|
|
254
|
-
return False
|
|
255
|
-
return phase.status in (PhaseStatus.COMPLETED, PhaseStatus.SKIPPED)
|
|
256
|
-
|
|
257
|
-
@property
|
|
258
|
-
def history(self) -> list[PhaseResult]:
|
|
259
|
-
"""Get the execution history."""
|
|
260
|
-
return self._history
|