@matt82198/aesop 0.1.0 → 0.3.1
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/CHANGELOG.md +117 -2
- package/README.md +59 -218
- package/bin/cli.js +168 -41
- package/daemons/run-watchdog.sh +16 -4
- package/daemons/selfheal.sh +231 -0
- package/docs/ANY-REPO.md +427 -0
- package/docs/CONTRIBUTING.md +72 -0
- package/docs/DEMO.md +334 -0
- package/docs/HOOK-INSTALL.md +15 -56
- package/docs/INSTALL.md +74 -4
- package/docs/PORTING.md +166 -0
- package/docs/README.md +33 -3
- package/docs/TEAM-STATE.md +372 -0
- package/docs/reproduce.md +33 -3
- package/driver/CLAUDE.md +150 -0
- package/driver/README.md +383 -0
- package/driver/aesop.config.example.json +80 -0
- package/driver/agent_driver.py +355 -0
- package/driver/backend_config.py +253 -0
- package/driver/claude_code_driver.py +198 -0
- package/driver/codex_driver.py +673 -0
- package/driver/openai_compatible_driver.py +249 -0
- package/driver/openai_transport.py +179 -0
- package/driver/verification_policy.py +75 -0
- package/driver/wave_bridge.py +254 -0
- package/driver/wave_loop.py +1408 -0
- package/driver/wave_scheduler.py +890 -0
- package/hooks/pre-push-policy.sh +131 -33
- package/mcp/server.mjs +320 -4
- package/monitor/collect-signals.mjs +69 -0
- package/package.json +22 -14
- package/skills/CLAUDE.md +132 -2
- package/skills/buildsystem/SKILL.md +330 -0
- package/skills/buildsystem/wave-flat-dispatch.template.mjs +658 -0
- package/skills/fleet/SKILL.md +113 -0
- package/skills/power/SKILL.md +246 -131
- package/state_store/__init__.py +4 -2
- package/state_store/api.py +19 -4
- package/state_store/coordination.py +209 -0
- package/state_store/identity.py +51 -0
- package/state_store/projections.py +63 -0
- package/state_store/read_api.py +156 -0
- package/state_store/store.py +185 -73
- package/state_store/write_api.py +462 -0
- package/templates/wave-presets/data.json +65 -0
- package/templates/wave-presets/library.json +65 -0
- package/templates/wave-presets/saas.json +64 -0
- package/tools/audit_report.py +388 -0
- package/tools/bench_runner.py +100 -3
- package/tools/ci_merge_wait.py +256 -35
- package/tools/ci_workflow_lint.py +430 -0
- package/tools/claudemd_drift.py +394 -0
- package/tools/claudemd_lint.py +359 -0
- package/tools/common.py +39 -3
- package/tools/cost_ceiling.py +166 -43
- package/tools/cost_econ.py +480 -0
- package/tools/cost_projection.py +559 -0
- package/tools/crossos_drift.py +394 -0
- package/tools/defect_escape.py +252 -0
- package/tools/doctor.js +1 -1
- package/tools/eod_sweep.py +188 -26
- package/tools/fleet.js +260 -0
- package/tools/fleet_ledger.py +209 -7
- package/tools/git_identity_check.py +315 -0
- package/tools/health-score.js +40 -0
- package/tools/health_score.py +361 -0
- package/tools/metrics_gate.py +13 -4
- package/tools/mutation_test.py +523 -0
- package/tools/portability_check.py +206 -0
- package/tools/proposals.mjs +47 -2
- package/tools/reconcile.py +7 -4
- package/tools/reproduce.js +405 -0
- package/tools/secret_scan.py +207 -65
- package/tools/self_stats.py +20 -0
- package/tools/stall_check.py +247 -16
- package/tools/stateapi_lint.py +325 -0
- package/tools/test_battery.py +173 -0
- package/tools/transcript_digest.py +380 -0
- package/tools/verify_activity_filter.py +437 -0
- package/tools/verify_agent_inspector.py +2 -0
- package/tools/verify_cost_panel.py +345 -0
- package/tools/verify_dash.py +2 -0
- package/tools/verify_dispatch_panel.py +301 -0
- package/tools/verify_failure_drilldown.py +188 -0
- package/tools/verify_prboard.py +2 -0
- package/tools/verify_scorecards.py +281 -0
- package/tools/verify_submit_encoding.py +2 -0
- package/tools/verify_ui_trio.py +409 -0
- package/tools/verify_wave_telemetry.py +268 -0
- package/tools/wave_backlog_analyzer.py +490 -0
- package/tools/wave_ledger_hook.py +150 -0
- package/tools/wave_preflight.py +779 -0
- package/tools/wave_resume.py +215 -0
- package/tools/wave_templates.py +340 -0
- package/ui/agents.py +68 -14
- package/ui/collectors.py +81 -55
- package/ui/config.py +7 -2
- package/ui/cost.py +231 -12
- package/ui/handler.py +383 -55
- package/ui/quality_scorecard.py +232 -0
- package/ui/sse.py +3 -3
- package/ui/wave_audit_tail.py +213 -0
- package/ui/wave_dispatch.py +280 -0
- package/ui/wave_failure.py +288 -0
- package/ui/wave_gantt.py +152 -0
- package/ui/wave_reasoning_tail.py +176 -0
- package/ui/wave_telemetry.py +383 -0
- package/ui/web/dist/assets/index-CNQxaiOW.css +1 -0
- package/ui/web/dist/assets/index-CP68RIh3.js +9 -0
- package/ui/web/dist/index.html +2 -2
- package/bin/CLAUDE.md +0 -76
- package/daemons/CLAUDE.md +0 -36
- package/dash/CLAUDE.md +0 -32
- package/docs/archive/README.md +0 -3
- package/docs/archive/spikes/tiered-cognition/ACTIVATION.md +0 -125
- package/docs/archive/spikes/tiered-cognition/DESIGN.md +0 -287
- package/docs/archive/spikes/tiered-cognition/FINDINGS.md +0 -113
- package/docs/archive/spikes/tiered-cognition/README.md +0 -27
- package/docs/archive/spikes/tiered-cognition/aesop-cognition.example.md +0 -32
- package/docs/archive/spikes/tiered-cognition/force-model-policy.merged.mjs +0 -673
- package/docs/archive/spikes/tiered-cognition/strip-tools-hook.mjs +0 -434
- package/hooks/CLAUDE.md +0 -89
- package/mcp/CLAUDE.md +0 -213
- package/monitor/CLAUDE.md +0 -40
- package/scan/CLAUDE.md +0 -30
- package/state_store/CLAUDE.md +0 -39
- package/tools/CLAUDE.md +0 -79
- package/ui/CLAUDE.md +0 -127
- package/ui/web/dist/assets/index-0qQYnvMC.js +0 -9
- package/ui/web/dist/assets/index-BdIlFieV.css +0 -1
package/docs/DEMO.md
ADDED
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
# Init-Prime-Demo: Your First Complete Aesop Flow
|
|
2
|
+
|
|
3
|
+
**TL;DR**: This 10-minute walkthrough takes you from nothing to a working orchestration harness, primed and ready for your first wave.
|
|
4
|
+
|
|
5
|
+
Covered in this demo:
|
|
6
|
+
1. Create a toy project (just a git repo)
|
|
7
|
+
2. Scaffold Aesop into a fleet harness
|
|
8
|
+
3. Run `/power` to prime the orchestrator
|
|
9
|
+
4. Understand what happens next
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## What You'll Need
|
|
14
|
+
|
|
15
|
+
Before starting, ensure you have:
|
|
16
|
+
|
|
17
|
+
- **Node.js** v18+ (for scaffolder and CLI)
|
|
18
|
+
- **Git** v2.40+ (for repo setup)
|
|
19
|
+
- **Bash** v4+ (for daemons; Windows: Git Bash)
|
|
20
|
+
- **Claude Code CLI** v0.1+ (for `/power` and `/buildsystem` skills)
|
|
21
|
+
|
|
22
|
+
Check versions:
|
|
23
|
+
```bash
|
|
24
|
+
node --version
|
|
25
|
+
git --version
|
|
26
|
+
bash --version
|
|
27
|
+
claude --version
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Step 1: Create a Toy Project (2 min)
|
|
33
|
+
|
|
34
|
+
This simulates a real project that Aesop will manage.
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Create a new directory and initialize git
|
|
38
|
+
mkdir ~/my-demo-project
|
|
39
|
+
cd ~/my-demo-project
|
|
40
|
+
git init
|
|
41
|
+
|
|
42
|
+
# Configure git (required for commits)
|
|
43
|
+
git config user.email "demo@aesop.test"
|
|
44
|
+
git config user.name "Demo User"
|
|
45
|
+
|
|
46
|
+
# Create a sample file and make an initial commit
|
|
47
|
+
echo "# My Demo Project" > README.md
|
|
48
|
+
git add README.md
|
|
49
|
+
git commit -m "Initial commit"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Your toy project is now ready. It's a clean git repo with one commit.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Step 2: Scaffold Aesop (2 min)
|
|
57
|
+
|
|
58
|
+
Create a fleet harness in a separate directory. The harness orchestrates your project(s).
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# Go to a working directory (e.g., your home or ~/projects)
|
|
62
|
+
cd ~
|
|
63
|
+
|
|
64
|
+
# Scaffold Aesop (creates ~/demo-fleet/)
|
|
65
|
+
npx @matt82198/aesop demo-fleet \
|
|
66
|
+
--name "demo-fleet" \
|
|
67
|
+
--repos "~/my-demo-project" \
|
|
68
|
+
--yes
|
|
69
|
+
|
|
70
|
+
# Move into the harness
|
|
71
|
+
cd ~/demo-fleet
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
What this does:
|
|
75
|
+
- Creates `daemons/`, `skills/`, `monitor/`, `tools/`, `ui/`, `docs/` subdirectories
|
|
76
|
+
- Generates `aesop.config.json` with your project path
|
|
77
|
+
- Creates `CLAUDE.md` (orchestrator brain template)
|
|
78
|
+
- Installs a git pre-push hook for secret scanning
|
|
79
|
+
- Initializes a git repo in the harness
|
|
80
|
+
|
|
81
|
+
Expected output:
|
|
82
|
+
```
|
|
83
|
+
✓ Creating ~/demo-fleet...
|
|
84
|
+
✓ Copying scaffold files...
|
|
85
|
+
✓ Generating CLAUDE.md...
|
|
86
|
+
✓ Generating aesop.config.json...
|
|
87
|
+
✓ Installing pre-push hook...
|
|
88
|
+
✓ Initializing git repo...
|
|
89
|
+
|
|
90
|
+
Next steps:
|
|
91
|
+
1. cd ~/demo-fleet
|
|
92
|
+
2. npx @matt82198/aesop doctor # Verify preflight checks
|
|
93
|
+
3. /power # Prime orchestrator brain
|
|
94
|
+
4. /buildsystem # Run your first wave
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Step 3: Verify Installation (1 min)
|
|
100
|
+
|
|
101
|
+
Run preflight checks to ensure everything is ready.
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
npx @matt82198/aesop doctor
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Expected output:
|
|
108
|
+
```
|
|
109
|
+
[doctor] Checking prerequisites...
|
|
110
|
+
✓ Node.js v18.14.0 found
|
|
111
|
+
✓ Git v2.42.0 found
|
|
112
|
+
✓ Bash v5.1.16 found
|
|
113
|
+
✓ Python v3.11.0 found (optional)
|
|
114
|
+
✓ aesop.config.json is readable
|
|
115
|
+
✓ Pre-push hook is installed and executable
|
|
116
|
+
✓ Port 8770 is available (for dashboard)
|
|
117
|
+
|
|
118
|
+
All checks passed. Ready to start.
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
If you see warnings about missing optional tools (Python, jq), that's OK for this demo. You can install them later.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Step 4: Prime the Orchestrator (/power) (3 min)
|
|
126
|
+
|
|
127
|
+
Now open Claude Code and invoke the `/power` skill. This reads your configuration and verifies the orchestrator is healthy.
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
/power
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
What `/power` does:
|
|
134
|
+
1. Reads `~/.claude/CLAUDE.md` (your global orchestrator rules)
|
|
135
|
+
2. Reads `aesop.config.json` (your fleet configuration)
|
|
136
|
+
3. Checks `state/STATE.md` (current phase and next steps)
|
|
137
|
+
4. Validates that daemons are healthy (checks heartbeat files)
|
|
138
|
+
5. Reports a health brief
|
|
139
|
+
|
|
140
|
+
Expected output:
|
|
141
|
+
```
|
|
142
|
+
Orchestrator Brain Loaded
|
|
143
|
+
|
|
144
|
+
✓ Global rules (CLAUDE.md) loaded
|
|
145
|
+
✓ Fleet config (aesop.config.json) loaded
|
|
146
|
+
- 1 repo configured: my-demo-project
|
|
147
|
+
- Brain root: ~/.claude
|
|
148
|
+
- State root: ~/demo-fleet/state
|
|
149
|
+
✓ Fleet daemons: healthy (watchdog heartbeat ~30s old)
|
|
150
|
+
✓ STATE.md initialized: Phase 1, ready for backlog
|
|
151
|
+
|
|
152
|
+
NEXT STEPS:
|
|
153
|
+
(1) Create a backlog (P1/P2 tasks)
|
|
154
|
+
(2) Run /buildsystem to execute a complete wave cycle
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
If you see errors about missing CLAUDE.md or heartbeat files, don't worry—they'll be created on first startup. Re-run `/power` after a few seconds.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Step 5: Understand the Backlog (Optional, 2 min)
|
|
162
|
+
|
|
163
|
+
Before running your first wave, you need a backlog of work. The orchestrator dispatches agents to complete these tasks.
|
|
164
|
+
|
|
165
|
+
Example backlog:
|
|
166
|
+
```markdown
|
|
167
|
+
## Wave 1 Backlog
|
|
168
|
+
|
|
169
|
+
- **P1: Add setup documentation** (backend-dev) — Document the initial setup process
|
|
170
|
+
- **P2: Fix README formatting** (docs-agent) — Improve readability of README.md
|
|
171
|
+
- **P3: Add a test scaffold** (test-bot) — Create tests/ directory with example test
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Each task should:
|
|
175
|
+
- Fit in 5–15 minutes for a Haiku agent
|
|
176
|
+
- Be scoped (not "refactor everything")
|
|
177
|
+
- Have a priority (P1=blocker, P2=quality, P3=tech debt)
|
|
178
|
+
- Be assigned to an agent type
|
|
179
|
+
|
|
180
|
+
For this demo, you can skip this step and just observe what `/buildsystem` would do. Or create 2–3 simple tasks.
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Step 6: Run Your First Wave (Optional, 10+ min)
|
|
185
|
+
|
|
186
|
+
Once you have a backlog, invoke `/buildsystem` in Claude Code:
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
/buildsystem
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
What `/buildsystem` does:
|
|
193
|
+
1. **Rank & Assign** — Reads your backlog, assigns agents to tasks
|
|
194
|
+
2. **Dispatch Fleet** — Spawns 3–8 Haiku agents in parallel worktrees
|
|
195
|
+
3. **Execute** — Each agent works on its task independently
|
|
196
|
+
4. **Verify** — Runs tests, checks compilation, validates changes
|
|
197
|
+
5. **Merge Train** — Commits and pushes completed tasks
|
|
198
|
+
6. **Checkpoint** — Saves state (STATE.md, BUILDLOG.md)
|
|
199
|
+
|
|
200
|
+
You'll see live updates as agents work. Each task runs in isolation (no conflicts).
|
|
201
|
+
|
|
202
|
+
Expected output:
|
|
203
|
+
```
|
|
204
|
+
Wave 1 / Rank & Assign
|
|
205
|
+
✓ Task 1: Add setup documentation (backend-dev)
|
|
206
|
+
✓ Task 2: Fix README formatting (docs-agent)
|
|
207
|
+
✓ Task 3: Add test scaffold (test-bot)
|
|
208
|
+
→ Dispatching 3 Haiku agents (est. 45–60 min)...
|
|
209
|
+
|
|
210
|
+
[Agent 1: backend-dev] Working on Task 1...
|
|
211
|
+
[Agent 2: docs-agent] Working on Task 2...
|
|
212
|
+
[Agent 3: test-bot] Working on Task 3...
|
|
213
|
+
|
|
214
|
+
Wave 1 / Merge Train
|
|
215
|
+
✓ All agents completed
|
|
216
|
+
✓ 3 PRs created
|
|
217
|
+
✓ All tests passed
|
|
218
|
+
✓ Merging to main...
|
|
219
|
+
|
|
220
|
+
Wave 1 Complete
|
|
221
|
+
Duration: 47 minutes
|
|
222
|
+
Cost: 3,200 tokens
|
|
223
|
+
Files changed: 12
|
|
224
|
+
NEXT STEPS: Review BUILDLOG.md, run Wave 2 if needed
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## What Happened?
|
|
230
|
+
|
|
231
|
+
You just ran a complete Aesop wave cycle:
|
|
232
|
+
|
|
233
|
+
1. **Orchestrator** (you) → defined the backlog
|
|
234
|
+
2. **Dispatch** (Aesop) → analyzed tasks, assigned agents
|
|
235
|
+
3. **Execution** → 3+ Haiku agents worked in parallel (each in their own worktree)
|
|
236
|
+
4. **Verification** → tests passed, code reviewed, merged
|
|
237
|
+
5. **Checkpoint** → progress saved to `state/STATE.md` and `state/BUILDLOG.md`
|
|
238
|
+
|
|
239
|
+
Each wave is independent. You can run wave 2 with a new backlog, or pause and review results.
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Exploring the Harness
|
|
244
|
+
|
|
245
|
+
Now that you've seen it work, explore:
|
|
246
|
+
|
|
247
|
+
### 1. Check the state files
|
|
248
|
+
```bash
|
|
249
|
+
cat state/STATE.md # Current phase and next steps
|
|
250
|
+
cat state/BUILDLOG.md # Append-only progress log
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### 2. View the dashboard (optional)
|
|
254
|
+
```bash
|
|
255
|
+
npx @matt82198/aesop dash # Launches http://localhost:8770
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Monitor waves in real-time: see active agents, heartbeats, logs, and costs.
|
|
259
|
+
|
|
260
|
+
### 3. Check the daemons
|
|
261
|
+
```bash
|
|
262
|
+
ls -la daemons/
|
|
263
|
+
bash daemons/run-watchdog.sh --once # Run watchdog once (no daemon)
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
The watchdog handles backup, secret scanning, and fleet health checks.
|
|
267
|
+
|
|
268
|
+
### 4. Review the configuration
|
|
269
|
+
```bash
|
|
270
|
+
cat aesop.config.json # Your fleet configuration
|
|
271
|
+
cat CLAUDE.md # Orchestrator brain (domain map, rules)
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## Scaling to Real Projects
|
|
277
|
+
|
|
278
|
+
Once you're comfortable with the demo flow, you can:
|
|
279
|
+
|
|
280
|
+
1. **Add more repos** — Edit `aesop.config.json` and list your real projects
|
|
281
|
+
2. **Customize domains** — Edit `CLAUDE.md` to define your team structure
|
|
282
|
+
3. **Tune the backlog** — Work with your team to prioritize tasks
|
|
283
|
+
4. **Run continuous waves** — Schedule `/buildsystem` to run on a cadence
|
|
284
|
+
5. **Set cost ceilings** — Add spending limits to prevent runaway bills
|
|
285
|
+
|
|
286
|
+
See [CONFIGURE.md](CONFIGURE.md) and [INSTALL.md](INSTALL.md) for full details.
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Troubleshooting
|
|
291
|
+
|
|
292
|
+
**Q: `/power` says "CLAUDE.md not found"**
|
|
293
|
+
- A: Copy the skills to your Claude Code home:
|
|
294
|
+
```bash
|
|
295
|
+
cp -r skills/power ~/.claude/skills/
|
|
296
|
+
cp -r skills/buildsystem ~/.claude/skills/
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
**Q: `aesop doctor` reports missing Python**
|
|
300
|
+
- A: Python is optional for the demo. If you want secret scanning or log rotation, install it:
|
|
301
|
+
```bash
|
|
302
|
+
python3 --version # Check if installed
|
|
303
|
+
pip install pyyaml # If needed
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**Q: Watchdog fails with "not inside a git repository"**
|
|
307
|
+
- A: Make sure you've run the scaffold from a location with git installed and initialized. Re-run scaffold:
|
|
308
|
+
```bash
|
|
309
|
+
npx @matt82198/aesop demo-fleet --yes
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
**Q: Dashboard won't open (port 8770 in use)**
|
|
313
|
+
- A: The scaffold will use the next available port (8771, 8772, etc). Check `aesop.config.json` for the actual port.
|
|
314
|
+
|
|
315
|
+
See [INSTALL.md](INSTALL.md) for more troubleshooting and [CONCEPTS.md](CONCEPTS.md) for deeper understanding.
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## Next Steps
|
|
320
|
+
|
|
321
|
+
1. **Run the full test suite** — Verify everything works:
|
|
322
|
+
```bash
|
|
323
|
+
npm run test:all
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
2. **Read [FIRST-WAVE.md](FIRST-WAVE.md)** — Deep dive into the wave cycle
|
|
327
|
+
|
|
328
|
+
3. **Explore [CONCEPTS.md](CONCEPTS.md)** — Understand the dispatch model and state architecture
|
|
329
|
+
|
|
330
|
+
4. **Add your real repos** — Scale from demo to production
|
|
331
|
+
|
|
332
|
+
5. **Set up continuous integration** — Schedule waves to run automatically
|
|
333
|
+
|
|
334
|
+
Enjoy! 🚀
|
package/docs/HOOK-INSTALL.md
CHANGED
|
@@ -1,82 +1,41 @@
|
|
|
1
|
-
# Git Pre-Push Hook
|
|
1
|
+
# Git Pre-Push Hook Setup
|
|
2
2
|
|
|
3
|
-
**
|
|
4
|
-
|
|
5
|
-
## Security Model: Local Convenience Defense Only
|
|
6
|
-
|
|
7
|
-
**IMPORTANT**: The pre-push hook is a **local-machine convenience defense** — it is **NOT cryptographic protection**. Any developer can bypass it with `git push --no-verify` or by editing/deleting `.git/hooks/pre-push`. The audit log (`SECURITY-AUDIT.log`) is stored locally and can also be edited by a user with file system access.
|
|
8
|
-
|
|
9
|
-
**Real enforcement requires server-side branch protection.** See GitHub Configuration below.
|
|
3
|
+
**TL;DR**: The hook is **auto-installed during scaffold**. Real enforcement requires server-side GitHub branch protection.
|
|
10
4
|
|
|
11
5
|
## What the Hook Does
|
|
12
6
|
|
|
13
|
-
`hooks/pre-push-policy.sh` enforces
|
|
7
|
+
`hooks/pre-push-policy.sh` enforces:
|
|
8
|
+
1. **Branch Policy** — No direct pushes to `main`/`master` (feature branches only)
|
|
9
|
+
2. **Secret Scan** — `tools/secret_scan.py --staged` blocks credentials
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
2. **Secret Scan**: Runs `tools/secret_scan.py --staged` to detect credentials before they reach the remote.
|
|
11
|
+
## Security Model
|
|
17
12
|
|
|
18
|
-
|
|
13
|
+
**IMPORTANT**: Local hook is a **convenience defense only**—NOT cryptographic protection. Bypass with `git push --no-verify`.
|
|
19
14
|
|
|
20
|
-
|
|
15
|
+
**Real enforcement**: Pair with GitHub branch protection (server-side). See below.
|
|
21
16
|
|
|
22
|
-
|
|
17
|
+
## Auto-Installation
|
|
23
18
|
|
|
24
|
-
-
|
|
25
|
-
- **On Windows**: Copies the hook directly (symlinks don't work reliably on all NTFS setups)
|
|
26
|
-
- **Idempotent**: Re-running scaffold doesn't clobber a user-customized hook
|
|
27
|
-
- **Preserve Existing**: If you have a different pre-push hook, scaffold warns and preserves it
|
|
28
|
-
- **Force Replace**: Use `npx @matt82198/aesop [target-dir] --force` to replace any existing hook
|
|
29
|
-
|
|
30
|
-
**Example:**
|
|
19
|
+
Scaffold auto-installs the hook (symlink on Unix, copy on Windows):
|
|
31
20
|
|
|
32
21
|
```bash
|
|
33
|
-
# Initial scaffold (creates and installs hook automatically)
|
|
34
|
-
npx @matt82198/aesop my-fleet
|
|
35
|
-
|
|
36
|
-
# Later: re-scaffold the same directory (preserves customizations)
|
|
37
22
|
npx @matt82198/aesop my-fleet
|
|
38
|
-
|
|
39
|
-
# Force replace (even if hook was customized)
|
|
40
|
-
npx @matt82198/aesop my-fleet --force
|
|
41
23
|
```
|
|
42
24
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
If you're installing into an existing repo (not scaffolded), or you need to manually add the hook:
|
|
46
|
-
|
|
47
|
-
### Option 1: Symlink (Linux / macOS / Git Bash on Windows)
|
|
48
|
-
|
|
49
|
-
The cleanest method — hook stays in sync with repo updates:
|
|
50
|
-
|
|
25
|
+
Manual install:
|
|
51
26
|
```bash
|
|
27
|
+
# Option 1: Symlink (Unix/macOS/Git Bash)
|
|
52
28
|
ln -s ../../hooks/pre-push-policy.sh .git/hooks/pre-push
|
|
53
|
-
chmod +x .git/hooks/pre-push
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
### Option 2: Copy (Windows, or to break sync)
|
|
57
|
-
|
|
58
|
-
Copy the hook directly into `.git/hooks/`:
|
|
59
|
-
|
|
60
|
-
```powershell
|
|
61
|
-
Copy-Item hooks\pre-push-policy.sh .git\hooks\pre-push
|
|
62
|
-
```
|
|
63
29
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
```bash
|
|
67
|
-
git config core.filemode false
|
|
30
|
+
# Option 2: Copy (Windows)
|
|
31
|
+
cp hooks/pre-push-policy.sh .git/hooks/pre-push
|
|
68
32
|
```
|
|
69
33
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
Before committing to org-wide deployment, verify the hook works:
|
|
73
|
-
|
|
34
|
+
Test:
|
|
74
35
|
```bash
|
|
75
36
|
bash hooks/pre-push-policy.sh --test
|
|
76
37
|
```
|
|
77
38
|
|
|
78
|
-
Expected output: **PASS** for all three checks (branch policy, feature branch allowance, audit log format).
|
|
79
|
-
|
|
80
39
|
## GitHub Configuration (Server-Side Enforcement)
|
|
81
40
|
|
|
82
41
|
To pair this local hook with real enforcement, enable branch protection on GitHub:
|
package/docs/INSTALL.md
CHANGED
|
@@ -33,7 +33,7 @@ The fastest way to get started is to use the Aesop template scaffolder. It creat
|
|
|
33
33
|
### Step 1: Scaffold the harness
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
|
-
npx @matt82198/aesop
|
|
36
|
+
npx @matt82198/aesop my-fleet \
|
|
37
37
|
--name "my-api" \
|
|
38
38
|
--repos "/path/to/repo1,/path/to/repo2"
|
|
39
39
|
```
|
|
@@ -196,6 +196,75 @@ export DEBUG=1
|
|
|
196
196
|
|
|
197
197
|
---
|
|
198
198
|
|
|
199
|
+
## Using Non-Claude Backends
|
|
200
|
+
|
|
201
|
+
By default, Aesop uses Claude Code (the orchestration harness) as its backend. You can configure it to use other models via the **AgentDriver abstraction**—enabling Ollama, OpenAI-compatible endpoints, OpenRouter, and more.
|
|
202
|
+
|
|
203
|
+
### Configure a backend in aesop.config.json
|
|
204
|
+
|
|
205
|
+
Add or modify the `backend` section:
|
|
206
|
+
|
|
207
|
+
```json
|
|
208
|
+
{
|
|
209
|
+
"backend": "openai-compatible",
|
|
210
|
+
"model": "ollama-mistral",
|
|
211
|
+
"base_url": "http://localhost:11434/v1",
|
|
212
|
+
"api_key_env": "OLLAMA_API_KEY"
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Supported backends:
|
|
217
|
+
- `"claude"` (default) — Claude Code CLI harness
|
|
218
|
+
- `"openai-compatible"` — OpenAI Chat Completions API (Ollama, OpenRouter, etc.)
|
|
219
|
+
- `"codex"` — CodeX OpenAI backend (legacy)
|
|
220
|
+
|
|
221
|
+
### Example: Local Ollama
|
|
222
|
+
|
|
223
|
+
To run Aesop against Mistral locally via Ollama:
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
# 1. Install Ollama (https://ollama.ai) and start the daemon
|
|
227
|
+
ollama serve
|
|
228
|
+
|
|
229
|
+
# 2. In another terminal, pull a model
|
|
230
|
+
ollama pull mistral
|
|
231
|
+
|
|
232
|
+
# 3. Configure Aesop to use it
|
|
233
|
+
cat > aesop.config.json <<EOF
|
|
234
|
+
{
|
|
235
|
+
"backend": "openai-compatible",
|
|
236
|
+
"model": "mistral",
|
|
237
|
+
"base_url": "http://localhost:11434/v1",
|
|
238
|
+
"api_key_env": "OLLAMA_API_KEY"
|
|
239
|
+
}
|
|
240
|
+
EOF
|
|
241
|
+
|
|
242
|
+
# 4. Start Aesop (it will use Mistral for subagent dispatch)
|
|
243
|
+
npx @matt82198/aesop my-fleet --name "my-api"
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Verification tiers: weaker backends get more checking
|
|
247
|
+
|
|
248
|
+
The AgentDriver framework applies **honest verification tiers** — weaker backends (lower accuracy, no structured output) trigger stronger verification in the orchestrator:
|
|
249
|
+
|
|
250
|
+
| Backend | Accuracy | Verification Tier | What it means |
|
|
251
|
+
|---------|----------|-------------------|---------------|
|
|
252
|
+
| Claude Code | ~0.99 | 1 (minimal) | Orchestrator trusts output; spot-check tests |
|
|
253
|
+
| OpenAI (GPT-4) | ~0.95 | 2 | Validate all JSON, run full test suite |
|
|
254
|
+
| Ollama (Mistral) | ~0.70 | 4 (maximum) | Validate all JSON, adversarial review, expensive repair cap |
|
|
255
|
+
|
|
256
|
+
Lower tiers cost less but require more orchestrator work. See [driver/README.md](../driver/README.md) for full verification-policy details.
|
|
257
|
+
|
|
258
|
+
### Troubleshooting
|
|
259
|
+
|
|
260
|
+
**Backend won't connect**: Check `OLLAMA_API_KEY` (or your backend's API key env var) is set and the `base_url` is reachable.
|
|
261
|
+
|
|
262
|
+
**Verification tier too strict**: If your backend is over-verified (tier 4 when it should be tier 2), update `probe_capabilities()` in the driver to report higher accuracy scores honestly.
|
|
263
|
+
|
|
264
|
+
For more details, see [driver/README.md](../driver/README.md).
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
199
268
|
## Pre-push Hook Installation
|
|
200
269
|
|
|
201
270
|
The `npx` scaffold installs the pre-push hook automatically. If you cloned the repo manually, install it:
|
|
@@ -216,9 +285,10 @@ To bypass during testing: `git push --no-verify` (not recommended for production
|
|
|
216
285
|
|
|
217
286
|
## Next Steps
|
|
218
287
|
|
|
219
|
-
1. **Read [
|
|
220
|
-
2. **
|
|
221
|
-
3. **
|
|
288
|
+
1. **Read [PORTING.md](PORTING.md)** — Step-by-step guide for adopting Aesop on a foreign repo (10 common failure modes)
|
|
289
|
+
2. **Read [CONFIGURE.md](CONFIGURE.md)** — Customize repos, ports, and brain root
|
|
290
|
+
3. **Run [FIRST-WAVE.md](FIRST-WAVE.md)** — Test a full `/power` → `/buildsystem` cycle
|
|
291
|
+
4. **Understand [CONCEPTS.md](CONCEPTS.md)** — Learn the dispatch model and state model
|
|
222
292
|
4. **Explore the dashboard** — `python3 ui/serve.py` then open http://localhost:8770
|
|
223
293
|
|
|
224
294
|
For troubleshooting, see the [Aesop README](../README.md#troubleshooting) or [GOVERNANCE.md](GOVERNANCE.md) for operational policies.
|
package/docs/PORTING.md
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# Porting Aesop to Your Repository
|
|
2
|
+
|
|
3
|
+
Guide for adopters porting the orchestration harness to a foreign repo. Step-by-step with prerequisites, scaffold, config, and the 10 likeliest failure modes from real deployments.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
Ensure you have:
|
|
10
|
+
- **Node.js** ≥18 (from `package.json`, `.nvmrc`: v18.20.5)
|
|
11
|
+
- **Python** ≥3.10 (for daemons, health checks, secret-scan)
|
|
12
|
+
- **Git** ≥2.40 (worktree + pre-push hooks)
|
|
13
|
+
- **Bash** v4+ (or Git Bash on Windows)
|
|
14
|
+
- **Optional**: Playwright (for UI verification testing); jq (for dashboard JSON)
|
|
15
|
+
|
|
16
|
+
Check versions:
|
|
17
|
+
```bash
|
|
18
|
+
node --version && python3 --version && git --version && bash --version
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### OS Notes
|
|
22
|
+
- **Windows**: Use Git Bash for all shell commands; paths use `/c/Users/...` POSIX style
|
|
23
|
+
- **Linux/macOS**: Standard Bash; ensure `/usr/bin/bash` or equivalent exists
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 1. Scaffold & Install
|
|
28
|
+
|
|
29
|
+
### Step 1: Create your harness
|
|
30
|
+
```bash
|
|
31
|
+
npx @matt82198/aesop my-fleet \
|
|
32
|
+
--name "my-project" \
|
|
33
|
+
--repos "/path/to/repo1,/path/to/repo2"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Creates `my-fleet/` with daemons, skills, config, and UI.
|
|
37
|
+
|
|
38
|
+
### Step 2: Copy skills to Claude Code home
|
|
39
|
+
```bash
|
|
40
|
+
cp -r my-fleet/skills/power ~/.claude/skills/power
|
|
41
|
+
cp -r my-fleet/skills/buildsystem ~/.claude/skills/buildsystem
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Step 3: Configure & test
|
|
45
|
+
Edit `my-fleet/aesop.config.json`:
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"backend": "claude",
|
|
49
|
+
"aesop_root": "/path/to/my-fleet",
|
|
50
|
+
"brain_root": "~/.claude",
|
|
51
|
+
"repos": [
|
|
52
|
+
{ "path": "/path/to/repo1", "name": "my-project" }
|
|
53
|
+
],
|
|
54
|
+
"dashboardPort": 8770
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Test dashboard backend (Ollama example):
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"backend": "openai-compatible",
|
|
62
|
+
"base_url": "http://localhost:11434/v1",
|
|
63
|
+
"model": "mistral",
|
|
64
|
+
"is_local": true
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Step 4: Install pre-push hook
|
|
69
|
+
```bash
|
|
70
|
+
mkdir -p my-fleet/.git/hooks
|
|
71
|
+
cp my-fleet/hooks/pre-push-policy.sh my-fleet/.git/hooks/pre-push
|
|
72
|
+
chmod +x my-fleet/.git/hooks/pre-push
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Step 5: Verify with health check
|
|
76
|
+
```bash
|
|
77
|
+
cd my-fleet
|
|
78
|
+
python tools/health_score.py
|
|
79
|
+
```
|
|
80
|
+
Expected output: All checks ✓; port 8770 available; git hooks installed.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## 2. First `/power`, First Wave
|
|
85
|
+
|
|
86
|
+
Run the orchestrator once to prime the brain:
|
|
87
|
+
```bash
|
|
88
|
+
cd my-fleet
|
|
89
|
+
/power
|
|
90
|
+
```
|
|
91
|
+
Expected output: State created (STATE.md, BUILDLOG.md, .watchdog-heartbeat).
|
|
92
|
+
|
|
93
|
+
Run one complete wave:
|
|
94
|
+
```bash
|
|
95
|
+
/buildsystem --one-turn
|
|
96
|
+
```
|
|
97
|
+
Expected verdicts: All items "PASS" or "REVIEW"; zero code defects. Health score should report ≥85/100.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 3. The 10 Likeliest Failure Modes
|
|
102
|
+
|
|
103
|
+
Each: symptom → cause → fix.
|
|
104
|
+
|
|
105
|
+
### 1. Secret-scan blocks legit push
|
|
106
|
+
- **Symptom**: `git push` fails: "secret detected" but code has no real secret
|
|
107
|
+
- **Cause**: Test fixtures with dummy secrets (credit card, API key patterns) are parsed as real
|
|
108
|
+
- **Fix**: Assemble secrets at runtime: `"key" + "_" + "123"` not `"key_123"`; use `---` delimiters in comments. Secret-scan only scans staged files, not .git.
|
|
109
|
+
|
|
110
|
+
### 2. Worktree isolation violated
|
|
111
|
+
- **Symptom**: Editing feature branch X; changes also appear in primary tree
|
|
112
|
+
- **Cause**: Agents not using isolated worktrees; sharing same `.git/index`
|
|
113
|
+
- **Fix**: Each agent task must use `git worktree add ../wt-item-slug -b feature/item-slug origin/main`; verify with `git worktree list`
|
|
114
|
+
|
|
115
|
+
### 3. Heartbeat stale/missing
|
|
116
|
+
- **Symptom**: Watchdog won't start; error: "unreadable state dir" or "stale heartbeat"
|
|
117
|
+
- **Cause**: `state/.watchdog-heartbeat` missing/corrupted or directory unreadable (permissions)
|
|
118
|
+
- **Fix**: `rm -f state/.watchdog-heartbeat && bash daemons/run-watchdog.sh --once` (re-creates it)
|
|
119
|
+
|
|
120
|
+
### 4. Port 8770 conflict
|
|
121
|
+
- **Symptom**: `python ui/serve.py` fails: "Address already in use"
|
|
122
|
+
- **Cause**: Old dashboard process still bound, or another service using port 8770
|
|
123
|
+
- **Fix**: `lsof -i :8770 | grep -v PID | awk '{print $2}' | xargs kill -9` (Mac/Linux); Windows: `netstat -ano | grep 8770`, kill the PID. Or change `dashboardPort` in config.
|
|
124
|
+
|
|
125
|
+
### 5. Git identity placeholder
|
|
126
|
+
- **Symptom**: Pre-push hook fails: "user identity invalid"; commits fail
|
|
127
|
+
- **Cause**: Git config has template defaults (e.g., "John Doe") instead of your name
|
|
128
|
+
- **Fix**: `git config user.name "Your Name" && git config user.email "you@example.com"`
|
|
129
|
+
|
|
130
|
+
### 6. CRLF line endings corrupt scripts
|
|
131
|
+
- **Symptom**: Bash script fails: "command not found" at line 50 (but line 50 exists)
|
|
132
|
+
- **Cause**: Editor/Windows converted LF to CRLF; bash reads `\r` as part of command
|
|
133
|
+
- **Fix**: `git config core.autocrlf false` locally; convert file: `dos2unix daemons/run-watchdog.sh`
|
|
134
|
+
|
|
135
|
+
### 7. Test count drift in CI
|
|
136
|
+
- **Symptom**: Health-check fails: "expected 127 tests, got 128"
|
|
137
|
+
- **Cause**: Added new test file but didn't update baseline in tools/health_score.py or CI config
|
|
138
|
+
- **Fix**: Run `python tools/health_score.py --json` to get true count; update baseline in CI gate
|
|
139
|
+
|
|
140
|
+
### 8. UTF-8 encoding on Windows
|
|
141
|
+
- **Symptom**: Pre-publish gate fails with encoding error in secret_scan.py
|
|
142
|
+
- **Cause**: Python opens files in system encoding (cp1252) instead of UTF-8
|
|
143
|
+
- **Fix**: Aesop tools now force UTF-8 internally; ensure `PYTHONIOENCODING=utf-8` if running external Python scripts
|
|
144
|
+
|
|
145
|
+
### 9. Cost ceiling never triggers
|
|
146
|
+
- **Symptom**: Cost ceilings configured; spending uncapped; halt never fires
|
|
147
|
+
- **Cause**: Claude Code driver returns `get_tokens_spent()=None`; coerces to 0; ledger fallback skipped
|
|
148
|
+
- **Fix**: For Claude Code, cost tracking integrates live API; for non-Claude backends, ledger fallback logs at end of wave
|
|
149
|
+
|
|
150
|
+
### 10. Hook TTY behavior blocks CI pushes
|
|
151
|
+
- **Symptom**: `git push` fails in CI/cron: "cannot read stdin"; interactive prompt hangs
|
|
152
|
+
- **Cause**: Hook tries to detect TTY when stdin is `/dev/null` (non-interactive context)
|
|
153
|
+
- **Fix**: Hook now handles empty stdin (rc=2 for delete-only, skip scan + log); use `hooks/pre-push-policy.sh --test` in CI (no-op validation)
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Next Steps
|
|
158
|
+
|
|
159
|
+
1. **Read [INSTALL.md](./INSTALL.md)** — Full setup and environment variables
|
|
160
|
+
2. **Run [health_score.py](../tools/health_score.py)** — Continuous readiness checks
|
|
161
|
+
3. **Explore the [README](../README.md)** — Demo walkthrough and proof numbers
|
|
162
|
+
4. **For troubleshooting**, check [GOVERNANCE.md](./GOVERNANCE.md) or open an issue on GitHub
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
**License**: PolyForm Strict 1.0.0 (source-available, noncommercial). See [LICENSE](../LICENSE) for details.
|