Files
ai-app/server
iris 68704fce7c Ask the driver whether a command can go, not the status it reported
A `/clear` that did nothing, traced to the end. There was no race to lose:
the driver sees every line it writes and every line that comes back, so it
always knew. What it knew was being asked of the wrong thing.

Two views of "is a turn running" had grown apart. The driver's moves the
instant it writes a line; `SessionStatus` moves when output is *recorded*.
Messages ask the driver -- which is why they behave -- and commands asked
the status, which for a command is stale for its whole round trip: a
command's reply carries no assistant text, so nothing proved a turn had
started and the recorded status stayed idle from the moment it went out
until the moment it came back. A second command in that window went
straight out too, landing inside the turn the first one had started, where
the CLI reads it as text instead of running it. Nothing anywhere says so:
a command read as a message looks like a message.

So `Commands` asks `Driver::between_turns()` now, and asks again when it
releases a held one -- the recorded idle that woke it is a moment in the
past by then. `local_command` says `Running` when it writes, which is both
true and what makes the next idle a change worth recording; without it the
idle at the end of a command was equal to the idle before it, and nothing
behind it was ever released.

The other half was a turn nobody here started. The CLI picks the
conversation back up on its own -- measured: a backgrounded `sleep`
finished nine seconds after the turn's result and it began again unprompted
-- and it announces that with a `system/init` about a second and a half
before its first assistant text. We had been ignoring that line and
learning about the turn from the text, so for that second and a half the
session read as idle. It is a turn now, told apart from the `init` at
startup by the translator already having a session id, and from our own
`/clear` by `running` already being true.

Measured against the real CLI, not argued: two `/clear`s sent back to back
on one connection now record `commandSent`, `running`, `commandQueued`,
`cleared`, `idle`, `commandSent`, `cleared` -- held, then run, in order,
both of them. Before this the second was swallowed. The self-started turn
shows as `running` eleven seconds after the previous turn's idle, which is
the window a command used to disappear into.

Also measured on the way, and worth writing down: a message written into a
running turn is *folded into it* -- one `result`, `num_turns: 2`, both
things answered -- so an idle after one is honest and there was nothing to
fix there. A command written when the CLI is genuinely between turns is
executed even ten milliseconds after the result, so the boundary itself was
never the problem.
2026-08-30 01:42:47 -04:00
..