Three things a phone could not see, all of them the same shape: the
session was doing something and nothing on screen said so.
A turn nobody here started never reported itself. `Running` was sent
where a message was *sent*, so a session picked up mid-turn, one
compacting on its own, or one another agent wrote to sat there reading
as idle until it finished. The driver now says it from what it observes
-- output that could only come from a turn in flight -- which is the
same set of events that already announced a steer, with the ends
swapped.
An imported session had it worse: nothing but replayed lines ever
reaches it, and a status was not among them, so it was permanently
whatever it was when it was adopted. Its file does not record a turn
ending, but it does record why each assistant message stopped, and
`tool_use` versus anything else answers it. A record that says nothing
leaves the status alone rather than voting for idle.
Messages from other agents were dropped outright: the CLI marks them
meta, and this replayed everything except meta. They are now a row of
their own, closed by default like a tool call, named for the session
that sent it -- not the reader's own bubble, because they did not say
it, and a session working on something this phone never asked for is
exactly what one of these explains.
Measured against a real session file rather than guessed: the peer
record carries the sender's name and the message body in `origin`,
beside a copy wrapped for the model to read.
The Compacting status had been declared, rendered in four places, and
never once emitted: no driver produced it, and the app had no control to
ask for a compaction in the first place. Pressing nothing for two
minutes and then quietly having less context was the whole experience.
The CLI turns out to announce all of it, which was worth measuring
rather than guessing at. Driven through /compact against 2.1.237 it
emits a `status: "compacting"` line at the start, a `status: null`
carrying `compact_result` at the end -- `"failed"` with a sentence
saying why, when it does -- and then a `compact_boundary` with the token
counts. The same records appear in the CLI's own transcript file with
camelCase keys, which is the obvious place to read the shape off and
gets every field name wrong.
So none of it is inferred here. The driver writes the line and says
nothing; the translator reports what the CLI reports. A failed
compaction surfaces the CLI's own sentence, which is specific enough to
act on.
The counts are the part worth keeping afterwards, so they land in the
transcript rather than only in a status that vanishes: a session that
went from 128,402 tokens to 9,617 has just been given its context back.
They are optional throughout, because a compaction whose size nobody
reported has to be able to say so -- a zero would read as "recovered
nothing".
Also here, all found on the way:
- `rename_all` renames variants; fields need `rename_all_fields`. Every
field in Event was a single word until `pre_tokens`, which went out as
snake_case, was not found by the app, and rendered as the "no counts
reported" case -- a state it is allowed to be in, so nothing looked
wrong. There is now a test on the wire names.
- The unparseable-line warning sliced bytes, not chars, on output that
is full of em dashes. A panic there kills the task reading the
session's stdout, and the session goes deaf with nothing on screen.
The other three truncations in the tree already did this correctly.
- Echo compacts too, with invented numbers and a real shape, so this
screen can be looked at without spending two minutes of somebody's
account to reach the state.