# 0.10.1 — Cost-trajectory hardening: tweedles out of M8 + tool-result cap

Two focused substrate fixes shipped from a full cost-driver analysis on obol-260522-1. Together estimated at **28-35% cost reduction on $92.64 baseline** (combined ~$26-32/pilot savings).

The analysis itself (`paper/artifacts/caterpillar-m8-cost-analysis.md`) is the paper-grade work — six parts walking through per-meeting decomposition, per-agent breakdowns, act/pass signal as overhead-vs-work discriminator, the cache-interpretation gotcha that flipped the initial framing, and cross-agent savings projections. The two fixes below are what landed; the artifact documents the methodology.

**T-ab54** removes tweedles from M8 review roster. They were the dominant M8 cost driver (2.2× Caterpillar's spend) at 80% pass rate — pure window-opening overhead since the meeting's actual work is Caterpillar's verdict. Their M7 implementation summaries + contract notes still seed into M8 via existing bindings, so review context is preserved.

**T-ab57** caps tool-result size at 5K chars in the agent deliberation loop. Each tool result lives in `loop_messages` for the rest of the deliberation, so a 35K-byte grep or 65K git_diff multiplies its cost across many subsequent cache_read cycles. The cap is a forcing function for targeted tool use (line ranges, narrower patterns) — the truncation marker actively tells the model how to recover dropped content. Helps ALL tool-using agents: 52% of total tool-result bytes saved, with Mad Hatter benefiting proportionally MORE than tweedles (his test-writing pattern hits the grep long-tail hardest).

Cumulative arc: original substrate baseline → mvp-demo2 (~$83) → mvp-demo-rerun-A ($79.71) → projected post-T-ab57 pilot (~$50-60 worst case).

**Invisible savings worth flagging**: the $50-60 estimate assumes prior pilots' rerun-cycle cost as baseline. obol-260522-1 hit $92.64 in part because cross-milestone bleed (closed in 0.10.0 via T-ab51) forced many design reruns. A clean post-0.10.0 + 0.10.1 pilot should see design phases pass on first attempt — eliminating the rerun-bug cost component entirely. The design-phase decomposition shows a clean-pass at $1.16 fixed + $0.42/feature × N features = ~$8-10 for an 18-feature app, vs the $21 obol-260522-1 actually paid (most of which was rerun overhead). Same logic applies to implement-phase reruns from substrate bugs we've since fixed.

A clean-pass mvp-demo equivalent could plausibly land closer to **$40** when you add the rerun-elimination savings on top of T-ab54 + T-ab57 efficiency gains. Substrate moving toward cost regime where multi-agent overhead is sized for the quality artifacts (test coverage, ADRs, contract notes, per-feature reviews) rather than the same work done expensively.

---

## M8 review roster narrowed to Caterpillar-only (T-ab54)

obol-260522-1 cost analysis (`paper/artifacts/caterpillar-m8-cost-analysis.md`) found tweedles were the dominant M8 review cost driver — **$15.60 vs Caterpillar's $7.13 across 29 review threads**, a 2.2× ratio. Tweedles passed 80% of their M8 priority windows but each window paid full compose_context + tool-loop cost (~$0.012/window with ~22 calls per window from cache_creation + tool exploration). The 20% acting case did produce meaningful artifacts (implementation summaries + contract_note finalizations) but the 80% silent case was pure overhead.

The tdd-implement YAML already noted the design intent: tweedles were meant to "buzz in without a standing roster slot" via the §III selectively-engaging rule. But the M8 roster had drifted to `[caterpillar, tweedledee, tweedledum]` with `team_groupings: [[caterpillar, tweedledee, tweedledum]]` (concurrent Two-Headed Giant windows), so tweedles got guaranteed priority windows regardless of whether they had something to add.

Fix: roster narrowed to `[caterpillar]`; team_groupings removed (single-member team gets the default one-agent-per-team behavior). Caterpillar's review context is unchanged — tweedles' M7 implementation summaries + contract_notes still seed into M8 via the existing `from: implementation kinds: [implementation]` and `kinds: [contract_note]` bindings. If tweedles spot a misreading in Caterpillar's verdict they can publish a concern to the bus from outside the meeting (§III opt-in path), landing as cross-meeting input rather than guaranteed-window cost.

Also validated as part of the same analysis: **T-ab39's `memory_scope: meeting_only`** is working as intended. Caterpillar's M8 per-call cache_creation_input_tokens median stays at 500–850 across all milestones (M1–M6 in the pilot). Cost driver is call volume (tool-loop iteration), not per-call context bloat.

**Estimated impact on next pilot**: M8 cost drops from ~$1.00–$1.50 per feature to ~$0.30–$0.50 per feature. At ~18 features per pilot, $12–$18 saved per pilot. Compounds with the 0.10.0 cross-milestone-bleed fixes for a materially flatter per-milestone cost trajectory.

**Receipt check needed on next pilot**: confirm review quality holds without tweedles in the room. Easiest check is adversarial-review parity against obol-260522-1 baselines on shipped feature artifacts. If quality drops, the answer might be Lever B (sequential team_groupings) instead — tweedles still get windows but see Caterpillar's verdict first and can pass cheaper.

## Tool-result truncation in deliberation loop (T-ab57)

obol-260522-1 cost analysis (`paper/artifacts/caterpillar-m8-cost-analysis.md`, Parts 5+6) traced a non-obvious M7 cost driver. The episodic-memory hypothesis (operator suspicion) fell on investigation: 99-100% of stored thread content is seeds, and T-ab25a's `memory_scope: meeting_only` already filters those out of compose_context. The 30K cache_read median per call came from somewhere else — the deliberation tool loop itself.

Reading `agent.py:1000-1066`: the tool loop appends each `{assistant, user(tool_results)}` pair to `loop_messages` for the rest of the deliberation. A 35K-byte grep result lives in every subsequent LLM call's message list within that deliberation. Tweedles average ~13 LLM calls per deliberation; by call 10 the message list carries 9 prior tool_result blocks. The cache_read amplification is real and per-deliberation.

Tool-result size distribution across all tool-using agents in obol-260522-1:

| Tool | Median | p90 | Total bytes |
|---|---|---|---|
| read_file | 1,806 | 9,375 | 14.6 MB |
| grep | 316 | 35,716 | 9.1 MB |
| git_diff | 3,812 | 65,578 | 2.0 MB |
| list_files | 496 | 5,707 | 3.4 MB |

Long-tail dominates — single-call results above 5K account for **53% of total stored tool-result bytes** across the pilot.

Fix: `agent.py` adds `_maybe_truncate_tool_result(content, tool_name)` called inline before `tool_results.append`:
- Cap: 5,000 chars
- Head-preserve strategy (most tool outputs front-load useful info — grep matches, file content from line 1)
- Append marker: `[truncated N bytes for context budget. If load-bearing, re-run <tool> with narrower scope (e.g. line range, more specific pattern).]`
- Non-string content passes through unchanged (defensive)

The marker actively educates the model to use narrower args on retries — read_file supports line ranges, grep accepts narrower patterns, list_files can target sub-directories. The cap is a forcing function for targeted tool use over dump-everything.

Cross-agent savings (5K cap):

| Agent | Calls | Saved | % |
|---|---|---|---|
| tweedledum | 3,548 | 6.3 MB | 52% |
| tweedledee | 3,334 | 6.0 MB | 52% |
| mad_hatter | 901 | 2.1 MB | **59%** |
| caterpillar | 1,173 | 2.1 MB | **53%** |
| **TOTAL** | **9,058** | **16.5 MB = 4.1M tokens** | **53%** |

Two non-obvious findings: (a) Mad Hatter saves proportionally MORE than tweedles — his M6 test-writing pattern hits the grep long-tail hardest; (b) Caterpillar's biggest savings come from git_diff in M8 reviews (1.2 MB alone).

Estimated savings: **$12-18/pilot** (direct LLM cost + indirect from less model distraction → fewer iterations needed). On obol-260522-1's $92.64 baseline, combined with T-ab54's ~$15: **$26-32/pilot = 28-35% reduction**.

3 regression tests cover small-result passthrough, oversized truncation + marker shape + tool name reference, non-string defensive handling.

Open follow-ups parked: per-tool smarter truncation (grep first-N + count; git_diff most-recent files; pytest failure-summaries-only) is worth doing if 5K flat cap proves insufficient on next pilot. The "no episodic memory in M7" experiment (operator hypothesis) is also still on the table as a post-pilot A/B.
