Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ All notable changes to `asa` are documented here.
## Unreleased

### Added
- **Optional MT3 polyphonic transcription stage** ([`apps/backend/mt3_transcription.py`](apps/backend/mt3_transcription.py), `apps/ui/src/services/mt3Client.ts`): Google MT3 (T5X) wired as an opt-in, additive staged backend — peer of pitch/note translation. Gated by run-level form field `mt3_mode='enabled'` on `POST /api/analysis-runs` (canonical) and env var `ASA_ENABLE_MT3=1` on the legacy `analyze.py` CLI. Emits per-stem MIDI as artifacts and an `mt3` namespace on the run snapshot. Never overrides measurement (PURPOSE.md invariant #1); heavy dependencies pinned separately in `apps/backend/requirements-mt3.txt`. New endpoint: `POST /api/analysis-runs/{run_id}/mt3-transcriptions`. See [`JSON_SCHEMA.md` "Optional MT3 Namespace"](apps/backend/JSON_SCHEMA.md#optional-mt3-namespace).
- **Live 12 source-catalogue + Phase 2 output-validation gates** ([`apps/backend/live12_catalogue.py`](apps/backend/live12_catalogue.py), [`apps/backend/phase2_catalogue_gates.py`](apps/backend/phase2_catalogue_gates.py), [`data/live12_catalogue.json`](data/live12_catalogue.json) + schema, [`scripts/build_live12_catalogue.py`](scripts/build_live12_catalogue.py)): regenerable static device/parameter catalogue extracted from the upstream `gluon/AbletonLive12_MIDIRemoteScripts`. Backend cross-checks every `{device, parameter, value, phase1Fields}` record in `mixAndMasterChain`, `abletonRecommendations`, and `secretSauce.workflowSteps` against the catalogue and emits **warn-and-keep** `RECOMMENDATION_UNVERIFIED` events on `validationWarnings` (reasons: `device_unknown`, `parameter_unknown`, `value_out_of_range`, `citation_missing`). Never drops a recommendation, never rewrites a parameter — an earlier fuzzy-rewrite path produced confidently-wrong output, so the contract is warn-only.
- **Transcription pianoroll endpoint + symusic consolidation** ([`apps/backend/transcription_pianoroll.py`](apps/backend/transcription_pianoroll.py), `apps/ui/src/services/transcriptionPianorollClient.ts`, `apps/ui/src/components/TranscriptionPianoroll.tsx` / `TranscriptionPianorollBlock.tsx`): velocity-encoded `(pitch, time)` uint8 matrix backed by `symusic`. Backs `GET /api/analysis-runs/{run_id}/transcription/pianoroll`; mounted in the Session Musician suite when `transcriptionDetail.noteCount > 0`. Derived view — Phase 1 stays authoritative; response cites the Phase 1 `bpm` and `timeSignature` so every cell traces back to a measurement.
- **Recommendation-proof campaign** ([`GOAL.md`](GOAL.md) + [`apps/backend/NEEDS.md`](apps/backend/NEEDS.md) + [`apps/backend/RECOMMENDATION_VERDICT.md`](apps/backend/RECOMMENDATION_VERDICT.md)): recommendation-quality scorer ([`apps/backend/recommendation_evaluation.py`](apps/backend/recommendation_evaluation.py) + `scripts/evaluate_recommendations.py`), Node 23+ deterministic source bridge (`scripts/emit_deterministic_recs.ts`), per-recommendation UI corpus-verification badge (`apps/ui/src/services/recommendationVerification.ts`, `apps/ui/src/data/recommendationVerification.ts`, `apps/ui/src/components/RecommendationVerificationBadge.tsx`), and the known-settings fixture corpus at `apps/backend/tests/fixtures/recommendation_tracks/`. Off the product path; badge hidden until corpus has scored fixtures.
- **Backend Phase 2 citation-path verification** (defense-in-depth): [`_validate_phase2_citation_paths`](apps/backend/server_phase2.py) (called from [`server.py`](apps/backend/server.py)) flags any cited `phase1Fields` path that doesn't resolve against the authoritative measurement payload, mirroring the frontend's `validatePhase1FieldCitations`. WARNING-only — rides the existing `validationWarnings` channel and surfaces in the UI's interpretation-caution section; Phase 1 stays authoritative and citations are never rejected.
- **`packages/loudness-spectro-wasm`** (Phase 1): browser-first Rust→WASM DSP that lifts openmeters' ITU-R BS.1770-5 / EBU R128 loudness (K-weighting, momentary/short-term, 4× true-peak) and adds integrated loudness + gating + LRA, plus an A-weighted whole-file spectrum and a spectral-reassignment spectrogram. Loudness is validated against absolute EBU Tech 3341/3342 conformance signals, the `ebur128` crate, and a pyloudnorm cross-check, with CI. Standalone — not yet imported by `apps/ui` or `apps/backend`; the Essentia path remains the authoritative Phase 1 loudness source and the product reassigned-spectrogram endpoint runs on librosa. GPL-3.0-or-later (inherited from openmeters). See [`packages/loudness-spectro-wasm/README.md`](packages/loudness-spectro-wasm/README.md).
- **Loudness-action guardrail** in Phase 2 validation: a `MISSING_LOUDNESS_ACTION` consistency check (`validateLoudnessActionPresence`) backed by [`apps/ui/src/services/loudnessGuardrails.ts`](apps/ui/src/services/loudnessGuardrails.ts). When Phase 1 measures an objective loudness defect (digital clipping via `saturationDetail.clippedSampleCount`, or a true-peak over via `truePeak`), Phase 2 must include a MASTERING/DYNAMICS card citing the triggering measurement. The Phase 2 system prompt was updated to require it.
Expand Down Expand Up @@ -41,7 +45,7 @@ All notable changes to `asa` are documented here.
- **UI design-system migration ("D-series").** Introduced a shared primitive layer in `apps/ui/src/components/ui/` (`Button`, `Panel`, `DeviceRack`, `SectionHeader`, `MetricBar`/`MetricBarRow`/`MetricTile`, `DataTable`, `EmptyState`, `LedIndicator`, `Pill`, `SignalChain`, `ChainSeparator`, `TimeReadout`, `Checkbox`, `Tooltip`) with Storybook stories and semantic design tokens in `src/index.css`, then migrated feature components onto it — inline hex colors replaced with tokens and bespoke layout boxes replaced with primitives. Also: TypeScript strict mode, `prefers-reduced-motion` support, and a source-SR-preserving STFT spectrogram as the default spectrogram tab.
- **Backend monolith split** into domain modules (commit `5c40dd44`): `analyze_core.py`, `analyze_audio_io.py`, `analyze_detection.py`, `analyze_estimate.py`, `analyze_rhythm.py`, `analyze_segments.py`, `analyze_structure.py`, `analyze_transcription.py`, `analyze_fast.py`. Server routes likewise split into `server_phase1.py`, `server_phase2.py`, `server_upload.py`, `server_samples.py`.
- **`BatchedBandpass` centralization** ([`apps/backend/dsp_bandbank.py`](apps/backend/dsp_bandbank.py)): per-band 4th-order Butterworth filtering with zero-phase `filtfilt` now lives in one place instead of being duplicated across detectors.
- **Hosted runtime foundation** landed without disturbing local mode: [`runtime_profile.py`](apps/backend/runtime_profile.py), [`worker.py`](apps/backend/worker.py), [`artifact_storage.py`](apps/backend/artifact_storage.py), [`auth_context.py`](apps/backend/auth_context.py). See [`docs/PUBLIC_HOSTING_FOUNDATION.md`](docs/PUBLIC_HOSTING_FOUNDATION.md).
- **Hosted runtime foundation** landed without disturbing local mode: [`runtime_profile.py`](apps/backend/runtime_profile.py), [`worker.py`](apps/backend/worker.py), [`artifact_storage.py`](apps/backend/artifact_storage.py), [`auth_context.py`](apps/backend/auth_context.py). See [`docs/history/public-hosting-foundation-2026-04-01.md`](docs/history/public-hosting-foundation-2026-04-01.md).
- Synthesis character labels aligned to phase2 prompt thresholds (three-tier: clean subtractive / FM-acid / wavetable-noise)
- Removed citation instructions from Phase 2 system prompt (citations added noise, not value)
- `dynamicCharacter` forwarded through `_build_phase1()` to Gemini Phase 2
Expand Down
Loading
Loading