Files
orca/src/shared/__fixtures__
Brennan Benson 2ce252f471 fix(grok): announce a completion once, when Grok is actually finished (#20523)
* fix(grok): announce a completion once, when Grok is actually finished

Orca pinged on every Grok turn-end. Grok runs turns the user never asked for:
when a background task finishes it wakes itself, does a little work, and ends
another turn. One request produced several pings.

Grok already reports, on every turn-end, whether it still has work outstanding.
Read that instead of trying to classify which turns are "real":

  backgroundTasks absent          -> silent, this is the session-end tail
  StopFailure / StopCancelled     -> announce, a failure is never hidden
  stopHookActive                  -> silent, a Stop hook is keeping it working
  a shell task or subagent running -> silent, the work is not done
  otherwise                       -> announce

Nothing here knows what an auto-wake turn is. A turn that ends with work
outstanding stays quiet; the later turn where that work is finally done is the
one that announces. That is also why this survives the case where Grok completes
a user's goal inside one of those turns — prefix-based suppression would have
silenced it.

Monitors and scheduled entries are deliberately not counted as outstanding work.
They can run indefinitely, so counting them would suppress a user's completion
permanently, and a lost ping is worse than an extra one.

Also registers StopCancelled, which Grok fires instead of Stop on a user
interrupt, a declined permission, --max-turns, or a no-progress bail-out. Orca
never subscribed to it, so those turns were reported as successes.

Also removes a stale notification matcher that searched for prose the shipping
binary never sends; the typed notification kind is matched instead, and neither
idle_prompt nor task_complete is treated as a completion.

Needs-input behaviour (permission prompts and ask_user_question waits) is
unchanged and stays ungated by background work.

* fix(grok): never hide a failed or cancelled turn behind the background-work gate

The announce predicate checked field-absence before terminal outcome. Grok's
StopFailure and StopCancelled payloads carry no background inventory at all, so
the absent-field branch — added so the session-end tail stays silent — fired
first and silenced every failure and every cancellation.

That inverted the rule it was meant to serve. Before this series a cancelled turn
at least surfaced as a (wrong) success; gated this way it surfaced as nothing.

Terminal outcome is now checked first, so a failure or cancellation announces
regardless of what other fields the payload happens to carry.

The existing tests passed straight through the bug because they built failure
payloads with a backgroundTasks field Grok never sends for those events. They now
model the real payload shapes, verified against the provider's payload
definitions and the captured envelopes.

* fix(grok): settle completion from provider lifecycle state

* fix(grok): fence stale turn ends without prompt ids
2026-09-13 21:09:01 -07:00
..