arkaos 2.0.0 → 2.0.2
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 +100 -74
- package/VERSION +1 -1
- package/bin/arkaos +1 -1
- package/config/constitution.yaml +4 -0
- package/config/hooks/user-prompt-submit-v2.sh +20 -38
- package/core/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/agents/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/agents/__pycache__/loader.cpython-313.pyc +0 -0
- package/core/agents/__pycache__/schema.cpython-313.pyc +0 -0
- package/core/agents/__pycache__/validator.cpython-313.pyc +0 -0
- package/core/budget/__init__.py +6 -0
- package/core/budget/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/budget/__pycache__/manager.cpython-313.pyc +0 -0
- package/core/budget/__pycache__/schema.cpython-313.pyc +0 -0
- package/core/budget/manager.py +193 -0
- package/core/budget/schema.py +82 -0
- package/core/conclave/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/conclave/__pycache__/advisor_db.cpython-313.pyc +0 -0
- package/core/conclave/__pycache__/display.cpython-313.pyc +0 -0
- package/core/conclave/__pycache__/matcher.cpython-313.pyc +0 -0
- package/core/conclave/__pycache__/persistence.cpython-313.pyc +0 -0
- package/core/conclave/__pycache__/profiler.cpython-313.pyc +0 -0
- package/core/conclave/__pycache__/prompts.cpython-313.pyc +0 -0
- package/core/conclave/__pycache__/schema.cpython-313.pyc +0 -0
- package/core/governance/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/governance/__pycache__/constitution.cpython-313.pyc +0 -0
- package/core/obsidian/__init__.py +6 -0
- package/core/obsidian/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/obsidian/__pycache__/templates.cpython-313.pyc +0 -0
- package/core/obsidian/__pycache__/writer.cpython-313.pyc +0 -0
- package/core/obsidian/templates.py +76 -0
- package/core/obsidian/writer.py +148 -0
- package/core/orchestration/__init__.py +6 -0
- package/core/orchestration/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/orchestration/__pycache__/patterns.cpython-313.pyc +0 -0
- package/core/orchestration/__pycache__/protocol.cpython-313.pyc +0 -0
- package/core/orchestration/patterns.py +136 -0
- package/core/orchestration/protocol.py +96 -0
- package/core/registry/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/registry/__pycache__/generator.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/base.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/claude_code.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/codex_cli.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/cursor.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/gemini_cli.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/registry.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/subagent.cpython-313.pyc +0 -0
- package/core/specs/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/specs/__pycache__/manager.cpython-313.pyc +0 -0
- package/core/specs/__pycache__/schema.cpython-313.pyc +0 -0
- package/core/squads/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/squads/__pycache__/loader.cpython-313.pyc +0 -0
- package/core/squads/__pycache__/registry.cpython-313.pyc +0 -0
- package/core/squads/__pycache__/schema.cpython-313.pyc +0 -0
- package/core/synapse/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/synapse/__pycache__/cache.cpython-313.pyc +0 -0
- package/core/synapse/__pycache__/engine.cpython-313.pyc +0 -0
- package/core/synapse/__pycache__/layers.cpython-313.pyc +0 -0
- package/core/tasks/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/tasks/__pycache__/manager.cpython-313.pyc +0 -0
- package/core/tasks/__pycache__/schema.cpython-313.pyc +0 -0
- package/core/tasks/schema.py +6 -0
- package/core/workflow/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/workflow/__pycache__/engine.cpython-313.pyc +0 -0
- package/core/workflow/__pycache__/loader.cpython-313.pyc +0 -0
- package/core/workflow/__pycache__/schema.cpython-313.pyc +0 -0
- package/core/workflow/engine.py +44 -0
- package/core/workflow/schema.py +1 -0
- package/departments/dev/skills/agent-design/SKILL.md +4 -0
- package/departments/dev/skills/agent-design/references/architecture-patterns.md +223 -0
- package/departments/dev/skills/ai-security/SKILL.md +4 -0
- package/departments/dev/skills/ai-security/references/prompt-injection-catalog.md +230 -0
- package/departments/dev/skills/ci-cd-pipeline/SKILL.md +4 -0
- package/departments/dev/skills/ci-cd-pipeline/references/github-actions-patterns.md +202 -0
- package/departments/dev/skills/db-schema/SKILL.md +4 -0
- package/departments/dev/skills/db-schema/references/indexing-strategy.md +197 -0
- package/departments/dev/skills/dependency-audit/SKILL.md +4 -0
- package/departments/dev/skills/dependency-audit/references/license-matrix.md +191 -0
- package/departments/dev/skills/incident/SKILL.md +4 -0
- package/departments/dev/skills/incident/references/severity-playbook.md +221 -0
- package/departments/dev/skills/observability/SKILL.md +4 -0
- package/departments/dev/skills/observability/references/slo-design.md +200 -0
- package/departments/dev/skills/rag-architect/SKILL.md +5 -0
- package/departments/dev/skills/rag-architect/references/chunking-strategies.md +129 -0
- package/departments/dev/skills/rag-architect/references/evaluation-guide.md +158 -0
- package/departments/dev/skills/red-team/SKILL.md +4 -0
- package/departments/dev/skills/red-team/references/mitre-attack-web.md +165 -0
- package/departments/dev/skills/security-audit/SKILL.md +4 -0
- package/departments/dev/skills/security-audit/references/owasp-2025-deep.md +409 -0
- package/departments/dev/skills/security-compliance/SKILL.md +117 -0
- package/departments/finance/skills/ciso-advisor/SKILL.md +4 -0
- package/departments/finance/skills/ciso-advisor/references/compliance-roadmap.md +172 -0
- package/departments/marketing/skills/programmatic-seo/SKILL.md +4 -0
- package/departments/marketing/skills/programmatic-seo/references/template-playbooks.md +289 -0
- package/departments/ops/skills/gdpr-compliance/SKILL.md +104 -0
- package/departments/ops/skills/iso27001/SKILL.md +113 -0
- package/departments/ops/skills/quality-management/SKILL.md +118 -0
- package/departments/ops/skills/risk-management/SKILL.md +120 -0
- package/departments/ops/skills/soc2-compliance/SKILL.md +120 -0
- package/departments/strategy/skills/cto-advisor/SKILL.md +4 -0
- package/departments/strategy/skills/cto-advisor/references/build-vs-buy-framework.md +190 -0
- package/installer/cli.js +13 -2
- package/installer/index.js +1 -2
- package/installer/migrate.js +123 -0
- package/installer/update.js +28 -15
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/core/agents/__pycache__/registry_gen.cpython-313.pyc +0 -0
package/README.md
CHANGED
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
# ArkaOS
|
|
2
2
|
|
|
3
|
-
**The Operating System for AI Agent Teams.**
|
|
3
|
+
**The Operating System for AI Agent Teams.** 62 agents across 17 departments, 250+ skills backed by 116 enterprise frameworks, 8 Python CLI tools. One install.
|
|
4
4
|
|
|
5
5
|
```
|
|
6
6
|
npx arkaos install
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
+
[](https://github.com/andreagroferreira/arka-os/actions) [](https://www.npmjs.com/package/arkaos) [](LICENSE)
|
|
10
|
+
|
|
9
11
|
## What ArkaOS Does
|
|
10
12
|
|
|
11
|
-
ArkaOS orchestrates AI agents that cover every business function. Not just code. Marketing, brand, finance, strategy, sales, operations, product management, e-commerce, communities, content, and more.
|
|
13
|
+
ArkaOS orchestrates AI agents that cover every business function. Not just code. Marketing, brand, finance, strategy, sales, operations, compliance, product management, e-commerce, communities, content, and more.
|
|
12
14
|
|
|
13
|
-
Each agent has a defined role, personality, expertise, and authority level. They work in squads, follow
|
|
15
|
+
Each agent has a defined role, personality, expertise, and authority level. They work in squads, follow YAML workflows, and every output passes through a mandatory Quality Gate.
|
|
14
16
|
|
|
15
17
|
```
|
|
16
18
|
You: "validate my saas idea for a scheduling tool"
|
|
19
|
+
|
|
17
20
|
ArkaOS: → Routes to SaaS department
|
|
18
21
|
→ Tiago (SaaS Strategist) leads validation workflow
|
|
19
|
-
→ Market sizing, competitor analysis, business model, pricing
|
|
22
|
+
→ Market sizing, competitor analysis, business model, pricing
|
|
20
23
|
→ Financial viability check by Leonor (Financial Analyst)
|
|
21
24
|
→ Quality Gate: Marta, Eduardo, Francisca review
|
|
22
25
|
→ Delivers: validated report with go/no-go recommendation
|
|
@@ -25,108 +28,127 @@ ArkaOS: → Routes to SaaS department
|
|
|
25
28
|
## Install
|
|
26
29
|
|
|
27
30
|
```bash
|
|
28
|
-
#
|
|
29
|
-
npx arkaos install
|
|
30
|
-
|
|
31
|
-
# Or specify the runtime
|
|
31
|
+
npx arkaos install # auto-detects runtime
|
|
32
32
|
npx arkaos install --runtime claude-code
|
|
33
33
|
npx arkaos install --runtime codex
|
|
34
34
|
npx arkaos install --runtime gemini
|
|
35
35
|
npx arkaos install --runtime cursor
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
Requires
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
|
45
|
-
|
|
46
|
-
|
|
|
47
|
-
|
|
|
48
|
-
|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
|
|
|
54
|
-
|
|
|
55
|
-
|
|
|
56
|
-
|
|
|
57
|
-
|
|
|
58
|
-
|
|
|
59
|
-
|
|
|
60
|
-
|
|
|
38
|
+
Requires Node.js 18+ and Python 3.11+.
|
|
39
|
+
|
|
40
|
+
**Upgrading from v1?** Run `npx arkaos migrate`
|
|
41
|
+
|
|
42
|
+
## 17 Departments, 62 Agents
|
|
43
|
+
|
|
44
|
+
| Department | Prefix | Agents | Skills | What It Does |
|
|
45
|
+
|-----------|--------|--------|--------|-------------|
|
|
46
|
+
| Development | `/dev` | 9 | 41 | Features, APIs, architecture, security, CI/CD, RAG, agents |
|
|
47
|
+
| Marketing | `/mkt` | 4 | 14 | SEO, paid ads, email, growth loops, programmatic SEO |
|
|
48
|
+
| Brand & Design | `/brand` | 4 | 12 | Brand identity, UX/UI, design systems, naming |
|
|
49
|
+
| Finance | `/fin` | 3 | 8 | DCF valuation, unit economics, CISO advisory |
|
|
50
|
+
| Strategy | `/strat` | 3 | 9 | Five Forces, Blue Ocean, BMC, CTO/board advisory |
|
|
51
|
+
| E-Commerce | `/ecom` | 4 | 12 | Store optimization, CRO, RFM, pricing |
|
|
52
|
+
| Knowledge | `/kb` | 3 | 12 | Research, Zettelkasten, personas, Obsidian |
|
|
53
|
+
| Operations | `/ops` | 2 | 15 | Automation, SOPs, GDPR, ISO 27001, SOC 2, risk |
|
|
54
|
+
| Project Mgmt | `/pm` | 3 | 13 | Scrum, Shape Up, discovery, agile PO |
|
|
55
|
+
| SaaS | `/saas` | 3 | 15 | Validation, metrics, PLG, scaffolding |
|
|
56
|
+
| Landing Pages | `/landing` | 4 | 15 | Sales copy, funnels, offers, page generation |
|
|
57
|
+
| Content | `/content` | 4 | 14 | Viral design, hooks, scripts, repurposing |
|
|
58
|
+
| Communities | `/community` | 2 | 14 | Groups, membership, gamification |
|
|
59
|
+
| Sales | `/sales` | 2 | 10 | Pipeline, SPIN selling, negotiation |
|
|
60
|
+
| Leadership | `/lead` | 2 | 10 | Team health, OKRs, culture, hiring |
|
|
61
|
+
| Organization | `/org` | 1 | 10 | Org design, team topologies |
|
|
62
|
+
| **Quality Gate** | (auto) | 3 | — | Mandatory on every workflow. Veto power. |
|
|
61
63
|
|
|
62
64
|
## How It Works
|
|
63
65
|
|
|
64
66
|
**Just describe what you need.** ArkaOS routes it to the right squad.
|
|
65
67
|
|
|
66
68
|
```
|
|
67
|
-
"add user authentication"
|
|
68
|
-
"create a brand for my app"
|
|
69
|
-
"plan our Q3 budget"
|
|
70
|
-
"design a sales funnel"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
69
|
+
"add user authentication" → /dev feature
|
|
70
|
+
"create a brand for my app" → /brand identity
|
|
71
|
+
"plan our Q3 budget" → /fin budget
|
|
72
|
+
"design a sales funnel" → /landing funnel
|
|
73
|
+
"are we GDPR compliant?" → /ops gdpr-compliance
|
|
74
|
+
"score these headlines" → python scripts/tools/headline_scorer.py
|
|
73
75
|
```
|
|
74
76
|
|
|
75
|
-
Or use explicit commands: `/dev feature "user auth"`, `/saas validate "scheduling tool"
|
|
77
|
+
Or use explicit commands: `/dev feature "user auth"`, `/saas validate "scheduling tool"`
|
|
78
|
+
|
|
79
|
+
## Python CLI Tools
|
|
80
|
+
|
|
81
|
+
8 stdlib-only tools for quantitative analysis. No dependencies.
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
python scripts/tools/headline_scorer.py "10x Your Revenue" --json
|
|
85
|
+
python scripts/tools/seo_checker.py page.html --json
|
|
86
|
+
python scripts/tools/rice_prioritizer.py features.json --json
|
|
87
|
+
python scripts/tools/dcf_calculator.py --revenue 1000000 --growth 20 --json
|
|
88
|
+
python scripts/tools/tech_debt_analyzer.py src/ --json
|
|
89
|
+
python scripts/tools/saas_metrics.py --new-mrr 50000 --json
|
|
90
|
+
python scripts/tools/brand_voice_analyzer.py content.txt --json
|
|
91
|
+
python scripts/tools/okr_cascade.py growth --json
|
|
92
|
+
```
|
|
76
93
|
|
|
77
94
|
## Agent DNA
|
|
78
95
|
|
|
79
|
-
Every agent has a
|
|
96
|
+
Every agent has a behavioral profile from 4 frameworks:
|
|
80
97
|
|
|
81
|
-
- **DISC** — How they communicate
|
|
98
|
+
- **DISC** — How they communicate
|
|
82
99
|
- **Enneagram** — What motivates them (9 types with wings)
|
|
83
|
-
- **Big Five** — Personality traits
|
|
84
|
-
- **MBTI** — How they process information
|
|
85
|
-
|
|
86
|
-
This creates agents with consistent, realistic personalities that communicate differently based on their role and the situation.
|
|
100
|
+
- **Big Five** — Personality traits (0-100 scale)
|
|
101
|
+
- **MBTI** — How they process information
|
|
87
102
|
|
|
88
103
|
## Quality Gate
|
|
89
104
|
|
|
90
|
-
Nothing reaches you without
|
|
105
|
+
Nothing reaches you without all three reviewers:
|
|
106
|
+
|
|
107
|
+
- **Marta** (CQO) — orchestrates and issues final verdict
|
|
108
|
+
- **Eduardo** — text quality: spelling, grammar, tone, AI patterns
|
|
109
|
+
- **Francisca** — technical quality: code, tests, UX, security
|
|
91
110
|
|
|
92
|
-
|
|
93
|
-
- **Eduardo** reviews all text: spelling, grammar, tone, AI patterns
|
|
94
|
-
- **Francisca** reviews all technical output: code quality, tests, UX, security
|
|
111
|
+
APPROVED or REJECTED. No exceptions.
|
|
95
112
|
|
|
96
|
-
|
|
113
|
+
## The Conclave
|
|
114
|
+
|
|
115
|
+
Personal AI advisory board with 20 real-world advisor personas (Munger, Dalio, Bezos, Naval, Jobs, Sinek, etc.). Matched to your behavioral DNA via 17-question profiling.
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
/arka conclave # Start profiling
|
|
119
|
+
/arka conclave ask # Ask all advisors
|
|
120
|
+
/arka conclave debate # Advisors debate a topic
|
|
121
|
+
```
|
|
97
122
|
|
|
98
123
|
## Enterprise Frameworks
|
|
99
124
|
|
|
100
|
-
ArkaOS agents
|
|
125
|
+
ArkaOS agents apply validated frameworks, not generic prompts:
|
|
101
126
|
|
|
102
127
|
| Area | Frameworks |
|
|
103
128
|
|------|-----------|
|
|
104
|
-
| Development | Clean Code, SOLID, DDD, TDD, DORA
|
|
129
|
+
| Development | Clean Code, SOLID, DDD, TDD, DORA, OWASP, MITRE ATT&CK |
|
|
105
130
|
| Branding | Primal Branding, StoryBrand, 12 Archetypes, Positioning |
|
|
106
131
|
| Strategy | Porter's Five Forces, Blue Ocean, BMC, Wardley Maps, 7 Powers |
|
|
107
|
-
| Finance | DCF Valuation, Unit Economics, COSO ERM,
|
|
132
|
+
| Finance | DCF Valuation, Unit Economics, COSO ERM, ALE Risk Quantification |
|
|
108
133
|
| Marketing | AARRR, Growth Loops, Schwartz 5 Levels, PLG, STEPPS |
|
|
109
|
-
|
|
|
110
|
-
|
|
|
111
|
-
| PM | Scrum, Kanban, Shape Up, Continuous Discovery, Monte Carlo |
|
|
134
|
+
| Compliance | GDPR, ISO 27001, SOC 2, ISO 31000, ISO 9001 |
|
|
135
|
+
| PM | Scrum, Kanban, Shape Up, Continuous Discovery, RICE |
|
|
112
136
|
|
|
113
137
|
## Multi-Runtime
|
|
114
138
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
|
118
|
-
|
|
119
|
-
|
|
|
120
|
-
|
|
|
121
|
-
| Gemini CLI | Supported | Subagents, MCP, 1M context |
|
|
122
|
-
| Cursor | Supported | Agent mode, MCP |
|
|
139
|
+
| Runtime | Status |
|
|
140
|
+
|---------|--------|
|
|
141
|
+
| Claude Code | Primary — hooks, subagents, MCP, 1M context |
|
|
142
|
+
| Codex CLI | Supported — subagents, sandboxed execution |
|
|
143
|
+
| Gemini CLI | Supported — subagents, MCP, 1M context |
|
|
144
|
+
| Cursor | Supported — agent mode, MCP |
|
|
123
145
|
|
|
124
146
|
## Architecture
|
|
125
147
|
|
|
126
148
|
```
|
|
127
149
|
User Input
|
|
128
150
|
↓
|
|
129
|
-
Synapse (8-layer context injection
|
|
151
|
+
Synapse (8-layer context injection)
|
|
130
152
|
↓
|
|
131
153
|
Orchestrator (/do → department routing)
|
|
132
154
|
↓
|
|
@@ -134,21 +156,25 @@ Squad (YAML workflow with phases and gates)
|
|
|
134
156
|
↓
|
|
135
157
|
Quality Gate (Marta + Eduardo + Francisca)
|
|
136
158
|
↓
|
|
137
|
-
|
|
159
|
+
Output (Obsidian vault + structured deliverables)
|
|
138
160
|
```
|
|
139
161
|
|
|
140
|
-
Built with: Python core engine, Node.js installer, Bash hooks, YAML workflows.
|
|
162
|
+
Built with: Python core engine, Node.js installer, Bash hooks, YAML workflows, 1688 tests.
|
|
141
163
|
|
|
142
|
-
##
|
|
164
|
+
## Commands
|
|
143
165
|
|
|
144
|
-
|
|
166
|
+
```bash
|
|
167
|
+
npx arkaos install # Install
|
|
168
|
+
npx arkaos update # Update to latest
|
|
169
|
+
npx arkaos migrate # Migrate from v1
|
|
170
|
+
npx arkaos doctor # Health check
|
|
171
|
+
npx arkaos uninstall # Remove
|
|
172
|
+
```
|
|
145
173
|
|
|
146
|
-
|
|
174
|
+
## Contributing
|
|
147
175
|
|
|
148
|
-
|
|
176
|
+
See [CONTRIBUTING.md](.github/CONTRIBUTING.md). PRs welcome — all changes require review.
|
|
149
177
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
---
|
|
178
|
+
## License
|
|
153
179
|
|
|
154
|
-
|
|
180
|
+
MIT — [WizardingCode](https://wizardingcode.com)
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.0.
|
|
1
|
+
2.0.2
|
package/bin/arkaos
CHANGED
package/config/constitution.yaml
CHANGED
|
@@ -118,6 +118,10 @@ enforcement_levels:
|
|
|
118
118
|
- id: complexity-assessment
|
|
119
119
|
rule: "Assess task complexity before starting. Route to appropriate workflow tier."
|
|
120
120
|
|
|
121
|
+
- id: communication-standard
|
|
122
|
+
rule: "Bottom-line first output. Lead with answer, then why, then how. Confidence tags on assessments."
|
|
123
|
+
enforcement: "See config/standards/communication.md for full standard"
|
|
124
|
+
|
|
121
125
|
tier_hierarchy:
|
|
122
126
|
description: "Agent authority levels inspired by SpaceX/Google/Anthropic org structures"
|
|
123
127
|
tiers:
|
|
@@ -19,7 +19,18 @@ _hook_ms() {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
# ─── Paths ───────────────────────────────────────────────────────────────
|
|
22
|
-
ARKAOS_ROOT
|
|
22
|
+
# Resolve ARKAOS_ROOT: env var → .repo-path → npm package → fallback
|
|
23
|
+
if [ -n "${ARKAOS_ROOT:-}" ]; then
|
|
24
|
+
: # already set
|
|
25
|
+
elif [ -f "$HOME/.arkaos/.repo-path" ]; then
|
|
26
|
+
ARKAOS_ROOT=$(cat "$HOME/.arkaos/.repo-path")
|
|
27
|
+
elif [ -d "$HOME/.arkaos" ]; then
|
|
28
|
+
ARKAOS_ROOT="$HOME/.arkaos"
|
|
29
|
+
else
|
|
30
|
+
ARKAOS_ROOT="${ARKA_OS:-$HOME/.claude/skills/arkaos}"
|
|
31
|
+
fi
|
|
32
|
+
export ARKAOS_ROOT
|
|
33
|
+
|
|
23
34
|
CACHE_DIR="/tmp/arkaos-context-cache"
|
|
24
35
|
CACHE_TTL=300 # Constitution cache: 5 minutes
|
|
25
36
|
|
|
@@ -35,46 +46,17 @@ if [ -z "$user_input" ]; then
|
|
|
35
46
|
user_input=$(echo "$input" | head -c 2000)
|
|
36
47
|
fi
|
|
37
48
|
|
|
38
|
-
# ─── Try Python Synapse
|
|
49
|
+
# ─── Try Python Synapse bridge first ────────────────────────────────────
|
|
39
50
|
python_result=""
|
|
40
|
-
|
|
41
|
-
python_result=$(python3 -c "
|
|
42
|
-
import sys, os
|
|
43
|
-
sys.path.insert(0, '${ARKAOS_ROOT}')
|
|
44
|
-
try:
|
|
45
|
-
from core.synapse.engine import create_default_engine
|
|
46
|
-
from core.synapse.layers import PromptContext
|
|
47
|
-
from core.governance.constitution import load_constitution
|
|
48
|
-
import subprocess
|
|
51
|
+
BRIDGE_SCRIPT="${ARKAOS_ROOT}/scripts/synapse-bridge.py"
|
|
49
52
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if os.path.exists(const_path):
|
|
54
|
-
c = load_constitution(const_path)
|
|
55
|
-
compressed = c.compress_for_context()
|
|
53
|
+
if command -v python3 &>/dev/null && [ -f "$BRIDGE_SCRIPT" ]; then
|
|
54
|
+
bridge_output=$(echo "{\"user_input\":$(echo "$user_input" | python3 -c "import sys,json; print(json.dumps(sys.stdin.read()))" 2>/dev/null || echo '""')}" \
|
|
55
|
+
| ARKAOS_ROOT="$ARKAOS_ROOT" python3 "$BRIDGE_SCRIPT" --root "$ARKAOS_ROOT" 2>/dev/null)
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
branch = subprocess.run(['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
|
|
61
|
-
capture_output=True, text=True, timeout=2).stdout.strip()
|
|
62
|
-
except Exception:
|
|
63
|
-
pass
|
|
64
|
-
|
|
65
|
-
# Create engine and inject
|
|
66
|
-
engine = create_default_engine(constitution_compressed=compressed)
|
|
67
|
-
ctx = PromptContext(
|
|
68
|
-
user_input='''${user_input}''',
|
|
69
|
-
cwd=os.getcwd(),
|
|
70
|
-
git_branch=branch,
|
|
71
|
-
)
|
|
72
|
-
result = engine.inject(ctx)
|
|
73
|
-
print(result.context_string)
|
|
74
|
-
except Exception as e:
|
|
75
|
-
print(f'[arkaos:error] {e}', file=sys.stderr)
|
|
76
|
-
print('')
|
|
77
|
-
" 2>/dev/null)
|
|
57
|
+
if [ -n "$bridge_output" ]; then
|
|
58
|
+
python_result=$(echo "$bridge_output" | python3 -c "import sys,json; print(json.loads(sys.stdin.read()).get('context_string',''))" 2>/dev/null)
|
|
59
|
+
fi
|
|
78
60
|
fi
|
|
79
61
|
|
|
80
62
|
# ─── Fallback: Bash-only context (if Python unavailable) ────────────────
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"""Token budget system — tracking and enforcement for agent operations."""
|
|
2
|
+
|
|
3
|
+
from core.budget.schema import BudgetConfig, BudgetUsage, BudgetSummary, TierBudget
|
|
4
|
+
from core.budget.manager import BudgetManager
|
|
5
|
+
|
|
6
|
+
__all__ = ["BudgetConfig", "BudgetUsage", "BudgetSummary", "TierBudget", "BudgetManager"]
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"""Budget manager — track, enforce, and report on token budgets."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from datetime import date, datetime
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
from core.budget.schema import BudgetConfig, BudgetSummary, BudgetUsage, TierBudget
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class BudgetManager:
|
|
12
|
+
"""Manages token budget allocation, tracking, and enforcement.
|
|
13
|
+
|
|
14
|
+
Budgets are tier-based with monthly reset. Usage is persisted to JSON.
|
|
15
|
+
Tier 0 agents have unlimited budgets. Other tiers need Tier 0 approval
|
|
16
|
+
when usage exceeds the approval threshold (default 80%).
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(self, storage_path: str | Path = "", config: BudgetConfig | None = None) -> None:
|
|
20
|
+
self._config = config or BudgetConfig()
|
|
21
|
+
self._usages: list[BudgetUsage] = []
|
|
22
|
+
self._counter: int = 0
|
|
23
|
+
self._storage_path = Path(storage_path) if storage_path else None
|
|
24
|
+
if self._storage_path and self._storage_path.exists():
|
|
25
|
+
self._load()
|
|
26
|
+
|
|
27
|
+
def record_usage(
|
|
28
|
+
self,
|
|
29
|
+
agent_id: str,
|
|
30
|
+
tokens: int,
|
|
31
|
+
tier: int = 2,
|
|
32
|
+
department: str = "",
|
|
33
|
+
workflow_id: str = "",
|
|
34
|
+
task_id: str = "",
|
|
35
|
+
description: str = "",
|
|
36
|
+
approved_by: str = "",
|
|
37
|
+
) -> BudgetUsage:
|
|
38
|
+
"""Record a token usage event."""
|
|
39
|
+
self._counter += 1
|
|
40
|
+
usage = BudgetUsage(
|
|
41
|
+
id=f"usage-{self._counter:06d}",
|
|
42
|
+
agent_id=agent_id,
|
|
43
|
+
department=department,
|
|
44
|
+
tier=tier,
|
|
45
|
+
tokens=tokens,
|
|
46
|
+
workflow_id=workflow_id,
|
|
47
|
+
task_id=task_id,
|
|
48
|
+
description=description,
|
|
49
|
+
timestamp=datetime.now().isoformat(),
|
|
50
|
+
approved_by=approved_by,
|
|
51
|
+
)
|
|
52
|
+
self._usages.append(usage)
|
|
53
|
+
self._save()
|
|
54
|
+
return usage
|
|
55
|
+
|
|
56
|
+
def get_period_usage(self, tier: int, department: str = "") -> int:
|
|
57
|
+
"""Get total tokens used this billing period for a tier/department."""
|
|
58
|
+
period_start = self._current_period_start()
|
|
59
|
+
total = 0
|
|
60
|
+
for u in self._usages:
|
|
61
|
+
if u.tier != tier:
|
|
62
|
+
continue
|
|
63
|
+
if department and u.department != department:
|
|
64
|
+
continue
|
|
65
|
+
if u.timestamp and u.timestamp >= period_start.isoformat():
|
|
66
|
+
total += u.tokens
|
|
67
|
+
return total
|
|
68
|
+
|
|
69
|
+
def get_remaining(self, tier: int, department: str = "") -> int:
|
|
70
|
+
"""Get remaining tokens for this period. Returns -1 for unlimited."""
|
|
71
|
+
budget = self._config.get_tier_budget(tier)
|
|
72
|
+
if budget.is_unlimited:
|
|
73
|
+
return -1
|
|
74
|
+
used = self.get_period_usage(tier, department)
|
|
75
|
+
return max(0, budget.monthly_tokens - used)
|
|
76
|
+
|
|
77
|
+
def check_budget(self, tier: int, estimated_tokens: int, department: str = "") -> bool:
|
|
78
|
+
"""Check if there's enough budget for an operation. True = OK."""
|
|
79
|
+
budget = self._config.get_tier_budget(tier)
|
|
80
|
+
if budget.is_unlimited:
|
|
81
|
+
return True
|
|
82
|
+
|
|
83
|
+
# Check per-task limit
|
|
84
|
+
if budget.per_task_max > 0 and estimated_tokens > budget.per_task_max:
|
|
85
|
+
return False
|
|
86
|
+
|
|
87
|
+
# Check remaining monthly budget
|
|
88
|
+
remaining = self.get_remaining(tier, department)
|
|
89
|
+
return estimated_tokens <= remaining
|
|
90
|
+
|
|
91
|
+
def needs_approval(self, tier: int, department: str = "") -> bool:
|
|
92
|
+
"""Check if usage has exceeded the approval threshold."""
|
|
93
|
+
budget = self._config.get_tier_budget(tier)
|
|
94
|
+
if budget.is_unlimited:
|
|
95
|
+
return False
|
|
96
|
+
used = self.get_period_usage(tier, department)
|
|
97
|
+
return used >= (budget.monthly_tokens * budget.approval_threshold)
|
|
98
|
+
|
|
99
|
+
def get_summary(self, tier: int, department: str = "") -> BudgetSummary:
|
|
100
|
+
"""Get a complete budget summary for a tier/department."""
|
|
101
|
+
budget = self._config.get_tier_budget(tier)
|
|
102
|
+
used = self.get_period_usage(tier, department)
|
|
103
|
+
period_start = self._current_period_start()
|
|
104
|
+
|
|
105
|
+
if budget.is_unlimited:
|
|
106
|
+
return BudgetSummary(
|
|
107
|
+
tier=tier,
|
|
108
|
+
department=department,
|
|
109
|
+
period_start=period_start.isoformat(),
|
|
110
|
+
allocated=0,
|
|
111
|
+
used=used,
|
|
112
|
+
remaining=-1,
|
|
113
|
+
percent_used=0,
|
|
114
|
+
is_unlimited=True,
|
|
115
|
+
usage_count=self._count_period_usages(tier, department),
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
remaining = max(0, budget.monthly_tokens - used)
|
|
119
|
+
percent = (used / budget.monthly_tokens * 100) if budget.monthly_tokens > 0 else 0
|
|
120
|
+
overruns = sum(
|
|
121
|
+
1 for u in self._usages
|
|
122
|
+
if u.tier == tier
|
|
123
|
+
and (not department or u.department == department)
|
|
124
|
+
and u.timestamp >= period_start.isoformat()
|
|
125
|
+
and u.is_overrun_approved
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
return BudgetSummary(
|
|
129
|
+
tier=tier,
|
|
130
|
+
department=department,
|
|
131
|
+
period_start=period_start.isoformat(),
|
|
132
|
+
allocated=budget.monthly_tokens,
|
|
133
|
+
used=used,
|
|
134
|
+
remaining=remaining,
|
|
135
|
+
percent_used=round(percent, 1),
|
|
136
|
+
is_unlimited=False,
|
|
137
|
+
needs_approval=self.needs_approval(tier, department),
|
|
138
|
+
usage_count=self._count_period_usages(tier, department),
|
|
139
|
+
overruns=overruns,
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
def reset_monthly(self) -> int:
|
|
143
|
+
"""Archive old usages and start a new billing period. Returns archived count."""
|
|
144
|
+
period_start = self._current_period_start()
|
|
145
|
+
old = [u for u in self._usages if u.timestamp < period_start.isoformat()]
|
|
146
|
+
self._usages = [u for u in self._usages if u.timestamp >= period_start.isoformat()]
|
|
147
|
+
self._save()
|
|
148
|
+
return len(old)
|
|
149
|
+
|
|
150
|
+
def _current_period_start(self) -> date:
|
|
151
|
+
"""Get the start of the current billing period."""
|
|
152
|
+
today = date.today()
|
|
153
|
+
day = self._config.billing_start_day
|
|
154
|
+
if today.day >= day:
|
|
155
|
+
return date(today.year, today.month, day)
|
|
156
|
+
# Previous month
|
|
157
|
+
month = today.month - 1
|
|
158
|
+
year = today.year
|
|
159
|
+
if month < 1:
|
|
160
|
+
month = 12
|
|
161
|
+
year -= 1
|
|
162
|
+
return date(year, month, day)
|
|
163
|
+
|
|
164
|
+
def _count_period_usages(self, tier: int, department: str = "") -> int:
|
|
165
|
+
period_start = self._current_period_start()
|
|
166
|
+
return sum(
|
|
167
|
+
1 for u in self._usages
|
|
168
|
+
if u.tier == tier
|
|
169
|
+
and (not department or u.department == department)
|
|
170
|
+
and u.timestamp >= period_start.isoformat()
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
def _save(self) -> None:
|
|
174
|
+
if self._storage_path is None:
|
|
175
|
+
return
|
|
176
|
+
self._storage_path.parent.mkdir(parents=True, exist_ok=True)
|
|
177
|
+
data = {
|
|
178
|
+
"counter": self._counter,
|
|
179
|
+
"usages": [u.model_dump(mode="json") for u in self._usages],
|
|
180
|
+
}
|
|
181
|
+
with open(self._storage_path, "w") as f:
|
|
182
|
+
json.dump(data, f, indent=2)
|
|
183
|
+
|
|
184
|
+
def _load(self) -> None:
|
|
185
|
+
if self._storage_path is None or not self._storage_path.exists():
|
|
186
|
+
return
|
|
187
|
+
content = self._storage_path.read_text().strip()
|
|
188
|
+
if not content:
|
|
189
|
+
return
|
|
190
|
+
data = json.loads(content)
|
|
191
|
+
self._counter = data.get("counter", 0)
|
|
192
|
+
for udata in data.get("usages", []):
|
|
193
|
+
self._usages.append(BudgetUsage.model_validate(udata))
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""Budget schema — token allocation, usage tracking, and summaries."""
|
|
2
|
+
|
|
3
|
+
from datetime import date, datetime
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TierBudget(BaseModel):
|
|
10
|
+
"""Token budget for a single agent tier."""
|
|
11
|
+
tier: int
|
|
12
|
+
monthly_tokens: int # 0 = unlimited
|
|
13
|
+
per_task_max: int # 0 = unlimited
|
|
14
|
+
approval_threshold: float = 0.8 # Needs Tier 0 approval at this % used
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def is_unlimited(self) -> bool:
|
|
18
|
+
return self.monthly_tokens == 0
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# Default tier budgets (configurable via BudgetConfig)
|
|
22
|
+
DEFAULT_TIER_BUDGETS = {
|
|
23
|
+
0: TierBudget(tier=0, monthly_tokens=0, per_task_max=0), # Unlimited
|
|
24
|
+
1: TierBudget(tier=1, monthly_tokens=5_000_000, per_task_max=500_000),
|
|
25
|
+
2: TierBudget(tier=2, monthly_tokens=2_000_000, per_task_max=200_000),
|
|
26
|
+
3: TierBudget(tier=3, monthly_tokens=1_000_000, per_task_max=100_000),
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class BudgetConfig(BaseModel):
|
|
31
|
+
"""Budget configuration for the system."""
|
|
32
|
+
tier_budgets: dict[int, TierBudget] = Field(default_factory=lambda: dict(DEFAULT_TIER_BUDGETS))
|
|
33
|
+
billing_start_day: int = 1 # Day of month billing resets
|
|
34
|
+
|
|
35
|
+
def get_tier_budget(self, tier: int) -> TierBudget:
|
|
36
|
+
return self.tier_budgets.get(tier, DEFAULT_TIER_BUDGETS.get(tier, TierBudget(tier=tier, monthly_tokens=1_000_000, per_task_max=100_000)))
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class BudgetUsage(BaseModel):
|
|
40
|
+
"""A single token usage record."""
|
|
41
|
+
id: str
|
|
42
|
+
agent_id: str
|
|
43
|
+
department: str = ""
|
|
44
|
+
tier: int = 2
|
|
45
|
+
tokens: int = 0
|
|
46
|
+
workflow_id: str = ""
|
|
47
|
+
task_id: str = ""
|
|
48
|
+
description: str = ""
|
|
49
|
+
timestamp: str = ""
|
|
50
|
+
approved_by: str = "" # Tier 0 agent who approved overrun
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def is_overrun_approved(self) -> bool:
|
|
54
|
+
return bool(self.approved_by)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class BudgetSummary(BaseModel):
|
|
58
|
+
"""Current budget status for a tier or department."""
|
|
59
|
+
tier: int
|
|
60
|
+
department: str = ""
|
|
61
|
+
period_start: str = ""
|
|
62
|
+
period_end: str = ""
|
|
63
|
+
allocated: int = 0 # Monthly allocation
|
|
64
|
+
used: int = 0 # Tokens used this period
|
|
65
|
+
remaining: int = 0 # Tokens remaining
|
|
66
|
+
percent_used: float = 0.0 # 0-100
|
|
67
|
+
is_unlimited: bool = False
|
|
68
|
+
needs_approval: bool = False # >80% threshold
|
|
69
|
+
usage_count: int = 0 # Number of operations this period
|
|
70
|
+
overruns: int = 0 # Number of approved overruns
|
|
71
|
+
|
|
72
|
+
@property
|
|
73
|
+
def status(self) -> str:
|
|
74
|
+
if self.is_unlimited:
|
|
75
|
+
return "UNLIMITED"
|
|
76
|
+
if self.percent_used >= 100:
|
|
77
|
+
return "EXCEEDED"
|
|
78
|
+
if self.needs_approval:
|
|
79
|
+
return "APPROVAL_REQUIRED"
|
|
80
|
+
if self.percent_used >= 50:
|
|
81
|
+
return "MODERATE"
|
|
82
|
+
return "HEALTHY"
|