Files
2026-05-27 23:29:53 +01:00

117 lines
5.5 KiB
Markdown
Raw Permalink 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.
# OpenSpec Change: enterprise-react-audio-fingerprint
- **Change ID**: enterprise-react-audio-fingerprint
- **Package**: `@suaveplan/react-audio-fingerprint`
- **Category**: react
- **Target path**: `packages/ui/react/react-audio-fingerprint`
- **Status**: PROPOSED
- **Date**: 2026-05-15
- **Design**: `./design.md`
- **Spec delta**: `./specs/react-audio-fingerprint/spec.md`
> Replaces the prior 2026-04-24 draft flagged `NEEDS-REWRITE`. See `../REACT_AUDIO_WAVE_REWRITE_COMPLETE.md`.
---
## Summary
Deliver `@suaveplan/react-audio-fingerprint` on genesis from scratch at enterprise quality. The package provides client-side audio fingerprinting (Shazam-style constellation hashing) and identity matching as React hooks + components, built on the unified architecture:
1. **`AudioFingerprinter`** — a universal class (no React) implementing chromagram FFT + 2D local-peak detection + constellation pair hashing per the classic algorithm; produces a deterministic `Fingerprint` (a sorted list of `(hash, timeOffsetSec)` pairs). Sources audio via the `@suaveplan/audio-analysis-spectrum` package's FFT primitives so there is **one FFT implementation across the audio family**, not a duplicate.
2. **`FingerprintMatcher`** — universal Jaccard-similarity matcher that scores a query fingerprint against a corpus and returns ranked matches with confidence scores.
3. **Hooks**: `useAudioFingerprint(source)`, `useFingerprintMatcher(corpus)`, `useFingerprintProgress(hashHandle)`.
4. **Components**: `<AudioFingerprintUploader>` (file drop + URL paste), `<FingerprintMatchDisplay>` (ranked results with thumbnails + confidence bars), `<FingerprintVisualizer>` (constellation plot over the spectrogram).
5. **OTel instrumentation** (fingerprint duration, match duration, corpus size gauge).
6. **Integration with `@suaveplan/python-audio-fingerprint`** (optional server-side high-accuracy backend) via an injectable `FingerprintBackend` interface — local algorithm is the default; server delegation is opt-in for large corpora.
The package owns **no DSP outside the local fingerprinting algorithm itself** — FFT primitives come from `audio-analysis-spectrum`, audio loading comes from `audio-engine-browser`'s decode path, persistence and corpus storage are injectable.
---
## Current-state audit (genesis)
The package does not exist on genesis yet — fresh build replacing the obsolete pre-tier 2026-04-24 draft.
---
## Parity Checklist (vs upstream)
| Capability | Upstream | Migrated | Notes |
|---|:---:|:---:|---|
| `AudioFingerprinter` (chromagram + peak detect + constellation) | ✅ | ⬆️ | FFT delegated to `audio-analysis-spectrum`; one implementation across audio family. |
| `FingerprintMatcher` (Jaccard similarity) | ✅ | ✅ | Pure universal; no DOM deps. |
| `AudioLoader` | ✅ | ⬆️ | Replaced by `audio-engine-browser` decode + WebCodecs path; consistent across all audio surfaces. |
| `useAudioFingerprint` hook | ✅ | ✅ | Suspense-friendly via `useSyncExternalStore`. |
| `useFingerprintMatcher` hook | ✅ | ✅ | Subscribes to corpus changes. |
| `<AudioFingerprintUploader>` component | ✅ | ✅ | DnD + URL + file picker; accessible. |
| `<FingerprintMatchDisplay>` component | ✅ | ✅ | Ranked results + confidence bars. |
| `<FingerprintVisualizer>` component | ✅ | ✅ | Constellation overlay on spectrogram. |
| Server backend integration (NEW) | – | ⬆️ | Optional `python-audio-fingerprint` backend via injectable `FingerprintBackend`. |
| Storybook coverage | partial | ✅ | Default + interactive + edge. |
| Coverage | ~72 % | ✅ | 100/100/100/100. |
No 🚫 rows.
---
## Available workspace deps on genesis
| Package | Role |
|---|---|
| `@suaveplan/react-audio` (`workspace:^`) | Hooks + provider |
| `@suaveplan/audio-analysis-spectrum` (`workspace:^`) | FFT + spectrogram primitives |
| `@suaveplan/audio-engine-browser` (`workspace:^`) | Source decode + buffer load |
| `@suaveplan/python-audio-fingerprint` (`workspace:^`, optional peer for backend gating) | Optional server backend |
| `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/opentelemetry`, `@suaveplan/events` | foundations |
| `react` (peer), `zustand` (`catalog:state`), `framer-motion` (`catalog:animation`), `lucide-react` (`catalog:ui`), `zod` (`catalog:forms`) |
---
## File layout
```text
packages/ui/react/react-audio-fingerprint/
src/
index.ts
error-codes.ts
fingerprint/
audio-fingerprinter/ (.ts .md .types.ts .schemas.ts .test.ts)
fingerprint-matcher/ ...
constellation/ ...
peak-detector/ ...
backends/
local-backend/ ...
python-backend/ ← optional subpath
hooks/
use-audio-fingerprint/ (.ts .md .test.tsx)
use-fingerprint-matcher/ ...
use-fingerprint-progress/ ...
components/
audio-fingerprint-uploader/ (.tsx .md .types.ts .test.tsx .stories.tsx)
fingerprint-match-display/ ...
fingerprint-visualizer/ ...
corpus/
memory-corpus/ ...
indexeddb-corpus/ ...
__benchmarks__/
fingerprint.bench.ts
match.bench.ts
tests/
integration.test.tsx
purity.test.ts
exports.test.ts
property.test.ts ← fingerprint(A) ≠ fingerprint(B) for distinct inputs
```
---
## Impact
**Breaking changes**: none — fresh build.
**Prerequisites**: `react-audio`, `audio-analysis-spectrum`, `audio-engine-browser`, foundations. `python-audio-fingerprint` optional.
### Affected dependents
No dependents in this batch (verified by `bunx turbo ls --filter=...@suaveplan/react-audio-fingerprint`).