feat(voice): GET /architect/transcribe/health probe (VOICE-2, #774) #779

Merged
code-lead merged 1 commit from dev/774 into dev/773 2026-05-02 22:18:15 +00:00
Collaborator

Adds GET /architect/transcribe/health so the composer and dashboard can check whether speaches is enabled and reachable before rendering the mic button.

  • Returns { enabled, reachable, model, default_language, allowed_languages, last_error? } — always 200
  • Probes ${transcribe_url}/v1/models (HEAD); result cached 30 s; ?refresh=1 busts it
  • enabled=false returns early — no upstream call
  • Timeout and non-2xx → reachable: false + last_error
  • Auth: guardMutating, same as the rest of /architect/*
  • Stacked on VOICE-1 (dev/773); base branch is dev/773

Test plan

  • enabled=falsereachable=false, no upstream fetch called
  • Cache hit within 30 s does not re-probe; ?refresh=1 does
  • Simulated AbortError → reachable=false, last_error="timeout", 200
  • Upstream 503 → reachable=false, last_error="upstream returned 503"
  • Upstream 200 → reachable=true, no last_error
  • allowed_languages_json=nullallowed_languages=[]

Closes #774

Adds `GET /architect/transcribe/health` so the composer and dashboard can check whether speaches is enabled and reachable before rendering the mic button. - Returns `{ enabled, reachable, model, default_language, allowed_languages, last_error? }` — always 200 - Probes `${transcribe_url}/v1/models` (HEAD); result cached 30 s; `?refresh=1` busts it - `enabled=false` returns early — no upstream call - Timeout and non-2xx → `reachable: false` + `last_error` - Auth: `guardMutating`, same as the rest of `/architect/*` - Stacked on VOICE-1 (`dev/773`); base branch is `dev/773` ## Test plan - `enabled=false` → `reachable=false`, no upstream fetch called - Cache hit within 30 s does not re-probe; `?refresh=1` does - Simulated AbortError → `reachable=false, last_error="timeout"`, 200 - Upstream 503 → `reachable=false, last_error="upstream returned 503"` - Upstream 200 → `reachable=true`, no `last_error` - `allowed_languages_json=null` → `allowed_languages=[]` Closes #774
dev self-assigned this 2026-05-02 22:01:29 +00:00
Returns { enabled, reachable, model, default_language, allowed_languages, last_error? }.
Probes speaches /v1/models with a 30 s cache; ?refresh=1 busts it. Disabled when
speech.enabled=false (200 with reachable=false, no upstream call). Timeout and
non-2xx failures surface as reachable=false + last_error. Auth: guardMutating.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
dev requested review from reviewer 2026-05-02 22:04:31 +00:00
Collaborator

CI still pending at review time (no run found for sha 1c56be8). Stepping off the review request — will be re-dispatched automatically when CI completes.

CI still pending at review time (no run found for sha `1c56be8`). Stepping off the review request — will be re-dispatched automatically when CI completes.
Collaborator

CI still pending at review time (no runs found for sha 1c56be8). Stepping off the review request — will be re-dispatched automatically when CI completes.

CI still pending at review time (no runs found for sha `1c56be8`). Stepping off the review request — will be re-dispatched automatically when CI completes.
reviewer approved these changes 2026-05-02 22:14:49 +00:00
reviewer left a comment

All ACs met: health endpoint returns correct shape, cache + refresh logic correct, probe error handling covers timeout and non-2xx, guardMutating auth in place. Tests cover all required unit cases.

Nit: guardMutating on a GET is a naming oddity but matches the spec — not blocking.

All ACs met: health endpoint returns correct shape, cache + refresh logic correct, probe error handling covers timeout and non-2xx, guardMutating auth in place. Tests cover all required unit cases. Nit: `guardMutating` on a GET is a naming oddity but matches the spec — not blocking.
code-lead merged commit ea47da1ef0 into dev/773 2026-05-02 22:18:15 +00:00
code-lead deleted branch dev/774 2026-05-02 22:18:15 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks!779
No description provided.