Files
pluriwave/openspec/changes/archive/2026-07-10-eq-device-disconnect-revert/tasks.md
T
FreeTLab 8f7ca8059b
Build & Deploy PluriWave / Análisis de código (push) Successful in 36s
Build & Deploy PluriWave / Build APK + AAB release (push) Successful in 2m30s
fix(eq): resolve base-speaker preset live instead of pinning a stale copy
_onDispositivoCambiado() bootstrapped a device-level preset entry for
every never-seen device id, including the built-in speaker. That
persistent level-3 entry masked later global-preset edits (level 3
beats level 4 on every resolution), so disconnecting a BT device or
cold-starting without one could leave the EQ stuck on an outdated
copy instead of the current global preset.

The base speaker is now excluded from the first-seen bootstrap:
disconnect and cold start always resolve through the live hierarchy.
BT/wired/USB devices keep their bootstrap behavior unchanged.
2026-07-10 23:54:01 +02:00

2.8 KiB

Tasks: EQ Device Disconnect / Cold-Start Revert

Review Workload Forecast

Field Value
Estimated changed lines ~130-160
400-line budget risk Low
Chained PRs recommended No
Suggested split Single PR
Delivery strategy ask-on-risk
Chain strategy pending

Decision needed before apply: No Chained PRs recommended: No Chain strategy: pending 400-line budget risk: Low

Suggested Work Units

Unit Goal Likely PR Notes
1 Bootstrap guard fix + proof tests (RED-GREEN-REFACTOR) PR 1 (single PR) Base: main. One logical change, well under 400-line budget

Phase 1: RED — Write Failing Tests

  • 1.1 Add group 'device disconnect / cold-start revert (Phase D)' to test/estado/estado_ecualizador_test.dart after L334, reusing existing fakes (no new fake types)
  • 1.2 D.1 disconnect resolves+applies base preset (spec Req 1, scenario "Disconnect resolves and applies the base preset")
  • 1.3 D.2 disconnect does NOT bootstrap presetsDispositivo['builtin_speaker'] from the disconnecting device (spec Req 2)
  • 1.4 D.3 cold start with no device applies base resolution via cargarPersistido() only, not a stale device preset (spec Req 3)
  • 1.5 D.4 connect→disconnect→reconnect cycle: correct preset at each step, matrix override honored, device preset unchanged by disconnect (spec Req 4, locks 5.5b)
  • 1.6 D.5 station override still wins over global on disconnect-to-base (design Testing Strategy D.5)
  • 1.7 Run flutter test test/estado/estado_ecualizador_test.dart — confirm D.1-D.5 FAIL; D.2 must fail on the real bootstrap-collision bug, not a tautology

Phase 2: GREEN — Minimal Fix

  • 2.1 In lib/estado/estado_ecualizador.dart _onDispositivoCambiado() (L216-220), gate bootstrap on dispositivo.tipo != TipoDispositivo.altavozInterno
  • 2.2 Leave L213 (_dispositivoActualId assignment) and L222-226 (resolve+apply) unchanged — single handler, no branching on event type
  • 2.3 Run test suite — confirm D.1-D.5 PASS

Phase 3: Regression Lock

  • 3.1 Run full estado_ecualizador_test.dart — all existing groups green (5.1-5.8, 2.1-2.4, rename API, guardarPresetDispositivo)
  • 3.2 Confirm 5.5a and 2.2 (both bluetoothA2dp) unaffected — guard is base-device-scoped only
  • 3.3 Confirm 5.5b and toggle-off 5.7a/5.8b pass unmodified — named consistency locks

Phase 4: REFACTOR

  • 4.1 Add one-line comment above the bootstrap block explaining the altavozInterno exclusion (prevents L3 masking future L4 edits)
  • 4.2 flutter analyze on both modified files — zero new warnings

Phase 5: Manual Sanity (light, non-blocking)

  • 5.1 On-device: connect BT/USB with own preset, disconnect (reverts to base), reconnect (returns to device preset) — one-time confidence check