# 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**: `` (file drop + URL paste), `` (ranked results with thumbnails + confidence bars), `` (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. | | `` component | ✅ | ✅ | DnD + URL + file picker; accessible. | | `` component | ✅ | ✅ | Ranked results + confidence bars. | | `` 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`).