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

194 lines
9.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
---
## Artifact Links
- **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)