Patch release. No API change — a drop-in upgrade from 0.18.0.
Fixed
Summarization retries panicked in debug builds. RetryConfig::delay_for_attempt documents a 1-indexed attempt and computes attempt - 1; llm_compaction.rs passed the raw 0..=max_retries loop variable, so the first retry underflowed usize. agent_loop.rs increments before calling and was correct — this was confined to compaction.
The panic landed on a detached task, so nothing surfaced: the summarization simply vanished, no briefing arrived, and compaction fell back to the deterministic tiers. If you use LlmCompaction and have seen CompactionMethod::Deterministic more often than expected on a debug build, this is a likely cause. delay_for_attempt now saturates, so a caller that misses the 1-indexed contract loses the backoff rather than the task.
A briefing rejected on fingerprint mismatch now reports what it cost. The ContextCompacted event carried summary: None, so a caller doing cost accounting off SummaryStats under-counted exactly the failure mode that wastes the most.
Added
LlmCompaction warns when briefings keep losing the race. A session whose compactions all take the deterministic path gets DefaultCompaction's retention while still issuing summarization requests it never splices. After five consecutive fallbacks it says so once, naming the likely cause; a splice that lands resets the streak and clears the latch.
The warning is gated on a request having actually been issued, so it cannot claim a cost in the inert configuration — where nothing is ever spawned and warn_inert_once already gives the correct, opposite advice.
The module docs now lead with the summarizer choice, which is the actual cause: reusing the loop's ModelConfig is the obvious call and, for a slow loop model, the worst one. Measured on the long_horizon harness at a 30K configured budget, one run each — the model is not deterministic, so read these as the shape of the effect:
| summarizer | first compaction | history retained |
|---|---|---|
| the loop's model (Sonnet 5) | Deterministic |
3 msgs / 1.7K tokens |
| a fast model (Haiku 4.5) | Summarized |
22 msgs / 16.7K tokens |
Verification
627 tests, clippy clean under -Dwarnings, all three feature combos green, live price audit 26 compared / 0 drifted.
Known
#150 — compact_headroom_turns defaults to Some(30), so any session growing faster than ~2.8% of its budget per turn pins the compaction target ratio to its MIN_HEADROOM_RATIO floor of 0.15. That is the aggression that makes compaction destructive, and changing it is a defaults change for every user that wants measurement across growth rates first.