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

55 lines
2.8 KiB
Markdown

# 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
- [x] 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)
- [x] 1.2 D.1 disconnect resolves+applies base preset (spec Req 1, scenario "Disconnect resolves and applies the base preset")
- [x] 1.3 D.2 disconnect does NOT bootstrap `presetsDispositivo['builtin_speaker']` from the disconnecting device (spec Req 2)
- [x] 1.4 D.3 cold start with no device applies base resolution via `cargarPersistido()` only, not a stale device preset (spec Req 3)
- [x] 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)
- [x] 1.6 D.5 station override still wins over global on disconnect-to-base (design Testing Strategy D.5)
- [x] 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
- [x] 2.1 In `lib/estado/estado_ecualizador.dart` `_onDispositivoCambiado()` (L216-220), gate bootstrap on `dispositivo.tipo != TipoDispositivo.altavozInterno`
- [x] 2.2 Leave L213 (`_dispositivoActualId` assignment) and L222-226 (resolve+apply) unchanged — single handler, no branching on event type
- [x] 2.3 Run test suite — confirm D.1-D.5 PASS
## Phase 3: Regression Lock
- [x] 3.1 Run full `estado_ecualizador_test.dart` — all existing groups green (5.1-5.8, 2.1-2.4, rename API, guardarPresetDispositivo)
- [x] 3.2 Confirm 5.5a and 2.2 (both `bluetoothA2dp`) unaffected — guard is base-device-scoped only
- [x] 3.3 Confirm 5.5b and toggle-off 5.7a/5.8b pass unmodified — named consistency locks
## Phase 4: REFACTOR
- [x] 4.1 Add one-line comment above the bootstrap block explaining the `altavozInterno` exclusion (prevents L3 masking future L4 edits)
- [x] 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