Files
pluriwave/openspec/changes/archive/2026-07-10-eq-device-disconnect-revert/archive-report.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

9.6 KiB
Raw Blame History

Archive Report: EQ Device Disconnect / Cold-Start Revert

Change: eq-device-disconnect-revert
Archive Date: 2026-07-10
Artifact Store Mode: hybrid
Status: ARCHIVED


Verification Verdict

PASS WITH WARNINGS

  • Critical Issues: 0
  • Warnings: 1
  • Suggestions: 3
  • Tests Passed: 43/43 (target file), 68/68 (target + regression suite)
  • Tasks Complete: 15/16 (Phase 5.1 intentionally pending as non-blocking manual gate)

Change Summary

Scope: EQ device disconnect handling and cold-start resolution guarantee

What was changed:

  • Added first-seen bootstrap guard in _onDispositivoCambiado() to exclude altavozInterno (base speaker) from device-preset caching, ensuring the base device always resolves live through the 4-level hierarchy (matrix → station → device → global)
  • Added 5 new test cases (D.1D.5) covering disconnect revert, cold-start guarantees, connect-disconnect-reconnect cycles, station/matrix override interaction, and toggle-off invariance
  • All changes isolated to lib/estado/estado_ecualizador.dart (~9 lines modified) and test/estado/estado_ecualizador_test.dart (~214 lines added)

Why it matters:

  • Fixes a correctness gap: disconnect and cold-start events now explicitly re-resolve and apply the EQ preset, not coincidentally
  • Closes a L3-masks-L4 bug: base speaker can no longer be pinned by a stale device-level entry from the old bootstrap
  • Maintains full byte-for-byte compatibility when multi-device EQ is disabled

Engram Artifacts (Observation IDs for Traceability)

All SDD artifacts persisted to Engram project pluriwave for cross-session recovery and audit trail:

Artifact Topic Key Observation ID Created Details
Proposal sdd/eq-device-disconnect-revert/proposal #2301 2026-07-10 17:53:45 Intent, scope, approach, risks, rollback plan
Spec (Delta) sdd/eq-device-disconnect-revert/spec #2306 2026-07-10 17:59:15 5 formal requirements, 6 scenarios; no prior main spec existed
Design sdd/eq-device-disconnect-revert/design #2303 2026-07-10 17:58:01 6 architecture decisions, bootstrap guard fix, testing strategy
Tasks sdd/eq-device-disconnect-revert/tasks #2315 2026-07-10 18:11:25 Phases 15, review workload forecast (Low risk, single PR)
Apply Progress sdd/eq-device-disconnect-revert/apply-progress #2323 2026-07-10 19:02:32 Phases 14 complete (15 tasks), TDD cycle evidence, deviations log
Verify Report sdd/eq-device-disconnect-revert/verify-report #2325 2026-07-10 23:38:59 Completeness, spec compliance, coherence, TDD compliance, assertions, issues found

This Archive Report will be persisted to Engram as:

  • Topic Key: sdd/eq-device-disconnect-revert/archive-report
  • Type: architecture
  • Project: pluriwave

Spec Merge Status

Delta Spec → Main Spec

Action File Result
Create openspec/specs/multi-device-eq/spec.md Created (no prior spec existed; delta copied as full spec)

Content merged: 5 ADDED Requirements with 6 scenarios (no MODIFIED or REMOVED entries). All requirements cover disconnect/cold-start revert behavior within the 4-level EQ hierarchy. On-disk delta spec at openspec/changes/eq-device-disconnect-revert/specs/multi-device-eq/spec.md was used as authoritative source (post-verify refinement applied by orchestrator to resolve WARNING-1 wording drift).


Filesystem Archive Structure

Move completed: openspec/changes/eq-device-disconnect-revert/openspec/changes/archive/2026-07-10-eq-device-disconnect-revert/

Contents preserved:

  • proposal.md — Intent and approach
  • design.md — Architecture decisions and bootstrap guard fix
  • tasks.md — Phases 15 with task checklist
  • specs/multi-device-eq/spec.md — Full delta spec (5 requirements)
  • verify-report.md — Completeness, spec compliance, TDD compliance
  • state.yaml — DAG state (archived status recorded)
  • archive-report.md — This document

Artifacts NOT in openspec/:

  • Engram artifacts remain in Engram at topic keys listed above (not moved; persisted independently)

Issue Tracking and Resolutions

Verification WARNING (1)

WARNING-1: Spec Text / Implementation Divergence on Requirement 2

  • Description: Spec scenario literally states presetsDispositivo['builtin_speaker'] is bootstrapped to the global preset with the implication the entry is created. Implementation (matching Design Decision #2) NEVER creates that entry — the esBase guard unconditionally skips the bootstrap block.
  • Status: RESOLVED (post-verify spec refinement)
  • Resolution: The on-disk spec file at openspec/changes/eq-device-disconnect-revert/specs/multi-device-eq/spec.md was edited by the orchestrator post-verify to correct the THEN clause: now states no entry is ever created and resolution always falls through to the hierarchy. This is functionally correct and safer than the literal wording.
  • Proof: Test D.2 asserts presetsDispositivo.containsKey('builtin_speaker') is false — proves no entry exists, and the edit aligns the spec with this proven behavior.

Verification SUGGESTIONS (3)

SUGGESTION-1: Reconcile spec text per WARNING-1 resolution (already done in on-disk file; no action needed).

SUGGESTION-2: Apply-progress TDD Cycle Evidence table uses 3-column format (RED/GREEN/REFACTOR) instead of full 5-column strict-TDD template. Substance is present; format nitpick for future runs.

SUGGESTION-3: Pre-existing cambiarPresetPrincipal() hierarchy-bypass (applies raw global instead of re-resolving) observed during apply, noted as tracked tech debt. Out of scope for this change; recommend a follow-up ticket.


Non-Blocking Items

Task 5.1: On-Device Manual Sanity Check — PENDING

  • Description: Connect BT/USB device with own preset, disconnect (verify revert to base), reconnect (verify return to device preset)
  • Status: Intentionally unchecked
  • Reason: Non-automatable human gate requiring real hardware; verified via automated unit tests (D.1D.5) to be theoretically sound
  • Blocking the release?: No. Can be executed anytime on real hardware as a confidence check; not required for PR merge.

Tech Debt Carried Forward

Pre-existing cambiarPresetPrincipal() Bypass

  • Description: The cambiarPresetPrincipal() method immediately calls audio.aplicarPresetActivo(preset), bypassing _resolverPresetActivo() and applying the raw global preset directly without re-resolving the hierarchy. This could allow a station or matrix override to be transiently bypassed for one apply call.
  • Scope: Out of scope for this change; pre-existing behavior unrelated to disconnect/cold-start revert
  • Recommendation: Follow-up ticket to refactor cambiarPresetPrincipal to push through _resolverPresetActivo() for hierarchy consistency

Review Workload Impact

Metric Value
Estimated changed lines (from task forecast) 130160
Actual changed lines (via git) ~221 (9 lib + 214 test)
400-line budget risk Low
Chained PRs recommended No
Delivery strategy applied ask-on-risk → single PR (no split needed)

Completeness Checklist

Item Status Notes
Proposal read and logged #2301
Spec read and merged #2306 → openspec/specs/multi-device-eq/spec.md
Design read and verified #2303, all 6 decisions followed
Tasks read and tracked #2315, 15/16 complete
Apply progress read #2323, Phases 14 complete
Verify report read and resolved #2325, PASS WITH WARNINGS, WARNING resolved in spec
All artifacts moved to archive Filesystem and Engram copies established
State recorded (archived) state.yaml written with status and notes
Archive report created This document (both filesystem and Engram)

SDD Cycle Complete

This change has successfully completed all phases:

  1. Explore — Investigated device-event handling and revert semantics
  2. Propose — Defined scope and approach
  3. Spec — Formal 5-requirement specification with 6 scenarios
  4. Design — Architecture decisions and bootstrap guard detail
  5. Tasks — Breakdown with phases, forecast, and completeness tracking
  6. Apply — Implemented with Strict TDD (15/16 tasks automated, 1/16 manual gate)
  7. Verify — PASS WITH WARNINGS (43/43 tests, 0 CRITICAL, 1 WARNING resolved)
  8. Archive — All artifacts consolidated, spec merged, change moved to archive

Ready for: Next change or release planning


  • Main spec: openspec/specs/multi-device-eq/spec.md
  • Archived change folder: openspec/changes/archive/2026-07-10-eq-device-disconnect-revert/
  • Engram topic keys (full content via mem_get_observation):
    • Proposal: sdd/eq-device-disconnect-revert/proposal (#2301)
    • Spec: sdd/eq-device-disconnect-revert/spec (#2306)
    • Design: sdd/eq-device-disconnect-revert/design (#2303)
    • Tasks: sdd/eq-device-disconnect-revert/tasks (#2315)
    • Apply Progress: sdd/eq-device-disconnect-revert/apply-progress (#2323)
    • Verify Report: sdd/eq-device-disconnect-revert/verify-report (#2325)
    • Archive Report: sdd/eq-device-disconnect-revert/archive-report (this document)

Archived by: SDD Archive Phase (haiku model)
Date: 2026-07-10 (ISO format)
Project: pluriwave
Mode: Hybrid (Engram + OpenSpec filesystem)