From 9ad1c4a195fd6e69bab89579616790f2f26fafeb Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 17 May 2026 20:37:52 +0000 Subject: [PATCH] docs: refresh stale items against current architecture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CHANGELOG.md "Unreleased" was missing nine shipped features (Phase 3 audition samples, URL ingest, admin DELETE bypass, source-audio route, CSV export, publicStatus, reassigned spectrogram, chain-of-custody audit overhaul, BatchedBandpass centralization, hosted runtime foundation, backend monolith split). Added them. CLAUDE.md's analyze.py CLI example only listed four flags; expanded to match the full surface (--standard, --pitch-note-only, --stem-dir, --stem-output-dir, --pitch-note-backend). Expanded the Frontend key service files list from 9 to 16 entries to cover the services that landed during the audit overhaul (httpClient, sampleGenerationClient, appliedRecommendations + userLabels, phase1Picker + phaseLabels, audioFile, fieldAnalytics + diagnosticLogs, sessionMusician helpers). apps/ui/AGENTS.md File Map likewise expanded from 4 to 14 service entries against the same list. docs/SAMPLE_GENERATION.md's "Snapshot integration" section claimed an `AnalysisRunSnapshot.stages.sampleGeneration` shape that does not exist in apps/ui/src/types/backend.ts — the snapshot tracks only measurement, pitchNoteTranslation, and interpretation. Replaced the stale TS block with a description that matches the actual on-demand artifact path (consistent with the doc's own line 47). apps/backend/AGENTS.md and apps/backend/ARCHITECTURE.md now flag symbolic_extract.py as orphaned and broken — it imports a removed BasicPitchBackend symbol from analyze.py, would raise ImportError at load, and is not referenced from any other module. Slated for removal. docs/history/README.md had `library-review-torchfx-2026-05-13.md` listed twice; removed the duplicate. docs/ARCHITECTURE_STRATEGY.md "Last updated" stamp bumped to May 2026 with a note that no shifts to the three-layer thesis or library decisions accompanied the recent feature work. Date stamps in apps/backend/AGENTS.md and apps/ui/AGENTS.md refreshed to 2026-05-17. https://claude.ai/code/session_01QEmFAUJSoRgTqPcFTfcnYW --- CHANGELOG.md | 11 +++++++++++ CLAUDE.md | 23 +++++++++++++++-------- apps/backend/AGENTS.md | 3 ++- apps/backend/ARCHITECTURE.md | 1 + apps/ui/AGENTS.md | 13 ++++++++++++- docs/ARCHITECTURE_STRATEGY.md | 2 +- docs/SAMPLE_GENERATION.md | 13 ++----------- docs/history/README.md | 1 - 8 files changed, 44 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90d89c60..d2233d84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to `asa` are documented here. ## Unreleased ### Added +- **Phase 3 audition samples** (`POST/GET /api/analysis-runs/{run_id}/samples`): on-demand heuristic WAV/MIDI clips derived from Phase 1 measurements (and Phase 2 context when available), with a citation manifest. PyTheory generates the musical plan, FluidSynth (with sine-additive fallback) renders audio, NumPy synthesizes drum one-shots. Not part of the staged-execution queue. See [`docs/SAMPLE_GENERATION.md`](docs/SAMPLE_GENERATION.md). +- **URL-mode ingestion** for `POST /api/analysis-runs`: provide a public `http`/`https` `url` form field instead of a multipart `track`. SSRF-guarded against private/loopback/link-local addresses; streams through the shared 100 MiB cap. See [`apps/backend/url_ingest.py`](apps/backend/url_ingest.py). +- **Operator `X-Admin-Key` DELETE bypass** for `DELETE /api/analysis-runs/{run_id}`: when `SONIC_ANALYZER_ADMIN_KEY` is set, operators can purge any run; otherwise owner-only deletes apply. Admin path is closed by default. +- **`GET /api/analysis-runs/{run_id}/source-audio`**: owner-only re-serve of the originally ingested audio (no admin bypass). Saves a round-trip vs looking up the source artifact id. +- **CSV export** of Phase 1 time-series fields: `GET /api/analysis-runs/{run_id}/export/csv/{field_path}`, backed by the registry in [`apps/backend/csv_export.py`](apps/backend/csv_export.py). Schema record: [`docs/adr/0001-phase1-json-schema-v1.md`](docs/adr/0001-phase1-json-schema-v1.md). +- **Additive `publicStatus` field** on every stage in the run snapshot — collapses the eight internal stage statuses into a five-value client-facing vocabulary (`queued`, `running`, `completed`, `failed`, `interrupted`, plus `null` for `not_requested`). See [`apps/backend/stage_status.py`](apps/backend/stage_status.py). +- **Reassigned spectrogram** as an opt-in spectral enhancement (`POST /api/analysis-runs/{run_id}/spectral-enhancements/reassigned`): sharper transient/frequency localization via `librosa.reassigned_spectrogram`. Joins existing `cqt`, `hpss`, `onset`, `chroma_interactive`. +- **Chain-of-custody audit pass**: recommendations-first information architecture, applied-recommendations tracker, and grammar post-process on Phase 2 output. New components: [`CitationBlock.tsx`](apps/ui/src/components/CitationBlock.tsx), [`appliedRecommendations.ts`](apps/ui/src/services/appliedRecommendations.ts). - **Stem summary interpretation** (Experiment B): Gemini stem listening via Structured Outputs on separated bass and musical stems, producing bar-aligned musical descriptions with scale degrees, rhythmic patterns, and uncertainty flags - Backend: stem files persist as run artifacts during pitch/note work; `stem_summary` profile runs against persisted `stem_bass` and `stem_other` audio; per-stem Gemini outputs combined into one product-facing result - Frontend: polling loop auto-queues `stem_summary` after pitch/note translation completes; renders separate "AI stem summary" section alongside Session Musician draft notes @@ -24,6 +32,9 @@ All notable changes to `asa` are documented here. - Dense techno boundary regression test (145 BPM) ### Changed +- **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). - 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 diff --git a/CLAUDE.md b/CLAUDE.md index e1d958d8..7eaedfed 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -51,7 +51,7 @@ npm run test:smoke -- tests/smoke/upload-phase1.spec.ts ```bash ./apps/backend/scripts/bootstrap.sh # Create/recreate venv (Python 3.11.x required) ./apps/backend/venv/bin/python apps/backend/server.py # FastAPI server on 8100 -./apps/backend/venv/bin/python apps/backend/analyze.py [--separate] [--transcribe] [--fast] [--yes] +./apps/backend/venv/bin/python apps/backend/analyze.py [--separate] [--transcribe] [--fast] [--standard] [--yes] [--pitch-note-only] [--stem-dir DIR] [--stem-output-dir DIR] [--pitch-note-backend BACKEND] # All backend tests (run from apps/backend/) ./venv/bin/python -m unittest discover -s tests @@ -156,17 +156,24 @@ The subprocess isolation means `analyze.py` works as a standalone CLI. Check `ap Single-page React 19 + Vite + TypeScript + Tailwind CSS v4 app with no router. View states managed via React conditionals (upload → estimate → analysis → results). Vitest for unit tests, Playwright for smoke tests. -**Key service files:** +**Key service files** (canonical transport + chain-of-custody contracts): 1. **`src/services/analysisRunsClient.ts`**: Canonical transport. Creates runs against `/api/analysis-runs`, polls snapshots, fetches pitch/note translations and interpretations. 2. **`src/services/analyzer.ts`**: Phase orchestration entry point — sequences run creation, polling, and display payload projection. 3. **`src/services/backendPhase1Client.ts`**: Legacy multipart transport (typed error classes, `AbortController` timeouts, identity probe via `/openapi.json`). Kept for the compatibility wrappers; new flows should go through `analysisRunsClient.ts`. -4. **`src/services/spectralArtifactsClient.ts`**: Fetches spectrogram/spectral-evolution artifacts via `/api/analysis-runs/{run_id}/artifacts/…`. -5. **`src/services/mixDoctor.ts`**: Mix advisory logic — client-side scoring and suggestions against measured spectral balance. -6. **`src/services/phase2Validator.ts`**: Runtime guardrail. Validates Phase 2 consistency against Phase 1 (`validateBPMConsistency`, `validateKeyConsistency`, `validateLUFSConsistency`, `validateGenreDSPConsistency`, `validateNumericBounds`). -7. **`src/services/midi/`**: MIDI export, preview, and quantization utilities (`midiExport.ts`, `midiPreview.ts`, `quantization.ts`). -8. **`src/types.ts`** + **`src/types/`**: `types.ts` is a barrel re-export of `./types/{measurement,interpretation,backend}.ts`. `Phase1Result` lives in `types/measurement.ts`; `AnalysisRunSnapshot` in `types/backend.ts`; `Phase2Result` in `types/interpretation.ts`. -9. **`src/config.ts`**: Runtime resolution of `VITE_API_BASE_URL` and feature flags; falls back to `http://127.0.0.1:8100`. Supports window-level overrides (`window.__VITE_API_BASE_URL_OVERRIDE__`, `window.__VITE_ENABLE_PHASE2_GEMINI_OVERRIDE__`) for hosted deployments that inject config at runtime without a rebuild. +4. **`src/services/httpClient.ts`**: Shared fetch helpers and request-header injection used by the run/artifact/sample clients. +5. **`src/services/spectralArtifactsClient.ts`**: Fetches spectrogram/spectral-evolution artifacts via `/api/analysis-runs/{run_id}/artifacts/…`. +6. **`src/services/sampleGenerationClient.ts`**: Phase 3 audition-sample POST/GET against `/api/analysis-runs/{run_id}/samples`, plus per-clip artifact streaming. +7. **`src/services/mixDoctor.ts`**: Mix advisory logic — client-side scoring and suggestions against measured spectral balance. +8. **`src/services/phase2Validator.ts`**: Runtime guardrail. Validates Phase 2 consistency against Phase 1 (`validateBPMConsistency`, `validateKeyConsistency`, `validateLUFSConsistency`, `validateGenreDSPConsistency`, `validateNumericBounds`). +9. **`src/services/appliedRecommendations.ts`** + **`userLabels.ts`**: Applied-recommendations tracker and persisted-label state used by the audit overhaul. +10. **`src/services/phase1Picker.ts`** + **`phaseLabels.ts`**: Phase-snapshot projection helpers consumed by the results surface. +11. **`src/services/audioFile.ts`**: Client-side audio validation, blank-MIME extension fallback, preview-URL lifecycle. +12. **`src/services/fieldAnalytics.ts`** + **`diagnosticLogs.ts`**: Instrumentation hooks and diagnostic-log capture for the request panel. +13. **`src/services/midi/`**: MIDI export, preview, and quantization utilities (`midiExport.ts`, `midiPreview.ts`, `quantization.ts`). +14. **`src/services/sessionMusician/`**: Session Musician helpers — `confidenceBand.ts`, `noteConversion.ts`, `renderState.ts`, `stemListeningNotes.ts`. +15. **`src/types.ts`** + **`src/types/`**: `types.ts` is a barrel re-export of `./types/{measurement,interpretation,backend}.ts`. `Phase1Result` lives in `types/measurement.ts`; `AnalysisRunSnapshot` in `types/backend.ts`; `Phase2Result` in `types/interpretation.ts`; `./types/samples.ts` is imported directly, not through the barrel. +16. **`src/config.ts`**: Runtime resolution of `VITE_API_BASE_URL` and feature flags; falls back to `http://127.0.0.1:8100`. Supports window-level overrides (`window.__VITE_API_BASE_URL_OVERRIDE__`, `window.__VITE_ENABLE_PHASE2_GEMINI_OVERRIDE__`) for hosted deployments that inject config at runtime without a rebuild. `AnalysisResults.tsx` is the large results surface, lazy-loaded via Suspense. Manual vendor chunks in `vite.config.ts` control bundle splitting. diff --git a/apps/backend/AGENTS.md b/apps/backend/AGENTS.md index 734aca14..ea6c41bf 100644 --- a/apps/backend/AGENTS.md +++ b/apps/backend/AGENTS.md @@ -7,7 +7,7 @@ - The repo is a local Python audio-analysis service with two entry points: - `analyze.py`: raw CLI analyzer - `server.py`: FastAPI wrapper around the CLI -- There are no repo-local Cursor rules, `.cursorrules`, or Copilot instruction files in this repo as of 2026-05-15. +- There are no repo-local Cursor rules, `.cursorrules`, or Copilot instruction files in this repo as of 2026-05-17. ## Working Style For Agents @@ -121,6 +121,7 @@ python3.11 -m venv venv - `phase1_evaluation.py` + `phase1_report_html.py`: Offline Phase 1 evaluation harness — deterministic-metric and detector-stability reporting, with a standalone HTML render. Not on the product path; driven by `scripts/evaluate_phase1.py`. - `polyphonic_evaluation.py` + `scripts/evaluate_polyphonic.py`: **Research-only.** Offline polyphonic-transcription evaluation harness, not part of the shipped product path. - `utils/cleanup.py`: Periodic artifact cleanup helpers used by the server background-task loop. +- `symbolic_extract.py`: **Orphaned and broken.** Earlier worker-process entry point for pitch/note translation; superseded by `analyze.py --pitch-note-only`. Still imports a removed `BasicPitchBackend` symbol from `analyze.py`, so loading the module would raise `ImportError`. Not referenced from any other module. Slated for removal — do not extend it. - `tests/test_server.py`: OpenAPI and envelope contract tests. - `tests/test_analyze.py`: generated WAV fixture, `EXPECTED_TOP_LEVEL_KEYS` snapshot, raw payload assertions. - `tests/test_csv_export.py`, `tests/test_sample_*.py`, `tests/test_server_samples.py`: Coverage for CSV export and Phase 3 audition samples. diff --git a/apps/backend/ARCHITECTURE.md b/apps/backend/ARCHITECTURE.md index ebccb5d6..734f5295 100644 --- a/apps/backend/ARCHITECTURE.md +++ b/apps/backend/ARCHITECTURE.md @@ -21,6 +21,7 @@ | `phase1_evaluation.py` + `phase1_report_html.py` | Offline Phase 1 evaluation harness — deterministic-metric and detector-stability reporting, with a standalone HTML render. Not on the product path; driven by `scripts/evaluate_phase1.py`. | | `polyphonic_evaluation.py` + `scripts/evaluate_polyphonic.py` | Research-only offline polyphonic-transcription evaluation harness. Not on the product path. | | `utils/cleanup.py` | Periodic artifact cleanup helpers used by the server background-task loop. | +| `symbolic_extract.py` | **Orphaned.** Earlier worker-process entry point for pitch/note translation; superseded by `analyze.py --pitch-note-only`. Currently imports a removed `BasicPitchBackend` and would fail at module load. Not invoked from anywhere else in the tree; slated for removal. | | `tests/test_server.py` | Contract tests for estimate, timeout, and success envelopes. | | `tests/test_analyze.py` | Structural snapshot tests for the raw analyzer JSON output. Owns `EXPECTED_TOP_LEVEL_KEYS` — update it whenever you add a root field. | | `tests/test_spectral_viz.py` | Unit tests for spectrogram generation, time-series computation, and artifact orchestration. | diff --git a/apps/ui/AGENTS.md b/apps/ui/AGENTS.md index 094a2386..10876980 100644 --- a/apps/ui/AGENTS.md +++ b/apps/ui/AGENTS.md @@ -5,7 +5,7 @@ - This file applies to `apps/ui` inside the `asa` monorepo. - Stack: React 19, TypeScript, Vite 6, Tailwind CSS v4, Vitest, Playwright. - The app talks to the local `sonic-analyzer` backend. Gemini is backend-mediated; the UI does **not** import an AI SDK. -- No repo-local `.cursorrules`, `.cursor/rules/`, or `.github/copilot-instructions.md` exist here as of 2026-05-15. +- No repo-local `.cursorrules`, `.cursor/rules/`, or `.github/copilot-instructions.md` exist here as of 2026-05-17. ## Working Style For Agents @@ -91,6 +91,17 @@ RUN_GEMINI_LIVE_SMOKE=true VITE_ENABLE_PHASE2_GEMINI=true GEMINI_API_KEY=your_ke - `src/services/analysisRunsClient.ts`: canonical transport — creates runs against `/api/analysis-runs`, polls stage snapshots, fetches pitch/note translations and interpretations. - `src/services/backendPhase1Client.ts`: legacy multipart transport (typed errors, `AbortController` timeouts). Kept only for the compatibility wrappers; new flows go through `analysisRunsClient.ts`. - `src/services/analyzer.ts`: phase orchestration — sequences run creation, polling, and display payload projection. +- `src/services/httpClient.ts`: shared fetch helpers and request-header injection used by the run/artifact/sample clients. +- `src/services/spectralArtifactsClient.ts`: spectrogram and spectral-evolution artifact fetches via `/api/analysis-runs/{run_id}/artifacts/…`. +- `src/services/sampleGenerationClient.ts`: Phase 3 audition-sample POST/GET against `/api/analysis-runs/{run_id}/samples` plus per-clip artifact streaming. +- `src/services/audioFile.ts`: client-side audio validation, blank-MIME extension fallback, and preview-URL lifecycle. +- `src/services/mixDoctor.ts`: client-side spectral-balance scoring against genre profiles. +- `src/services/phase2Validator.ts`: runtime guardrail — chain-of-custody checks of Phase 2 against Phase 1 (BPM, key, LUFS, genre/DSP, numeric bounds). +- `src/services/phase1Picker.ts` + `phaseLabels.ts`: phase-snapshot projection helpers used by the results surface. +- `src/services/appliedRecommendations.ts` + `userLabels.ts`: applied-recommendations tracker and persisted label state used by the audit overhaul. +- `src/services/fieldAnalytics.ts` + `diagnosticLogs.ts`: instrumentation hooks and diagnostic log capture for the request panel. +- `src/services/midi/`: MIDI export, preview, and quantization (`midiExport.ts`, `midiPreview.ts`, `quantization.ts`). +- `src/services/sessionMusician/`: Session Musician helpers — `confidenceBand.ts`, `noteConversion.ts`, `renderState.ts`, `stemListeningNotes.ts`. - `src/types.ts` + `src/types/`: shared frontend contract types. `types.ts` is a barrel re-export of `./types/{measurement,interpretation,backend}.ts`; `./types/samples.ts` exists but is imported directly, not through the barrel. - `src/index.css`: Tailwind theme tokens and visual language. - `tests/services/*`: unit and service tests. diff --git a/docs/ARCHITECTURE_STRATEGY.md b/docs/ARCHITECTURE_STRATEGY.md index e3e2e0b6..fb195e10 100644 --- a/docs/ARCHITECTURE_STRATEGY.md +++ b/docs/ARCHITECTURE_STRATEGY.md @@ -1,6 +1,6 @@ # ASA Architecture Strategy -**Last updated:** March 2026 +**Last updated:** May 2026 (Phase 3 audition samples shipped; CSV export, URL ingest, admin DELETE, source-audio route, `publicStatus`, and reassigned spectrogram landed in the same window — no shifts to the three-layer thesis or library decisions below) **Status:** Living document — update when experiments produce results or the AI capability landscape shifts materially. **Sources:** ChatGPT o3 deep research (March 2026), Codex architecture hardening audit, Perplexity ecosystem research (Demucs/separation alternatives), session analysis with Claude Sonnet, and the 2026-03-18 reality audit ([archived](archive/stage3-reality-audit-2026-03-18.md)). The three `deep-research-report*.md` files originally cited here were external research inputs and are not committed to this repo. diff --git a/docs/SAMPLE_GENERATION.md b/docs/SAMPLE_GENERATION.md index 2331f93a..9268a1c7 100644 --- a/docs/SAMPLE_GENERATION.md +++ b/docs/SAMPLE_GENERATION.md @@ -182,18 +182,9 @@ This keeps audition WAV/MIDI access on the same code path as every other run-sco ### Snapshot integration -`AnalysisRunSnapshot.stages.sampleGeneration` becomes: +Sample generation is **not** a stage on `AnalysisRunSnapshot.stages` — the snapshot still tracks the three queued stages only (`measurement`, `pitchNoteTranslation`, `interpretation`). Audition samples ride on the existing `run_artifacts` table with `kind` values `sample_audio`, `sample_midi`, and `sample_manifest`, and the manifest itself is fetched directly via `GET /api/analysis-runs/{run_id}/samples` (404 when not yet generated). -```ts -{ - status: "not_requested" | "completed" | "failed", - manifestSampleCount?: number, - generatedAt?: string, - synthesisBackend?: "fluidsynth" | "sine_fallback" -} -``` - -`not_requested` is the default — the stage is opt-in, not auto-enqueued. This is intentional: until audition value is validated, we don't want to pay the synthesis cost on every run. +The synthesis backend used and the generated-at timestamp are recorded on the manifest body, not on the snapshot. Promotion to a first-class stage with `publicStatus` tracking is a follow-up if audition value pans out. ## Dependencies diff --git a/docs/history/README.md b/docs/history/README.md index 2e4bb837..8394a974 100644 --- a/docs/history/README.md +++ b/docs/history/README.md @@ -16,7 +16,6 @@ Everything in this directory is past-tense. Treat it as a paper trail, not a sou - `phase1-hardening-plan.md` — completed Phase 1 hardening plan. - `library-review-torchfx-2026-05-13.md` — one-shot library evaluation of torchfx against ASA's DSP path. - `phase1-audit/` — one-shot advisory deliverable: audit, decks, evidence index, visual story pack. -- `library-review-torchfx-2026-05-13.md` — completed library review. - `external-repo-review-2026-05-13.md` — completed external-repo incorporation review (openmeters / soundscope / Partiels / forever-jukebox). All three tracks resolved. - `track1-spike-outcome-2026-05-13.md` — completed loudness verification spike. Fix shipped; regression test retained. - `archive/` — older archived plans and result stubs.