@matt82198/aesop 0.1.0-beta.3 → 0.1.0-beta.5
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 +79 -95
- package/CLAUDE-TEMPLATE.md +115 -0
- package/README.md +126 -245
- package/aesop.config.example.json +34 -26
- package/bin/CLAUDE.md +67 -0
- package/bin/cli.js +593 -36
- package/daemons/CLAUDE.md +36 -0
- package/daemons/backup-fleet.sh +92 -21
- package/daemons/run-watchdog.sh +95 -12
- package/dash/CLAUDE.md +32 -0
- package/dash/dash-extra.mjs +194 -21
- package/dash/watchdog-gui.sh +23 -6
- package/docs/BEHAVIORAL-PR-REVIEW.md +86 -0
- package/docs/CHECKPOINTING.md +100 -0
- package/docs/DISPATCH-MODEL.md +11 -7
- package/docs/FORENSICS.md +204 -0
- package/docs/GOVERNANCE.md +4 -2
- package/docs/HOOK-INSTALL.md +307 -0
- package/docs/HOW-THE-LOOP-WORKS.md +175 -0
- package/docs/MEMORY-TEMPLATE.md +61 -0
- package/docs/README.md +44 -0
- package/docs/RELEASING.md +159 -0
- package/docs/RELIABILITY.md +61 -0
- package/docs/RESTORE.md +397 -0
- package/docs/SCRIPTS-POLICY.md +97 -0
- package/docs/archive/README.md +3 -0
- package/docs/archive/spikes/tiered-cognition/ACTIVATION.md +125 -0
- package/docs/archive/spikes/tiered-cognition/DESIGN.md +287 -0
- package/docs/archive/spikes/tiered-cognition/FINDINGS.md +113 -0
- package/docs/archive/spikes/tiered-cognition/README.md +27 -0
- package/docs/archive/spikes/tiered-cognition/aesop-cognition.example.md +32 -0
- package/docs/archive/spikes/tiered-cognition/force-model-policy.merged.mjs +673 -0
- package/docs/archive/spikes/tiered-cognition/strip-tools-hook.mjs +434 -0
- package/docs/case-study-portfolio.md +61 -0
- package/docs/self-stats-data.json +11 -0
- package/docs/templates/FLEET-OPS-ANALYSIS.example.md +27 -0
- package/docs/templates/FLEET-OPS-RECOMMENDATIONS.example.md +24 -0
- package/docs/templates/PROPOSALS-LOG.example.md +64 -0
- package/hooks/CLAUDE.md +61 -0
- package/hooks/claude/force-model-policy.mjs +159 -0
- package/hooks/pre-push-policy.sh +753 -0
- package/mcp/CLAUDE.md +213 -0
- package/mcp/package.json +26 -0
- package/mcp/server.mjs +543 -0
- package/monitor/.signal-state.json +3 -0
- package/monitor/ACTIONS.log +1 -0
- package/monitor/BRIEF.md +24 -0
- package/monitor/CHARTER.md +75 -88
- package/monitor/CLAUDE.md +40 -0
- package/monitor/SIGNALS.json +54 -0
- package/monitor/collect-signals.mjs +613 -61
- package/package.json +15 -3
- package/scan/fleet-scan.example.mjs +292 -0
- package/skills/CLAUDE.md +3 -0
- package/skills/healthcheck/SKILL.md +44 -0
- package/skills/power/SKILL.md +161 -0
- package/state_store/CLAUDE.md +39 -0
- package/state_store/__init__.py +24 -0
- package/state_store/__pycache__/__init__.cpython-314.pyc +0 -0
- package/state_store/__pycache__/api.cpython-314.pyc +0 -0
- package/state_store/__pycache__/export.cpython-314.pyc +0 -0
- package/state_store/__pycache__/ingest.cpython-314.pyc +0 -0
- package/state_store/__pycache__/projections.cpython-314.pyc +0 -0
- package/state_store/__pycache__/store.cpython-314.pyc +0 -0
- package/state_store/api.py +35 -0
- package/state_store/export.py +19 -0
- package/state_store/ingest.py +24 -0
- package/state_store/projections.py +52 -0
- package/state_store/store.py +102 -0
- package/tools/CLAUDE.md +72 -0
- package/tools/__pycache__/alert_bridge.cpython-314.pyc +0 -0
- package/tools/__pycache__/buildlog.cpython-314.pyc +0 -0
- package/tools/__pycache__/ci_merge_wait.cpython-314.pyc +0 -0
- package/tools/__pycache__/ensure_state.cpython-314.pyc +0 -0
- package/tools/__pycache__/eod_sweep.cpython-314.pyc +0 -0
- package/tools/__pycache__/fleet_ledger.cpython-314.pyc +0 -0
- package/tools/__pycache__/fleet_prompt_extractor.cpython-314.pyc +0 -0
- package/tools/__pycache__/healthcheck.cpython-314.pyc +0 -0
- package/tools/__pycache__/heartbeat.cpython-314.pyc +0 -0
- package/tools/__pycache__/inbox_drain.cpython-314.pyc +0 -0
- package/tools/__pycache__/launch_tui.cpython-314.pyc +0 -0
- package/tools/__pycache__/metrics_gate.cpython-314.pyc +0 -0
- package/tools/__pycache__/orchestrator_status.cpython-314.pyc +0 -0
- package/tools/__pycache__/power_selftest.cpython-314.pyc +0 -0
- package/tools/__pycache__/prepublish_scan.cpython-314.pyc +0 -0
- package/tools/__pycache__/rotate_logs.cpython-314.pyc +0 -0
- package/tools/__pycache__/scanner_selftest.cpython-314.pyc +0 -0
- package/tools/__pycache__/secret_scan.cpython-314.pyc +0 -0
- package/tools/__pycache__/self_stats.cpython-314.pyc +0 -0
- package/tools/__pycache__/session_usage_summary.cpython-314.pyc +0 -0
- package/tools/__pycache__/stall_check.cpython-314.pyc +0 -0
- package/tools/__pycache__/transcript_replay.cpython-314.pyc +0 -0
- package/tools/__pycache__/transcript_timeline.cpython-314.pyc +0 -0
- package/tools/__pycache__/verify_dash.cpython-314.pyc +0 -0
- package/tools/__pycache__/verify_submit_encoding.cpython-314.pyc +0 -0
- package/tools/agent-forensics.sh +186 -0
- package/tools/alert_bridge.py +449 -0
- package/tools/buildlog.py +182 -0
- package/tools/ci_merge_wait.py +317 -0
- package/tools/ensure_state.py +94 -0
- package/tools/eod_sweep.py +239 -0
- package/tools/fleet_ledger.py +272 -0
- package/tools/fleet_prompt_extractor.py +134 -0
- package/tools/healthcheck.py +296 -0
- package/tools/heartbeat.py +131 -0
- package/tools/inbox_drain.py +249 -0
- package/tools/launch_tui.py +51 -3
- package/tools/lock.mjs +211 -0
- package/tools/metrics_gate.py +205 -0
- package/tools/orchestrator_status.py +99 -0
- package/tools/power_selftest.py +386 -0
- package/tools/prepublish_scan.py +84 -0
- package/tools/proposals.mjs +248 -0
- package/tools/reconstitute.sh +467 -0
- package/tools/rotate_logs.py +228 -0
- package/tools/scanner_selftest.py +303 -0
- package/tools/secret_scan.py +138 -31
- package/tools/self_stats.py +509 -0
- package/tools/session_usage_summary.py +198 -0
- package/tools/stall_check.py +172 -0
- package/tools/svg_to_png.mjs +50 -0
- package/tools/transcript_replay.py +236 -0
- package/tools/transcript_timeline.py +184 -0
- package/tools/verify_dash.py +513 -0
- package/tools/verify_submit_encoding.py +202 -0
- package/ui/CLAUDE.md +125 -0
- package/ui/__pycache__/agents.cpython-314.pyc +0 -0
- package/ui/__pycache__/collectors.cpython-314.pyc +0 -0
- package/ui/__pycache__/config.cpython-314.pyc +0 -0
- package/ui/__pycache__/cost.cpython-314.pyc +0 -0
- package/ui/__pycache__/csrf.cpython-314.pyc +0 -0
- package/ui/__pycache__/handler.cpython-314.pyc +0 -0
- package/ui/__pycache__/render.cpython-314.pyc +0 -0
- package/ui/__pycache__/serve.cpython-314.pyc +0 -0
- package/ui/__pycache__/sse.cpython-314.pyc +0 -0
- package/ui/agents.py +183 -0
- package/ui/api/__init__.py +84 -0
- package/ui/api/__pycache__/__init__.cpython-314.pyc +0 -0
- package/ui/api/__pycache__/submit.cpython-314.pyc +0 -0
- package/ui/api/__pycache__/tracker.cpython-314.pyc +0 -0
- package/ui/api/submit.py +97 -0
- package/ui/api/tracker.py +116 -0
- package/ui/collectors.py +735 -0
- package/ui/config.py +123 -0
- package/ui/cost.py +260 -0
- package/ui/csrf.py +144 -0
- package/ui/handler.py +676 -0
- package/ui/render.py +49 -0
- package/ui/serve.py +68 -796
- package/ui/sse.py +183 -0
- package/ui/web/.gitattributes +13 -0
- package/ui/web/dist/assets/index-2LZDQirC.js +9 -0
- package/ui/web/dist/assets/index-D4M1qyOv.css +1 -0
- package/ui/web/dist/index.html +14 -0
- package/ui/web/index.html +13 -0
- package/ui/web/package-lock.json +2225 -0
- package/ui/web/package.json +26 -0
- package/ui/web/src/App.test.tsx +74 -0
- package/ui/web/src/App.tsx +142 -0
- package/ui/web/src/CONTRIBUTING-UI.md +49 -0
- package/ui/web/src/components/AgentRow.css +187 -0
- package/ui/web/src/components/AgentRow.test.tsx +209 -0
- package/ui/web/src/components/AgentRow.tsx +207 -0
- package/ui/web/src/components/AgentsPanel.css +108 -0
- package/ui/web/src/components/AgentsPanel.test.tsx +41 -0
- package/ui/web/src/components/AgentsPanel.tsx +58 -0
- package/ui/web/src/components/AlertsPanel.css +88 -0
- package/ui/web/src/components/AlertsPanel.test.tsx +51 -0
- package/ui/web/src/components/AlertsPanel.tsx +67 -0
- package/ui/web/src/components/BacklogPanel.test.tsx +126 -0
- package/ui/web/src/components/BacklogPanel.tsx +122 -0
- package/ui/web/src/components/CostChart.css +110 -0
- package/ui/web/src/components/CostChart.test.tsx +144 -0
- package/ui/web/src/components/CostChart.tsx +152 -0
- package/ui/web/src/components/CostTable.css +93 -0
- package/ui/web/src/components/CostTable.test.tsx +165 -0
- package/ui/web/src/components/CostTable.tsx +94 -0
- package/ui/web/src/components/EventsFeed.css +68 -0
- package/ui/web/src/components/EventsFeed.test.tsx +36 -0
- package/ui/web/src/components/EventsFeed.tsx +31 -0
- package/ui/web/src/components/HealthHeader.css +137 -0
- package/ui/web/src/components/HealthHeader.test.tsx +278 -0
- package/ui/web/src/components/HealthHeader.tsx +281 -0
- package/ui/web/src/components/InboxForm.css +135 -0
- package/ui/web/src/components/InboxForm.test.tsx +208 -0
- package/ui/web/src/components/InboxForm.tsx +116 -0
- package/ui/web/src/components/MessagesTail.module.css +144 -0
- package/ui/web/src/components/MessagesTail.test.tsx +176 -0
- package/ui/web/src/components/MessagesTail.tsx +94 -0
- package/ui/web/src/components/ReposPanel.css +90 -0
- package/ui/web/src/components/ReposPanel.test.tsx +45 -0
- package/ui/web/src/components/ReposPanel.tsx +67 -0
- package/ui/web/src/components/Scorecard.css +106 -0
- package/ui/web/src/components/Scorecard.test.tsx +117 -0
- package/ui/web/src/components/Scorecard.tsx +85 -0
- package/ui/web/src/components/Timeline.module.css +151 -0
- package/ui/web/src/components/Timeline.test.tsx +215 -0
- package/ui/web/src/components/Timeline.tsx +99 -0
- package/ui/web/src/components/TrackerBoard.test.tsx +121 -0
- package/ui/web/src/components/TrackerBoard.tsx +107 -0
- package/ui/web/src/components/TrackerCard.test.tsx +180 -0
- package/ui/web/src/components/TrackerCard.tsx +160 -0
- package/ui/web/src/components/TrackerForm.test.tsx +189 -0
- package/ui/web/src/components/TrackerForm.tsx +144 -0
- package/ui/web/src/lib/api.ts +218 -0
- package/ui/web/src/lib/format.test.ts +89 -0
- package/ui/web/src/lib/format.ts +103 -0
- package/ui/web/src/lib/sanitizeUrl.test.ts +84 -0
- package/ui/web/src/lib/sanitizeUrl.ts +38 -0
- package/ui/web/src/lib/types.ts +230 -0
- package/ui/web/src/lib/useHashRoute.test.ts +60 -0
- package/ui/web/src/lib/useHashRoute.ts +23 -0
- package/ui/web/src/lib/useSSE.ts +175 -0
- package/ui/web/src/main.tsx +10 -0
- package/ui/web/src/styles/global.css +179 -0
- package/ui/web/src/styles/theme.css +184 -0
- package/ui/web/src/styles/work.css +572 -0
- package/ui/web/src/test/fixtures.ts +385 -0
- package/ui/web/src/test/setup.ts +49 -0
- package/ui/web/src/views/Activity.module.css +43 -0
- package/ui/web/src/views/Activity.test.tsx +89 -0
- package/ui/web/src/views/Activity.tsx +31 -0
- package/ui/web/src/views/Cost.css +87 -0
- package/ui/web/src/views/Cost.test.tsx +142 -0
- package/ui/web/src/views/Cost.tsx +54 -0
- package/ui/web/src/views/Overview.css +51 -0
- package/ui/web/src/views/Overview.test.tsx +76 -0
- package/ui/web/src/views/Overview.tsx +46 -0
- package/ui/web/src/views/Work.test.tsx +82 -0
- package/ui/web/src/views/Work.tsx +79 -0
- package/ui/web/src/vite-env.d.ts +10 -0
- package/ui/web/tsconfig.json +22 -0
- package/ui/web/vite.config.ts +25 -0
- package/ui/web/vitest.config.ts +12 -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,27 @@
|
|
|
1
|
+
# Tiered Cognition/Execution — spike + staged wave-12 artifact
|
|
2
|
+
|
|
3
|
+
> **STATUS: CANCELLED 2026-07-14** after A/B testing measured 4.6x weighted cost for identical quality (see MEMORY.md wave-11 entry). Kept for reference; do not activate. Nothing in this directory is wired into `~/.claude/settings.json` or `~/.claude/hooks/`. The live model-policy hook (`force-haiku-subagents.mjs`) is untouched and still governs the fleet.
|
|
4
|
+
|
|
5
|
+
## Contents
|
|
6
|
+
|
|
7
|
+
| File | Status | What |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| `DESIGN.md` | wave-11 spike | Architecture, hook mechanism, WORK-ORDER/EXEC-BRIEF schemas, executed round-trip |
|
|
10
|
+
| `FINDINGS.md` | wave-11 spike | GO (conditional) verdict, risks, phased rollout plan |
|
|
11
|
+
| `strip-tools-hook.mjs` | wave-11 prototype | Tier policy alone (superseded by the merged file below) |
|
|
12
|
+
| `aesop-cognition.example.md` | example, not installed | Message-only shim agent definition the merged hook rewrites to |
|
|
13
|
+
| **`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`) |
|
|
14
|
+
| `ACTIVATION.md` | wave-12 runbook | Exact swap-in steps (backup, copy, verify, restart) and rollback |
|
|
15
|
+
|
|
16
|
+
## Why the merged file exists
|
|
17
|
+
|
|
18
|
+
FINDINGS.md risk 1 (top risk): the live `force-haiku-subagents.mjs` and the
|
|
19
|
+
spike's `strip-tools-hook.mjs` both emit `updatedInput` on the same
|
|
20
|
+
`Agent|Task` matcher, with undefined merge order — either rewrite could be
|
|
21
|
+
silently dropped. `force-model-policy.merged.mjs` resolves this by computing
|
|
22
|
+
the final model (model policy) first, deriving the cognition tier from that
|
|
23
|
+
final model, and emitting BOTH rewrites in a single `updatedInput`.
|
|
24
|
+
|
|
25
|
+
It is a drop-in replacement candidate for
|
|
26
|
+
`~/.claude/hooks/force-haiku-subagents.mjs`. Activation is a deliberate,
|
|
27
|
+
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.
|