@matt82198/aesop 0.1.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +117 -2
- package/README.md +59 -218
- package/bin/cli.js +168 -41
- package/daemons/run-watchdog.sh +16 -4
- package/daemons/selfheal.sh +231 -0
- package/docs/ANY-REPO.md +427 -0
- package/docs/CONTRIBUTING.md +72 -0
- package/docs/DEMO.md +334 -0
- package/docs/HOOK-INSTALL.md +15 -56
- package/docs/INSTALL.md +74 -4
- package/docs/PORTING.md +166 -0
- package/docs/README.md +33 -3
- package/docs/TEAM-STATE.md +372 -0
- package/docs/reproduce.md +33 -3
- package/driver/CLAUDE.md +150 -0
- package/driver/README.md +383 -0
- package/driver/aesop.config.example.json +80 -0
- package/driver/agent_driver.py +355 -0
- package/driver/backend_config.py +253 -0
- package/driver/claude_code_driver.py +198 -0
- package/driver/codex_driver.py +673 -0
- package/driver/openai_compatible_driver.py +249 -0
- package/driver/openai_transport.py +179 -0
- package/driver/verification_policy.py +75 -0
- package/driver/wave_bridge.py +254 -0
- package/driver/wave_loop.py +1408 -0
- package/driver/wave_scheduler.py +890 -0
- package/hooks/pre-push-policy.sh +131 -33
- package/mcp/server.mjs +320 -4
- package/monitor/collect-signals.mjs +69 -0
- package/package.json +22 -14
- package/skills/CLAUDE.md +132 -2
- package/skills/buildsystem/SKILL.md +330 -0
- package/skills/buildsystem/wave-flat-dispatch.template.mjs +658 -0
- package/skills/fleet/SKILL.md +113 -0
- package/skills/power/SKILL.md +246 -131
- package/state_store/__init__.py +4 -2
- package/state_store/api.py +19 -4
- package/state_store/coordination.py +209 -0
- package/state_store/identity.py +51 -0
- package/state_store/projections.py +63 -0
- package/state_store/read_api.py +156 -0
- package/state_store/store.py +185 -73
- package/state_store/write_api.py +462 -0
- package/templates/wave-presets/data.json +65 -0
- package/templates/wave-presets/library.json +65 -0
- package/templates/wave-presets/saas.json +64 -0
- package/tools/audit_report.py +388 -0
- package/tools/bench_runner.py +100 -3
- package/tools/ci_merge_wait.py +256 -35
- package/tools/ci_workflow_lint.py +430 -0
- package/tools/claudemd_drift.py +394 -0
- package/tools/claudemd_lint.py +359 -0
- package/tools/common.py +39 -3
- package/tools/cost_ceiling.py +166 -43
- package/tools/cost_econ.py +480 -0
- package/tools/cost_projection.py +559 -0
- package/tools/crossos_drift.py +394 -0
- package/tools/defect_escape.py +252 -0
- package/tools/doctor.js +1 -1
- package/tools/eod_sweep.py +188 -26
- package/tools/fleet.js +260 -0
- package/tools/fleet_ledger.py +209 -7
- package/tools/git_identity_check.py +315 -0
- package/tools/health-score.js +40 -0
- package/tools/health_score.py +361 -0
- package/tools/metrics_gate.py +13 -4
- package/tools/mutation_test.py +523 -0
- package/tools/portability_check.py +206 -0
- package/tools/proposals.mjs +47 -2
- package/tools/reconcile.py +7 -4
- package/tools/reproduce.js +405 -0
- package/tools/secret_scan.py +207 -65
- package/tools/self_stats.py +20 -0
- package/tools/stall_check.py +247 -16
- package/tools/stateapi_lint.py +325 -0
- package/tools/test_battery.py +173 -0
- package/tools/transcript_digest.py +380 -0
- package/tools/verify_activity_filter.py +437 -0
- package/tools/verify_agent_inspector.py +2 -0
- package/tools/verify_cost_panel.py +345 -0
- package/tools/verify_dash.py +2 -0
- package/tools/verify_dispatch_panel.py +301 -0
- package/tools/verify_failure_drilldown.py +188 -0
- package/tools/verify_prboard.py +2 -0
- package/tools/verify_scorecards.py +281 -0
- package/tools/verify_submit_encoding.py +2 -0
- package/tools/verify_ui_trio.py +409 -0
- package/tools/verify_wave_telemetry.py +268 -0
- package/tools/wave_backlog_analyzer.py +490 -0
- package/tools/wave_ledger_hook.py +150 -0
- package/tools/wave_preflight.py +779 -0
- package/tools/wave_resume.py +215 -0
- package/tools/wave_templates.py +340 -0
- package/ui/agents.py +68 -14
- package/ui/collectors.py +81 -55
- package/ui/config.py +7 -2
- package/ui/cost.py +231 -12
- package/ui/handler.py +383 -55
- package/ui/quality_scorecard.py +232 -0
- package/ui/sse.py +3 -3
- package/ui/wave_audit_tail.py +213 -0
- package/ui/wave_dispatch.py +280 -0
- package/ui/wave_failure.py +288 -0
- package/ui/wave_gantt.py +152 -0
- package/ui/wave_reasoning_tail.py +176 -0
- package/ui/wave_telemetry.py +383 -0
- package/ui/web/dist/assets/index-CNQxaiOW.css +1 -0
- package/ui/web/dist/assets/index-CP68RIh3.js +9 -0
- package/ui/web/dist/index.html +2 -2
- package/bin/CLAUDE.md +0 -76
- package/daemons/CLAUDE.md +0 -36
- package/dash/CLAUDE.md +0 -32
- package/docs/archive/README.md +0 -3
- package/docs/archive/spikes/tiered-cognition/ACTIVATION.md +0 -125
- package/docs/archive/spikes/tiered-cognition/DESIGN.md +0 -287
- package/docs/archive/spikes/tiered-cognition/FINDINGS.md +0 -113
- package/docs/archive/spikes/tiered-cognition/README.md +0 -27
- package/docs/archive/spikes/tiered-cognition/aesop-cognition.example.md +0 -32
- package/docs/archive/spikes/tiered-cognition/force-model-policy.merged.mjs +0 -673
- package/docs/archive/spikes/tiered-cognition/strip-tools-hook.mjs +0 -434
- package/hooks/CLAUDE.md +0 -89
- package/mcp/CLAUDE.md +0 -213
- package/monitor/CLAUDE.md +0 -40
- package/scan/CLAUDE.md +0 -30
- package/state_store/CLAUDE.md +0 -39
- package/tools/CLAUDE.md +0 -79
- package/ui/CLAUDE.md +0 -127
- package/ui/web/dist/assets/index-0qQYnvMC.js +0 -9
- package/ui/web/dist/assets/index-BdIlFieV.css +0 -1
package/ui/web/dist/index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Aesop Fleet Dashboard</title>
|
|
7
7
|
<script>window.__AESOP_CSRF_TOKEN__ = __AESOP_CSRF_SENTINEL__;</script>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-CP68RIh3.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CNQxaiOW.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="root"></div>
|
package/bin/CLAUDE.md
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
# bin/ — CLI scaffolder
|
|
2
|
-
|
|
3
|
-
**Purpose**: Node.js CLI entry point that clones the aesop orchestration template into a target directory with idempotent validation, plus an interactive onboarding wizard for new adopters.
|
|
4
|
-
|
|
5
|
-
## Invocation
|
|
6
|
-
|
|
7
|
-
- **npm registry**: `npx @matt82198/aesop [target-dir]` (default: `aesop-fleet`)
|
|
8
|
-
- **Local dev**: `node bin/cli.js [target-dir]`
|
|
9
|
-
- **Help**: `npx @matt82198/aesop --help` or `-h`
|
|
10
|
-
- **Interactive wizard**: `npx @matt82198/aesop wizard` (on a TTY, prompts; with `--yes`, uses defaults)
|
|
11
|
-
|
|
12
|
-
## Runtime subcommands
|
|
13
|
-
|
|
14
|
-
cli.js dispatches runtime management subcommands to `tools/{subcommand}.js`:
|
|
15
|
-
|
|
16
|
-
- **`aesop doctor`** (or `node bin/cli.js doctor`) — Preflight readiness check; validates Node.js, Python, git, config, directories, hooks, and dashboard port availability.
|
|
17
|
-
- **`aesop watch`** (or `node bin/cli.js watch`) — Launch the watchdog daemon; spawns `daemons/run-watchdog.sh` for continuous fleet monitoring.
|
|
18
|
-
- **`aesop dash`** (or `node bin/cli.js dash`) — Launch the web dashboard; spawns `python ui/serve.py` to serve realtime fleet status at localhost:8770 (default).
|
|
19
|
-
- **`aesop status`** (or `node bin/cli.js status`) — One-shot fleet status snapshot; displays heartbeats, dashboard port, and git branch status.
|
|
20
|
-
|
|
21
|
-
## What gets copied
|
|
22
|
-
|
|
23
|
-
Files in `filesToCopy` array (cli.js lines 239–256):
|
|
24
|
-
- **Directories**: `daemons/`, `dash/`, `monitor/`, `tools/`, `ui/`, `docs/`, `state_store/`, `skills/`, `mcp/`, `scan/`, `hooks/`
|
|
25
|
-
- **Files**: `aesop.config.example.json`, `README.md`, `LICENSE`, `CHANGELOG.md`, `CLAUDE-TEMPLATE.md`
|
|
26
|
-
- **Brain templates** (in docs/): `MEMORY-TEMPLATE.md` (via docs/ directory copy)
|
|
27
|
-
|
|
28
|
-
## What does NOT get copied
|
|
29
|
-
|
|
30
|
-
- `aesop.config.json` (users must `cp aesop.config.example.json` and edit)
|
|
31
|
-
- `state/` (runtime durable state, git-ignored, created by daemons)
|
|
32
|
-
- `.git/`, `node_modules/`, build artifacts
|
|
33
|
-
|
|
34
|
-
## Post-scaffold guidance
|
|
35
|
-
|
|
36
|
-
Scaffolder prints steps for users:
|
|
37
|
-
1. `cd target-dir && cp aesop.config.example.json aesop.config.json`
|
|
38
|
-
2. Edit config with paths and repos
|
|
39
|
-
3. Initialize brain: `cp CLAUDE-TEMPLATE.md ~/.claude/CLAUDE.md` (edit)
|
|
40
|
-
4. Initialize memory: `cp docs/MEMORY-TEMPLATE.md ~/.claude/MEMORY.md` (edit)
|
|
41
|
-
5. Test daemon: `bash daemons/run-watchdog.sh --once`
|
|
42
|
-
6. Launch dashboard: `python ui/serve.py`
|
|
43
|
-
|
|
44
|
-
## Interactive wizard (`aesop wizard`)
|
|
45
|
-
|
|
46
|
-
The wizard mode provides an interactive onboarding flow for new adopters, guiding them through fleet setup in ~60 seconds:
|
|
47
|
-
|
|
48
|
-
1. **Trigger**: `npx @matt82198/aesop wizard` on a TTY (interactive terminal)
|
|
49
|
-
2. **Questions** (all have sensible defaults, press Enter-Enter-Enter to skip):
|
|
50
|
-
- Project name (default: "my-fleet")
|
|
51
|
-
- Repos to watch (auto-discovers git repos under `~`, offers choices)
|
|
52
|
-
- Dashboard port (default: 8770, validates 1–65535)
|
|
53
|
-
- Brain root directory (default: `~/.claude`)
|
|
54
|
-
3. **Output**:
|
|
55
|
-
- Scaffolds template files
|
|
56
|
-
- Generates CLAUDE.md (substituted with project name)
|
|
57
|
-
- Generates aesop.config.json (with discovered repos)
|
|
58
|
-
- Prints "next 3 commands" epilogue
|
|
59
|
-
- Offers to run `watchdog --once` smoke test immediately
|
|
60
|
-
4. **Non-interactive mode** (`--yes` flag or non-TTY stdin): Uses defaults, zero prompts (CI-safe)
|
|
61
|
-
|
|
62
|
-
### Wizard implementation details
|
|
63
|
-
|
|
64
|
-
- **Repo discovery** (`discoverRepos`): Scans `~` for `.git` directories at first level (non-recursive)
|
|
65
|
-
- **Port validation** (`validatePort`): Rejects invalid ports, accepts 1–65535
|
|
66
|
-
- **Portable paths**: All config paths use `~` form (`~/.claude`, `~/scripts`, etc.) for cross-platform compatibility
|
|
67
|
-
- **Defaults**: Every prompt has a default so users can skip it (press Enter)
|
|
68
|
-
- **Non-destructive**: Never overwrites existing `aesop.config.json` without user confirmation
|
|
69
|
-
|
|
70
|
-
## Invariants & gotchas
|
|
71
|
-
|
|
72
|
-
- **Idempotent on empty targets**: Fails if `targetDir` exists and is non-empty (non-destructive). Safe to retry.
|
|
73
|
-
- **Adding shipped files**: Any new file/dir added to `filesToCopy` array must also be added to `package.json` `files` array (lines 9–27 in package.json) so npm publish includes it.
|
|
74
|
-
- **No machine-specific paths**: Use relative paths only; `__dirname` and `path.join()` handle cross-platform resolution.
|
|
75
|
-
- **Wizard prompts are async**: Main execution is wrapped in async IIFE to support readline prompts
|
|
76
|
-
- **Help text accuracy**: If invocation steps or output paths change, update help text
|
package/daemons/CLAUDE.md
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# daemons/ — Watchdog daemon
|
|
2
|
-
|
|
3
|
-
**Purpose**: Long-running backup and secret-scan daemon for fleet-wide repo safety.
|
|
4
|
-
|
|
5
|
-
## Files
|
|
6
|
-
|
|
7
|
-
- **run-watchdog.sh** (1.7K): Interactive daemon supervisor; spawns backup-fleet.sh every 150s, maintains heartbeat guard (200s dedupe window), logs to FLEET-BACKUP.log. Calls tools/alert_bridge.py --scan after each cycle to post HIGH/CRITICAL alerts to Slack/Discord (opt-in). Traps INT/TERM cleanly.
|
|
8
|
-
- **backup-fleet.sh** (5K): Core backup worker; discovers repos (~/.*, ~/*, ~/dev/*), stashes uncommitted work to backup/* branches, pushes unpushed commits, scans tracked files for secrets. Blocks push if secret-scan fails (marks BLOCKED state).
|
|
9
|
-
|
|
10
|
-
## Contracts
|
|
11
|
-
|
|
12
|
-
**Env vars consumed**: `AESOP_ROOT` (defaults to `.`) — root of project; prepends to all state/ and tools/ paths.
|
|
13
|
-
|
|
14
|
-
**State files written** (git-ignored):
|
|
15
|
-
- `$AESOP_ROOT/state/.watchdog-heartbeat` — epoch seconds; dedupe guard (200s window).
|
|
16
|
-
- `$AESOP_ROOT/state/.watchdog-repos.json` — per-cycle snapshot: [{repo, state: CLEAN|PUSHED|SNAPSHOTTED|BLOCKED, age}].
|
|
17
|
-
- `$AESOP_ROOT/state/FLEET-BACKUP.log` — append-only; cycle start/end, repo statuses, secret-scan blocks.
|
|
18
|
-
- `$AESOP_ROOT/state/SECURITY-ALERTS.log` — append-only; security alerts (read by alert_bridge.py to post to webhooks).
|
|
19
|
-
- `$AESOP_ROOT/state/.alert-bridge-cursor` — line number of last sent alert (ensures idempotent alert dispatch).
|
|
20
|
-
|
|
21
|
-
**Exit behaviors**: run-watchdog exits 0 always (trap handles clean shutdown). backup-fleet exits 0 even on secret-scan block (marks repo BLOCKED, continues).
|
|
22
|
-
|
|
23
|
-
**Cadence**: 150s cycle; heartbeat dedupe within 200s.
|
|
24
|
-
|
|
25
|
-
## Invariants & Gotchas
|
|
26
|
-
|
|
27
|
-
1. **Single-instance guard (atomic lock)**: run-watchdog.sh uses atomic mkdir-based lockfile (`.watchdog-lock/`) to prevent concurrent daemons.
|
|
28
|
-
- Atomic acquire: `mkdir $LOCK_DIR` is guaranteed atomic on POSIX systems (returns 0 only to first caller).
|
|
29
|
-
- Stale-lock recovery: Crashed holder won't wedge daemon forever; lock older than 300s is reclaimed atomically.
|
|
30
|
-
- Guards both daemon mode and `--once` mode (no bypass).
|
|
31
|
-
2. **Testing override**: Set `AESOP_WATCHDOG_CYCLE_CMD` env var to replace backup-fleet.sh invocation (allows tests to use mock cycle without running real backup).
|
|
32
|
-
3. **CRLF-safe, no line continuations**: Use POSIX-safe heredocs; never add `\` for line wrap.
|
|
33
|
-
4. **Secret-scan gate**: `scan_tracked_files()` calls `$AESOP_ROOT/tools/secret_scan.py` on tracked modifications and untracked files; non-0 exit blocks push, marks repo BLOCKED.
|
|
34
|
-
5. **Append-only logs**: FLEET-BACKUP.log only grows; rotate via tools/rotate_logs.py.
|
|
35
|
-
6. **Path dedup via realpath**: Avoids processing symlinked repos or dot-dir aliases twice.
|
|
36
|
-
7. **Alert Bridge integration** (NEW wave-14): After each backup-fleet.sh cycle, run-watchdog.sh calls `python $AESOP_ROOT/tools/alert_bridge.py --scan || true` to post HIGH/CRITICAL security alerts and heartbeat staleness to Slack/Discord. No-op if webhook_url null/absent in aesop.config.json (feature opt-in). Uses cursor file for idempotent dispatch (no re-sends). See tools/alert_bridge.py for details.
|
package/dash/CLAUDE.md
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# dash/ — Dashboard TUI
|
|
2
|
-
|
|
3
|
-
**Purpose**: Real-time TUI fleet monitoring — watchdog daemon + agent activity display.
|
|
4
|
-
|
|
5
|
-
## Files
|
|
6
|
-
|
|
7
|
-
- **watchdog-gui.sh** — Read-only terminal UI (4s refresh, double-buffered, no flicker). Displays daemon status, backed-up repos, heartbeats, recent events. Launch in own window; never inside tool shell. CRLF-safe (no line continuations).
|
|
8
|
-
- **dash-extra.mjs** — Node.js agent activity detector. Scans AESOP_TRANSCRIPTS_ROOT for agent-*.jsonl files (last 12 min). TUI output by default; --json for web endpoints. Requires node on PATH (unavailable fallback if missing).
|
|
9
|
-
|
|
10
|
-
## State contracts
|
|
11
|
-
|
|
12
|
-
**watchdog-gui.sh reads** (heartbeat staleness thresholds applied):
|
|
13
|
-
- `state/.watchdog-heartbeat` (epoch, threshold: 300s for watchdog)
|
|
14
|
-
- `state/FLEET-BACKUP.log` (append-only, tail 3 lines)
|
|
15
|
-
- `state/SECURITY-ALERTS.log` (counts HIGH/MED, grep filtering RESOLVED-FP)
|
|
16
|
-
- `state/.watchdog-repos.json` (jq-parsed, status per repo)
|
|
17
|
-
- `state/.heartbeats/*` (epoch, per-agent thresholds: 3600s monitor, 300s watchdog, 1800s default)
|
|
18
|
-
|
|
19
|
-
**dash-extra.mjs reads**:
|
|
20
|
-
- `~/.claude/projects/**/ agent-*.jsonl` (modified time, <12min filter, top 8 recent)
|
|
21
|
-
- `state/SECURITY-ALERTS.log` (severity classification: HIGH/MED/DRIFT)
|
|
22
|
-
|
|
23
|
-
**Refresh cadence**:
|
|
24
|
-
- watchdog-gui.sh: 4s loop (infinite, Ctrl-C to exit)
|
|
25
|
-
- dash-extra.mjs: called on-demand (no built-in loop)
|
|
26
|
-
|
|
27
|
-
## Invariants & TUI conventions
|
|
28
|
-
|
|
29
|
-
- **Never modify fleet state** — both tools are read-only dashboards.
|
|
30
|
-
- **Infinite loop design** — watchdog-gui.sh runs forever; launch in dedicated terminal window, never inside tool shells.
|
|
31
|
-
- **CRLF-safe** — no bash line continuations; portable POSIX.
|
|
32
|
-
- **Node optional** — dash-extra.mjs gracefully prints "unavailable" if node missing; doesn't fail watchdog-gui.sh.
|
package/docs/archive/README.md
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
# ACTIVATION runbook — force-model-policy.merged.mjs
|
|
2
|
-
|
|
3
|
-
Swap the staged merged hook in for the live model-policy hook. **Do not run
|
|
4
|
-
this casually** — the live hook governs every subagent dispatch in every
|
|
5
|
-
session. Perform the swap between waves, not mid-fleet.
|
|
6
|
-
|
|
7
|
-
Paths used below:
|
|
8
|
-
|
|
9
|
-
- LIVE hook: `C:\Users\matt8\.claude\hooks\force-haiku-subagents.mjs`
|
|
10
|
-
- STAGED file: `<aesop>\docs\spikes\tiered-cognition\force-model-policy.merged.mjs`
|
|
11
|
-
- Shim agent def: `<aesop>\docs\spikes\tiered-cognition\aesop-cognition.example.md`
|
|
12
|
-
|
|
13
|
-
## Phase A activation (recommended first step)
|
|
14
|
-
|
|
15
|
-
Default behavior after the swap: model policy identical to today, plus
|
|
16
|
-
opus/fable-frontmatter dispatches rewritten to the message-only
|
|
17
|
-
`aesop-cognition` shim. Sonnet specialists untouched (no prompt loss —
|
|
18
|
-
FINDINGS.md condition 3 deferred). Layer 2 stays dormant.
|
|
19
|
-
|
|
20
|
-
1. **Install the shim agent definition** (the merged hook rewrites cognition
|
|
21
|
-
dispatches to `subagent_type: aesop-cognition`; without the definition
|
|
22
|
-
those dispatches would fail):
|
|
23
|
-
|
|
24
|
-
```powershell
|
|
25
|
-
Copy-Item <aesop>\docs\spikes\tiered-cognition\aesop-cognition.example.md `
|
|
26
|
-
C:\Users\matt8\.claude\agents\aesop-cognition.md
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
Then edit the copied file's `description:` to remove the "NOT INSTALLED"
|
|
30
|
-
sentence. Keep `tools: Agent, SendMessage, TaskStop, Monitor` and do NOT
|
|
31
|
-
add a `model:` line (the hook passes the effective model explicitly).
|
|
32
|
-
|
|
33
|
-
2. **Back up the live hook** (timestamped, same directory):
|
|
34
|
-
|
|
35
|
-
```powershell
|
|
36
|
-
Copy-Item C:\Users\matt8\.claude\hooks\force-haiku-subagents.mjs `
|
|
37
|
-
C:\Users\matt8\.claude\hooks\force-haiku-subagents.mjs.bak-$(Get-Date -Format yyyyMMdd-HHmmss)
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
3. **Verify the staged file before copying** (must print `SELF-TEST: ALL PASS`,
|
|
41
|
-
exit 0):
|
|
42
|
-
|
|
43
|
-
```powershell
|
|
44
|
-
node --check <aesop>\docs\spikes\tiered-cognition\force-model-policy.merged.mjs
|
|
45
|
-
node <aesop>\docs\spikes\tiered-cognition\force-model-policy.merged.mjs --self-test
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
4. **Copy over the live hook, keeping the live FILENAME** so settings.json
|
|
49
|
-
needs no edit:
|
|
50
|
-
|
|
51
|
-
```powershell
|
|
52
|
-
Copy-Item <aesop>\docs\spikes\tiered-cognition\force-model-policy.merged.mjs `
|
|
53
|
-
C:\Users\matt8\.claude\hooks\force-haiku-subagents.mjs -Force
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
5. **Verify the settings matcher is unchanged and correct.** In
|
|
57
|
-
`C:\Users\matt8\.claude\settings.json` the `hooks.PreToolUse` entry with
|
|
58
|
-
matcher `Agent|Task` must point at
|
|
59
|
-
`~/.claude/hooks/force-haiku-subagents.mjs` (node command). Do NOT add any
|
|
60
|
-
other hook on that matcher — this file must remain the ONLY `updatedInput`
|
|
61
|
-
owner for `Agent|Task`; wiring a second rewriting hook there reintroduces
|
|
62
|
-
the exact collision this merge exists to fix.
|
|
63
|
-
|
|
64
|
-
6. **Re-run the self-test on the installed copy** (proves the copy is intact):
|
|
65
|
-
|
|
66
|
-
```powershell
|
|
67
|
-
node C:\Users\matt8\.claude\hooks\force-haiku-subagents.mjs --self-test
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
7. **Restart.** Claude Code snapshots hook config at session start — running
|
|
71
|
-
sessions keep the old hook until restarted. Restart the orchestrator
|
|
72
|
-
session and any long-lived fleet sessions/daemons that dispatch subagents.
|
|
73
|
-
|
|
74
|
-
8. **Smoke-check in a fresh session:** dispatch a generic Haiku agent (expect
|
|
75
|
-
pass/route-to-haiku, no shim), a `bash-pro` (expect claude-sonnet-5, no
|
|
76
|
-
shim), and — if any opus/fable-frontmatter agent def is installed — one of
|
|
77
|
-
those (expect the `⛓ … tools stripped via 'aesop-cognition' shim` system
|
|
78
|
-
message). Confirm escape uses append to
|
|
79
|
-
`state/MODEL-POLICY-ESCAPES.log` / `state/TIER-POLICY-ESCAPES.log`.
|
|
80
|
-
|
|
81
|
-
## Phase B (later, deliberate)
|
|
82
|
-
|
|
83
|
-
Set `TIER_STRIP_SCOPE=all` in the environment Claude Code launches from to
|
|
84
|
-
extend the shim to sonnet specialists — ONLY after per-specialist cognition
|
|
85
|
-
variants exist (FINDINGS.md condition 3), otherwise specialist system prompts
|
|
86
|
-
are lost to the generic shim. `TIER_STRIP_SCOPE=off` reduces the hook to pure
|
|
87
|
-
live-hook model-policy behavior (useful as a soft rollback).
|
|
88
|
-
|
|
89
|
-
## Phase C — arming Layer 2 (call-time backstop; later, deliberate)
|
|
90
|
-
|
|
91
|
-
Dormant until BOTH of these are true:
|
|
92
|
-
|
|
93
|
-
1. `TIER_ENFORCE=1` in the environment.
|
|
94
|
-
2. settings.json gains a second `PreToolUse` entry running this same hook file
|
|
95
|
-
with a matcher covering the denied tools, e.g.
|
|
96
|
-
`Read|Write|Edit|MultiEdit|NotebookEdit|Bash|PowerShell|Glob|Grep|WebFetch|WebSearch|Skill|Artifact`.
|
|
97
|
-
(That entry never emits `updatedInput` — deny/allow only — so the
|
|
98
|
-
single-owner rule is preserved.)
|
|
99
|
-
|
|
100
|
-
Before arming: validate transcript sniffing on real sidechain transcripts and
|
|
101
|
-
decide the main-thread carve-out (FINDINGS.md condition 2 / risk 4).
|
|
102
|
-
|
|
103
|
-
## Rollback
|
|
104
|
-
|
|
105
|
-
1. Restore the newest backup:
|
|
106
|
-
|
|
107
|
-
```powershell
|
|
108
|
-
Copy-Item C:\Users\matt8\.claude\hooks\force-haiku-subagents.mjs.bak-<TS> `
|
|
109
|
-
C:\Users\matt8\.claude\hooks\force-haiku-subagents.mjs -Force
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
2. Optionally remove `C:\Users\matt8\.claude\agents\aesop-cognition.md`
|
|
113
|
-
(harmless to leave installed; nothing routes to it without the merged hook).
|
|
114
|
-
3. Unset `TIER_ENFORCE` / `TIER_STRIP_SCOPE` if set; remove any Layer-2
|
|
115
|
-
matcher added in Phase C.
|
|
116
|
-
4. Restart running sessions (same snapshot rule as step 7 above).
|
|
117
|
-
|
|
118
|
-
## Env knobs (merged hook)
|
|
119
|
-
|
|
120
|
-
| Var | Default | Effect |
|
|
121
|
-
|---|---|---|
|
|
122
|
-
| `FORCE_ALL_HAIKU=1` | off | Every dispatch → haiku (bash-pro excepted) — unchanged from live hook |
|
|
123
|
-
| `TIER_STRIP_SCOPE` | `opus-fable` | `opus-fable` (Phase A) / `all` (Phase B) / `off` (model policy only) |
|
|
124
|
-
| `TIER_ENFORCE=1` | off | Arms the Layer-2 call-time backstop (needs the Phase C matcher too) |
|
|
125
|
-
| `AESOP_ROOT` | `~/aesop` | Root for `state/*-ESCAPES.log` audit logs |
|
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
# Tiered Cognition/Execution — Wave-11 Spike Design
|
|
2
|
-
|
|
3
|
-
> **STATUS: SPIKE — NOTHING HERE IS ACTIVATED.** No live hook, settings.json,
|
|
4
|
-
> or skill was modified. The prototype (`strip-tools-hook.mjs`) and shim agent
|
|
5
|
-
> (`aesop-cognition.example.md`) live only in this directory. Rollout is a
|
|
6
|
-
> wave-12 decision — see `FINDINGS.md` for the GO/NO-GO and steps.
|
|
7
|
-
|
|
8
|
-
Source plan: `conductor3/plans/aesop-wave11-tiered-cognition.md`.
|
|
9
|
-
|
|
10
|
-
## 1. Architecture recap
|
|
11
|
-
|
|
12
|
-
```
|
|
13
|
-
Fable 5 ⇄ Haiku ⇄ Opus ⇄ Haiku ⇄ Sonnet 5 ⇄ Haiku ⇄ (files / git / tools / tests)
|
|
14
|
-
(cognition) courier (cognition) courier (cognition) executor
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
| Tier | Models | May do | May NOT do |
|
|
18
|
-
|---|---|---|---|
|
|
19
|
-
| Cognition | Fable 5, Opus, Sonnet 5 | Reason, decide, emit WORK-ORDERs, dispatch/message Haiku | Read, Write, Edit, Bash, Glob, Grep, WebFetch — any direct I/O/exec |
|
|
20
|
-
| Substrate | Haiku | Everything real: read/write/exec/git/tests + carry messages between tiers | Improvise, silently "fix" a work-order, summarize away errors |
|
|
21
|
-
|
|
22
|
-
Two mechanisms realize this: **(A)** a PreToolUse hook that strips I/O/exec
|
|
23
|
-
tools from cognition-tier subagents, and **(B)** a structured courier/executor
|
|
24
|
-
hand-off (WORK-ORDER → EXEC-BRIEF) so cognition output is mechanically
|
|
25
|
-
applicable and results flow back as typed briefs.
|
|
26
|
-
|
|
27
|
-
## 2. Mechanism A — the tool-stripping PreToolUse hook
|
|
28
|
-
|
|
29
|
-
Prototype: [`strip-tools-hook.mjs`](strip-tools-hook.mjs) — standalone, pure
|
|
30
|
-
`decide()` core, `--self-test` builds fixtures and asserts 27 cases (all pass).
|
|
31
|
-
|
|
32
|
-
### 2.1 Harness facts that shape the design
|
|
33
|
-
|
|
34
|
-
1. **The Agent tool input has NO `tools` field.** Its schema is
|
|
35
|
-
`{description, prompt, subagent_type, model, isolation, run_in_background}`
|
|
36
|
-
with `additionalProperties: false`. A hook's `updatedInput` therefore
|
|
37
|
-
*cannot* inject a per-dispatch tool list (it would be an
|
|
38
|
-
InputValidationError). The only supported way to constrain a subagent's
|
|
39
|
-
tools today is the agent definition's `tools:` frontmatter
|
|
40
|
-
(`~/.claude/agents/*.md`) — so dispatch-time stripping is implemented as a
|
|
41
|
-
**rewrite to a shim agent type** whose definition carries the allowlist.
|
|
42
|
-
2. **PreToolUse hooks fire for subagents' own tool calls too**, which enables a
|
|
43
|
-
call-time backstop independent of how the agent was dispatched.
|
|
44
|
-
3. **The hook payload does not name the session's model**
|
|
45
|
-
(`{session_id, transcript_path, cwd, tool_name, tool_input, ...}`), so
|
|
46
|
-
call-time tier detection is inferred from the transcript (§2.3).
|
|
47
|
-
4. **Hook composition hazard:** the live `force-haiku-subagents.mjs` already
|
|
48
|
-
emits `updatedInput` on the same `Agent|Task` matcher. Two hooks rewriting
|
|
49
|
-
the same call have no defined merge; at rollout the tier policy must be
|
|
50
|
-
**merged into the model-policy hook as one file** (model routing decides the
|
|
51
|
-
tier; the same decision then strips or keeps tools — one decision point, no
|
|
52
|
-
ordering hazard).
|
|
53
|
-
|
|
54
|
-
### 2.2 Layer 1 — dispatch guard (matcher `Agent|Task`)
|
|
55
|
-
|
|
56
|
-
**Tier detection**, in order:
|
|
57
|
-
|
|
58
|
-
1. Explicit `tool_input.model` — substring match: `haiku` → substrate;
|
|
59
|
-
`sonnet` / `opus` / `fable` → cognition.
|
|
60
|
-
2. Blank model + `subagent_type` → the installed agent definition's `model:`
|
|
61
|
-
frontmatter (same catalog walk the model-policy hook uses).
|
|
62
|
-
3. Neither → **haiku** (correct by construction: the model-policy hook lands
|
|
63
|
-
every non-specialist, non-escaped dispatch on Haiku).
|
|
64
|
-
|
|
65
|
-
**Decision table:**
|
|
66
|
-
|
|
67
|
-
| Dispatch | Action |
|
|
68
|
-
|---|---|
|
|
69
|
-
| Tier = haiku (or `subagent_type: fork`) | pass untouched |
|
|
70
|
-
| Tier = cognition, prompt has escape token | allow untouched + **audit** (§2.4) |
|
|
71
|
-
| Tier = cognition, no escape | **strip** — rewrite `subagent_type` → `aesop-cognition`, prepend `[COGNITION CONTRACT v1]` header naming the originally requested type |
|
|
72
|
-
| Malformed payload / unreadable catalog | pass (fail-open) |
|
|
73
|
-
|
|
74
|
-
**Kept tools** (via the shim's `tools:` frontmatter, see
|
|
75
|
-
[`aesop-cognition.example.md`](aesop-cognition.example.md)):
|
|
76
|
-
`Agent, SendMessage, TaskStop, Monitor` — reason, message, dispatch Haiku,
|
|
77
|
-
stop/monitor what it dispatched. Nothing else.
|
|
78
|
-
|
|
79
|
-
**Stripped (denied) tools:**
|
|
80
|
-
`Read, Write, Edit, MultiEdit, NotebookEdit, Bash, PowerShell, BashOutput,
|
|
81
|
-
KillShell, Glob, Grep, WebFetch, WebSearch, Skill, Artifact, ToolSearch,
|
|
82
|
-
EnterWorktree, ExitWorktree`.
|
|
83
|
-
|
|
84
|
-
Note the mission's generalization: cognition tiers lose **Read/Grep/Glob too**
|
|
85
|
-
— facts arrive via Haiku courier briefs, never raw file ingestion. This is the
|
|
86
|
-
"orchestrator reads nothing" cardinal rule applied to every expensive tier.
|
|
87
|
-
|
|
88
|
-
**Cost of the shim rewrite:** the original specialist's system prompt (its
|
|
89
|
-
`.md` body) is lost; the role survives only as the contract header line. §5
|
|
90
|
-
lists the wave-12 fix (generated per-specialist cognition variants).
|
|
91
|
-
|
|
92
|
-
### 2.3 Layer 2 — call-time backstop (matcher `Read|Write|Edit|NotebookEdit|Bash|PowerShell|Glob|Grep|WebFetch|WebSearch|Skill|Artifact`)
|
|
93
|
-
|
|
94
|
-
Defense in depth for dispatches that bypass Layer 1 (pre-existing sessions,
|
|
95
|
-
SDK-defined agents, the main thread, drift after a harness update).
|
|
96
|
-
|
|
97
|
-
1. Parse `transcript_path` (JSONL). Tier = model of the **last** assistant
|
|
98
|
-
entry (`message.model`) — robust to mid-session model switches.
|
|
99
|
-
2. Escape check: any user entry containing an escape token (a subagent's
|
|
100
|
-
dispatch prompt is the first user message of its transcript, so an escaped
|
|
101
|
-
dispatch is visible here).
|
|
102
|
-
3. Decision: haiku or escaped → allow; cognition → **deny**; transcript
|
|
103
|
-
missing/unreadable/model-free → pass (fail-open, no opinion).
|
|
104
|
-
|
|
105
|
-
The deny is **self-correcting**: `permissionDecision: "deny"` returns the
|
|
106
|
-
reason to the model, and the reason is an instruction —
|
|
107
|
-
|
|
108
|
-
> "Do NOT retry {tool}. Instead emit a WORK-ORDER v1 … and dispatch a Haiku
|
|
109
|
-
> executor agent to apply it and report back an EXEC-BRIEF."
|
|
110
|
-
|
|
111
|
-
so a cognition agent that tries to touch a file is redirected into the courier
|
|
112
|
-
pattern mid-flight instead of just failing.
|
|
113
|
-
|
|
114
|
-
**Main-thread consequence:** the backstop as specified also denies a Fable
|
|
115
|
-
main thread's direct writes — which *is* the cardinal rule ("orchestrator
|
|
116
|
-
never hand-writes files") — but today's orchestrator legitimately runs short
|
|
117
|
-
git one-liners. Rollout needs either a read-only Bash allowlist
|
|
118
|
-
(`git status|log|diff --stat` patterns) or a main-thread carve-out. Flagged in
|
|
119
|
-
FINDINGS; the spike prototype governs the listed tools uniformly.
|
|
120
|
-
|
|
121
|
-
### 2.4 Escape hatch — `[[ALLOW-TIER-TOOLS]]`
|
|
122
|
-
|
|
123
|
-
Same contract as the model policy's `[[ALLOW-NON-HAIKU]]`:
|
|
124
|
-
|
|
125
|
-
- Token in the dispatch prompt → the agent keeps its full toolset.
|
|
126
|
-
- **Never silent**: announced via `permissionDecisionReason` in the transcript
|
|
127
|
-
AND appended as a JSON line to
|
|
128
|
-
`${AESOP_ROOT:-~/aesop}/state/TIER-POLICY-ESCAPES.log`
|
|
129
|
-
(`{ts, event: "tier_policy_escape", tool, session_id, cwd, description,
|
|
130
|
-
requested_model, prompt_head}`).
|
|
131
|
-
- During migration, `[[ALLOW-NON-HAIKU]]` is grandfathered as implying tool
|
|
132
|
-
retention (today's escalations are hands-on missions — this spike itself ran
|
|
133
|
-
under it). Once cognition dispatch is the norm, escalate-model-but-stay-
|
|
134
|
-
cognition becomes the default and `[[ALLOW-NON-HAIKU]]` stops implying tools.
|
|
135
|
-
|
|
136
|
-
## 3. Mechanism B — the courier/executor hand-off
|
|
137
|
-
|
|
138
|
-
### 3.1 WORK-ORDER v1 (cognition → executor)
|
|
139
|
-
|
|
140
|
-
A cognition agent's entire real-world intent for one coherent change-set,
|
|
141
|
-
batched into a single JSON document:
|
|
142
|
-
|
|
143
|
-
```json
|
|
144
|
-
{
|
|
145
|
-
"kind": "work-order",
|
|
146
|
-
"version": 1,
|
|
147
|
-
"id": "wo-<slug>",
|
|
148
|
-
"intent": "one-line goal (for logs and the brief)",
|
|
149
|
-
"worktree": "C:/abs/path/to/isolated/worktree",
|
|
150
|
-
"branch": "expected branch (executor verifies before acting)",
|
|
151
|
-
"patch": "<unified diff as a single string, or null>",
|
|
152
|
-
"commands": [
|
|
153
|
-
{ "run": "exact command line", "cwd": "abs path", "expect_exit": 0, "timeout_s": 120 }
|
|
154
|
-
],
|
|
155
|
-
"verify": [
|
|
156
|
-
{ "run": "exact command line", "expect_exit": 0, "expect_stdout_re": "optional regex" }
|
|
157
|
-
],
|
|
158
|
-
"report": { "format": "exec-brief/v1", "max_words": 200 }
|
|
159
|
-
}
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
Semantics:
|
|
163
|
-
|
|
164
|
-
- `patch` is applied with `git apply` (byte-exact context; a failed hunk is a
|
|
165
|
-
FAILED brief, never hand-merged). `commands` run in listed order, stopping at
|
|
166
|
-
the first unexpected exit. `verify` always runs after (even partially) —
|
|
167
|
-
it is the evidence section of the brief.
|
|
168
|
-
- Ambiguity is an error: if the executor cannot apply the order *exactly as
|
|
169
|
-
written*, it stops and reports; it never substitutes judgment.
|
|
170
|
-
- One work-order per coherent change-set (**batching amortizes the round-trip**
|
|
171
|
-
— a whole patch + command plan, never line-by-line).
|
|
172
|
-
|
|
173
|
-
### 3.2 EXEC-BRIEF v1 (executor → cognition)
|
|
174
|
-
|
|
175
|
-
```json
|
|
176
|
-
{
|
|
177
|
-
"kind": "exec-brief",
|
|
178
|
-
"version": 1,
|
|
179
|
-
"work_order_id": "wo-<slug>",
|
|
180
|
-
"status": "APPLIED | FAILED | PARTIAL",
|
|
181
|
-
"steps": [ { "step": "apply-patch | cmd:<n> | verify:<n>", "ok": true, "detail": "≤1 line" } ],
|
|
182
|
-
"verify_results": [ { "run": "…", "exit": 0, "stdout_tail": "last ≤3 lines" } ],
|
|
183
|
-
"verbatim_errors": [ "exact error text, untrimmed — empty array iff none" ],
|
|
184
|
-
"files_touched": [ "relative paths" ],
|
|
185
|
-
"commit": "sha or null"
|
|
186
|
-
}
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
### 3.3 Courier honesty rules
|
|
190
|
-
|
|
191
|
-
1. Apply **exactly** what the order says; no improvisation, no "small fixes".
|
|
192
|
-
2. Failures are reported **verbatim** in `verbatim_errors` — never summarized,
|
|
193
|
-
never softened. The substrate must not editorialize.
|
|
194
|
-
3. A brief is **always** produced (inputs always produce outputs) — even a
|
|
195
|
-
crash mid-order yields `status: FAILED` with whatever evidence exists.
|
|
196
|
-
4. Verification stays owner-owned: the executor *runs* the verify commands;
|
|
197
|
-
the owning cognition tier *judges* the pass/fail brief
|
|
198
|
-
(per `[[subagents-push-orchestrator-verifies]]`).
|
|
199
|
-
|
|
200
|
-
## 4. Worked example — a real round-trip (executed in this spike)
|
|
201
|
-
|
|
202
|
-
Task: one-line real doc change — link this spike directory from
|
|
203
|
-
`docs/README.md`. The cognition tier (Fable, this session) authored the
|
|
204
|
-
work-order below; a **real Haiku executor subagent** applied it.
|
|
205
|
-
|
|
206
|
-
### 4.1 The cognition-authored WORK-ORDER
|
|
207
|
-
|
|
208
|
-
```json
|
|
209
|
-
{
|
|
210
|
-
"kind": "work-order",
|
|
211
|
-
"version": 1,
|
|
212
|
-
"id": "wo-w11-readme-spikes-link",
|
|
213
|
-
"intent": "Add a Design Spikes section to docs/README.md linking the tiered-cognition spike",
|
|
214
|
-
"worktree": "C:/Users/matt8/aesop-wt-wave11-mission-spike",
|
|
215
|
-
"branch": "spike/wave11-tiered-cognition",
|
|
216
|
-
"patch": "<the unified diff below, embedded verbatim>",
|
|
217
|
-
"commands": [],
|
|
218
|
-
"verify": [
|
|
219
|
-
{ "run": "git -C C:/Users/matt8/aesop-wt-wave11-mission-spike diff --numstat -- docs/README.md", "expect_exit": 0, "expect_stdout_re": "^4\\t0\\tdocs/README.md$" },
|
|
220
|
-
{ "run": "grep -n \"## Design Spikes\" docs/README.md", "expect_exit": 0, "expect_stdout_re": "^38:" },
|
|
221
|
-
{ "run": "grep -c \"spikes/tiered-cognition/\" docs/README.md", "expect_exit": 0, "expect_stdout_re": "^1$" }
|
|
222
|
-
],
|
|
223
|
-
"report": { "format": "exec-brief/v1", "max_words": 200 }
|
|
224
|
-
}
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
```diff
|
|
228
|
-
--- a/docs/README.md
|
|
229
|
-
+++ b/docs/README.md
|
|
230
|
-
@@ -33,4 +33,8 @@
|
|
231
|
-
## Operational Guides
|
|
232
|
-
|
|
233
|
-
- [PUBLISHING.md](PUBLISHING.md) — Release Aesop to npm using GitHub Actions with OIDC trusted publishing
|
|
234
|
-
- [av-resilience.md](av-resilience.md) — Antivirus & behavioral-engine resilience patterns for reliable agent execution
|
|
235
|
-
+
|
|
236
|
-
+## Design Spikes
|
|
237
|
-
+
|
|
238
|
-
+- [spikes/tiered-cognition/](spikes/tiered-cognition/) — Wave-11 spike: tiered cognition/execution architecture (Haiku as sole I/O substrate; Sonnet/Opus/Fable cognition tiers emit structured work-orders)
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
### 4.2 The EXEC-BRIEF as received from the Haiku executor
|
|
242
|
-
|
|
243
|
-
Captured verbatim from a live general-purpose sub-dispatch (which the live
|
|
244
|
-
model policy landed on **Haiku**, as the architecture requires). Round-trip:
|
|
245
|
-
**33.9 s wall-clock, 33,932 subagent tokens, 6 tool uses**; the change was then
|
|
246
|
-
independently re-verified by the owner (`git diff --numstat` = `4 0
|
|
247
|
-
docs/README.md`, nothing else touched, em-dash bytes intact).
|
|
248
|
-
|
|
249
|
-
```json
|
|
250
|
-
{
|
|
251
|
-
"kind": "exec-brief",
|
|
252
|
-
"version": 1,
|
|
253
|
-
"work_order_id": "wo-w11-readme-spikes-link",
|
|
254
|
-
"status": "APPLIED",
|
|
255
|
-
"steps": [
|
|
256
|
-
{ "step": "branch-check", "ok": true, "detail": "On spike/wave11-tiered-cognition" },
|
|
257
|
-
{ "step": "write-patch", "ok": true, "detail": "Patch file written to scratchpad" },
|
|
258
|
-
{ "step": "apply-patch", "ok": true, "detail": "git apply succeeded with exit 0" },
|
|
259
|
-
{ "step": "verify:1", "ok": true, "detail": "diff --numstat: 4 additions, 0 deletions" },
|
|
260
|
-
{ "step": "verify:2", "ok": true, "detail": "## Design Spikes found at line 38" },
|
|
261
|
-
{ "step": "verify:3", "ok": true, "detail": "tiered-cognition reference count: 1" }
|
|
262
|
-
],
|
|
263
|
-
"verify_results": [
|
|
264
|
-
{ "run": "git diff --numstat -- docs/README.md", "exit": 0, "stdout_tail": "4\t0\tdocs/README.md" },
|
|
265
|
-
{ "run": "grep -n '## Design Spikes' docs/README.md", "exit": 0, "stdout_tail": "38:## Design Spikes" },
|
|
266
|
-
{ "run": "grep -c 'spikes/tiered-cognition/' docs/README.md", "exit": 0, "stdout_tail": "1" }
|
|
267
|
-
],
|
|
268
|
-
"verbatim_errors": [],
|
|
269
|
-
"files_touched": ["docs/README.md"],
|
|
270
|
-
"commit": null
|
|
271
|
-
}
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
## 5. Rollout sketch (wave 12 — only if GO)
|
|
275
|
-
|
|
276
|
-
1. Merge the tier policy into `force-haiku-subagents.mjs` (one decision point:
|
|
277
|
-
route model → strip or keep tools) — eliminates the dual-`updatedInput`
|
|
278
|
-
hazard of §2.1(4).
|
|
279
|
-
2. Install `aesop-cognition.md`; generate per-specialist cognition variants
|
|
280
|
-
(`aesop-cognition-<specialist>.md`: specialist body + cognition tool
|
|
281
|
-
allowlist) so the specialist system prompt survives stripping.
|
|
282
|
-
3. Add the Layer-2 backstop matcher to settings.json; decide the main-thread
|
|
283
|
-
carve-out (read-only git allowlist vs. exempting the top-level session).
|
|
284
|
-
4. Teach `/buildsystem` dispatch prompts the WORK-ORDER/EXEC-BRIEF contract;
|
|
285
|
-
add an `aesop-executor` Haiku agent definition embedding §3.3.
|
|
286
|
-
5. Verify transcript-sniff fidelity on real sidechain transcripts (the one
|
|
287
|
-
mechanism this spike could not fully validate in-harness — see FINDINGS).
|