Follow-up to the boundary clamps: drive the REAL compress() pipeline over
the live 8-message transcript shape from #75588 (system + tool-only
suffix, aligned head == len(messages)). Asserts no exception, the summary
LLM is never invoked when the window is out of range, and the transcript
is returned unchanged. Sanity-checks the clamped tail-cut boundary so a
future regression of the n+1 floor is caught even where downstream
callsite clamps mask the IndexError.
Fix#75588
## Root cause
When a short conversation ends in a tool-call/result group and the
protected head alignment reaches the end of the message list,
_find_tail_cut_by_tokens() could return len(messages) + 1. This
happened because the final return used max(cut_idx, head_end + 1)
which could push past the array length when head_end >= len(messages).
The out-of-range value then propagated into _find_context_summaries()
which iterated range(start, end) and indexed messages[idx] without
clamping, raising IndexError and failing the active gateway turn.
## Fix
Two-layer defense:
1. Source fix: _find_tail_cut_by_tokens() now clamps its return to
min(n, ...) so it never exceeds len(messages).
2. Defensive clamp: _find_context_summaries() now bounds start/end
to [0, len(messages)] so even if a future caller passes bad values,
it cannot crash.
## Verification
- 7 new regression tests for the exact boundary conditions
- All 214 existing test_context_compressor.py tests pass