V2/LCD Parity Matrix And Regression Harness¶
Date: 2026-04-11
Status: Draft
Issue: #644
Based on: #641, #642, #643, #646
Base commit: f0e78cc0ea0fcfbafdadbb4a20167ba0bc110d6a
Objective¶
Define what "parity" means for standard v2 and LCD, and which checks must exist before and during migration to the unified architecture.
Parity here means:
- same runtime behavior
- same capability semantics
- same command side effects
- same audio/scope lifecycle behavior
It does not mean identical DOM or identical visuals.
First-class capability scenarios¶
These capability combinations must be treated as explicit scenarios.
Scenario A¶
- hardware scope: yes
- live audio: yes
Expected presentations:
- standard layout available
- LCD layout available
- audio and scope both functional
Scenario B¶
- hardware scope: no
- live audio: yes
Expected presentations:
- LCD is a valid first-class layout
- live audio still works exactly as in Scenario A
- lack of scope must not change audio behavior
This is the most important regression scenario for the current problem.
Scenario C¶
- hardware scope: yes
- live audio: no
Expected presentations:
- scope still works
- no
LIVEmonitor path is offered - local AF control still works if radio supports AF
Scenario D¶
- hardware scope: no
- live audio: no
Expected presentations:
- LCD remains valid
- no live-audio path
- no scope path
- core tuning / mode / meter / tx behavior still works
High-risk flows¶
These are the flows most likely to regress during runtime unification.
1. App bootstrap¶
Check:
- state polling starts
- capabilities load
- control WS connects
- runtime derives the correct semantic availability for scope/audio
2. Layout selection¶
Check:
autochooses the expected layout from capabilities- forcing LCD/standard changes presentation only
- switching layout does not change transport ownership
3. RX monitor mode transitions¶
Check:
RADIO -> LIVELIVE -> MUTEMUTE -> RADIOMUTE -> LIVE
Expected:
- same state transitions in standard and LCD
- same audio controller behavior
- same AF-level semantics
4. AF level changes¶
Check separately:
- AF level change in
RADIO - AF level change in
LIVE
Expected:
RADIOcontrols radio AF command pathLIVEcontrols browser playback volume path- LCD and standard must not disagree about which path is active
5. Receiver switching¶
Check:
- MAIN/SUB active receiver change
- monitor mode preserved correctly
- commands address the intended receiver
- displayed meter/frequency/mode are derived from the same active receiver semantics
6. Reconnect / remount¶
Check:
- control WS reconnect
- audio WS reconnect
- layout remount while runtime remains alive
- runtime rehydrates view models correctly
Expected:
- mounted component path does not decide which transport reconnects
7. Scope unavailable while audio remains available¶
Check:
- capability or runtime state where scope is absent but audio is present
Expected:
LIVEstill functions- no hidden dependency on scope mount state
8. PTT / TX interaction with audio¶
Check:
- entering TX
- leaving TX
- monitor/audio state around TX transitions
Expected:
- same TX audio lifecycle regardless of layout
Parity matrix¶
Scenario A: scope=true, audio=true¶
| Flow | Standard V2 | LCD | Automation target |
|---|---|---|---|
| Bootstrap | Pass | Pass | unit + component |
LIVE playback path |
Must work | Must work | unit + browser/manual |
| Scope stream | Must work | Optional render variant, same runtime ownership | unit + browser/manual |
| Layout switch | No transport restart due only to layout | Same | browser/manual |
| Receiver switch | Same active receiver semantics | Same | unit + component |
Scenario B: scope=false, audio=true¶
| Flow | Standard V2 | LCD | Automation target |
|---|---|---|---|
| Auto layout choice | LCD fallback or equivalent | Pass | unit |
LIVE playback path |
Must work | Must work | unit + browser/manual |
| Scope ownership | Absent | Absent | unit |
| AF level semantics | Same | Same | unit |
| Layout remount | Audio unaffected | Audio unaffected | browser/manual |
Scenario C: scope=true, audio=false¶
| Flow | Standard V2 | LCD | Automation target |
|---|---|---|---|
LIVE option visibility |
Hidden | Hidden | component |
| Scope path | Works | Same runtime semantics if rendered | unit + browser/manual |
| AF local control | Works if radio AF exists | Works | unit |
Scenario D: scope=false, audio=false¶
| Flow | Standard V2 | LCD | Automation target |
|---|---|---|---|
| Auto layout choice | LCD fallback or equivalent | Pass | unit |
LIVE option visibility |
Hidden | Hidden | component |
| Core radio control flows | Same | Same | unit + component |
Regression harness strategy¶
Layer 1: pure unit tests¶
Target:
- adapters
- capability resolution
- layout selection logic
- monitor mode derivation
- receiver selection semantics
Good candidates:
state-adapter- layout mode resolution
- semantic view-model builders
Layer 2: component tests¶
Target:
- semantic components
- layout composition decisions
- option visibility
- callback wiring
Good candidates:
RxAudioControlScopeSurfaceVfoDisplay- layout wrappers
Layer 3: controller/runtime tests¶
Target:
- audio controller
- scope controller
- reconnect behavior
- ownership invariants
Needed especially for:
LIVEstart/stop- ws reconnect
- layout remount while runtime state persists
This layer is currently weak and should be added during migration.
Layer 4: browser integration tests¶
Target:
- autoplay/user-gesture interactions
- actual
AudioContextstate - layout switching in a browser environment
- route through real runtime shell
These should use Playwright with controlled mocks for backend endpoints where possible.
Layer 5: manual / hardware validation¶
Still required for:
- real radio codec negotiation
- actual audio output audibility
- hardware scope + audio coexistence
- radio/backend-specific codec combinations
Current blind spots¶
These are the important gaps in current automation.
Blind spot 1¶
No meaningful tests for audioManager RX lifecycle.
Current tests do not prove:
/api/v1/audioconnect/start behavior- reconnect behavior
- first-frame handling
Blind spot 2¶
No meaningful tests for Opus decode availability.
Current tests do not prove:
AudioDecoderpresence/absence handling- decoder recreation after error
Blind spot 3¶
No tests for mounted-layout independence.
Current tests do not prove:
- transport ownership is unchanged when switching between standard and LCD
Blind spot 4¶
No backend tests around codec normalization edge cases.
Current tests do not prove:
PCM_1CH_8BITpath- u-law decode path end-to-end to browser framing
Blind spot 5¶
No automation for browser autoplay/suspended-context failures.
This is exactly the kind of issue that can make "frames arrived" look healthy while playback is dead.
Acceptance checks before cutover¶
Before the unified architecture becomes default, the migration should satisfy:
- Scenario B (
scope=false,audio=true) has explicit automated coverage - Layout switching does not restart or re-own transports
LIVEmode has one tested controller path- Receiver switching semantics are identical across layouts
- At least one manual hardware validation run confirms audio playback on the previously failing class of radio
Provisional conclusion¶
The migration should be judged against parity of behavior slices, not against visual similarity.
The most critical regression target is:
scope=false + audio=true
because that is the scenario most likely to reveal whether the architecture is truly unified or only visually similar.