Fourth pipeline stage — non-destructive view-time projection.
Claude Code's CONTEXT_COLLAPSE doesn't drop messages from
state.messages; it builds a projected view used only for the
next model request. The original conversation stays intact (so
resume / replay / rewind don't lose anything), but the model sees a
shrunk picture that elides redundancy.
Patterns we collapse here:
- Superseded reads: when an
Editmodifies a file that an earlierReadreturned in full, theReadbody is replaced with a short stub that names the file. The model already used the read result; the post-edit content is what matters now. - Repeated identical tool calls: same tool name + identical arguments executed N consecutive times collapses to "(Nx) <call>".
The projection is stored at state.meta[:compact_view] — a list of
messages the request builder uses on the next iteration in place of
state.messages. The actual message list is never modified.
Why non-destructive?
Storage / resume / sidechain replay (PR4 + PR5) care about the
authoritative event log; rewriting state.messages would corrupt
the session JSONL. Projection-only keeps both consumers happy.