@matt82198/aesop 0.1.0-beta.3 → 0.1.0-beta.4

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 (108) hide show
  1. package/CHANGELOG.md +37 -94
  2. package/CLAUDE-TEMPLATE.md +115 -0
  3. package/README.md +89 -264
  4. package/aesop.config.example.json +27 -26
  5. package/bin/CLAUDE.md +39 -0
  6. package/bin/cli.js +368 -24
  7. package/daemons/CLAUDE.md +33 -0
  8. package/daemons/backup-fleet.sh +92 -21
  9. package/daemons/run-watchdog.sh +90 -10
  10. package/dash/CLAUDE.md +32 -0
  11. package/dash/dash-extra.mjs +194 -21
  12. package/dash/watchdog-gui.sh +23 -6
  13. package/docs/BEHAVIORAL-PR-REVIEW.md +86 -0
  14. package/docs/CHECKPOINTING.md +100 -0
  15. package/docs/DISPATCH-MODEL.md +11 -7
  16. package/docs/FORENSICS.md +204 -0
  17. package/docs/GOVERNANCE.md +4 -2
  18. package/docs/HOOK-INSTALL.md +307 -0
  19. package/docs/HOW-THE-LOOP-WORKS.md +175 -0
  20. package/docs/MEMORY-TEMPLATE.md +61 -0
  21. package/docs/README.md +44 -0
  22. package/docs/RELIABILITY.md +61 -0
  23. package/docs/RESTORE.md +397 -0
  24. package/docs/SCRIPTS-POLICY.md +97 -0
  25. package/docs/spikes/tiered-cognition/ACTIVATION.md +125 -0
  26. package/docs/spikes/tiered-cognition/DESIGN.md +287 -0
  27. package/docs/spikes/tiered-cognition/FINDINGS.md +113 -0
  28. package/docs/spikes/tiered-cognition/README.md +29 -0
  29. package/docs/spikes/tiered-cognition/aesop-cognition.example.md +32 -0
  30. package/docs/spikes/tiered-cognition/force-model-policy.merged.mjs +673 -0
  31. package/docs/spikes/tiered-cognition/strip-tools-hook.mjs +434 -0
  32. package/hooks/CLAUDE.md +38 -0
  33. package/hooks/claude/force-model-policy.mjs +159 -0
  34. package/hooks/pre-push-policy.sh +753 -0
  35. package/monitor/.signal-state.json +3 -0
  36. package/monitor/ACTIONS.log +1 -0
  37. package/monitor/BRIEF.md +24 -0
  38. package/monitor/CHARTER.md +29 -8
  39. package/monitor/CLAUDE.md +40 -0
  40. package/monitor/SIGNALS.json +54 -0
  41. package/monitor/collect-signals.mjs +529 -62
  42. package/package.json +12 -3
  43. package/skills/CLAUDE.md +3 -0
  44. package/skills/power/SKILL.md +161 -0
  45. package/tools/CLAUDE.md +191 -0
  46. package/tools/__pycache__/buildlog.cpython-314.pyc +0 -0
  47. package/tools/__pycache__/ci_merge_wait.cpython-314.pyc +0 -0
  48. package/tools/__pycache__/ensure_state.cpython-314.pyc +0 -0
  49. package/tools/__pycache__/eod_sweep.cpython-314.pyc +0 -0
  50. package/tools/__pycache__/fleet_ledger.cpython-314.pyc +0 -0
  51. package/tools/__pycache__/heartbeat.cpython-314.pyc +0 -0
  52. package/tools/__pycache__/inbox_drain.cpython-314.pyc +0 -0
  53. package/tools/__pycache__/launch_tui.cpython-314.pyc +0 -0
  54. package/tools/__pycache__/orchestrator_status.cpython-314.pyc +0 -0
  55. package/tools/__pycache__/power_selftest.cpython-314.pyc +0 -0
  56. package/tools/__pycache__/prepublish_scan.cpython-314.pyc +0 -0
  57. package/tools/__pycache__/rotate_logs.cpython-314.pyc +0 -0
  58. package/tools/__pycache__/scanner_selftest.cpython-314.pyc +0 -0
  59. package/tools/__pycache__/secret_scan.cpython-314.pyc +0 -0
  60. package/tools/__pycache__/stall_check.cpython-314.pyc +0 -0
  61. package/tools/__pycache__/verify_dash.cpython-314.pyc +0 -0
  62. package/tools/__pycache__/verify_submit_encoding.cpython-314.pyc +0 -0
  63. package/tools/agent-forensics.sh +186 -0
  64. package/tools/buildlog.py +182 -0
  65. package/tools/ci_merge_wait.py +204 -0
  66. package/tools/ensure_state.py +94 -0
  67. package/tools/eod_sweep.py +239 -0
  68. package/tools/fleet_ledger.py +272 -0
  69. package/tools/heartbeat.py +131 -0
  70. package/tools/inbox_drain.py +249 -0
  71. package/tools/launch_tui.py +51 -3
  72. package/tools/lock.mjs +211 -0
  73. package/tools/metrics_gate.py +205 -0
  74. package/tools/orchestrator_status.py +99 -0
  75. package/tools/power_selftest.py +386 -0
  76. package/tools/prepublish_scan.py +84 -0
  77. package/tools/proposals.mjs +248 -0
  78. package/tools/reconstitute.sh +467 -0
  79. package/tools/rotate_logs.py +228 -0
  80. package/tools/scanner_selftest.py +303 -0
  81. package/tools/secret_scan.py +131 -31
  82. package/tools/stall_check.py +172 -0
  83. package/tools/verify_dash.py +694 -0
  84. package/tools/verify_submit_encoding.py +194 -0
  85. package/ui/CLAUDE.md +109 -0
  86. package/ui/__pycache__/agents.cpython-314.pyc +0 -0
  87. package/ui/__pycache__/collectors.cpython-314.pyc +0 -0
  88. package/ui/__pycache__/config.cpython-314.pyc +0 -0
  89. package/ui/__pycache__/csrf.cpython-314.pyc +0 -0
  90. package/ui/__pycache__/handler.cpython-314.pyc +0 -0
  91. package/ui/__pycache__/render.cpython-314.pyc +0 -0
  92. package/ui/__pycache__/serve.cpython-314.pyc +0 -0
  93. package/ui/__pycache__/sse.cpython-314.pyc +0 -0
  94. package/ui/agents.py +179 -0
  95. package/ui/api/__init__.py +84 -0
  96. package/ui/api/__pycache__/__init__.cpython-314.pyc +0 -0
  97. package/ui/api/__pycache__/submit.cpython-314.pyc +0 -0
  98. package/ui/api/__pycache__/tracker.cpython-314.pyc +0 -0
  99. package/ui/api/submit.py +58 -0
  100. package/ui/api/tracker.py +116 -0
  101. package/ui/collectors.py +586 -0
  102. package/ui/config.py +114 -0
  103. package/ui/csrf.py +140 -0
  104. package/ui/handler.py +426 -0
  105. package/ui/render.py +29 -0
  106. package/ui/serve.py +68 -796
  107. package/ui/sse.py +168 -0
  108. package/ui/templates/dashboard.html +1202 -0
@@ -0,0 +1,287 @@
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).
@@ -0,0 +1,113 @@
1
+ # Tiered Cognition/Execution — Wave-11 Spike Findings
2
+
3
+ **Verdict: GO (conditional)** — mechanism is buildable with today's harness
4
+ primitives, the courier round-trip works with full fidelity on a real task,
5
+ and the prototype hook passes its self-test. Three conditions must be closed
6
+ in wave 12 before activation (below).
7
+
8
+ ## What was proven
9
+
10
+ 1. **Hook prototype works.** `strip-tools-hook.mjs --self-test`:
11
+ **27/27 PASS** (Node v24.16.0). Covers: sonnet/opus/fable dispatches
12
+ stripped via the `aesop-cognition` shim rewrite; haiku and
13
+ haiku-frontmatter dispatches untouched; blank-model specialist resolution
14
+ via agent-catalog frontmatter; escape token honored + audited to
15
+ `state/TIER-POLICY-ESCAPES.log`; legacy `[[ALLOW-NON-HAIKU]]`
16
+ grandfathered; fork pass-through; call-time deny of Write/Bash under a
17
+ sonnet transcript with a redirect-to-work-order reason; allow under haiku;
18
+ fail-open on malformed payloads and missing transcripts.
19
+ 2. **Courier round-trip works end-to-end on a real change.** A cognition-
20
+ authored WORK-ORDER (unified diff + 3 verify steps, DESIGN.md §4) was
21
+ applied by a **live Haiku executor sub-dispatch** (the existing model
22
+ policy routed it to Haiku with no special handling — the two policies
23
+ compose). Result: `status: APPLIED`, all verifies green, byte-exact
24
+ application (UTF-8 em-dashes and LF endings survived the
25
+ prompt → Write → git-apply path), zero collateral edits, honest typed
26
+ brief returned.
27
+ 3. **`git apply` is a sufficient fidelity gate.** Because the executor applies
28
+ the diff mechanically and the diff carries byte-exact context, any drift
29
+ the courier introduces fails the apply loudly instead of corrupting the
30
+ file. The verify list then provides positive evidence, not just absence of
31
+ error.
32
+
33
+ ## Round-trip overhead observed
34
+
35
+ | Metric | Value |
36
+ |---|---|
37
+ | Wall-clock, dispatch → EXEC-BRIEF | **33.9 s** |
38
+ | Executor tokens (Haiku) | 33,932 |
39
+ | Executor tool uses | 6 (branch check, patch write, apply, 3 verifies) |
40
+ | Cognition-side cost | authoring the work-order (one message) + reading a ~200-word brief |
41
+
42
+ Interpretation: ~30–60 s and a few-cent Haiku bill per coherent change-set is
43
+ acceptable **iff work-orders stay batched** (whole patch + command plan per
44
+ round trip). At line-by-line granularity the architecture would be unusable —
45
+ batching is a hard rule, not an optimization.
46
+
47
+ ## Fidelity risks / what breaks (honest list)
48
+
49
+ 1. **Hook composition (must fix before activation).** The live
50
+ `force-haiku-subagents.mjs` and this hook both emit `updatedInput` on the
51
+ same `Agent|Task` matcher; merge order is undefined. **Condition 1: merge
52
+ tier policy into the model-policy hook as one file.** Not fixable by
53
+ ordering config alone — one decision point is the correct design anyway.
54
+ 2. **Layer-2 tier detection is transcript-sniffed and unverified in-harness.**
55
+ The hook payload doesn't name the session model; the prototype infers it
56
+ from `transcript_path` JSONL (`message.model` of the last assistant
57
+ entry). This works on fixture transcripts, but sidechain/subagent
58
+ transcript layout in the current harness build was NOT exercised live
59
+ (this spike's session is escape-token-exempt, so a live negative test
60
+ wasn't possible without wiring the hook in — out of spike scope).
61
+ **Condition 2: validate the sniffer against real subagent transcripts
62
+ before trusting Layer 2; treat Layer 1 as the primary control.**
63
+ 3. **Specialist prompt loss under the shim rewrite.** Rewriting
64
+ `subagent_type` → `aesop-cognition` drops the specialist's system prompt;
65
+ the role survives only as a contract-header line. Cognition quality for
66
+ typed specialists will degrade until per-specialist cognition variants are
67
+ generated (DESIGN §5.2). **Condition 3 for full fleet rollout; not a
68
+ blocker for a Fable/Opus-orchestrator-only first phase.**
69
+ 4. **Main-thread carve-out undecided.** Uniform Layer-2 denial would break the
70
+ orchestrator's legitimate short git one-liners. Needs a read-only Bash
71
+ allowlist or a top-session exemption (DESIGN §2.3). Decide at rollout.
72
+ 5. **Fail-open stance.** Every failure path passes (consistent with the model
73
+ policy hook). A malformed transcript therefore silently disables Layer 2 —
74
+ same shape as the known `proposals-lock fail-open` issue. Acceptable for a
75
+ guardrail whose primary layer is dispatch-time, but worth a revisit when
76
+ Layer 2 is trusted.
77
+ 6. **Executor honesty is prompt-enforced, not mechanical.** The brief schema
78
+ and "verbatim errors" rule live in the dispatch prompt. A lazy executor
79
+ could still fabricate a green brief; mitigation is the existing
80
+ owner-verifies rule (the owning tier re-runs/reads the cheap verify
81
+ evidence, as done in this spike) plus `git apply`'s mechanical honesty.
82
+ 7. **Escape-token smuggling** applies to `[[ALLOW-TIER-TOOLS]]` exactly as to
83
+ the model policy's token: prompts are untrusted text. Same mitigation
84
+ inherited: never silent, always audited to state log.
85
+
86
+ ## GO / NO-GO
87
+
88
+ **GO** for wave-12 rollout, phased:
89
+
90
+ 1. **Phase A (cheap, high value):** merge tier policy into
91
+ `force-haiku-subagents.mjs` (Condition 1); install `aesop-cognition.md` +
92
+ an `aesop-executor` Haiku agent def embedding the courier honesty rules;
93
+ teach `/buildsystem` dispatch prompts the WORK-ORDER/EXEC-BRIEF schema.
94
+ Apply stripping to **opus/fable dispatches only** first (no specialist
95
+ prompt loss — Condition 3 deferred safely).
96
+ 2. **Phase B:** generate per-specialist cognition variants; extend stripping
97
+ to sonnet specialists; measure fix-item throughput vs. the current
98
+ Sonnet-hands-on baseline for one wave before making it default.
99
+ 3. **Phase C:** wire Layer-2 backstop after validating transcript sniffing on
100
+ real sidechains (Condition 2) and deciding the main-thread carve-out.
101
+
102
+ Top risk if rolled out as-is without the conditions: **the dual-hook
103
+ `updatedInput` collision (risk 1)** — it could silently drop the model
104
+ rewrite or the tool strip depending on harness ordering, i.e. a policy hole
105
+ that looks green.
106
+
107
+ ## Spike inventory (all inert)
108
+
109
+ - `docs/spikes/tiered-cognition/DESIGN.md` — mechanism + schemas + executed worked example
110
+ - `docs/spikes/tiered-cognition/strip-tools-hook.mjs` — prototype hook, self-test 27/27 PASS
111
+ - `docs/spikes/tiered-cognition/aesop-cognition.example.md` — shim agent def (NOT installed)
112
+ - `docs/README.md` — one real change, applied by the Haiku executor round-trip
113
+ - Nothing wired into `~/.claude/settings.json`, live hooks, or `/buildsystem`.
@@ -0,0 +1,29 @@
1
+ # Tiered Cognition/Execution — spike + staged wave-12 artifact
2
+
3
+ > **STATUS: STAGED, NOT ACTIVATED.** Nothing in this directory is wired into
4
+ > `~/.claude/settings.json` or `~/.claude/hooks/`. The live model-policy hook
5
+ > (`force-haiku-subagents.mjs`) is untouched and still governs the fleet.
6
+
7
+ ## Contents
8
+
9
+ | File | Status | What |
10
+ |---|---|---|
11
+ | `DESIGN.md` | wave-11 spike | Architecture, hook mechanism, WORK-ORDER/EXEC-BRIEF schemas, executed round-trip |
12
+ | `FINDINGS.md` | wave-11 spike | GO (conditional) verdict, risks, phased rollout plan |
13
+ | `strip-tools-hook.mjs` | wave-11 prototype | Tier policy alone (superseded by the merged file below) |
14
+ | `aesop-cognition.example.md` | example, not installed | Message-only shim agent definition the merged hook rewrites to |
15
+ | **`force-model-policy.merged.mjs`** | **wave-12 STAGED CANDIDATE** | Model policy + tier policy merged into ONE hook — the single `updatedInput` owner for the `Agent\|Task` matcher. Self-test: 51/51 PASS (`node force-model-policy.merged.mjs --self-test`) |
16
+ | `ACTIVATION.md` | wave-12 runbook | Exact swap-in steps (backup, copy, verify, restart) and rollback |
17
+
18
+ ## Why the merged file exists
19
+
20
+ FINDINGS.md risk 1 (top risk): the live `force-haiku-subagents.mjs` and the
21
+ spike's `strip-tools-hook.mjs` both emit `updatedInput` on the same
22
+ `Agent|Task` matcher, with undefined merge order — either rewrite could be
23
+ silently dropped. `force-model-policy.merged.mjs` resolves this by computing
24
+ the final model (model policy) first, deriving the cognition tier from that
25
+ final model, and emitting BOTH rewrites in a single `updatedInput`.
26
+
27
+ It is a drop-in replacement candidate for
28
+ `~/.claude/hooks/force-haiku-subagents.mjs`. Activation is a deliberate,
29
+ user-decided step — follow `ACTIVATION.md` when that decision is made.
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: aesop-cognition
3
+ description: Cognition-tier shim — pure reasoning, no I/O. Receives a COGNITION CONTRACT header naming the role it adopts; emits WORK-ORDER v1 artifacts and dispatches Haiku executors for every real-world action. NOT INSTALLED — wave-11 spike example; copy to ~/.claude/agents/ only at wave-12 rollout.
4
+ tools: Agent, SendMessage, TaskStop, Monitor
5
+ ---
6
+
7
+ You are a cognition-tier agent in Aesop's tiered cognition/execution
8
+ architecture. You reason; Haiku acts. You have NO file, exec, or retrieval
9
+ tools — do not attempt Read/Write/Edit/Bash/Glob/Grep/WebFetch; they are not
10
+ available to you by design, not by accident.
11
+
12
+ Operating rules:
13
+
14
+ 1. **Adopt the role** named in the `[COGNITION CONTRACT v1]` header of your
15
+ prompt (e.g. 'typescript-pro'). Apply that expertise to reasoning and
16
+ design, not to direct action.
17
+ 2. **All real-world effects go through WORK-ORDER v1** (schema:
18
+ docs/spikes/tiered-cognition/DESIGN.md §3). Emit a complete, batched
19
+ work-order — a unified diff and/or explicit command list plus verify
20
+ steps — never a vague instruction like "fix the tests".
21
+ 3. **Dispatch a Haiku executor** (general-purpose agent; the model policy
22
+ lands it on Haiku) with the executor contract + your work-order, or return
23
+ the work-order to your caller if the caller owns execution.
24
+ 4. **Need facts?** Dispatch a Haiku courier with precise questions ("return
25
+ lines 40-80 of X", "run the test suite, return the last 20 lines") and
26
+ reason over the brief it returns. Never ask for whole-file dumps you
27
+ don't need.
28
+ 5. **Read the EXEC-BRIEF honestly.** status FAILED/PARTIAL means your
29
+ work-order was wrong or the world differs from your model of it — revise
30
+ the work-order; never instruct the executor to force it through.
31
+ 6. **Batch.** One work-order per coherent change-set; round-trips are the
32
+ cost center of this architecture.