fix: STT backend constant casing + audioLevel NaN guard (#37, #47) #196

Merged
KofTwentyTwo merged 2 commits from fix/v0.2-wave-1-code-fixes into develop 2026-05-14 14:50:51 +00:00
KofTwentyTwo commented 2026-05-14 14:34:25 +00:00 (Migrated from github.com)

Summary

Third PR in the v0.2 Wave 1 sequence (per docs/superpowers/specs/2026-05-14-v0.2-wave-1-sequencing-design.md). Two small code fixes, one commit each.

#37 — STT backend constant casing

Discovery: the runtime mismatch was already resolved at call sites (AppDelegate.swift:1631-1642 and :2562-2575 now reference STTBackendSelector.backend* constants instead of the pre-2026-05-12 camelCase literals), and the existing test STTBackendSwitchTests.testB5_canonicalConstantsRoundTripThroughMake already locks the round-trip contract for both happy path (snake_case constants) and anti-pattern (camelCase literals fall through to default branch + warn). Close action is just to make the contract self-documenting at the declaration site — added a doc-comment on the two public static let backend* constants that names the regression test, references #29 + #37, and warns against silent rename.

No code change for #37. swift test --package-path packages/Voice continues to pass (26 tests).

#47 — audioLevel NaN guard (LATENT, not actively firing)

Verified via grep in webview/packages/hud/src/bus/client.ts: the case 'audioLevel' arm is a no-op (ring shader still on the synthetic sine from Plan 03-03). So the bug would only fire once the HUD-side consumer activates — but the clamp is cheap, the bug is one CoreAudio glitch away from production, and shipping it now means the contract is pinned before the consumer wakes.

Inline clamp at BusOutbound.swift's .audioLevel encode arm: let safe = rms.isFinite ? rms : 0.0. Catches NaN AND ±∞ in one check.

Two new tests in CodableRoundTripTests:

  • test_audioLevel_nanIsClampedToZero — round-trips .nan, asserts rms == 0.0 and rms.isFinite.
  • test_audioLevel_infinityIsClampedToZero — companion for ±∞ so a future refactor can't narrow the guard to NaN-only.

swift test --package-path packages/Bus --filter CodableRoundTripTests passes (30 tests, +2).

Test plan

  • Local: swift test --package-path packages/Bus --filter CodableRoundTripTests — 30/30 pass
  • Local: swift test --package-path packages/Voice — 26/26 pass
  • CI: full SPM matrix green (Memory flake policy applies — rerun once)

Non-goals

Closes #37
Closes #47

## Summary Third PR in the v0.2 Wave 1 sequence (per `docs/superpowers/specs/2026-05-14-v0.2-wave-1-sequencing-design.md`). Two small code fixes, one commit each. ### #37 — STT backend constant casing Discovery: the runtime mismatch was already resolved at call sites (`AppDelegate.swift:1631-1642` and `:2562-2575` now reference `STTBackendSelector.backend*` constants instead of the pre-2026-05-12 camelCase literals), and the existing test `STTBackendSwitchTests.testB5_canonicalConstantsRoundTripThroughMake` already locks the round-trip contract for both happy path (snake_case constants) and anti-pattern (camelCase literals fall through to default branch + warn). Close action is just to make the contract self-documenting at the declaration site — added a doc-comment on the two `public static let backend*` constants that names the regression test, references #29 + #37, and warns against silent rename. No code change for #37. `swift test --package-path packages/Voice` continues to pass (26 tests). ### #47 — audioLevel NaN guard (LATENT, not actively firing) Verified via `grep` in `webview/packages/hud/src/bus/client.ts`: the `case 'audioLevel'` arm is a no-op (ring shader still on the synthetic sine from Plan 03-03). So the bug would only fire once the HUD-side consumer activates — but the clamp is cheap, the bug is one CoreAudio glitch away from production, and shipping it now means the contract is pinned before the consumer wakes. Inline clamp at `BusOutbound.swift`'s `.audioLevel` encode arm: `let safe = rms.isFinite ? rms : 0.0`. Catches NaN AND ±∞ in one check. Two new tests in `CodableRoundTripTests`: - `test_audioLevel_nanIsClampedToZero` — round-trips `.nan`, asserts `rms == 0.0` and `rms.isFinite`. - `test_audioLevel_infinityIsClampedToZero` — companion for ±∞ so a future refactor can't narrow the guard to NaN-only. `swift test --package-path packages/Bus --filter CodableRoundTripTests` passes (30 tests, +2). ## Test plan - [x] Local: `swift test --package-path packages/Bus --filter CodableRoundTripTests` — 30/30 pass - [x] Local: `swift test --package-path packages/Voice` — 26/26 pass - [ ] CI: full SPM matrix green (Memory flake policy applies — rerun once) ## Non-goals - Doesn't touch PRs #185, #191, #192 - Doesn't refactor `AudioLevelEmitter` (per spec — separate concern) - Doesn't wire the HUD audioLevel consumer (still latent; that's a Phase 6 follow-up tracked elsewhere) Closes #37 Closes #47
Sign in to join this conversation.