@matt82198/aesop 0.1.0 → 0.2.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/CHANGELOG.md +89 -2
- package/README.md +63 -12
- package/bin/cli.js +164 -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/INSTALL.md +70 -1
- package/docs/QUICKSTART.md +80 -0
- package/docs/README.md +33 -3
- package/docs/TEAM-STATE.md +540 -0
- package/driver/CLAUDE.md +148 -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 +626 -0
- package/driver/openai_compatible_driver.py +249 -0
- package/driver/openai_transport.py +146 -0
- package/driver/verification_policy.py +75 -0
- package/driver/wave_bridge.py +246 -0
- package/driver/wave_loop.py +1041 -0
- package/hooks/pre-push-policy.sh +109 -28
- package/mcp/server.mjs +320 -4
- package/package.json +23 -15
- 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 +2 -1
- package/state_store/api.py +19 -4
- package/state_store/coordination.py +209 -0
- package/state_store/identity.py +51 -0
- package/state_store/store.py +185 -73
- 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 +63 -31
- package/tools/cost_econ.py +480 -0
- package/tools/defect_escape.py +252 -0
- package/tools/doctor.js +1 -1
- package/tools/eod_sweep.py +58 -0
- 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 +401 -0
- package/tools/portability_check.py +206 -0
- package/tools/reconcile.py +7 -4
- package/tools/secret_scan.py +137 -50
- package/tools/self_stats.py +20 -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_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 +512 -0
- package/tools/wave_resume.py +215 -0
- package/tools/wave_templates.py +215 -0
- package/ui/agents.py +68 -14
- package/ui/collectors.py +0 -55
- package/ui/config.py +7 -2
- package/ui/cost.py +231 -12
- package/ui/handler.py +183 -0
- package/ui/quality_scorecard.py +232 -0
- 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 +377 -0
- package/ui/web/dist/assets/index-BGbgw2Nh.js +9 -0
- package/ui/web/dist/assets/index-DqZLgwNg.css +1 -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
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Self-healing fleet supervisor: detects stale sibling heartbeats and restarts daemons.
|
|
3
|
+
# Monitors run-watchdog.sh and run-monitor.sh with safe, idempotent recovery actions.
|
|
4
|
+
# Usage: selfheal.sh [--once]
|
|
5
|
+
#
|
|
6
|
+
# Configuration: export AESOP_ROOT=/path/to/aesop before running (defaults to script directory's parent).
|
|
7
|
+
# Testing: export AESOP_SELFHEAL_SKIP_RESTART=1 to skip actual daemon restarts (test-only flag).
|
|
8
|
+
|
|
9
|
+
set -u
|
|
10
|
+
|
|
11
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
12
|
+
AESOP_ROOT="${AESOP_ROOT:-$(dirname "$SCRIPT_DIR")}"
|
|
13
|
+
CONDUCTOR_ROOT="${CONDUCTOR_ROOT:-$(dirname "$AESOP_ROOT")/conductor3}"
|
|
14
|
+
MODE="${1:-daemon}"
|
|
15
|
+
|
|
16
|
+
SELFHEAL_LOCK_DIR="$AESOP_ROOT/state/.selfheal-lock"
|
|
17
|
+
SELFHEAL_LOG="$AESOP_ROOT/state/SELFHEAL.log"
|
|
18
|
+
SELFHEAL_STALE_THRESHOLD=600
|
|
19
|
+
|
|
20
|
+
WATCHDOG_HB="$AESOP_ROOT/state/.watchdog-heartbeat"
|
|
21
|
+
WATCHDOG_STALE_THRESHOLD=600
|
|
22
|
+
|
|
23
|
+
MONITOR_HB="$CONDUCTOR_ROOT/monitor/.monitor-heartbeat"
|
|
24
|
+
MONITOR_STALE_THRESHOLD=600
|
|
25
|
+
|
|
26
|
+
ts() {
|
|
27
|
+
date '+%Y-%m-%d %H:%M:%S'
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
log_heal() {
|
|
31
|
+
local msg="$1"
|
|
32
|
+
echo "[$(ts)] $msg" | tee -a "$SELFHEAL_LOG"
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
ensure_log_dir() {
|
|
36
|
+
mkdir -p "$(dirname "$SELFHEAL_LOG")" 2>/dev/null || true
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
acquire_lock() {
|
|
40
|
+
local lock_dir="$1"
|
|
41
|
+
local stale_threshold="$2"
|
|
42
|
+
|
|
43
|
+
mkdir -p "$(dirname "$lock_dir")" 2>/dev/null || true
|
|
44
|
+
|
|
45
|
+
if mkdir "$lock_dir" 2>/dev/null; then
|
|
46
|
+
if ! date +%s > "$lock_dir/timestamp" 2>/dev/null || ! echo $$ > "$lock_dir/pid" 2>/dev/null; then
|
|
47
|
+
rm -rf "$lock_dir" 2>/dev/null || true
|
|
48
|
+
return 1
|
|
49
|
+
fi
|
|
50
|
+
return 0
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
if [ -d "$lock_dir" ]; then
|
|
54
|
+
local lock_pid=""
|
|
55
|
+
if [ -f "$lock_dir/pid" ]; then
|
|
56
|
+
lock_pid=$(cat "$lock_dir/pid" 2>/dev/null)
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
if [ -f "$lock_dir/timestamp" ] && [ -f "$lock_dir/pid" ] && [ -n "$lock_pid" ]; then
|
|
60
|
+
local lock_ts=$(cat "$lock_dir/timestamp" 2>/dev/null)
|
|
61
|
+
local lock_mtime=${lock_ts:-0}
|
|
62
|
+
local now=$(date +%s)
|
|
63
|
+
local lock_age=$((now - lock_mtime))
|
|
64
|
+
|
|
65
|
+
if [ "$lock_age" -gt "$stale_threshold" ]; then
|
|
66
|
+
rm -rf "$lock_dir" 2>/dev/null || true
|
|
67
|
+
if mkdir "$lock_dir" 2>/dev/null; then
|
|
68
|
+
date +%s > "$lock_dir/timestamp" 2>/dev/null || true
|
|
69
|
+
echo $$ > "$lock_dir/pid" 2>/dev/null || true
|
|
70
|
+
return 2
|
|
71
|
+
fi
|
|
72
|
+
fi
|
|
73
|
+
else
|
|
74
|
+
local should_reclaim=0
|
|
75
|
+
if [ -f "$lock_dir/pid" ] && [ -n "$lock_pid" ]; then
|
|
76
|
+
if ! kill -0 "$lock_pid" 2>/dev/null; then
|
|
77
|
+
should_reclaim=1
|
|
78
|
+
fi
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
if [ $should_reclaim -eq 0 ] && [ -f "$lock_dir/timestamp" ]; then
|
|
82
|
+
local lock_ts=$(cat "$lock_dir/timestamp" 2>/dev/null)
|
|
83
|
+
local lock_mtime=${lock_ts:-0}
|
|
84
|
+
local now=$(date +%s)
|
|
85
|
+
local lock_age=$((now - lock_mtime))
|
|
86
|
+
|
|
87
|
+
if [ "$lock_age" -gt "$stale_threshold" ]; then
|
|
88
|
+
should_reclaim=1
|
|
89
|
+
fi
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
if [ $should_reclaim -eq 1 ]; then
|
|
93
|
+
rm -rf "$lock_dir" 2>/dev/null || true
|
|
94
|
+
if mkdir "$lock_dir" 2>/dev/null; then
|
|
95
|
+
date +%s > "$lock_dir/timestamp" 2>/dev/null || true
|
|
96
|
+
echo $$ > "$lock_dir/pid" 2>/dev/null || true
|
|
97
|
+
return 2
|
|
98
|
+
fi
|
|
99
|
+
fi
|
|
100
|
+
fi
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
return 1
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
release_lock() {
|
|
107
|
+
local lock_dir="$1"
|
|
108
|
+
rm -rf "$lock_dir" 2>/dev/null || true
|
|
109
|
+
if [ -d "$lock_dir" ]; then
|
|
110
|
+
ensure_log_dir
|
|
111
|
+
log_heal "WARN: release_lock: failed to remove lock dir: $lock_dir (may be in-use on Windows)"
|
|
112
|
+
fi
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
is_heartbeat_stale() {
|
|
116
|
+
local hb_file="$1"
|
|
117
|
+
local stale_threshold="$2"
|
|
118
|
+
|
|
119
|
+
if [ ! -f "$hb_file" ]; then
|
|
120
|
+
return 0
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
local hb_ts=$(cat "$hb_file" 2>/dev/null)
|
|
124
|
+
if [ -z "$hb_ts" ] || ! [[ "$hb_ts" =~ ^[0-9]+$ ]]; then
|
|
125
|
+
return 0
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
local now=$(date +%s)
|
|
129
|
+
local age=$((now - hb_ts))
|
|
130
|
+
|
|
131
|
+
if [ "$age" -gt "$stale_threshold" ]; then
|
|
132
|
+
return 0
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
return 1
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
restart_watchdog() {
|
|
139
|
+
ensure_log_dir
|
|
140
|
+
|
|
141
|
+
if is_heartbeat_stale "$WATCHDOG_HB" "$WATCHDOG_STALE_THRESHOLD"; then
|
|
142
|
+
if [ -z "${AESOP_SELFHEAL_SKIP_RESTART:-}" ]; then
|
|
143
|
+
log_heal "ACTION: run-watchdog heartbeat stale, restarting..."
|
|
144
|
+
if command -v bash >/dev/null 2>&1; then
|
|
145
|
+
bash "$AESOP_ROOT/daemons/run-watchdog.sh" >/dev/null 2>&1 &
|
|
146
|
+
log_heal "RESTART watchdog: spawned (PID: $!)"
|
|
147
|
+
else
|
|
148
|
+
log_heal "WARN: Cannot restart watchdog, bash not found"
|
|
149
|
+
fi
|
|
150
|
+
else
|
|
151
|
+
log_heal "DRY-RUN: watchdog heartbeat stale (would restart)"
|
|
152
|
+
fi
|
|
153
|
+
return 0
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
return 1
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
restart_monitor() {
|
|
160
|
+
ensure_log_dir
|
|
161
|
+
|
|
162
|
+
if [ ! -d "$CONDUCTOR_ROOT" ]; then
|
|
163
|
+
return 1
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
if is_heartbeat_stale "$MONITOR_HB" "$MONITOR_STALE_THRESHOLD"; then
|
|
167
|
+
if [ -z "${AESOP_SELFHEAL_SKIP_RESTART:-}" ]; then
|
|
168
|
+
log_heal "ACTION: run-monitor heartbeat stale, restarting..."
|
|
169
|
+
if command -v bash >/dev/null 2>&1; then
|
|
170
|
+
bash "$CONDUCTOR_ROOT/monitor/run-monitor.sh" >/dev/null 2>&1 &
|
|
171
|
+
log_heal "RESTART monitor: spawned (PID: $!)"
|
|
172
|
+
else
|
|
173
|
+
log_heal "WARN: Cannot restart monitor, bash not found"
|
|
174
|
+
fi
|
|
175
|
+
else
|
|
176
|
+
log_heal "DRY-RUN: monitor heartbeat stale (would restart)"
|
|
177
|
+
fi
|
|
178
|
+
return 0
|
|
179
|
+
fi
|
|
180
|
+
|
|
181
|
+
return 1
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
cycle_once() {
|
|
185
|
+
ensure_log_dir
|
|
186
|
+
log_heal "=== Selfheal cycle START ==="
|
|
187
|
+
|
|
188
|
+
local any_action=0
|
|
189
|
+
|
|
190
|
+
restart_watchdog
|
|
191
|
+
if [ $? -eq 0 ]; then
|
|
192
|
+
any_action=1
|
|
193
|
+
fi
|
|
194
|
+
|
|
195
|
+
restart_monitor
|
|
196
|
+
if [ $? -eq 0 ]; then
|
|
197
|
+
any_action=1
|
|
198
|
+
fi
|
|
199
|
+
|
|
200
|
+
if [ $any_action -eq 0 ]; then
|
|
201
|
+
log_heal "No stale heartbeats detected"
|
|
202
|
+
fi
|
|
203
|
+
|
|
204
|
+
log_heal "=== Selfheal cycle END ==="
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
main() {
|
|
208
|
+
lock_result=0
|
|
209
|
+
acquire_lock "$SELFHEAL_LOCK_DIR" "$SELFHEAL_STALE_THRESHOLD"
|
|
210
|
+
lock_result=$?
|
|
211
|
+
|
|
212
|
+
if [ $lock_result -eq 1 ]; then
|
|
213
|
+
exit 0
|
|
214
|
+
fi
|
|
215
|
+
|
|
216
|
+
trap "release_lock \"$SELFHEAL_LOCK_DIR\"; exit 0" INT TERM EXIT
|
|
217
|
+
|
|
218
|
+
if [ "$MODE" = "--once" ]; then
|
|
219
|
+
cycle_once
|
|
220
|
+
exit 0
|
|
221
|
+
fi
|
|
222
|
+
|
|
223
|
+
while true; do
|
|
224
|
+
cycle_once
|
|
225
|
+
sleep 60
|
|
226
|
+
done
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
230
|
+
main "$@"
|
|
231
|
+
fi
|
package/docs/ANY-REPO.md
ADDED
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
# Aesop in ANY Repository — Portability Walkthrough
|
|
2
|
+
|
|
3
|
+
**Aesop works in any Git repository**, no matter the stack, size, or language.
|
|
4
|
+
This guide walks you through initializing Aesop into a codebase you've just cloned,
|
|
5
|
+
then running a full orchestration cycle to see how the system works.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Prerequisites
|
|
10
|
+
|
|
11
|
+
Before starting, make sure you have:
|
|
12
|
+
|
|
13
|
+
- **Claude Code CLI** (v0.1+) with `/power` and `/buildsystem` skills installed
|
|
14
|
+
- **Git** (v2.40+)
|
|
15
|
+
- **Bash** (v4+) or Git Bash on Windows
|
|
16
|
+
- **Node.js** (v18+), **Python** (v3.10+) — for orchestration daemons
|
|
17
|
+
- A Git repository you want to orchestrate (can be your own repo, a fork, or a fresh clone of an existing project)
|
|
18
|
+
|
|
19
|
+
Check versions:
|
|
20
|
+
```bash
|
|
21
|
+
claude --version
|
|
22
|
+
git --version
|
|
23
|
+
bash --version
|
|
24
|
+
node --version
|
|
25
|
+
python3 --version
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Step 1: Clone or Navigate to Your Target Repo
|
|
31
|
+
|
|
32
|
+
Let's say you've just cloned a project you want to orchestrate:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
cd ~/my-target-repo
|
|
36
|
+
git status # confirm you're in a git repo
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
If the repo **already has `CLAUDE.md` + `STATE.md`**, you can jump to [Step 3](#step-3-run-power-fast-path-already-primed).
|
|
40
|
+
|
|
41
|
+
If the repo has **no CLAUDE.md layer**, continue to [Step 2](#step-2-install-aesop-harness).
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Step 2: Install Aesop Harness
|
|
46
|
+
|
|
47
|
+
Scaffold the Aesop daemons, skills, and configuration templates into your target repo root:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Option 1: Scaffold into current directory (target repo already exists)
|
|
51
|
+
npx @matt82198/aesop .
|
|
52
|
+
|
|
53
|
+
# Option 2: Scaffold into a new aesop-fleet subdirectory
|
|
54
|
+
npx @matt82198/aesop
|
|
55
|
+
|
|
56
|
+
# Option 3: Scaffold with project name and repos (headless mode)
|
|
57
|
+
npx @matt82198/aesop orchestrator --name "my-project" --repos "/path/to/repo1"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
This creates (or adds to) the following structure in your repo:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
.
|
|
64
|
+
├── .git/
|
|
65
|
+
├── .github/
|
|
66
|
+
│ └── workflows/ (optional CI examples)
|
|
67
|
+
├── daemons/
|
|
68
|
+
│ ├── run-watchdog.sh (background monitor: backup, secret-scan, heartbeat)
|
|
69
|
+
│ ├── backup-fleet.sh
|
|
70
|
+
│ └── ...
|
|
71
|
+
├── skills/
|
|
72
|
+
│ ├── power/ (orchestrator brain-priming skill)
|
|
73
|
+
│ └── buildsystem/ (wave automation skill)
|
|
74
|
+
├── monitor/
|
|
75
|
+
│ ├── collect-signals.mjs (extensible health signal collectors)
|
|
76
|
+
│ └── CHARTER.md
|
|
77
|
+
├── ui/
|
|
78
|
+
│ ├── serve.py (dashboard backend)
|
|
79
|
+
│ └── web/ (React frontend; optional)
|
|
80
|
+
├── hooks/
|
|
81
|
+
│ ├── pre-push-policy.sh (secret-scan + branch discipline enforcement)
|
|
82
|
+
│ ├── pre-commit-waveguard.sh (wave checkpoint guard)
|
|
83
|
+
│ └── install-waveguard.sh (hook installer script)
|
|
84
|
+
├── tools/
|
|
85
|
+
│ ├── secret_scan.py (block credentials before push)
|
|
86
|
+
│ ├── power_selftest.py (verify orchestration health)
|
|
87
|
+
│ └── ...
|
|
88
|
+
├── state/ (git-ignored; runtime checkpoints live here)
|
|
89
|
+
│ └── .gitkeep
|
|
90
|
+
├── aesop.config.example.json
|
|
91
|
+
└── aesop.config.json (your personalized config, git-ignored)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Automatic Hook Installation**: The scaffold process automatically installs git hooks in `.git/hooks/`:
|
|
95
|
+
- **pre-push** (auto-installed copy of `hooks/pre-push-policy.sh`): runs secret scanning and branch discipline checks before allowing pushes
|
|
96
|
+
- **pre-commit** (auto-installed waveguard hook): implements wave checkpointing guard (ensures consistent state)
|
|
97
|
+
|
|
98
|
+
These hooks are copied (not symlinked) to `.git/hooks/` to work reliably across all platforms (Windows, macOS, Linux). On re-scaffold with `--force`, hooks are replaced; without it, existing hooks are preserved (unless they differ from source, in which case a warning is shown).
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Step 3: Run `/power` (Init-Prime)
|
|
103
|
+
|
|
104
|
+
Now run the `/power` skill in the repository root:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
cd ~/my-target-repo
|
|
108
|
+
/power
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**What happens:**
|
|
112
|
+
|
|
113
|
+
Aesop detects that your repo has **no CLAUDE.md layer** and enters **init-prime mode**:
|
|
114
|
+
|
|
115
|
+
1. **Fan-out exploration** (4 parallel Haiku subagents, ~30s each):
|
|
116
|
+
- Haiku-A scans repository structure, build system, entry points
|
|
117
|
+
- Haiku-B catalogs key libraries, frameworks, dependencies
|
|
118
|
+
- Haiku-C explores testing, CI/CD, deployment
|
|
119
|
+
- Haiku-D identifies gotchas, non-obvious invariants
|
|
120
|
+
|
|
121
|
+
2. **Write CLAUDE.md layer**:
|
|
122
|
+
- **Project-root `CLAUDE.md`**: purpose, build/run commands, gotchas, domain map
|
|
123
|
+
- **Domain `CLAUDE.md` units**: e.g., `src/CLAUDE.md`, `api/CLAUDE.md`, `tests/CLAUDE.md`
|
|
124
|
+
- **`STATE.md` checkpoint seed**: intent, phase, next steps (durable across wipes)
|
|
125
|
+
|
|
126
|
+
3. **Commit + Push** (gated by secret-scan):
|
|
127
|
+
```
|
|
128
|
+
git add CLAUDE.md STATE.md src/CLAUDE.md ...
|
|
129
|
+
git commit -m "init: initialize aesop orchestration semantics"
|
|
130
|
+
python tools/secret_scan.py --staged
|
|
131
|
+
git push origin feat/aesop-init-prime
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
4. **Report completion**:
|
|
135
|
+
```
|
|
136
|
+
✓ Aesop init-prime complete
|
|
137
|
+
- Project-root CLAUDE.md written (purpose, commands, gotchas, 4 domains)
|
|
138
|
+
- Domain CLAUDE.md units: src/, api/, core/, tests/
|
|
139
|
+
- STATE.md checkpoint seed created
|
|
140
|
+
- Pushed to origin feat/aesop-init-prime (secret-scan: all clear)
|
|
141
|
+
|
|
142
|
+
NEXT: Review the `.md` layer, iterate on domains, then run /buildsystem for your first orchestration wave.
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Step 4: Review the Generated `.md` Layer
|
|
148
|
+
|
|
149
|
+
The init-prime step wrote several new files. Let's review them:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# View project-root CLAUDE.md (purpose, commands, gotchas)
|
|
153
|
+
cat CLAUDE.md
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Example output:
|
|
157
|
+
```markdown
|
|
158
|
+
# my-target-repo — Orchestration Brain
|
|
159
|
+
|
|
160
|
+
**What**: my-target-repo is a Node.js + TypeScript REST API with PostgreSQL,
|
|
161
|
+
orchestrated through cost-optimized multi-agent dispatch.
|
|
162
|
+
|
|
163
|
+
## Cardinal Rules
|
|
164
|
+
1. Subagents are always Haiku (cost optimization at scale)
|
|
165
|
+
2. Orchestrator (Opus) on main thread only
|
|
166
|
+
3. State gates everything (git commit + push)
|
|
167
|
+
4. Secret-scan gates every push (no credentials leak)
|
|
168
|
+
5. Idempotent + append-only (safe to restart mid-cycle)
|
|
169
|
+
6. Observable machinery (every action logged)
|
|
170
|
+
|
|
171
|
+
## Domain Map
|
|
172
|
+
- **API layer** (`src/api/`): HTTP routes, middleware, controllers
|
|
173
|
+
- **Core logic** (`src/core/`): business logic, state machine, data model
|
|
174
|
+
- **Infrastructure** (`src/infra/`): database, caching, external services
|
|
175
|
+
- **Tests** (`tests/`): fixtures, test harness, mocking
|
|
176
|
+
|
|
177
|
+
## Key Commands
|
|
178
|
+
- `npm run build` — TypeScript compilation
|
|
179
|
+
- `npm run test` — Run test suite
|
|
180
|
+
- `npm start` — Start the server (localhost:3000)
|
|
181
|
+
- `npm run migrate` — Database migrations
|
|
182
|
+
|
|
183
|
+
## Gotchas
|
|
184
|
+
- Tests must run in isolation (no shared DB state)
|
|
185
|
+
- Docker build takes 5 minutes; cache aggressively
|
|
186
|
+
- Postgres connection pool size = 10 (hardcoded, needed for high concurrency)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# View a domain CLAUDE.md (contracts, invariants)
|
|
191
|
+
cat src/api/CLAUDE.md
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Example output:
|
|
195
|
+
```markdown
|
|
196
|
+
# API Layer
|
|
197
|
+
|
|
198
|
+
## Module Layout
|
|
199
|
+
- `routes.ts` — Express route handlers
|
|
200
|
+
- `middleware.ts` — CORS, auth, logging
|
|
201
|
+
- `controllers/` — business logic per endpoint
|
|
202
|
+
- `types.ts` — TypeScript interfaces for requests/responses
|
|
203
|
+
|
|
204
|
+
## Key Contracts
|
|
205
|
+
- All endpoints return `{ data: T, error?: string }`
|
|
206
|
+
- Authentication: Bearer token in Authorization header
|
|
207
|
+
- Content-Type: application/json only
|
|
208
|
+
|
|
209
|
+
## Anti-Patterns
|
|
210
|
+
- Don't call database directly from routes (use Core layer)
|
|
211
|
+
- Don't mutate global state in middleware
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
# View the state checkpoint
|
|
216
|
+
cat STATE.md
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Example output:
|
|
220
|
+
```markdown
|
|
221
|
+
# my-target-repo — State & Next Steps
|
|
222
|
+
|
|
223
|
+
**Phase**: init-prime (first CLAUDE.md layer written)
|
|
224
|
+
|
|
225
|
+
**Intent**: my-target-repo is now initialized with aesop orchestration semantics.
|
|
226
|
+
All domain rules live in scoped CLAUDE.md files. Ready to dispatch first work.
|
|
227
|
+
|
|
228
|
+
**NEXT STEPS**:
|
|
229
|
+
- [ ] Review + approve the written CLAUDE.md layer
|
|
230
|
+
- [ ] Adjust domains if needed (re-run init-prime or edit manually)
|
|
231
|
+
- [ ] Run `/buildsystem` to execute one example orchestration wave
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Step 5: Run `/buildsystem` (Orchestration Wave)
|
|
237
|
+
|
|
238
|
+
Now let's run a full orchestration cycle:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
cd ~/my-target-repo
|
|
242
|
+
/buildsystem
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**What happens:**
|
|
246
|
+
|
|
247
|
+
The `/buildsystem` skill reads your newly-written CLAUDE.md layer and orchestrates a full development wave:
|
|
248
|
+
|
|
249
|
+
1. **Phase 1: Backlog Review** (Opus orchestrator)
|
|
250
|
+
- Read your project's CLAUDE.md domains and current STATE.md
|
|
251
|
+
- Surface any open decisions, blockers, or proposed tasks
|
|
252
|
+
- Rank the backlog by priority and risk
|
|
253
|
+
|
|
254
|
+
2. **Phase 2: Parallel Haiku Fleets** (6-8 Haiku subagents in parallel)
|
|
255
|
+
- **One Haiku per domain** (API layer, core logic, tests, etc.)
|
|
256
|
+
- Each Haiku:
|
|
257
|
+
- Reads its domain CLAUDE.md (contracts, invariants, entry points)
|
|
258
|
+
- Writes minimal TDD-first test improvements
|
|
259
|
+
- Implements fixes or features
|
|
260
|
+
- Runs local compile + test checks
|
|
261
|
+
- **Pushes to a feature branch** (not main)
|
|
262
|
+
- **Continues until all are green or blocked**
|
|
263
|
+
|
|
264
|
+
3. **Phase 3: Merge Train** (Opus orchestrator)
|
|
265
|
+
- Collects all feature branches from Haiku fleets
|
|
266
|
+
- Runs full test suite (CI) on each
|
|
267
|
+
- Merges to main in order (if all green)
|
|
268
|
+
- Reports which features shipped + their costs
|
|
269
|
+
|
|
270
|
+
4. **Phase 4: Checkpoint** (git commit + push)
|
|
271
|
+
- Update `STATE.md` with new phase, completed work, next steps
|
|
272
|
+
- Append to `BUILDLOG.md` (append-only log of all dispatches, timestamps, costs)
|
|
273
|
+
- Commit + push (gated by secret-scan)
|
|
274
|
+
|
|
275
|
+
5. **Phase 5: Audit** (Haiku auditors, parallel)
|
|
276
|
+
- Security review of merged code
|
|
277
|
+
- Performance review of test times
|
|
278
|
+
- Documentation audit (ensure CLAUDE.md is still accurate)
|
|
279
|
+
- Report findings into the **next wave's backlog**
|
|
280
|
+
|
|
281
|
+
6. **Report Wave Summary**:
|
|
282
|
+
```
|
|
283
|
+
✓ Wave 1 complete
|
|
284
|
+
- Domains: API layer, Core logic, Tests, Infra (4 parallel Haikus)
|
|
285
|
+
- Work shipped: 3 feature branches merged to main
|
|
286
|
+
- fix/db-connection-pool (API layer) — 2 tests added, 1 bug fixed
|
|
287
|
+
- feat/cache-ttl (Core logic) — new cache invalidation strategy
|
|
288
|
+
- refactor/test-fixtures (Tests) — improved isolation, 5m faster suite
|
|
289
|
+
- Security audit: all clear (no new vulnerabilities)
|
|
290
|
+
- Cost: 2,847 tokens (Opus: 1,200 + 4x Haiku: 412 each)
|
|
291
|
+
- Duration: 4m 23s
|
|
292
|
+
|
|
293
|
+
STATE.md updated. Ready for Wave 2 when you are.
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## Step 6: Explore the New State Files
|
|
299
|
+
|
|
300
|
+
After the orchestration wave completes, several new files have appeared:
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
# State checkpoint — updated with new phase and next steps
|
|
304
|
+
cat STATE.md
|
|
305
|
+
|
|
306
|
+
# Append-only build log — every dispatch, cost, timestamp
|
|
307
|
+
tail -50 BUILDLOG.md
|
|
308
|
+
|
|
309
|
+
# Feature branches created by Haiku fleets (now merged to main)
|
|
310
|
+
git log --oneline main | head -5
|
|
311
|
+
|
|
312
|
+
# Watch the next wave begin (if autonomous)
|
|
313
|
+
tail -f state/POWER-SELFTEST.log
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
**Key files created/updated**:
|
|
317
|
+
|
|
318
|
+
| File | Purpose | Git-tracked? | Team-shareable? |
|
|
319
|
+
|------|---------|-------------|-----------------|
|
|
320
|
+
| `CLAUDE.md` | Project-root orchestration rules | ✓ Yes | ✓ Yes (team reference) |
|
|
321
|
+
| `src/CLAUDE.md`, etc. | Domain-scoped contracts + invariants | ✓ Yes | ✓ Yes (team reference) |
|
|
322
|
+
| `STATE.md` | Durable phase, locked decisions, next steps | ✓ Yes | ✓ Yes (team coordination) |
|
|
323
|
+
| `BUILDLOG.md` | Append-only log of every dispatch | ✓ Yes | ✓ Yes (audit trail, costs) |
|
|
324
|
+
| `aesop.config.json` | Personal paths, secrets (webhook URLs) | ✗ No (git-ignored) | ✗ No (per-developer) |
|
|
325
|
+
| `state/.watchdog-heartbeat` | Daemon liveness timestamp | ✗ No (git-ignored) | ✗ No (ephemeral) |
|
|
326
|
+
| `state/.power-selftest.log` | Orchestration health checks | ✗ No (git-ignored) | ✗ No (ephemeral) |
|
|
327
|
+
|
|
328
|
+
**Team-shareable files** (`CLAUDE.md`, `STATE.md`, `BUILDLOG.md`) are committed to git and shared across all developers.
|
|
329
|
+
They're the team's **persistent orchestration brain**.
|
|
330
|
+
|
|
331
|
+
**Personal files** (`aesop.config.json`, heartbeats, logs) are git-ignored and only live on each developer's machine.
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## Step 7: Running `/power` on Already-Primed Repo (Fast Path)
|
|
336
|
+
|
|
337
|
+
Now that your repo is primed (has CLAUDE.md + STATE.md), running `/power` again takes the **fast path**:
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
/power
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
**What happens (fast path)**:
|
|
344
|
+
|
|
345
|
+
1. **Detect priming**: Read project-root `CLAUDE.md` ✓
|
|
346
|
+
2. **Load rules**: Internalize dispatch model, cardinal rules
|
|
347
|
+
3. **Load memory**: Read team facts from `~/.claude/MEMORY.md`
|
|
348
|
+
4. **Load state**: Read `STATE.md` (current phase, locked decisions, next steps)
|
|
349
|
+
5. **Health check**: Run `tools/power_selftest.py` (hooks, secrets, heartbeats)
|
|
350
|
+
6. **Report compact brief**:
|
|
351
|
+
```
|
|
352
|
+
✓ Primed
|
|
353
|
+
- Project: my-target-repo (Node.js API, 4 domains)
|
|
354
|
+
- Dispatch model: Haiku subagents (one per domain), Opus orchestrator
|
|
355
|
+
- Phase: wave-1 complete; ready for wave-2
|
|
356
|
+
- Health: all clear (secret-scan: passing, hooks: installed, heartbeats: alive)
|
|
357
|
+
- Next steps: run /buildsystem for wave-2
|
|
358
|
+
```
|
|
359
|
+
7. **Continue**: Proceed autonomously under the loaded rules
|
|
360
|
+
|
|
361
|
+
**Fast path is 5-10x faster** than init-prime (no code scanning, no .md generation, just loading persisted state).
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## Customizing Your Domains
|
|
366
|
+
|
|
367
|
+
If init-prime identified domains incorrectly, or you want to refactor the domain map:
|
|
368
|
+
|
|
369
|
+
1. **Edit `CLAUDE.md`**: Update the domain map section
|
|
370
|
+
2. **Edit or add domain `CLAUDE.md` files**: Adjust contracts, invariants, entry points
|
|
371
|
+
3. **Update `STATE.md`** with a note: "Domains refactored in wave N"
|
|
372
|
+
4. **Commit + push**:
|
|
373
|
+
```bash
|
|
374
|
+
git add CLAUDE.md src/CLAUDE.md core/CLAUDE.md STATE.md
|
|
375
|
+
git commit -m "refactor: adjust domain map for clarity"
|
|
376
|
+
git push origin main
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
Next `/buildsystem` cycle will use the updated domain map to dispatch Haikus.
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## Troubleshooting
|
|
384
|
+
|
|
385
|
+
### "Init-prime didn't write files"
|
|
386
|
+
- Check that you're in the repo root: `pwd`
|
|
387
|
+
- Confirm the repo has no existing `CLAUDE.md`: `ls CLAUDE.md`
|
|
388
|
+
- Run `/power` with debug output: `DEBUG=1 /power`
|
|
389
|
+
|
|
390
|
+
### "Secret-scan blocked my commit"
|
|
391
|
+
- Review the leak: `git show --cached | grep -i "password\|secret\|key"`
|
|
392
|
+
- Fix the leaky file, re-stage, re-commit
|
|
393
|
+
- Never bypass the scan (`--no-verify` is not allowed)
|
|
394
|
+
|
|
395
|
+
### "Haikus didn't run; saw blank report"
|
|
396
|
+
- Check that `/buildsystem` skill is installed: `ls ~/.claude/skills/buildsystem/SKILL.md`
|
|
397
|
+
- Verify your domain `CLAUDE.md` files are readable and not corrupted
|
|
398
|
+
- Check `state/BUILDLOG.md` for error messages
|
|
399
|
+
|
|
400
|
+
### "I want to add a custom signal to the monitor"
|
|
401
|
+
- Edit `monitor/collect-signals.mjs` (it's a template)
|
|
402
|
+
- Add a new signal function (see the examples in the file)
|
|
403
|
+
- Restart the monitor (if running)
|
|
404
|
+
- Signal will appear in the next health check
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
## Next Steps
|
|
409
|
+
|
|
410
|
+
1. **Commit the CLAUDE.md layer** to your main branch (or review in a PR first)
|
|
411
|
+
2. **Run `/buildsystem` regularly** — it automates your team's development waves
|
|
412
|
+
3. **Iterate domain CLAUDE.md** as your team discovers invariants
|
|
413
|
+
4. **Monitor the dashboard** — `python ui/serve.py` and open http://localhost:8770
|
|
414
|
+
5. **Read [DISPATCH-MODEL.md](DISPATCH-MODEL.md)** to understand cost analysis + parallelism
|
|
415
|
+
|
|
416
|
+
---
|
|
417
|
+
|
|
418
|
+
## Key Takeaways
|
|
419
|
+
|
|
420
|
+
- **Aesop works in ANY repo** — no special stack, language, or project structure required
|
|
421
|
+
- **Init-prime is automatic** — one `/power` run generates the CLAUDE.md layer for you
|
|
422
|
+
- **Fast path is the default** — every subsequent `/power` loads state in seconds
|
|
423
|
+
- **State files are team-shareable** — CLAUDE.md, STATE.md, BUILDLOG.md are git-tracked and shared
|
|
424
|
+
- **Personal config is local** — aesop.config.json + heartbeats are git-ignored
|
|
425
|
+
- **Fully portable** — no hardcoded personal paths, all paths are configurable or relative
|
|
426
|
+
|
|
427
|
+
Your repo is now orchestrated. Happy deploying! 🚀
|