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.1–D.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 1–5, review workload forecast (Low risk, single PR)
Apply Progress sdd/eq-device-disconnect-revert/apply-progress #2323 2026-07-10 19:02:32 Phases 1–4 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 1–5 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.1–D.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) 130–160
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 1–4 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)