@matt82198/aesop 0.1.0-beta.5 → 0.1.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.
Files changed (198) hide show
  1. package/CHANGELOG.md +158 -5
  2. package/LICENSE +66 -21
  3. package/README.md +97 -33
  4. package/aesop.config.example.json +6 -0
  5. package/bin/CLAUDE.md +12 -3
  6. package/bin/cli.js +211 -40
  7. package/daemons/CLAUDE.md +1 -1
  8. package/daemons/backup-fleet.sh +209 -51
  9. package/daemons/run-watchdog.sh +208 -62
  10. package/dash/dash-extra.mjs +73 -4
  11. package/dash/watchdog-gui.sh +41 -35
  12. package/docs/ARCHITECTURE.md +296 -0
  13. package/docs/CONCEPTS.md +254 -0
  14. package/docs/CONFIGURE.md +256 -0
  15. package/docs/FIRST-WAVE.md +276 -0
  16. package/docs/INSTALL.md +224 -0
  17. package/docs/README.md +176 -27
  18. package/docs/autonomous-swe.md +149 -0
  19. package/docs/reproduce.md +121 -0
  20. package/hooks/CLAUDE.md +28 -0
  21. package/hooks/install-waveguard.sh +68 -0
  22. package/hooks/pre-commit-waveguard.sh +26 -0
  23. package/hooks/pre-push-policy.sh +253 -15
  24. package/monitor/CLAUDE.md +3 -3
  25. package/monitor/collect-signals.mjs +133 -20
  26. package/package.json +15 -7
  27. package/scan/CLAUDE.md +30 -0
  28. package/skills/CLAUDE.md +1 -0
  29. package/state_store/ingest.py +18 -1
  30. package/state_store/projections.py +78 -4
  31. package/state_store/store.py +102 -7
  32. package/tools/CLAUDE.md +25 -18
  33. package/tools/alert_bridge.py +14 -10
  34. package/tools/bench_runner.py +438 -0
  35. package/tools/buildlog.py +4 -7
  36. package/tools/ci_merge_wait.py +215 -34
  37. package/tools/common.py +62 -0
  38. package/tools/cost_ceiling.py +191 -0
  39. package/tools/dash.js +102 -0
  40. package/tools/doctor.js +220 -0
  41. package/tools/fleet_ledger.py +189 -17
  42. package/tools/halt.py +172 -0
  43. package/tools/healthcheck.py +24 -21
  44. package/tools/heartbeat.py +4 -7
  45. package/tools/metrics_gate.py +8 -2
  46. package/tools/orchestrator_status.py +4 -9
  47. package/tools/reconcile.py +277 -0
  48. package/tools/rotate_logs.py +152 -62
  49. package/tools/scanner_selftest.py +28 -3
  50. package/tools/secret_scan.py +359 -90
  51. package/tools/self_stats.py +292 -4
  52. package/tools/status.js +187 -0
  53. package/tools/verify_agent_inspector.py +289 -0
  54. package/tools/verify_prboard.py +344 -0
  55. package/tools/watch.js +49 -0
  56. package/ui/CLAUDE.md +2 -0
  57. package/ui/agents.py +332 -33
  58. package/ui/api/tracker.py +15 -7
  59. package/ui/collectors.py +125 -32
  60. package/ui/config.py +22 -2
  61. package/ui/cost.py +98 -3
  62. package/ui/csrf.py +2 -1
  63. package/ui/handler.py +209 -21
  64. package/ui/sse.py +102 -16
  65. package/ui/wave_prs.py +230 -0
  66. package/ui/web/dist/assets/index-0qQYnvMC.js +9 -0
  67. package/ui/web/dist/assets/index-BdIlFieV.css +1 -0
  68. package/ui/web/dist/index.html +2 -2
  69. package/monitor/.signal-state.json +0 -3
  70. package/monitor/ACTIONS.log +0 -1
  71. package/monitor/BRIEF.md +0 -24
  72. package/monitor/SIGNALS.json +0 -54
  73. package/state_store/__pycache__/__init__.cpython-314.pyc +0 -0
  74. package/state_store/__pycache__/api.cpython-314.pyc +0 -0
  75. package/state_store/__pycache__/export.cpython-314.pyc +0 -0
  76. package/state_store/__pycache__/ingest.cpython-314.pyc +0 -0
  77. package/state_store/__pycache__/projections.cpython-314.pyc +0 -0
  78. package/state_store/__pycache__/store.cpython-314.pyc +0 -0
  79. package/tools/__pycache__/alert_bridge.cpython-314.pyc +0 -0
  80. package/tools/__pycache__/buildlog.cpython-314.pyc +0 -0
  81. package/tools/__pycache__/ci_merge_wait.cpython-314.pyc +0 -0
  82. package/tools/__pycache__/ensure_state.cpython-314.pyc +0 -0
  83. package/tools/__pycache__/eod_sweep.cpython-314.pyc +0 -0
  84. package/tools/__pycache__/fleet_ledger.cpython-314.pyc +0 -0
  85. package/tools/__pycache__/fleet_prompt_extractor.cpython-314.pyc +0 -0
  86. package/tools/__pycache__/healthcheck.cpython-314.pyc +0 -0
  87. package/tools/__pycache__/heartbeat.cpython-314.pyc +0 -0
  88. package/tools/__pycache__/inbox_drain.cpython-314.pyc +0 -0
  89. package/tools/__pycache__/launch_tui.cpython-314.pyc +0 -0
  90. package/tools/__pycache__/metrics_gate.cpython-314.pyc +0 -0
  91. package/tools/__pycache__/orchestrator_status.cpython-314.pyc +0 -0
  92. package/tools/__pycache__/power_selftest.cpython-314.pyc +0 -0
  93. package/tools/__pycache__/prepublish_scan.cpython-314.pyc +0 -0
  94. package/tools/__pycache__/rotate_logs.cpython-314.pyc +0 -0
  95. package/tools/__pycache__/scanner_selftest.cpython-314.pyc +0 -0
  96. package/tools/__pycache__/secret_scan.cpython-314.pyc +0 -0
  97. package/tools/__pycache__/self_stats.cpython-314.pyc +0 -0
  98. package/tools/__pycache__/session_usage_summary.cpython-314.pyc +0 -0
  99. package/tools/__pycache__/stall_check.cpython-314.pyc +0 -0
  100. package/tools/__pycache__/transcript_replay.cpython-314.pyc +0 -0
  101. package/tools/__pycache__/transcript_timeline.cpython-314.pyc +0 -0
  102. package/tools/__pycache__/verify_dash.cpython-314.pyc +0 -0
  103. package/tools/__pycache__/verify_submit_encoding.cpython-314.pyc +0 -0
  104. package/ui/__pycache__/agents.cpython-314.pyc +0 -0
  105. package/ui/__pycache__/collectors.cpython-314.pyc +0 -0
  106. package/ui/__pycache__/config.cpython-314.pyc +0 -0
  107. package/ui/__pycache__/cost.cpython-314.pyc +0 -0
  108. package/ui/__pycache__/csrf.cpython-314.pyc +0 -0
  109. package/ui/__pycache__/handler.cpython-314.pyc +0 -0
  110. package/ui/__pycache__/render.cpython-314.pyc +0 -0
  111. package/ui/__pycache__/serve.cpython-314.pyc +0 -0
  112. package/ui/__pycache__/sse.cpython-314.pyc +0 -0
  113. package/ui/api/__pycache__/__init__.cpython-314.pyc +0 -0
  114. package/ui/api/__pycache__/submit.cpython-314.pyc +0 -0
  115. package/ui/api/__pycache__/tracker.cpython-314.pyc +0 -0
  116. package/ui/web/.gitattributes +0 -13
  117. package/ui/web/dist/assets/index-2LZDQirC.js +0 -9
  118. package/ui/web/dist/assets/index-D4M1qyOv.css +0 -1
  119. package/ui/web/index.html +0 -13
  120. package/ui/web/package-lock.json +0 -2225
  121. package/ui/web/package.json +0 -26
  122. package/ui/web/src/App.test.tsx +0 -74
  123. package/ui/web/src/App.tsx +0 -142
  124. package/ui/web/src/CONTRIBUTING-UI.md +0 -49
  125. package/ui/web/src/components/AgentRow.css +0 -187
  126. package/ui/web/src/components/AgentRow.test.tsx +0 -209
  127. package/ui/web/src/components/AgentRow.tsx +0 -207
  128. package/ui/web/src/components/AgentsPanel.css +0 -108
  129. package/ui/web/src/components/AgentsPanel.test.tsx +0 -41
  130. package/ui/web/src/components/AgentsPanel.tsx +0 -58
  131. package/ui/web/src/components/AlertsPanel.css +0 -88
  132. package/ui/web/src/components/AlertsPanel.test.tsx +0 -51
  133. package/ui/web/src/components/AlertsPanel.tsx +0 -67
  134. package/ui/web/src/components/BacklogPanel.test.tsx +0 -126
  135. package/ui/web/src/components/BacklogPanel.tsx +0 -122
  136. package/ui/web/src/components/CostChart.css +0 -110
  137. package/ui/web/src/components/CostChart.test.tsx +0 -144
  138. package/ui/web/src/components/CostChart.tsx +0 -152
  139. package/ui/web/src/components/CostTable.css +0 -93
  140. package/ui/web/src/components/CostTable.test.tsx +0 -165
  141. package/ui/web/src/components/CostTable.tsx +0 -94
  142. package/ui/web/src/components/EventsFeed.css +0 -68
  143. package/ui/web/src/components/EventsFeed.test.tsx +0 -36
  144. package/ui/web/src/components/EventsFeed.tsx +0 -31
  145. package/ui/web/src/components/HealthHeader.css +0 -137
  146. package/ui/web/src/components/HealthHeader.test.tsx +0 -278
  147. package/ui/web/src/components/HealthHeader.tsx +0 -281
  148. package/ui/web/src/components/InboxForm.css +0 -135
  149. package/ui/web/src/components/InboxForm.test.tsx +0 -208
  150. package/ui/web/src/components/InboxForm.tsx +0 -116
  151. package/ui/web/src/components/MessagesTail.module.css +0 -144
  152. package/ui/web/src/components/MessagesTail.test.tsx +0 -176
  153. package/ui/web/src/components/MessagesTail.tsx +0 -94
  154. package/ui/web/src/components/ReposPanel.css +0 -90
  155. package/ui/web/src/components/ReposPanel.test.tsx +0 -45
  156. package/ui/web/src/components/ReposPanel.tsx +0 -67
  157. package/ui/web/src/components/Scorecard.css +0 -106
  158. package/ui/web/src/components/Scorecard.test.tsx +0 -117
  159. package/ui/web/src/components/Scorecard.tsx +0 -85
  160. package/ui/web/src/components/Timeline.module.css +0 -151
  161. package/ui/web/src/components/Timeline.test.tsx +0 -215
  162. package/ui/web/src/components/Timeline.tsx +0 -99
  163. package/ui/web/src/components/TrackerBoard.test.tsx +0 -121
  164. package/ui/web/src/components/TrackerBoard.tsx +0 -107
  165. package/ui/web/src/components/TrackerCard.test.tsx +0 -180
  166. package/ui/web/src/components/TrackerCard.tsx +0 -160
  167. package/ui/web/src/components/TrackerForm.test.tsx +0 -189
  168. package/ui/web/src/components/TrackerForm.tsx +0 -144
  169. package/ui/web/src/lib/api.ts +0 -218
  170. package/ui/web/src/lib/format.test.ts +0 -89
  171. package/ui/web/src/lib/format.ts +0 -103
  172. package/ui/web/src/lib/sanitizeUrl.test.ts +0 -84
  173. package/ui/web/src/lib/sanitizeUrl.ts +0 -38
  174. package/ui/web/src/lib/types.ts +0 -230
  175. package/ui/web/src/lib/useHashRoute.test.ts +0 -60
  176. package/ui/web/src/lib/useHashRoute.ts +0 -23
  177. package/ui/web/src/lib/useSSE.ts +0 -175
  178. package/ui/web/src/main.tsx +0 -10
  179. package/ui/web/src/styles/global.css +0 -179
  180. package/ui/web/src/styles/theme.css +0 -184
  181. package/ui/web/src/styles/work.css +0 -572
  182. package/ui/web/src/test/fixtures.ts +0 -385
  183. package/ui/web/src/test/setup.ts +0 -49
  184. package/ui/web/src/views/Activity.module.css +0 -43
  185. package/ui/web/src/views/Activity.test.tsx +0 -89
  186. package/ui/web/src/views/Activity.tsx +0 -31
  187. package/ui/web/src/views/Cost.css +0 -87
  188. package/ui/web/src/views/Cost.test.tsx +0 -142
  189. package/ui/web/src/views/Cost.tsx +0 -54
  190. package/ui/web/src/views/Overview.css +0 -51
  191. package/ui/web/src/views/Overview.test.tsx +0 -76
  192. package/ui/web/src/views/Overview.tsx +0 -46
  193. package/ui/web/src/views/Work.test.tsx +0 -82
  194. package/ui/web/src/views/Work.tsx +0 -79
  195. package/ui/web/src/vite-env.d.ts +0 -10
  196. package/ui/web/tsconfig.json +0 -22
  197. package/ui/web/vite.config.ts +0 -25
  198. package/ui/web/vitest.config.ts +0 -12
package/docs/README.md CHANGED
@@ -1,44 +1,193 @@
1
- # Aesop Documentation Index
1
+ # Aesop Documentation
2
2
 
3
- Aesop is a fable-fleet orchestration harness for Claude Code. It runs fast, cheap delivery waves: parallel Haiku agents, lower cost via Haiku-first dispatch and faster wall-clock via parallel agents.
3
+ Aesop is a fable-fleet orchestration harness for Claude Code. It runs fast, cheap delivery waves: parallel Haiku agents, durable state, observable machinery, security gates.
4
4
 
5
- **New to Aesop?** Start here: [HOW-THE-LOOP-WORKS.md](HOW-THE-LOOP-WORKS.md) — a walkthrough of one wave cycle and why it's productive.
5
+ ---
6
+
7
+ ## Adopter Journey (Start Here)
8
+
9
+ If you're new to Aesop, follow this 4-stage path:
10
+
11
+ ### Stage 1: Install
12
+ **[INSTALL.md](INSTALL.md)** — Prerequisites, `npx` scaffold, what gets created
13
+
14
+ - System requirements (Claude Code CLI, Git, Bash, Node.js, Python)
15
+ - Quick-start: `npx @matt82198/aesop@beta my-fleet`
16
+ - Manual setup for development (git clone)
17
+ - Pre-push hook installation
18
+
19
+ ### Stage 2: Configure
20
+ **[CONFIGURE.md](CONFIGURE.md)** — aesop.config.json, repos, ports, brain root
21
+
22
+ - Field reference (`aesopRoot`, `braindRoot`, `repos`, `dashboardPort`, `dashboardOrigin`)
23
+ - Example configurations (single repo, microservices, Windows paths)
24
+ - Security notes (git-ignore config, no secrets in config)
25
+ - Environment variables
6
26
 
7
- For deeper governance + operational rules, see the reference docs below.
27
+ ### Stage 3: First Wave
28
+ **[FIRST-WAVE.md](FIRST-WAVE.md)** — Run `/power` then `/buildsystem` end-to-end
29
+
30
+ - What to expect from each phase (rank → dispatch → verify → close)
31
+ - Monitoring (dashboard, TUI, logs)
32
+ - When agents hang (watchdog protocol, retry cap)
33
+ - Common Q&A (wave duration, cost, cancellation, failure handling)
34
+
35
+ ### Stage 4: Concepts
36
+ **[CONCEPTS.md](CONCEPTS.md)** — Dispatch model, cost, state, security, governance
37
+
38
+ - The wave cycle at a glance
39
+ - Dispatch model (Haiku-first subagents, cost model, patterns)
40
+ - State & checkpointing (STATE.md, BUILDLOG.md, durable recovery)
41
+ - Security gates (secret-scan, branch discipline)
42
+ - Governance (single-writer files, heartbeat protocol)
43
+ - Reliability core (inputs always produce outputs, pride bar)
44
+ - Links to all deep-dive reference docs
8
45
 
9
46
  ---
10
47
 
11
- ## Quick Start
48
+ ## System Architecture
12
49
 
13
- - [HOW-THE-LOOP-WORKS.md](HOW-THE-LOOP-WORKS.md) — Concrete walkthrough of one `/buildsystem` wave (rank → fan out → verify → merge → close)
50
+ **[ARCHITECTURE.md](ARCHITECTURE.md)**Visual flow diagram + component overview
51
+
52
+ - Mermaid diagram: orchestrator → parallel fleet → merge train → checkpoint → audit → next backlog
53
+ - Component breakdown (watchdog, monitor, dashboard, durable state)
54
+ - Cost model and scaling characteristics
55
+ - Security model (pre-push hook + GitHub branch protection)
56
+
57
+ ---
14
58
 
15
- ## Core Governance & Rules (Reference)
59
+ ## Deep-Dive Reference Docs
16
60
 
17
- - [CARDINAL-RULES.md](CARDINAL-RULES.md) Foundational operational principles (dispatch model, cost, subagent discipline, retry caps)
18
- - [RELIABILITY.md](RELIABILITY.md) — Reliability core: never wait, inputs always produce outputs, pride bar for completion
19
- - [CHECKPOINTING.md](CHECKPOINTING.md) — Durable STATE.md/BUILDLOG.md lifecycle, recovery on resume, log rotation patterns
20
- - [SCRIPTS-POLICY.md](SCRIPTS-POLICY.md) — Local-only execution, shared script library, task-local vs. reusable heuristics
21
- - [DISPATCH-MODEL.md](DISPATCH-MODEL.md) — Fable/Haiku orchestration patterns and cost calculations
22
- - [GOVERNANCE.md](GOVERNANCE.md) — Single-instance loops, single-writer files, heartbeat protocol, security gates
61
+ Once you've completed the adopter journey, use these for operational reference:
23
62
 
24
- ## The Five Pillars
63
+ ### Wave Cycle & Orchestration
64
+ - **[HOW-THE-LOOP-WORKS.md](HOW-THE-LOOP-WORKS.md)** — Concrete walkthrough of one complete `/buildsystem` wave cycle (rank → fan-out → verify → merge → close)
65
+
66
+ ### Dispatch & Cost
67
+ - **[DISPATCH-MODEL.md](DISPATCH-MODEL.md)** — Haiku-first subagent dispatch, cost analysis, patterns (fan-out, sequential, hierarchical)
68
+
69
+ ### State Management & Recovery
70
+ - **[CHECKPOINTING.md](CHECKPOINTING.md)** — STATE.md and BUILDLOG.md lifecycle, recovery on resume, log rotation patterns
71
+
72
+ ### Foundational Principles
73
+ - **[CARDINAL-RULES.md](CARDINAL-RULES.md)** — 10 foundational principles (dispatch model, cost, subagent discipline, TDD, reliability, orchestrator isolation, orchestrator focus, durable handoff, control files, security & version control)
74
+
75
+ ### Operational Governance
76
+ - **[GOVERNANCE.md](GOVERNANCE.md)** — Single-instance loops, single-writer files, heartbeat protocol, inbox pattern, AUTO/PROPOSE action tiers
77
+
78
+ ### Reliability Guarantees
79
+ - **[RELIABILITY.md](RELIABILITY.md)** — Reliability core (inputs always produce outputs, no silent waits, pride bar for completion), failure scenarios, recovery patterns
80
+
81
+ ### Security & Hooks
82
+ - **[HOOK-INSTALL.md](HOOK-INSTALL.md)** — Install and customize `hooks/pre-push-policy.sh` (branch discipline, secret-scan enforcement at push time)
83
+
84
+ ### Team Onboarding
85
+ - **[MEMORY-TEMPLATE.md](MEMORY-TEMPLATE.md)** — Canonical format for team memory and facts (to be stored in `~/.claude/MEMORY.md`)
86
+
87
+ ### Behavioral Review Checklist
88
+ - **[BEHAVIORAL-PR-REVIEW.md](BEHAVIORAL-PR-REVIEW.md)** — Checklist for reviewing PRs that modify rules, policies, or orchestration behavior
89
+
90
+ ### Operational Guides
91
+ - **[FORENSICS.md](FORENSICS.md)** — Reconstruct agent failures using `tools/agent-forensics.sh`; make agent behavior git-debuggable
92
+ - **[RESTORE.md](RESTORE.md)** — Reconstitute Aesop & fleet on a new machine from git + watchdog backups
93
+ - **[PUBLISHING.md](PUBLISHING.md)** — Release Aesop to npm using GitHub Actions with OIDC trusted publishing
94
+ - **[av-resilience.md](av-resilience.md)** — Antivirus and behavioral-engine resilience patterns for reliable agent execution
95
+
96
+ ### Lessons & Case Studies
97
+ - **[autonomous-swe.md](autonomous-swe.md)** — The 0.1.0-rc.1 milestone told honestly: what "autonomous SWE" means here (a fleet running the wave loop under a human who owns the outward gates), the committed evidence behind each claim (held-out benchmark, verified audit, proven kill-switch, reproducible package), and the limits the project owns
98
+ - **[case-study-portfolio.md](case-study-portfolio.md)** — How Aesop built its own portfolio site; full audit trail and cost breakdown
99
+ - **[SCRIPTS-POLICY.md](SCRIPTS-POLICY.md)** — Local-only execution, shared script library (`~/scripts`), task-local vs. reusable heuristics
100
+
101
+ ---
25
102
 
26
- ### 1. Onboarding Templates
27
- - [MEMORY-TEMPLATE.md](MEMORY-TEMPLATE.md) — Canonical index format and structure for team memory & facts
103
+ ## Quick Index by Use Case
28
104
 
29
- ### 2. Policy Hooks
30
- - [HOOK-INSTALL.md](HOOK-INSTALL.md) Install and customize `hooks/pre-push-policy.sh` (branch/secret enforcement at push time)
105
+ **I'm setting up Aesop for the first time**
106
+ [INSTALL.md](INSTALL.md) [CONFIGURE.md](CONFIGURE.md) [FIRST-WAVE.md](FIRST-WAVE.md)
31
107
 
32
- ### 3. Behavioral PRs
33
- - [BEHAVIORAL-PR-REVIEW.md](BEHAVIORAL-PR-REVIEW.md) — Checklist for reviewing PRs that modify rules, policies, or orchestration behavior
108
+ **I want to understand the cost model**
109
+ → [DISPATCH-MODEL.md](DISPATCH-MODEL.md) or [HOW-THE-LOOP-WORKS.md](HOW-THE-LOOP-WORKS.md#why-its-fast--cheap)
34
110
 
35
- ### 4. Forensics (Git-Bisectable Agent Debugging)
36
- - [FORENSICS.md](FORENSICS.md) — Reconstruct agent failures using `tools/agent-forensics.sh`; make agent behavior git-debuggable
111
+ **I want to know what's actually proven vs. claimed (the rc.1 milestone)**
112
+ [autonomous-swe.md](autonomous-swe.md)
37
113
 
38
- ### 5. Restore (Cross-Machine Reconstitution)
39
- - [RESTORE.md](RESTORE.md) — Reconstitute Aesop & fleet on a new machine from git + watchdog backups after a wipe
114
+ **I need to understand how state survives a crash**
115
+ [CHECKPOINTING.md](CHECKPOINTING.md)
116
+
117
+ **I'm reviewing a PR that changes orchestration behavior**
118
+ → [BEHAVIORAL-PR-REVIEW.md](BEHAVIORAL-PR-REVIEW.md)
119
+
120
+ **An agent failed and I need to debug it**
121
+ → [FORENSICS.md](FORENSICS.md)
122
+
123
+ **I need to set up Aesop on a new machine after a wipe**
124
+ → [RESTORE.md](RESTORE.md)
125
+
126
+ **I want to release a new version of Aesop**
127
+ → [PUBLISHING.md](PUBLISHING.md)
128
+
129
+ **I'm experiencing reliability issues**
130
+ → [RELIABILITY.md](RELIABILITY.md) or [GOVERNANCE.md](GOVERNANCE.md)
131
+
132
+ ---
133
+
134
+ ## Architecture Diagram (Quick Reference)
135
+
136
+ ```
137
+ Ranked Backlog
138
+
139
+ Orchestrator (main thread)
140
+
141
+ Parallel Haiku Fleet (worktrees)
142
+ [test] [build] [docs] [ui] ...
143
+
144
+ Watchdog (heartbeat + respawn)
145
+
146
+ Integration Merge Train
147
+
148
+ Checkpoint (STATE.md + BUILDLOG.md)
149
+
150
+ Closing Audit (findings)
151
+
152
+ Monitor + Dashboard (signals)
153
+
154
+ Next Backlog (feedback loop)
155
+ ```
156
+
157
+ See [ARCHITECTURE.md](ARCHITECTURE.md) for the full diagram and component breakdown.
158
+
159
+ ---
160
+
161
+ ## Quick Answers
162
+
163
+ **Q: How do I start a wave?**
164
+ A: Type `/power` to prime your orchestrator brain, then `/buildsystem` to start a wave cycle. See [FIRST-WAVE.md](FIRST-WAVE.md).
165
+
166
+ **Q: How much does a wave cost?**
167
+ A: ~$0.03–$0.05 USD (1 Opus orchestrator + 5–8 Haiku agents). See [DISPATCH-MODEL.md](DISPATCH-MODEL.md).
168
+
169
+ **Q: What if an agent hangs?**
170
+ A: The watchdog detects it (>200s idle), respawns automatically (up to 3 retries), then surfaces to you if still stuck. See [CARDINAL-RULES.md](CARDINAL-RULES.md).
171
+
172
+ **Q: How do I add my repos?**
173
+ A: Edit `aesop.config.json` and add paths to `repos` array. See [CONFIGURE.md](CONFIGURE.md).
174
+
175
+ **Q: Do agents work in the primary tree?**
176
+ A: No. Each agent works in its own sibling worktree (via `git worktree add`). See [ARCHITECTURE.md](ARCHITECTURE.md).
177
+
178
+ **Q: How do I set up secret-scan?**
179
+ A: The pre-push hook is auto-installed. Customize `tools/secret_scan.py` with your rules. See [HOOK-INSTALL.md](HOOK-INSTALL.md).
180
+
181
+ ---
182
+
183
+ ## Contributing
184
+
185
+ Aesop is **source-available** under the PolyForm Strict License 1.0.0, which doesn't permit modification or redistribution — so outside code patches can't be merged as contributions. **Issues, bug reports, and discussion are warmly welcome**, and are the best way to help. The repo develops itself via its own `/buildsystem` loop; code changes are made by the maintainer at their discretion, or by prior arrangement.
186
+
187
+ See [CONTRIBUTING.md](../CONTRIBUTING.md) for details and [CARDINAL-RULES.md](CARDINAL-RULES.md) for core principles.
188
+
189
+ ---
40
190
 
41
- ## Operational Guides
191
+ ## License
42
192
 
43
- - [PUBLISHING.md](PUBLISHING.md) Release Aesop to npm using GitHub Actions with OIDC trusted publishing
44
- - [av-resilience.md](av-resilience.md) — Antivirus & behavioral-engine resilience patterns for reliable agent execution
193
+ **Source-available** under the [PolyForm Strict License 1.0.0](../LICENSE). Use is permitted for a permitted purpose; **modification and redistribution are not**. See [`LICENSE`](../LICENSE) for full terms.
@@ -0,0 +1,149 @@
1
+ # It shipped itself: the 0.1.0-rc.1 milestone, told honestly
2
+
3
+ Aesop reached its first release candidate — `0.1.0-rc.1` — by running its own
4
+ `/buildsystem` wave loop across the backlog that produced it: rank work, fan out
5
+ parallel Haiku workers on file-disjoint domains, watchdog them, verify merges,
6
+ close with an audit that seeds the next wave. This document is the honest account
7
+ of what that milestone is and is not. Aesop's entire premise is candor, so the
8
+ caveats here are load-bearing, not fine print.
9
+
10
+ ## What "autonomous SWE" means here
11
+
12
+ It means something specific and narrow:
13
+
14
+ > The **fleet** autonomously runs the wave loop — audit → parallel build → verify →
15
+ > merge-train — under a **human** who sets the goals and owns the outward gates.
16
+
17
+ Concretely:
18
+
19
+ - **The fleet drives the loop.** Ranking, dispatch, worktree isolation, verification,
20
+ and the merge train run without a human hand-writing the code in each domain.
21
+ - **A human owns the outward gates.** npm publishes, tagged releases, and git history
22
+ rewrites are all human-approved. The fleet proposes; a person disposes at the
23
+ repo boundary.
24
+ - **The dispatch core is out-of-repo.** The actual model calls happen inside the
25
+ Claude Code harness, which is *not* part of this repository. What Aesop ships is
26
+ the machinery *around* that core — orchestration rules, guardrails, durable state,
27
+ the dashboard, and tooling.
28
+
29
+ What it is **not**: it is not an unsupervised agent, not a hosted control plane, and
30
+ not AGI. Calling it "autonomous SWE" is accurate only with those boundaries stated.
31
+ Drop them and the phrase becomes hype.
32
+
33
+ ## The evidence, and the honest limit on each
34
+
35
+ The milestone's real differentiator is not that an AI wrote code — plenty of tools do
36
+ that. It is that the credibility and safety claims ship with **committed artifacts a
37
+ skeptical reader can check**, each paired with the limit the project already owns.
38
+
39
+ ### 1. Haiku is good enough for the judgment work a fleet does
40
+
41
+ The harness's whole cost model depends on cheap Haiku workers being adequate for
42
+ subagent judgment, not just extraction. That was long asserted from the fleet grading
43
+ its own output — agents vouching for agents, recorded in a private memory file. Not
44
+ evidence an outsider can check.
45
+
46
+ `bench/` plus `tools/bench_runner.py` replace that with a **held-out benchmark scored
47
+ by plain Python string/regex matching — no model, no agent in the grading loop**.
48
+ Across a combined **39 judgment tasks** (spanning bug-in-diff, finding-inflation,
49
+ acceptance-criteria coverage, severity calibration, root-cause-from-trace,
50
+ refactor-equivalence, and security-spotting):
51
+
52
+ | Model | Score | Cost (per-token) |
53
+ | ------ | ----- | ---------------- |
54
+ | Haiku | **39/39 (100%)** | ~1/3 of Opus |
55
+ | Sonnet | 39/39 (100%) | — |
56
+ | Opus | 38/39 (97%) | baseline |
57
+
58
+ On the single task any model missed — a severity call — it was *Opus* that erred, not
59
+ Haiku. Full dated runs: [`bench/results/`](../bench/results/).
60
+
61
+ **Honest limits (the project's own words):**
62
+
63
+ - **Curated, not sampled.** The tasks were constructed by reasoning about fleet work,
64
+ not drawn from real fleet transcripts. Selection bias remains.
65
+ - **N=39 is bigger, not statistically large.** Treat this as directional evidence for
66
+ this workload, not a universal law.
67
+ - **It measures a floor, not the frontier.** The benchmark found *no* task where Opus
68
+ beats Haiku. So the defensible claim is bounded: *Haiku is sufficient for the
69
+ judgment shapes measured here*, **not** *Haiku equals Opus at the reasoning
70
+ frontier*. If tasks exist where Opus's depth is worth 3×, this set hasn't captured
71
+ them.
72
+ - **Cost is the token-price ratio**, not measured wall-clock latency.
73
+
74
+ ### 2. Audits stop hallucinating findings
75
+
76
+ An earlier wave (wave-24) exposed a real failure mode: an all-Haiku audit reported
77
+ four P0 issues, **zero of which were real**. The release audit for this RC was run
78
+ with **adversarial verification of every finding** and closed with **0 hallucinated
79
+ issues**.
80
+
81
+ **Honest limit:** it is an internal audit. No third party has re-run it.
82
+
83
+ ### 3. The kill-switch actually aborts a wave
84
+
85
+ A halt control is only worth the claim if it's proven. The fleet-wide kill-switch
86
+ ([`tools/halt.py`](../tools/halt.py)) is wired into the **live dispatch path** and was
87
+ exercised end-to-end: a single signal **aborted a real wave with zero workers
88
+ spawned**.
89
+
90
+ **Honest limit:** it is operator-triggered — a manual brake a human pulls, not an
91
+ autonomous safety monitor that trips on its own.
92
+
93
+ ### 4. A cost ceiling brakes runaway spend
94
+
95
+ A per-wave spend ceiling ([`tools/cost_ceiling.py`](../tools/cost_ceiling.py)) halts
96
+ dispatch when the configured budget is exceeded.
97
+
98
+ **Honest limit:** it brakes against a **configured** ceiling; it is **not yet tied to
99
+ live token spend**. It's a guardrail you set, not a live meter.
100
+
101
+ ### 5. The package installs and reproduces from a clean clone
102
+
103
+ The npm tarball is a **~409 kB** package (measured via `npm pack`) that **builds and
104
+ validates from a fresh clone in CI** — the `reproduce` workflow proves the tarball is
105
+ self-contained. The dashboard views shipped this RC (Wave PR Board, Agent Inspector)
106
+ were **browser-proven** with Playwright. Steps to reproduce offline:
107
+ [docs/reproduce.md](./reproduce.md).
108
+
109
+ **Honest limit:** the offline reproduce job runs the test suites and the benchmark
110
+ *scorer*; it does **not** run real-model benchmark calls or the Playwright browser
111
+ proofs, which need local setup and (for the models) API keys.
112
+
113
+ ## The limits the project owns, in one place
114
+
115
+ None of these are hidden, because hiding them would betray the one thing the project is
116
+ actually selling — candor:
117
+
118
+ 1. **The benchmark is curated (N=39), not transcript-sampled.** Directional, not
119
+ definitive; it maps a floor, not the frontier.
120
+ 2. **The real dispatch core is out-of-repo.** It runs in the Claude Code harness. This
121
+ package is the harness around it, not a turnkey autonomous runtime.
122
+ 3. **No third party has reproduced any of it yet.** The artifacts are committed so a
123
+ skeptic can — that is transparency, not a substitute for independent replication.
124
+ 4. **The cost ceiling is a brake, not a live meter.** It enforces a configured budget,
125
+ not measured spend.
126
+ 5. **It is local-first.** State lives in git and local files; there is no hosted
127
+ control plane. Team scale beyond one machine is on the roadmap, not shipped.
128
+ 6. **It is a release candidate.** APIs, config, and dashboard contracts may still shift
129
+ before 0.1.0. Pin the exact version if you need stability.
130
+
131
+ ## Where to check the receipts
132
+
133
+ - [`bench/results/`](../bench/results/) — dated benchmark runs (v1 extraction, v2 & v3
134
+ judgment), each with its own honest interpretation and limits.
135
+ - [`bench/README.md`](../bench/README.md) — why the benchmark exists and how the scoring
136
+ removes agents from the grading loop.
137
+ - [`tools/halt.py`](../tools/halt.py), [`tools/cost_ceiling.py`](../tools/cost_ceiling.py)
138
+ — the kill-switch and cost-ceiling implementations.
139
+ - [docs/reproduce.md](./reproduce.md) — reproduce the tests and benchmark scorer from a
140
+ clean clone.
141
+ - [RELEASE-NOTES.md](../RELEASE-NOTES.md#honest-limits) — release-level "Honest limits".
142
+ - [CHANGELOG.md](../CHANGELOG.md) — the full `0.1.0-rc.1` entry.
143
+
144
+ ---
145
+
146
+ The one-line version: **the fleet built, tested, audited, and benchmarked its way to a
147
+ shippable release candidate, and every claim about that comes with a committed artifact
148
+ and a stated limit.** That combination — self-built *and* honest about the seams — is
149
+ the milestone.
@@ -0,0 +1,121 @@
1
+ # Reproducing Aesop
2
+
3
+ This document explains how to reproduce the project's claims from a clean checkout.
4
+
5
+ ## Overview
6
+
7
+ The Aesop project includes:
8
+ 1. **Full test suites** (Node.js + Python) that verify core functionality
9
+ 2. **An offline benchmark scorer** that proves the benchmark scoring logic works correctly
10
+
11
+ Both can be reproduced entirely offline, without API keys or external dependencies, from any clean clone of the repository.
12
+
13
+ ## Reproducing from a Clean Clone
14
+
15
+ ### Prerequisites
16
+
17
+ - **Node.js**: 18 or later
18
+ - **Python**: 3.12 or later
19
+ - **Git**: any recent version
20
+
21
+ ### Steps
22
+
23
+ 1. Clone the repository (no special flags needed):
24
+ ```bash
25
+ git clone https://github.com/matt82198/aesop.git
26
+ cd aesop
27
+ ```
28
+
29
+ 2. Verify Node.js and Python are installed:
30
+ ```bash
31
+ node --version
32
+ python --version
33
+ ```
34
+
35
+ 3. Install Node.js dependencies:
36
+ ```bash
37
+ npm ci
38
+ ```
39
+
40
+ 4. Run the full test suite (Python + Node.js):
41
+ ```bash
42
+ # Run Node.js tests
43
+ npm run test:node
44
+
45
+ # Run Python tests
46
+ python -m unittest discover -s tests
47
+ ```
48
+
49
+ 5. Run the benchmark scorer offline:
50
+ ```bash
51
+ # Run the benchmark unit tests (syntax, ground truth format, etc.)
52
+ python -m unittest tests.test_bench_runner -v
53
+
54
+ # Run the offline mock benchmark
55
+ python tools/bench_runner.py --runner mock
56
+ ```
57
+
58
+ ## What the `.github/workflows/reproduce.yml` Job Does
59
+
60
+ The `reproduce` workflow in GitHub Actions automates the above steps:
61
+
62
+ 1. **Fresh checkout**: Uses a clean clone (no state reuse from other CI jobs)
63
+ 2. **Syntax checks**: Validates all Node.js (.mjs) and shell scripts (.sh)
64
+ 3. **Node.js tests**: Runs the full test suite with `npm run test:node`
65
+ 4. **Python tests**: Runs the full test suite with `python -m unittest discover`
66
+ 5. **Benchmark scorer**: Proves the offline mock benchmark reproduces (no external API calls)
67
+
68
+ The workflow is triggered:
69
+ - **Manually**: Via GitHub Actions "Run workflow" button (workflow_dispatch)
70
+ - **Weekly**: Every Sunday at 2:00 AM UTC (schedule)
71
+
72
+ ## What Is and Isn't Reproduced
73
+
74
+ ### Reproduced (offline, no API keys needed)
75
+
76
+ - ✓ All committed test suites (correctness, integration, governance)
77
+ - ✓ The benchmark **scorer logic** (matching, scoring, reporting)
78
+ - ✓ The benchmark **mock runner** (deterministic offline accuracy score)
79
+ - ✓ The committed benchmark files (`bench/tasks.jsonl`, `bench/ground_truth.jsonl`)
80
+
81
+ ### Not Reproduced (requires external APIs)
82
+
83
+ - ✗ A real multi-model benchmark (calling Claude API, OpenAI, etc.)
84
+ - ✗ The dashboard browser tests (Playwright, requires UI setup)
85
+ - ✗ Performance/timing benchmarks
86
+ - ✗ The full CI job's additional linting and drift checks
87
+
88
+ The benchmark mock runner always returns the same accuracy score because it uses a hardcoded heuristic (plain string/regex matching), not a real model. This is intentional — the tests prove the *scorer* works correctly, not that any model achieves a specific accuracy.
89
+
90
+ ## Interpreting Results
91
+
92
+ ### Success
93
+
94
+ ```
95
+ YAML is valid
96
+ All Node.js tests pass
97
+ All Python tests pass
98
+ Benchmark reproduction successful
99
+ ```
100
+
101
+ ### Failure
102
+
103
+ If any step fails, the workflow exits with a non-zero exit code and prints the failure details. Common issues:
104
+
105
+ 1. **Node.js test failure**: Check `tests/*.test.mjs` for the specific failing test.
106
+ 2. **Python test failure**: Check the error message; most often a missing test fixture or a test isolation bug.
107
+ 3. **Benchmark reproduction failure**: Run `python tools/bench_runner.py --runner mock` manually to see the exact error.
108
+
109
+ ## For Project Maintainers
110
+
111
+ When you add new features or tests:
112
+
113
+ 1. Ensure all tests pass locally: `npm run test:all` (or individually per suite)
114
+ 2. The `reproduce` workflow will catch any regressions automatically
115
+ 3. If reproduction fails, it indicates the committed test fixtures or scorer are inconsistent
116
+
117
+ ## References
118
+
119
+ - Test discovery: `python -m unittest discover --help`
120
+ - Benchmark scorer: `python tools/bench_runner.py --help`
121
+ - GitHub Actions workflow syntax: https://docs.github.com/en/actions
package/hooks/CLAUDE.md CHANGED
@@ -30,6 +30,34 @@ Runs on `git push` via `.git/hooks/pre-push` symlink or copy.
30
30
  - See `docs/HOOK-INSTALL.md` for symlink (Linux/macOS/Git Bash) and copy (Windows) methods
31
31
  - Test with `bash hooks/pre-push-policy.sh --test` before org distribution
32
32
 
33
+ ## Hook: pre-commit-waveguard.sh
34
+
35
+ Prevents accidental commits to the PRIMARY aesop tree during a wave cycle. Runs on `git commit` via `.git/hooks/pre-commit`.
36
+
37
+ **Purpose**: During orchestrated waves, the orchestrator sets a marker file (`state/.wave-in-flight`) in the PRIMARY tree only. Sibling worktrees do not inherit this marker (separate working trees), so fleet agents commit freely in worktrees while stray commits to the primary tree are rejected.
38
+
39
+ **Mechanism**:
40
+ 1. **Marker Contract**: Orchestrator writes `state/.wave-in-flight` in the PRIMARY tree before dispatching wave work. The marker is git-ignored, so sibling worktrees checked out during the wave do NOT carry it.
41
+ 2. **Pre-Commit Check**: Hook resolves the marker relative to the CURRENT working tree via `git rev-parse --show-toplevel` (NOT a hardcoded `$HOME/aesop` — that resolved to the primary tree from every worktree and blocked the whole fleet mid-wave, the wave-24 incident). Primary tree (has marker during a wave) → exit 1 (reject); sibling worktree (no marker) → exit 0 (allow).
42
+ 3. **Override**: User or orchestrator may delete `state/.wave-in-flight` to manually allow commits to primary tree.
43
+
44
+ **Exit Contract**:
45
+ - Exit 0: Marker absent, commit allowed (normal operation)
46
+ - Exit 1: Marker present, commit blocked with clear error message
47
+
48
+ **Error Message**:
49
+ ```
50
+ Error: Wave in flight. Commit from a sibling worktree, or clear <marker_path> to override.
51
+ ```
52
+
53
+ **Installation**:
54
+ - Run `bash hooks/install-waveguard.sh` to idempotently install into `.git/hooks/pre-commit`.
55
+ - If a pre-commit hook already exists, installer backs it up (`.git/hooks/pre-commit.waveguard-backup`) and wraps both (waveguard first, then existing hook if present).
56
+
57
+ **Idempotency**:
58
+ - Installer checks if hook already calls waveguard; skips if already installed.
59
+ - Safe to re-run multiple times.
60
+
33
61
  ## Hook: hooks/claude/force-model-policy.mjs
34
62
 
35
63
  Claude Code hook enforcing subagent Haiku dispatch (cost optimization).
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env bash
2
+ set -uo pipefail
3
+
4
+ main() {
5
+ local repo_root
6
+ repo_root=$(git rev-parse --show-toplevel 2>/dev/null)
7
+ if [ -z "$repo_root" ]; then
8
+ printf 'Error: Not in a git repository\n' >&2
9
+ return 1
10
+ fi
11
+
12
+ local hooks_dir="$repo_root/.git/hooks"
13
+ local waveguard_src="$repo_root/hooks/pre-commit-waveguard.sh"
14
+ local pre_commit_dest="$hooks_dir/pre-commit"
15
+ local pre_commit_orig="$hooks_dir/pre-commit.waveguard-backup"
16
+
17
+ if [ ! -f "$waveguard_src" ]; then
18
+ printf 'Error: Source hook not found at %s\n' "$waveguard_src" >&2
19
+ return 1
20
+ fi
21
+
22
+ mkdir -p "$hooks_dir"
23
+
24
+ if [ -f "$pre_commit_dest" ]; then
25
+ if grep -q 'pre-commit-waveguard' "$pre_commit_dest" 2>/dev/null; then
26
+ printf 'Info: pre-commit hook already has waveguard; skipping.\n'
27
+ return 0
28
+ fi
29
+
30
+ cp "$pre_commit_dest" "$pre_commit_orig"
31
+ printf 'Info: Existing pre-commit hook backed up to %s\n' "$pre_commit_orig"
32
+ fi
33
+
34
+ cat > "$pre_commit_dest" <<'HOOK_WRAPPER'
35
+ #!/usr/bin/env bash
36
+ set -uo pipefail
37
+
38
+ repo_root=$(git rev-parse --show-toplevel 2>/dev/null || echo "")
39
+ if [ -z "$repo_root" ]; then
40
+ exit 1
41
+ fi
42
+
43
+ waveguard_hook="$repo_root/hooks/pre-commit-waveguard.sh"
44
+ if [ -f "$waveguard_hook" ]; then
45
+ bash "$waveguard_hook"
46
+ waveguard_exit=$?
47
+ if [ $waveguard_exit -ne 0 ]; then
48
+ exit $waveguard_exit
49
+ fi
50
+ fi
51
+
52
+ backup_hook="$repo_root/.git/hooks/pre-commit.waveguard-backup"
53
+ if [ -f "$backup_hook" ] && [ -x "$backup_hook" ]; then
54
+ bash "$backup_hook"
55
+ exit $?
56
+ fi
57
+
58
+ exit 0
59
+ HOOK_WRAPPER
60
+
61
+ chmod +x "$pre_commit_dest"
62
+ printf 'Info: Installed waveguard pre-commit hook to %s\n' "$pre_commit_dest"
63
+ return 0
64
+ }
65
+
66
+ if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
67
+ main "$@"
68
+ fi
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env bash
2
+ set -uo pipefail
3
+
4
+ main() {
5
+ # Resolve the marker relative to the CURRENT working tree, NOT a hardcoded primary path.
6
+ # This is load-bearing: the marker (state/.wave-in-flight) is git-ignored, so a sibling
7
+ # worktree checked out during a wave does NOT carry it — only the PRIMARY tree (where the
8
+ # orchestrator sets it) does. Checking the current tree's own toplevel means primary-tree
9
+ # commits are blocked during a wave while legitimate worktree-agent commits pass. A prior
10
+ # version hardcoded ${AESOP_ROOT:-$HOME/aesop}, which resolved to the primary tree from every
11
+ # worktree and thus blocked the entire fleet mid-wave (wave-24 incident). Do not reintroduce.
12
+ local toplevel
13
+ toplevel=$(git rev-parse --show-toplevel 2>/dev/null) || exit 0
14
+ local marker_file="$toplevel/state/.wave-in-flight"
15
+
16
+ if [ -f "$marker_file" ]; then
17
+ printf 'Error: Wave in flight in this tree (%s). Commit from a sibling worktree, or clear the marker to override.\n' "$marker_file" >&2
18
+ exit 1
19
+ fi
20
+
21
+ exit 0
22
+ }
23
+
24
+ if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
25
+ main "$@"
26
+ fi