# TASK-004

## Title

Analysis Framework

---

## Objective

Implement the core Analysis Framework for AI MusiMuse.

This task introduces the architecture that will power every future music analyzer.

No real audio analysis should be implemented yet.

The goal is to build a flexible, extensible, deterministic pipeline that can later host dozens of analyzers without changing the architecture.

This is one of the core architectural milestones of the project.

---

# Expected Commit Message

Add analysis framework

---

# Requirements

Read SPEC.md before implementing anything.

Follow all AI Rules.

Do not violate architectural boundaries.

---

# Scope

Create a new package:

src/analyzer/

```
__init__.py
analyzer.py
context.py
result.py
feature.py
pipeline.py
registry.py
exceptions.py
```

---

# AnalysisContext

Create an immutable AnalysisContext.

Responsibilities:

- contains Track
- contains DecodedAudio
- contains Settings
- provides read-only access
- no business logic

Must be a frozen dataclass.

---

# Feature

Create immutable domain objects.

Feature

Fields:

- name
- value
- unit (optional)
- analyzer
- version

FeatureSet

Responsibilities:

- collection of Feature
- iterable
- immutable
- helper lookup methods

No database models.

No SQLAlchemy.

---

# AnalysisResult

Create immutable AnalysisResult.

Fields:

- analyzer_name
- analyzer_version
- execution_time_ms
- success
- warnings
- FeatureSet

Responsibilities:

- output of one analyzer
- contains no database logic
- contains no file logic

---

# Analyzer

Create an abstract Analyzer base class.

Required interface:

```python
class Analyzer(ABC):

    name: str

    version: str

    @abstractmethod
    def analyze(
        self,
        context: AnalysisContext,
    ) -> AnalysisResult:
        ...
```

Rules:

Analyzer must

- never access SQLite
- never read files
- never perform logging directly
- never modify context

Analyzer receives everything through AnalysisContext.

---

# Registry

Create AnalyzerRegistry.

Responsibilities:

- register analyzer
- unregister analyzer
- list analyzers
- lookup by name

Registration must reject duplicate analyzer names.

---

# Pipeline

Create AnalysisPipeline.

Responsibilities:

- receive AnalysisContext
- execute analyzers in registration order
- collect AnalysisResult objects
- continue execution even if one analyzer fails
- isolate analyzer exceptions

Pipeline must never crash because one analyzer failed.

---

# Exceptions

Create

AnalysisError

AnalyzerRegistrationError

AnalyzerExecutionError

They should inherit from the project's base exception hierarchy.

---

# Dummy Analyzer

Create a built-in DummyAnalyzer.

Purpose:

Verify the framework.

Behavior:

Returns

Feature:

```
framework.version = 0.1
```

No DSP.

No audio analysis.

---

# CLI

Add command

```
musimuse analyze
```

Workflow:

```
Load tracks

↓

Decode audio

↓

Create AnalysisContext

↓

Run AnalysisPipeline

↓

Print summary
```

Example:

```
Tracks analyzed: 9

Analyzers executed: 1

Features produced: 9

Failures: 0
```

---

# Logging

Add structured logging.

Suggested events:

analysis.started

analysis.finished

pipeline.started

pipeline.finished

analyzer.started

analyzer.finished

analyzer.failed

Do not log from inside analyzers.

Only Pipeline performs logging.

---

# Tests

Create tests for:

AnalysisContext

Feature

FeatureSet

AnalysisResult

AnalyzerRegistry

AnalysisPipeline

DummyAnalyzer

Failure isolation

Duplicate registration

Execution order

Context immutability

FeatureSet iteration

Pipeline result aggregation

---

# Forbidden

Do NOT implement:

FFT

Tempo

Beat detection

Key detection

Loudness

Dynamics

MFCC

Spectrogram

Music DNA

Embeddings

Similarity

Recommendations

Database persistence of features

---

# Definition of Done

✓ AnalysisContext implemented

✓ Feature implemented

✓ FeatureSet implemented

✓ AnalysisResult implemented

✓ Analyzer base class implemented

✓ AnalyzerRegistry implemented

✓ AnalysisPipeline implemented

✓ DummyAnalyzer implemented

✓ CLI analyze command works

✓ Pipeline survives analyzer failures

✓ Duplicate registration prevented

✓ Context is immutable

✓ Result is immutable

✓ Tests pass

✓ Ruff passes

✓ Black passes

✓ isort passes

---

# Architectural Notes

This task intentionally produces almost no useful music analysis.

Its purpose is to establish the permanent architecture that all future analyzers will use.

Future analyzers (RMS, Tempo, Spectral, Harmony, Embeddings, Music DNA, Recommendations) must be implementable without modifying the pipeline itself.

Every analyzer should only require:

- subclassing Analyzer
- implementing analyze()
- registering itself

Nothing else.

The framework should be considered complete only when adding a new analyzer requires zero modifications to existing infrastructure.