# Changelog

All notable changes to AI MusiMuse are documented in this file.

The format is based on task completion milestones.

---

## [Unreleased]

### TASK-012 — Music DNA Vector Encoder

**Added**

- `src/music_dna/layout.py` — `MusicDNALayout` with explicit, versioned mapping of 55 feature identifiers to vector indices (Signal 0–12, Spectral 32–37, Dynamic 96–102, Rhythm 160–166, Harmony 224–245). Methods: `get_index`, `contains`, `dimension`, `list_entries`, `reserved_indices`, `feature_count`
- `src/music_dna/vector.py` — `MusicDNAVectorMetadata` and `MusicDNAVector` frozen dataclasses. Vector values are read-only `numpy.ndarray` with `float32` dtype and shape `(512,)`
- `src/music_dna/encoder.py` — `MusicDNAEncoder` that converts `MusicDNA` → `MusicDNAVector`. Floats/ints stored directly, bools → 0.0/1.0, strings → 0.0 (categorical placeholder), reserved dims → 0.0. Deterministic and validated
- `tests/unit/test_encoder.py` — 26 tests covering layout, vector immutability/dtype/shape, encoder happy path, value conversion, reserved dimensions, determinism, unknown feature errors, metadata, and all 55 features mapped correctly
- `musimuse encode` CLI command with structured logging (`encoder.started`, `encoder.track`, `encoder.validation_failed`, `encoder.completed`)

**Changed**

- `src/music_dna/__init__.py` — Added re-exports for `MusicDNAEncoder`, `MusicDNALayout`, `MusicDNAVector`, `MusicDNAVectorMetadata`
- `src/app/main.py` — Added `encode` CLI command and `MusicDNAEncoder` import
- `docs/02_ARCHITECTURE.md` — Updated `music_dna` module description to mention vector encoding

**Tests**

- 356 tests pass (26 new)
- black, isort, ruff all pass

---

### TASK-011 — Music DNA Builder

**Added**

- `src/music_dna/exceptions.py` — `MusicDNAError` base exception + 5 dedicated exceptions: `MissingFeatureError`, `UnknownFeatureError`, `DuplicateFeatureError`, `InvalidValueError`, `NormalizationError`
- `src/music_dna/music_dna.py` — Immutable `MusicDNA` and `MusicDNAMetadata` frozen dataclasses with `MappingProxyType` for readonly values and `source_analyzer_versions`
- `src/music_dna/normalizer.py` — `Normalizer` class with all 6 normalization strategies (identity, minmax, log, zscore, categorical, none) returning values unchanged (initial implementation)
- `src/music_dna/builder.py` — `MusicDNABuilder` that validates features against `FeatureRegistry`, deserializes string values to proper types (float/int/str/bool), normalizes via `Normalizer`, and produces deterministic immutable `MusicDNA`
- `tests/unit/test_music_dna.py` — 29 tests covering immutability, normalizer, builder happy path, validation errors (missing/unknown/duplicate/None/invalid), determinism, deserialization, metadata, and registry integration
- `musimuse dna` CLI command with structured logging (`dna.started`, `dna.track`, `dna.validation_failed`, `dna.completed`)

**Changed**

- `src/music_dna/__init__.py` — Replaced placeholder with proper module docstring and public re-exports
- `src/app/main.py` — Added `dna` CLI command, `MusicDNABuilder` and `FeatureRepository` imports
- `docs/02_ARCHITECTURE.md` — Updated `music_dna` module description in responsibilities table

**Tests**

- 330 tests pass (29 new)
- black, isort, ruff all pass

---

### TASK-010.5 — Feature Registry

**Added**

- `src/features/__init__.py` — Package docstring and public API re-exports
- `src/features/definition.py` — `FeatureCategory`, `DataType`, `NormalizationStrategy` enums + immutable `FeatureDefinition` dataclass with validation
- `src/features/registry.py` — `FeatureRegistry` with `register`, `unregister`, `contains`, `get`, `list`, `list_by_category`, `count`
- `src/features/default_registry.py` — `build_default_feature_registry()` registering all 55 feature definitions (signal: 13, spectral: 6, dynamic: 7, rhythm: 7, harmony: 22)
- `tests/unit/test_feature_registry.py` — 27 tests covering immutability, validation, registration, duplicate detection, lookup, category filtering, default registry completeness, and cross-validation with analyzer output

**Changed**

- `src/analyzer/basic/basic_signal_analyzer.py` — All feature names normalized to canonical `block.feature` format (e.g., `peak` → `signal.peak`, `rms` → `signal.rms`)
- `src/analyzer/spectral/spectral_analyzer.py` — All feature names normalized (e.g., `spectral_centroid` → `spectral.centroid`)
- `src/analyzer/dynamic/dynamic_analyzer.py` — All feature names normalized (e.g., `dynamic_range` → `dynamic.range`)
- `src/analyzer/rhythm/rhythm_analyzer.py` — All feature names normalized (e.g., `tempo_bpm` → `rhythm.tempo`)
- `src/analyzer/harmony/harmony_analyzer.py` — All feature names normalized (e.g., `estimated_key` → `harmony.key`, `chroma_a` → `harmony.chroma_a`)
- `tests/unit/test_basic_signal_analyzer.py` — Updated all `find_by_name` calls and expected name sets to canonical format
- `tests/unit/test_spectral_analyzer.py` — Updated all feature name references to canonical format
- `tests/unit/test_dynamic_analyzer.py` — Updated all feature name references to canonical format
- `tests/unit/test_rhythm_analyzer.py` — Updated all feature name references to canonical format
- `tests/unit/test_harmony_analyzer.py` — Updated all feature name references to canonical format
- `tests/unit/test_storage.py` — Updated feature names in helper functions and assertions
- `pyproject.toml` — Added `src/features` to packages list and `features` to isort/ruff known_first_party
- `docs/02_ARCHITECTURE.md` — Added `features` module to responsibilities table
- `docs/03_ANALYZER_API.md` — Updated Feature Registry section to reference `src/features` package with guidance for new analyzers

**Tests**

- 301 tests pass (27 new)
- black, isort, ruff all pass

---

### TASK-010 — Canonical Feature Naming

**Changed**

- All 5 analyzers (basic, spectral, dynamic, rhythm, harmony) updated to use canonical `block.feature` naming convention
- All 6 test files updated to match new feature identifiers in `find_by_name` calls, expected feature name sets, and mono/stereo comparison lists

---

### Earlier Tasks (TASK-001 through TASK-009)

These tasks established the foundational infrastructure of AI MusiMuse:

- **TASK-001**: Project scaffolding, pyproject.toml, directory structure
- **TASK-002**: Configuration system (`src/config/settings.py`)
- **TASK-003**: Structured logging (`src/log/logger.py` with structlog)
- **TASK-004**: Database models and SQLAlchemy setup (`src/database/`)
- **TASK-005**: File scanner (`src/scanner/scanner.py`)
- **TASK-006**: Track importer (`src/importer/importer.py`)
- **TASK-007**: Audio decoder (`src/decoder/`)
- **TASK-008**: Analysis framework — analyzer base class, registry, pipeline, feature/featureset domain objects, analysis context, result types
- **TASK-009**: Built-in analyzers — BasicSignalAnalyzer, SpectralAnalyzer, DynamicAnalyzer, RhythmAnalyzer, HarmonyAnalyzer with full test coverage
