Skip to content

health-check: add voice-transport probe for Gemini Live close errors - #258

Merged
sonichi merged 1 commit into
mainfrom
fix/health-check-voice-transport-probe
Apr 10, 2026
Merged

sonichi merged 1 commit into
mainfrom
fix/health-check-voice-transport-probe

Conversation

@sonichi

@sonichi sonichi commented Apr 9, 2026 •

Copy link
Copy Markdown
Owner

Summary

Closes a visibility gap exposed by the Gemini 3.1 dry-run earlier today. When I unpinned `VOICE_NATIVE_AUDIO_MODEL` to `gemini-3.1-flash-live-preview`, bodhi hit close code 1011 "exceeded your current quota" within 12 seconds of boot. Every existing health check still said ok: port 9900 listening, watchers registered (#250), bodhi uptime normal, startup banner present. The probe layer couldn't see the upstream transport failure. I found it only by manually tailing `voice-agent.log`.

This PR adds `check_voice_transport` that scans the log from the most recent `Sutando — Voice Interface` banner forward and reports the tail state of the Gemini transport.

Reports

State Status Detail
Latest event is `Gemini setup complete` `ok` no recent transport errors
Abnormal close followed by `setup complete` `ok` transport recovered after earlier error
Abnormal close with no recovery `fail` unrecovered transport close: code=N reason=...

Healthy close codes (don't flag)

Failure modes it catches

  • `1011` Gemini quota exhaustion / tier restriction (the 3.1 case I hit today)
  • `1007` "Request contains an invalid argument" — the CLOSED→CLOSED state-machine wedge I saw in the log this morning before the bodhi PR Add demo video to README #1 fixes landed
  • `1006` abnormal / network drop

Wiring

Placed right after `check_voice_watchers` so the voice-agent block in the health report is contiguous:

```
✓ voice-agent ok port 9900
✓ voice-watchers ok all 3 watchers active
✓ voice-transport ok no recent transport errors
```

Same degradation as `check_voice_watchers`: `warn` when voice-agent is down, `warn` if log is missing, `warn` if no banner found.

Test plan

  • Live check on current clean-boot voice-agent → `ok`
  • 6-case simulated-log harness (all pass):
    1. Clean boot with `setup complete` → `ok`
    2. Boot → 1011 unrecovered → `fail` with code+reason in detail
    3. Boot → 1011 → `setup complete` (auto-recovery) → `ok "recovered after earlier error"`
    4. Normal `code=1000` close → `ok` (not flagged)
    5. Custom `code=4000` goodbye → `ok` (not flagged)
    6. `code=1007` wedge unrecovered → `fail` with code+reason

Related

🤖 Generated with Claude Code

Fixes #390

During the Gemini 3.1 dry-run earlier today, bodhi hit a close code
1011 "exceeded your current quota" within 12 seconds of boot. Every
existing health check still said ok (port 9900 listening, watchers
registered, bodhi uptime normal, startup banner present) — the probe
layer couldn't see the upstream transport failure. I found it only by
manually tailing voice-agent.log.

Adds check_voice_transport: scans voice-agent.log from the most recent
"Sutando — Voice Interface" banner forward, tracks the tail state of
the Gemini transport. Reports:
- ok "no recent transport errors" when the latest event is
  "Gemini setup complete" with no abnormal close after it
- ok "transport recovered after earlier error" when an abnormal close
  was followed by a successful setup (auto-recovery worked)
- fail "unrecovered transport close: code=N reason=..." when the
  latest transport event is an abnormal close with no recovery

Healthy close codes: 1000 (normal), 4000 (sutando custom goodbye
disconnect, bodhi fork commit 44172b8). Everything else is flagged.

Catches:
- code=1011 Gemini quota exhaustion / tier restriction
- code=1007 "Request contains an invalid argument" (CLOSED→CLOSED
  state machine wedge — the exact pattern I saw earlier today before
  the bodhi PR #1 fixes landed)
- code=1006 abnormal / network drop

Wired into run_all_checks right after check_voice_watchers so the
voice-agent block in the report is contiguous:
  voice-agent         ok   port 9900
  voice-watchers      ok   all 3 watchers active
  voice-transport     ok   no recent transport errors

Test plan:
- ✓ Live check on current clean-boot voice-agent → ok
- ✓ 6-case simulated-log harness covering: clean boot, 1011 unrecovered,
  1011 recovered, 1000 normal close, 4000 custom goodbye, 1007 wedge
  unrecovered. All correct.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@sonichi
sonichi merged commit 0bb5237 into main Apr 10, 2026
1 check passed
@sonichi
sonichi deleted the fix/health-check-voice-transport-probe branch April 10, 2026 00:15
sonichi added a commit that referenced this pull request Apr 10, 2026
Fixes a false positive in the voice-transport probe (#258). Observed
live 2026-04-09 at 03:30: voice-agent sat idle for ~10 minutes, then:

  03:29:46 [VoiceSession] GoAway from Gemini (timeLeft=50s)
  03:30:46 [VoiceSession] Transport closed (state=ACTIVE code=1011
    reason="The service is currently unavailable.")
  03:30:46 [VoiceSession] Gemini disconnected — will reconnect fresh
    when client connects

That's Google's normal idle-timeout path: Gemini Live fires a GoAway
60s warning, then closes the transport with code=1011 and a
"service is currently unavailable" reason. The bodhi session
transitions to CLOSED and waits for the next client connect. When a
client comes back, `handleClientConnected` reconnects fresh. Not a
failure, just the expected lifecycle for an idle voice-agent.

The probe was flagging every 1011-after-idle as `fail` with
"unrecovered transport close" — which trains users to ignore the
signal exactly when we need them to trust it (real 1011s from #259
duplicate-tool or #262 googleSearch misconfig get lost in the noise).

Fix: track a `goaway_before_close` flag that flips true on GoAway
and false on setup complete. Abnormal closes while the flag is
true get reclassified as expected idle-timeouts (not flagged). The
flag also clears on setup complete so a RECOVERED idle timeout
followed by a fresh unrelated 1011 still correctly fails.

Test plan:
- ✓ Live probe on current log (has idle-timeout 1011 from 03:30):
  voice-transport ok
- ✓ 4-case simulated-log harness:
  1. GoAway → 1011 "service unavailable" unrecovered → ok (was fail)
  2. Unrecovered 1011 quota, no GoAway preceding → fail (as before)
  3. GoAway → 1011 → setup complete (reconnected) → ok
  4. Recovered idle-timeout + fresh 1011 with no new GoAway → fail
     (proves the flag correctly resets on setup complete)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
sonichi added a commit that referenced this pull request Apr 10, 2026
)

Fixes a false positive in the voice-transport probe (#258). Observed
live 2026-04-09 at 03:30: voice-agent sat idle for ~10 minutes, then:

  03:29:46 [VoiceSession] GoAway from Gemini (timeLeft=50s)
  03:30:46 [VoiceSession] Transport closed (state=ACTIVE code=1011
    reason="The service is currently unavailable.")
  03:30:46 [VoiceSession] Gemini disconnected — will reconnect fresh
    when client connects

That's Google's normal idle-timeout path: Gemini Live fires a GoAway
60s warning, then closes the transport with code=1011 and a
"service is currently unavailable" reason. The bodhi session
transitions to CLOSED and waits for the next client connect. When a
client comes back, `handleClientConnected` reconnects fresh. Not a
failure, just the expected lifecycle for an idle voice-agent.

The probe was flagging every 1011-after-idle as `fail` with
"unrecovered transport close" — which trains users to ignore the
signal exactly when we need them to trust it (real 1011s from #259
duplicate-tool or #262 googleSearch misconfig get lost in the noise).

Fix: track a `goaway_before_close` flag that flips true on GoAway
and false on setup complete. Abnormal closes while the flag is
true get reclassified as expected idle-timeouts (not flagged). The
flag also clears on setup complete so a RECOVERED idle timeout
followed by a fresh unrelated 1011 still correctly fails.

Test plan:
- ✓ Live probe on current log (has idle-timeout 1011 from 03:30):
  voice-transport ok
- ✓ 4-case simulated-log harness:
  1. GoAway → 1011 "service unavailable" unrecovered → ok (was fail)
  2. Unrecovered 1011 quota, no GoAway preceding → fail (as before)
  3. GoAway → 1011 → setup complete (reconnected) → ok
  4. Recovered idle-timeout + fresh 1011 with no new GoAway → fail
     (proves the flag correctly resets on setup complete)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
liususan091219 pushed a commit to liususan091219/sutando-fork that referenced this pull request May 28, 2026
…onichi#258)

During the Gemini 3.1 dry-run earlier today, bodhi hit a close code
1011 "exceeded your current quota" within 12 seconds of boot. Every
existing health check still said ok (port 9900 listening, watchers
registered, bodhi uptime normal, startup banner present) — the probe
layer couldn't see the upstream transport failure. I found it only by
manually tailing voice-agent.log.

Adds check_voice_transport: scans voice-agent.log from the most recent
"Sutando — Voice Interface" banner forward, tracks the tail state of
the Gemini transport. Reports:
- ok "no recent transport errors" when the latest event is
  "Gemini setup complete" with no abnormal close after it
- ok "transport recovered after earlier error" when an abnormal close
  was followed by a successful setup (auto-recovery worked)
- fail "unrecovered transport close: code=N reason=..." when the
  latest transport event is an abnormal close with no recovery

Healthy close codes: 1000 (normal), 4000 (sutando custom goodbye
disconnect, bodhi fork commit 44172b8). Everything else is flagged.

Catches:
- code=1011 Gemini quota exhaustion / tier restriction
- code=1007 "Request contains an invalid argument" (CLOSED→CLOSED
  state machine wedge — the exact pattern I saw earlier today before
  the bodhi PR sonichi#1 fixes landed)
- code=1006 abnormal / network drop

Wired into run_all_checks right after check_voice_watchers so the
voice-agent block in the report is contiguous:
  voice-agent         ok   port 9900
  voice-watchers      ok   all 3 watchers active
  voice-transport     ok   no recent transport errors

Test plan:
- ✓ Live check on current clean-boot voice-agent → ok
- ✓ 6-case simulated-log harness covering: clean boot, 1011 unrecovered,
  1011 recovered, 1000 normal close, 4000 custom goodbye, 1007 wedge
  unrecovered. All correct.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
liususan091219 pushed a commit to liususan091219/sutando-fork that referenced this pull request May 28, 2026
…onichi#263)

Fixes a false positive in the voice-transport probe (sonichi#258). Observed
live 2026-04-09 at 03:30: voice-agent sat idle for ~10 minutes, then:

  03:29:46 [VoiceSession] GoAway from Gemini (timeLeft=50s)
  03:30:46 [VoiceSession] Transport closed (state=ACTIVE code=1011
    reason="The service is currently unavailable.")
  03:30:46 [VoiceSession] Gemini disconnected — will reconnect fresh
    when client connects

That's Google's normal idle-timeout path: Gemini Live fires a GoAway
60s warning, then closes the transport with code=1011 and a
"service is currently unavailable" reason. The bodhi session
transitions to CLOSED and waits for the next client connect. When a
client comes back, `handleClientConnected` reconnects fresh. Not a
failure, just the expected lifecycle for an idle voice-agent.

The probe was flagging every 1011-after-idle as `fail` with
"unrecovered transport close" — which trains users to ignore the
signal exactly when we need them to trust it (real 1011s from sonichi#259
duplicate-tool or sonichi#262 googleSearch misconfig get lost in the noise).

Fix: track a `goaway_before_close` flag that flips true on GoAway
and false on setup complete. Abnormal closes while the flag is
true get reclassified as expected idle-timeouts (not flagged). The
flag also clears on setup complete so a RECOVERED idle timeout
followed by a fresh unrelated 1011 still correctly fails.

Test plan:
- ✓ Live probe on current log (has idle-timeout 1011 from 03:30):
  voice-transport ok
- ✓ 4-case simulated-log harness:
  1. GoAway → 1011 "service unavailable" unrecovered → ok (was fail)
  2. Unrecovered 1011 quota, no GoAway preceding → fail (as before)
  3. GoAway → 1011 → setup complete (reconnected) → ok
  4. Recovered idle-timeout + fresh 1011 with no new GoAway → fail
     (proves the flag correctly resets on setup complete)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

health-check missing voice-transport probe

1 participant