@matt82198/aesop 0.1.0-beta.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 +126 -0
- package/LICENSE +21 -0
- package/README.md +333 -0
- package/aesop.config.example.json +47 -0
- package/bin/cli.js +112 -0
- package/daemons/backup-fleet.sh +173 -0
- package/daemons/run-watchdog.sh +37 -0
- package/dash/dash-extra.mjs +184 -0
- package/dash/watchdog-gui.sh +141 -0
- package/docs/CARDINAL-RULES.md +146 -0
- package/docs/DISPATCH-MODEL.md +180 -0
- package/docs/PUBLISHING.md +150 -0
- package/docs/av-resilience.md +246 -0
- package/monitor/CHARTER.md +66 -0
- package/monitor/collect-signals.mjs +137 -0
- package/package.json +50 -0
- package/tools/launch_tui.py +245 -0
- package/tools/secret_scan.py +363 -0
- package/ui/README.md +141 -0
- package/ui/serve.py +806 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Aesop are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
#### Dashboard Integrations
|
|
13
|
+
- **`dash/dash-extra.mjs`**: Fleet agent detector scans transcripts for running agents, enables web dashboard agent panel. Detects agents in last 12 minutes, color-codes by alert severity, outputs JSON for REST endpoint or TUI text for terminal.
|
|
14
|
+
- **`tools/secret_scan.py`**: Pre-push secret/credential detection gate with comprehensive pattern library (PEM keys, AWS/GitHub/Slack/OpenAI tokens, .env patterns, credential filenames). Supports `--staged`, `--history`, and direct path scanning. Pragma escape hatch for allow-pattern-docs. Exit 1 blocks push on findings.
|
|
15
|
+
|
|
16
|
+
### Improved
|
|
17
|
+
- Web dashboard now properly detects and displays running subagents via `dash-extra.mjs`
|
|
18
|
+
- Secret-scan gate now active in watchdog cycle; blocks any push with unscanned credentials
|
|
19
|
+
|
|
20
|
+
## [1.0.0] - 2026-07-11
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
#### Web Dashboard (Primary Interface)
|
|
25
|
+
- Modern, responsive HTML dashboard replacing terminal UI
|
|
26
|
+
- Real-time fleet monitoring with 3-second refresh cycles
|
|
27
|
+
- Heartbeat liveness detection for daemon health
|
|
28
|
+
- Security alerts panel with unreviewed event tracking
|
|
29
|
+
- Inbox integration for direct orchestrator communication
|
|
30
|
+
- Agent tracking with status and runtime hints
|
|
31
|
+
- **Agent detail expansion**: Click agent rows to view full dispatch prompts, dispatcher, model, and message counts
|
|
32
|
+
- **GET /agent endpoint**: RESTful query for agent metadata and full dispatch details
|
|
33
|
+
- Repository synchronization status display
|
|
34
|
+
- Recent events log with the latest 8 backup operations
|
|
35
|
+
- Transcript integration showing main-thread conversation history
|
|
36
|
+
- Configurable port (default 8770) via environment variables
|
|
37
|
+
- Zero external dependencies (Python 3.10+ stdlib only)
|
|
38
|
+
|
|
39
|
+
#### Orchestration Engine
|
|
40
|
+
- Fable-fleet dispatch model (orchestrator + Haiku subagents)
|
|
41
|
+
- Cost-optimized multi-agent coordination
|
|
42
|
+
- Durable git-committed state (STATE.md, BUILDLOG.md)
|
|
43
|
+
- Autonomous watchdog daemon with 150-second cycle
|
|
44
|
+
- Secret-scan gate on every push (configurable via `tools/secret_scan.py`)
|
|
45
|
+
- Heartbeat-based liveness detection (300s watchdog, 3600s monitor)
|
|
46
|
+
- Append-only BUILDLOG for recovery and audit trails
|
|
47
|
+
|
|
48
|
+
#### Refinement Monitor
|
|
49
|
+
- Standing orchestration health monitor (Haiku loop)
|
|
50
|
+
- Dual-action tier system (AUTO for immediate, PROPOSE for staged)
|
|
51
|
+
- Signal collection and drift detection
|
|
52
|
+
- Automated health checks and rule-friction analysis
|
|
53
|
+
- Extensible signal collectors via `monitor/collect-signals.mjs`
|
|
54
|
+
|
|
55
|
+
#### State Machine & Durability
|
|
56
|
+
- Filesystem-first checkpoint design
|
|
57
|
+
- Git-committed STATE.md and BUILDLOG.md
|
|
58
|
+
- Recovery from machine wipes and interruptions
|
|
59
|
+
- Single-writer control file discipline
|
|
60
|
+
- Idempotent restart semantics
|
|
61
|
+
|
|
62
|
+
#### Security & Observability
|
|
63
|
+
- Configurable secret-scan gate (blocks pushes on policy violation)
|
|
64
|
+
- Observable machinery (every agent run logged, every cost tracked)
|
|
65
|
+
- Security alert collection and triaging
|
|
66
|
+
- AV-resilience patterns for Windows environments
|
|
67
|
+
- Support for dot-directory backup discovery
|
|
68
|
+
|
|
69
|
+
#### Documentation
|
|
70
|
+
- Cardinal Rules guide (10 principles for cost-optimized orchestration)
|
|
71
|
+
- Dispatch Model documentation (cost analysis, parallel patterns)
|
|
72
|
+
- State Machine guide (durability and recovery)
|
|
73
|
+
- AV-Resilience guide (Windows security software compatibility)
|
|
74
|
+
- Quickstart walkthrough and setup guide
|
|
75
|
+
- Architecture deep-dives for extend points
|
|
76
|
+
|
|
77
|
+
#### TUI Dashboard (Legacy Alternative)
|
|
78
|
+
- Terminal-based dashboard via `dash/watchdog-gui.sh`
|
|
79
|
+
- Real-time fleet status display
|
|
80
|
+
- Agent activity tracking
|
|
81
|
+
- Alert visualization
|
|
82
|
+
- Optional jq dependency for JSON parsing
|
|
83
|
+
|
|
84
|
+
### Configuration
|
|
85
|
+
|
|
86
|
+
#### aesop.config.json Schema
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"aesop_root": "/path/to/aesop",
|
|
90
|
+
"state_root": "/path/to/state",
|
|
91
|
+
"scan_root": "/path/to/scan",
|
|
92
|
+
"transcripts_root": "/path/to/transcripts",
|
|
93
|
+
"repos": [
|
|
94
|
+
{
|
|
95
|
+
"path": "/path/to/repo",
|
|
96
|
+
"name": "repo-name"
|
|
97
|
+
}
|
|
98
|
+
],
|
|
99
|
+
"watchdog_cycle_secs": 150,
|
|
100
|
+
"monitor_cycle_secs": 300,
|
|
101
|
+
"heartbeat_stale_threshold_secs": 300
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Development & Extension
|
|
106
|
+
|
|
107
|
+
- Plugin architecture for custom signal collectors
|
|
108
|
+
- Hook points for watchdog customization
|
|
109
|
+
- Dashboard extensibility via JavaScript injection
|
|
110
|
+
- Secret-scan policy implementation examples
|
|
111
|
+
- Support for Haiku-per-domain decomposition
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Initial Release
|
|
116
|
+
|
|
117
|
+
This is the first public release of Aesop, a clean-room open-source implementation of the fable-fleet orchestration harness. The codebase includes:
|
|
118
|
+
|
|
119
|
+
- The complete orchestration engine with watchdog and monitor
|
|
120
|
+
- Web dashboard for fleet observability
|
|
121
|
+
- Legacy TUI interface (bash + jq)
|
|
122
|
+
- Configuration framework and examples
|
|
123
|
+
- Comprehensive documentation and guides
|
|
124
|
+
- MIT License (© 2026 Matt Culliton)
|
|
125
|
+
|
|
126
|
+
Aesop is production-ready and implements the complete cardinal rules for cost-optimized, durable multi-agent coordination.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Matt Culliton
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
# Aesop — Fable-Fleet Orchestration Harness
|
|
2
|
+
|
|
3
|
+
**Aesop** is an open-source orchestration harness for Claude Code, implementing a cost-optimized, self-healing multi-agent dispatch system. One orchestrator model (Opus/Sonnet) directs a fleet of cheap subagents (Haiku) across durable, observable machinery.
|
|
4
|
+
|
|
5
|
+
The naming is a conceit: Aesop directs the Fables (the AI models). Like the tortoise and the hare, Aesop favors the slow, deliberate orchestrator directing a fleet of fast, cheap agents toward reliable outcomes.
|
|
6
|
+
|
|
7
|
+
## Origin
|
|
8
|
+
|
|
9
|
+
Aesop began as damage control: an endpoint-security agent kept deleting work mid-session, so everything was forced into git—committed continuously, pushed constantly, reconstructable from nothing but the remotes. What started as a survival mechanism against a machine that wiped itself grew into a full multi-agent orchestration system—and one worth sharing.
|
|
10
|
+
|
|
11
|
+
## What it is
|
|
12
|
+
|
|
13
|
+
A filesystem-first orchestration system that:
|
|
14
|
+
|
|
15
|
+
- **Dispatch pattern**: Opus orchestrator on the main thread coordinates tiny scoped tasks to Haiku subagents (1/3 the token cost).
|
|
16
|
+
- **Durable state**: git-committed checkpoints (STATE.md, BUILDLOG.md) survive machine wipes and interruptions.
|
|
17
|
+
- **Observable machinery**: every agent run logged, every cost tracked, every security breach detected.
|
|
18
|
+
- **Self-healing watchdog**: runs every 150s, backs up work, scans for secrets and drift, restores on reboot.
|
|
19
|
+
- **Refinement monitor**: standing Haiku loop that watches orchestration health and auto-acts on rule friction.
|
|
20
|
+
- **TUI dashboard**: real-time fleet status, security alerts, heartbeat liveness.
|
|
21
|
+
|
|
22
|
+
## Install & Quick Start
|
|
23
|
+
|
|
24
|
+
### Option 1: npm (Recommended for quick scaffolding)
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Create a new aesop fleet directory
|
|
28
|
+
npx @matt82198/aesop my-fleet
|
|
29
|
+
cd my-fleet
|
|
30
|
+
|
|
31
|
+
# Configure
|
|
32
|
+
cp aesop.config.example.json aesop.config.json
|
|
33
|
+
# Edit aesop.config.json with your paths and repos
|
|
34
|
+
|
|
35
|
+
# Start the daemon
|
|
36
|
+
bash daemons/run-watchdog.sh --once
|
|
37
|
+
|
|
38
|
+
# Launch the dashboard
|
|
39
|
+
python ui/serve.py
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Open `http://localhost:8770` to monitor your fleet.
|
|
43
|
+
|
|
44
|
+
### Option 2: git clone (For development or full customization)
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
git clone https://github.com/matt82198/aesop ~/aesop
|
|
48
|
+
cd ~/aesop
|
|
49
|
+
cp aesop.config.example.json aesop.config.json
|
|
50
|
+
# Edit aesop.config.json with your paths and repos
|
|
51
|
+
|
|
52
|
+
# Start the daemon
|
|
53
|
+
export AESOP_ROOT=$HOME/aesop
|
|
54
|
+
bash $AESOP_ROOT/daemons/run-watchdog.sh --once
|
|
55
|
+
|
|
56
|
+
# Launch the dashboard
|
|
57
|
+
python ui/serve.py
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Architecture
|
|
61
|
+
|
|
62
|
+
### Directory layout
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
aesop/
|
|
66
|
+
daemons/ # Watchdog daemon + backup scripts
|
|
67
|
+
dash/ # TUI dashboard (watchdog-gui.sh)
|
|
68
|
+
monitor/ # Orchestration monitor (collect-signals.mjs, CHARTER.md)
|
|
69
|
+
tools/ # Build utilities (stubs for extend)
|
|
70
|
+
docs/ # Migration guides, deep-dives
|
|
71
|
+
state/ # Durable checkpoints (created at runtime)
|
|
72
|
+
aesop.config.json # Your local configuration (git-ignored)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Operating the harness
|
|
76
|
+
|
|
77
|
+
#### 1. Bootstrap
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
git clone <aesop-repo> ~/aesop
|
|
81
|
+
cd ~/aesop
|
|
82
|
+
cp aesop.config.example.json aesop.config.json
|
|
83
|
+
# Edit aesop.config.json with your paths and repos
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### 2. Start the watchdog daemon
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
export AESOP_ROOT=$HOME/aesop
|
|
90
|
+
bash $AESOP_ROOT/daemons/run-watchdog.sh &
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Runs every 150s: discovers changed repos, stashes uncommitted work, pushes backups to `backup/wip-*` branches, runs secret-scan gate.
|
|
94
|
+
|
|
95
|
+
#### 3. Launch the Web Dashboard (Primary Interface)
|
|
96
|
+
|
|
97
|
+
The web dashboard is the recommended way to monitor your fleet. It provides real-time observability, security alerts, and inbox integration in a modern, responsive interface.
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
python $AESOP_ROOT/ui/serve.py
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Opens `http://localhost:8770` with:
|
|
104
|
+
- Real-time daemon heartbeats and liveness
|
|
105
|
+
- Active subagent tracking
|
|
106
|
+
- Security alerts panel
|
|
107
|
+
- Recent events log
|
|
108
|
+
- Inbox for orchestrator communication
|
|
109
|
+
- Repository sync status
|
|
110
|
+
|
|
111
|
+
See `ui/README.md` for configuration, environment variables, and troubleshooting.
|
|
112
|
+
|
|
113
|
+
#### (Optional) Legacy TUI Dashboard
|
|
114
|
+
|
|
115
|
+
If you prefer a terminal-based interface:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# On Windows (in a dedicated terminal):
|
|
119
|
+
Start-Process "C:\Program Files\Git\git-bash.exe" -ArgumentList '-c', 'bash /c/Users/you/aesop/dash/watchdog-gui.sh'
|
|
120
|
+
|
|
121
|
+
# On Unix:
|
|
122
|
+
bash ~/aesop/dash/watchdog-gui.sh &
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Note: The TUI is maintained for backward compatibility but is not actively developed. The web dashboard is recommended for new deployments.
|
|
126
|
+
|
|
127
|
+
#### 4. Arm the monitor loop
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# If using Claude Code, add to your CLAUDE.md or invoke via /power:
|
|
131
|
+
# Runs collect-signals.mjs every cycle, emits BRIEF.md + SIGNALS.json,
|
|
132
|
+
# then acts on AUTO-tier findings or stages PROPOSE-tier changes.
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Cardinal Rules (abridged)
|
|
136
|
+
|
|
137
|
+
Read `docs/CARDINAL-RULES.md` for the full text. Core principles:
|
|
138
|
+
|
|
139
|
+
1. **Dispatch**: Haiku subagents only (cost lever). Opus orchestrates main-thread only.
|
|
140
|
+
2. **TDD-first**: Fail tests before implementation. Tiny scoped domains; one Haiku per domain.
|
|
141
|
+
3. **Reliability**: Every input produces output (brief/log/heartbeat/FAILED). Never wait.
|
|
142
|
+
4. **Durable state**: STATE.md + BUILDLOG.md checkpoints survive wipes. Re-sync on resume.
|
|
143
|
+
5. **Push discipline**: feature/branch → PR (never main). Continuously push green work.
|
|
144
|
+
6. **Control files**: Single-writer discipline (STATE.md orchestrator, MEMORY.md keeper, BUILDLOG.md append-only).
|
|
145
|
+
7. **Local execution**: Python runs locally only (no cloud runners). Reusable scripts in ~/scripts.
|
|
146
|
+
8. **Secret gates**: `secret_scan.py` blocks every push. No credentials in repos.
|
|
147
|
+
9. **Observability**: Every agent run logged, every cost tracked, every security event triaged.
|
|
148
|
+
|
|
149
|
+
## Requirements
|
|
150
|
+
|
|
151
|
+
- **Claude Code CLI** (v0.1+): the agent-spawning harness.
|
|
152
|
+
- **Git** (v2.40+): version control for durable state.
|
|
153
|
+
- **Bash** (v4+): scripting (Git Bash on Windows, bash on Unix).
|
|
154
|
+
- **Node.js** (v18+): for monitor signal collection and dashboard extras.
|
|
155
|
+
- **Python** (v3.10+): for log rotation, secret-scan, and custom tooling.
|
|
156
|
+
- **jq** (optional): JSON parsing in TUI dashboard.
|
|
157
|
+
|
|
158
|
+
## Setup Walkthrough
|
|
159
|
+
|
|
160
|
+
### 1. Edit your configuration
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
cp aesop.config.example.json aesop.config.json
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Edit `aesop.config.json`:
|
|
167
|
+
- Set `aesop_root`, `brain_root`, `scripts_root`, `temp_root` to your paths.
|
|
168
|
+
- List your project repos under `repos[]`.
|
|
169
|
+
- Tune watchdog and monitor cycle times.
|
|
170
|
+
- Disable secret-scan if you don't have `tools/secret_scan.py` yet.
|
|
171
|
+
|
|
172
|
+
### 2. Create required directories
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
mkdir -p ~/aesop/state
|
|
176
|
+
mkdir -p ~/.heartbeats
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### 3. (Optional) Add your secret-scan script
|
|
180
|
+
|
|
181
|
+
If you have a security scanner, drop it at `aesop/tools/secret_scan.py`. The watchdog will call it before pushing.
|
|
182
|
+
|
|
183
|
+
Example stub:
|
|
184
|
+
```python
|
|
185
|
+
#!/usr/bin/env python3
|
|
186
|
+
import sys
|
|
187
|
+
sys.exit(0) # TODO: implement secret scanning
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### 4. Start the daemon
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
export AESOP_ROOT=$HOME/aesop
|
|
194
|
+
bash $AESOP_ROOT/daemons/run-watchdog.sh &
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Test mode: `bash $AESOP_ROOT/daemons/run-watchdog.sh --once`
|
|
198
|
+
|
|
199
|
+
### 5. Launch the dashboard
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
bash ~/aesop/dash/watchdog-gui.sh
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### 6. Arm the monitor (optional)
|
|
206
|
+
|
|
207
|
+
If you're using Claude Code, add this to your orchestrator loop:
|
|
208
|
+
```bash
|
|
209
|
+
export AESOP_ROOT=$HOME/aesop
|
|
210
|
+
node $AESOP_ROOT/monitor/collect-signals.mjs
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
The monitor will read `BRIEF.md` and `SIGNALS.json` each cycle and act on findings.
|
|
214
|
+
|
|
215
|
+
## Usage Patterns
|
|
216
|
+
|
|
217
|
+
### Dispatch model (how to scale cheaply)
|
|
218
|
+
|
|
219
|
+
```plaintext
|
|
220
|
+
Orchestrator (main thread)
|
|
221
|
+
├─ Haiku subagent 1 (domain A: tests)
|
|
222
|
+
├─ Haiku subagent 2 (domain B: build)
|
|
223
|
+
├─ Haiku subagent 3 (domain C: review)
|
|
224
|
+
└─ Haiku subagent 4 (domain D: docs)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Each subagent is **tiny**, **scoped**, and **disposable**. Total cost: ~25% of all-Opus fleet.
|
|
228
|
+
|
|
229
|
+
### Action tiers (AUTO vs PROPOSE)
|
|
230
|
+
|
|
231
|
+
- **AUTO**: immediate + logged (read-only checks, appends to logs, heartbeat updates).
|
|
232
|
+
- **PROPOSE**: staged in `monitor/PROPOSALS.md`, requires user approval before execution.
|
|
233
|
+
|
|
234
|
+
### Heartbeat pattern
|
|
235
|
+
|
|
236
|
+
Daemons write epoch-seconds to `.heartbeat` files. The dashboard reads these to detect stalls:
|
|
237
|
+
- Watchdog: alert if >300s old.
|
|
238
|
+
- Monitor: alert if >3600s old.
|
|
239
|
+
- Custom loops: check before spawning (skip if <200s).
|
|
240
|
+
|
|
241
|
+
## Security & Privacy
|
|
242
|
+
|
|
243
|
+
**⚠️ Important**: This harness assumes a **private brain directory** (`~/.claude`) that is **NEVER committed** to this repo. Your cardinal rules, agent catalog, and memory belong in your private remote (e.g., `claude-config`).
|
|
244
|
+
|
|
245
|
+
- `aesop.config.json` is git-ignored (keep your paths secret).
|
|
246
|
+
- `state/` and `.log` files are git-ignored (keep runtime data local).
|
|
247
|
+
- Implement `tools/secret_scan.py` with your own security rules.
|
|
248
|
+
- Use `secret_scan.py` as a gate on every push (don't bypass).
|
|
249
|
+
|
|
250
|
+
## Extension points
|
|
251
|
+
|
|
252
|
+
### Add a custom signal collector
|
|
253
|
+
|
|
254
|
+
Edit `monitor/collect-signals.mjs`:
|
|
255
|
+
```javascript
|
|
256
|
+
// Example: detect junk scripts
|
|
257
|
+
function findJunkScripts() {
|
|
258
|
+
const junk = fs.readdirSync('/tmp').filter(f => f.endsWith('.py'));
|
|
259
|
+
return junk;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Then add to signals:
|
|
263
|
+
signals.junkScripts = findJunkScripts();
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Customize the watchdog
|
|
267
|
+
|
|
268
|
+
Edit `daemons/backup-fleet.sh`:
|
|
269
|
+
- Parse `aesop.config.json` to discover repos dynamically.
|
|
270
|
+
- Add per-repo hooks (e.g., run linters before backup).
|
|
271
|
+
- Implement your own secret-scan gate.
|
|
272
|
+
|
|
273
|
+
### Extend the dashboard
|
|
274
|
+
|
|
275
|
+
Edit `dash/watchdog-gui.sh`:
|
|
276
|
+
- Add panels for CPU/memory/disk usage.
|
|
277
|
+
- Integrate with your monitoring system.
|
|
278
|
+
- Color-code alerts by severity.
|
|
279
|
+
|
|
280
|
+
## Troubleshooting
|
|
281
|
+
|
|
282
|
+
### Watchdog doesn't start
|
|
283
|
+
|
|
284
|
+
Check `state/FLEET-BACKUP.log` for errors. Verify `AESOP_ROOT` is set correctly.
|
|
285
|
+
|
|
286
|
+
### Dashboard shows "unavailable"
|
|
287
|
+
|
|
288
|
+
- If you see `(agents/processes panel unavailable)`, `node` is missing or `dash-extra.mjs` is not in sync.
|
|
289
|
+
- Install Node.js v18+ and re-run.
|
|
290
|
+
|
|
291
|
+
### Secret-scan blocks a legitimate push
|
|
292
|
+
|
|
293
|
+
Add a suppression to your `tools/secret_scan.py`. Aesop never auto-bypasses gates (by design).
|
|
294
|
+
|
|
295
|
+
### Monitor doesn't start
|
|
296
|
+
|
|
297
|
+
Ensure Node.js is on PATH and `collect-signals.mjs` has execute permissions. Check `monitor/BRIEF.md` for the latest cycle log.
|
|
298
|
+
|
|
299
|
+
## Architecture deep-dives
|
|
300
|
+
|
|
301
|
+
See `docs/` for detailed guides:
|
|
302
|
+
- `CARDINAL-RULES.md` — full text of the 10 cardinal rules.
|
|
303
|
+
- `DISPATCH-MODEL.md` — cost analysis and parallel orchestration patterns.
|
|
304
|
+
- `STATE-MACHINE.md` — how STATE.md and BUILDLOG.md survive wipes.
|
|
305
|
+
- `MONITOR-GOVERNANCE.md` — monitor AUTO/PROPOSE tiers and approval flow.
|
|
306
|
+
|
|
307
|
+
## License
|
|
308
|
+
|
|
309
|
+
MIT License. See `LICENSE` file.
|
|
310
|
+
|
|
311
|
+
## Contributing
|
|
312
|
+
|
|
313
|
+
Aesop is open-source and welcomes improvements. To contribute:
|
|
314
|
+
|
|
315
|
+
1. Fork this repo.
|
|
316
|
+
2. Create a feature branch: `git checkout -b feature/your-idea`.
|
|
317
|
+
3. Add tests (TDD first).
|
|
318
|
+
4. Commit with clear messages.
|
|
319
|
+
5. Push to origin and open a PR.
|
|
320
|
+
|
|
321
|
+
Maintain the cardinal rules: keep subagents cheap (Haiku), orchestrator lean, state durable, and machinery observable.
|
|
322
|
+
|
|
323
|
+
## References
|
|
324
|
+
|
|
325
|
+
- [Anthropic Claude API](https://docs.anthropic.com)
|
|
326
|
+
- [Claude Code CLI](https://github.com/anthropics/claude-code)
|
|
327
|
+
- [Git documentation](https://git-scm.com/doc)
|
|
328
|
+
- Inspiration: "The Missing Memory Layer", "Agent Cost Trauma", "120 Words to Shipped" (publications on AI orchestration patterns).
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
**Aesop Contributors**
|
|
333
|
+
Built with the fable-fleet dispatch model in mind. May your orchestrator be wise and your subagents swift.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Aesop configuration example. Copy to aesop.config.json and customize for your setup.",
|
|
3
|
+
"aesop_root": "/path/to/aesop",
|
|
4
|
+
"brain_root": "/path/to/your/brain",
|
|
5
|
+
"scripts_root": "/path/to/your/scripts",
|
|
6
|
+
"temp_root": "/path/to/temp/scratch",
|
|
7
|
+
"repos": [
|
|
8
|
+
{
|
|
9
|
+
"path": "/path/to/project1",
|
|
10
|
+
"name": "project1",
|
|
11
|
+
"primary_branch": "main",
|
|
12
|
+
"backup_branch": "backup/wip"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"path": "/path/to/project2",
|
|
16
|
+
"name": "project2",
|
|
17
|
+
"primary_branch": "main",
|
|
18
|
+
"backup_branch": "backup/wip"
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"watchdog": {
|
|
22
|
+
"cycle_seconds": 150,
|
|
23
|
+
"heartbeat_threshold_seconds": 200,
|
|
24
|
+
"enable_secret_scan": true,
|
|
25
|
+
"secret_scan_script": "tools/secret_scan.py"
|
|
26
|
+
},
|
|
27
|
+
"monitor": {
|
|
28
|
+
"enable": true,
|
|
29
|
+
"cycle_seconds": 3600,
|
|
30
|
+
"heartbeat_threshold_seconds": 3600,
|
|
31
|
+
"memory_staleness_days": 30,
|
|
32
|
+
"log_max_lines": 500,
|
|
33
|
+
"log_max_kb": 40
|
|
34
|
+
},
|
|
35
|
+
"dashboard": {
|
|
36
|
+
"refresh_seconds": 1,
|
|
37
|
+
"enable_jq_parsing": true,
|
|
38
|
+
"theme": "dark"
|
|
39
|
+
},
|
|
40
|
+
"cardinal_rules": {
|
|
41
|
+
"subagent_model": "haiku",
|
|
42
|
+
"orchestrator_model": "opus",
|
|
43
|
+
"tdd_first": true,
|
|
44
|
+
"never_push_main": true,
|
|
45
|
+
"secret_scan_gates_push": true
|
|
46
|
+
}
|
|
47
|
+
}
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
const args = process.argv.slice(2);
|
|
7
|
+
const helpFlag = args.includes('--help') || args.includes('-h');
|
|
8
|
+
|
|
9
|
+
if (helpFlag) {
|
|
10
|
+
console.log(`
|
|
11
|
+
aesop — Multi-agent orchestration template scaffolder
|
|
12
|
+
|
|
13
|
+
Usage:
|
|
14
|
+
npx @matt82198/aesop [target-dir]
|
|
15
|
+
|
|
16
|
+
Arguments:
|
|
17
|
+
target-dir Directory to scaffold the template into (default: "aesop-fleet")
|
|
18
|
+
|
|
19
|
+
Examples:
|
|
20
|
+
npx @matt82198/aesop # Creates ./aesop-fleet/
|
|
21
|
+
npx @matt82198/aesop my-fleet # Creates ./my-fleet/
|
|
22
|
+
npx @matt82198/aesop /tmp/my-orchestrator # Creates /tmp/my-orchestrator/
|
|
23
|
+
|
|
24
|
+
Options:
|
|
25
|
+
--help, -h Show this help message
|
|
26
|
+
|
|
27
|
+
After scaffolding, cd into the directory and:
|
|
28
|
+
1. Copy aesop.config.example.json → aesop.config.json
|
|
29
|
+
2. Edit aesop.config.json with your paths and repos
|
|
30
|
+
3. Run: bash daemons/run-watchdog.sh --once
|
|
31
|
+
4. Launch dashboard: python ui/serve.py
|
|
32
|
+
`);
|
|
33
|
+
process.exit(0);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const targetDir = args[0] || 'aesop-fleet';
|
|
37
|
+
|
|
38
|
+
if (args.length > 1) {
|
|
39
|
+
console.error('Error: Too many arguments. Use --help for usage.');
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Validate target directory doesn't exist or is empty
|
|
44
|
+
if (fs.existsSync(targetDir)) {
|
|
45
|
+
const contents = fs.readdirSync(targetDir);
|
|
46
|
+
if (contents.length > 0) {
|
|
47
|
+
console.error(`Error: Directory "${targetDir}" exists and is not empty.`);
|
|
48
|
+
console.error('Please choose a different target directory or remove the existing one.');
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Copy template files
|
|
56
|
+
const templateRoot = path.join(__dirname, '..');
|
|
57
|
+
const filesToCopy = [
|
|
58
|
+
'daemons',
|
|
59
|
+
'dash',
|
|
60
|
+
'monitor',
|
|
61
|
+
'tools',
|
|
62
|
+
'ui',
|
|
63
|
+
'docs',
|
|
64
|
+
'aesop.config.example.json',
|
|
65
|
+
'README.md',
|
|
66
|
+
'LICENSE',
|
|
67
|
+
'CHANGELOG.md'
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
let copiedCount = 0;
|
|
71
|
+
|
|
72
|
+
function copyRecursive(src, dest) {
|
|
73
|
+
const stat = fs.statSync(src);
|
|
74
|
+
if (stat.isDirectory()) {
|
|
75
|
+
if (!fs.existsSync(dest)) {
|
|
76
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
77
|
+
}
|
|
78
|
+
const entries = fs.readdirSync(src);
|
|
79
|
+
entries.forEach(entry => {
|
|
80
|
+
const srcFile = path.join(src, entry);
|
|
81
|
+
const destFile = path.join(dest, entry);
|
|
82
|
+
copyRecursive(srcFile, destFile);
|
|
83
|
+
});
|
|
84
|
+
} else {
|
|
85
|
+
fs.copyFileSync(src, dest);
|
|
86
|
+
copiedCount++;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
filesToCopy.forEach(item => {
|
|
92
|
+
const src = path.join(templateRoot, item);
|
|
93
|
+
const dest = path.join(targetDir, item);
|
|
94
|
+
if (fs.existsSync(src)) {
|
|
95
|
+
copyRecursive(src, dest);
|
|
96
|
+
console.log(`✓ Copied ${item}`);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
console.log(`\n✅ Scaffolded aesop template into "${targetDir}" (${copiedCount} files)`);
|
|
101
|
+
console.log('\nNext steps:');
|
|
102
|
+
console.log(` 1. cd ${targetDir}`);
|
|
103
|
+
console.log(' 2. cp aesop.config.example.json aesop.config.json');
|
|
104
|
+
console.log(' 3. Edit aesop.config.json with your configuration');
|
|
105
|
+
console.log(' 4. bash daemons/run-watchdog.sh --once (test run)');
|
|
106
|
+
console.log(' 5. python ui/serve.py (launch dashboard)');
|
|
107
|
+
console.log('\nFor full documentation, see the README.md in the scaffolded directory.');
|
|
108
|
+
process.exit(0);
|
|
109
|
+
} catch (err) {
|
|
110
|
+
console.error(`Error scaffolding template: ${err.message}`);
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|