User story
As a team member evaluating the RFC 0001 rewrite, I want a low-risk, self-contained Rust spike, so that we can validate the agent-driven Rust development loop and cross-hardware output parity before committing to the full rewrite.
Background
In response to Saloni's review comment on #90 — "LGTMT, Thank you for the detailed RFC! But I would think we should do a quick spike with Rust to see if we are ok with the dev of it" — Claude suggested porting the AudioSyncer FFT cross-correlation function as the ideal candidate:
- Self-contained with well-defined I/O (two audio buffers in → offset seconds out)
- No GPU, no ML models, no subprocess dependencies — isolates the pure Rust + cargo dev loop
- We already have deterministic ground truth from
scripts/sync/AudioSyncer.js to diff against
- The algorithm is tuned team-owned logic (cross-correlation, deterministic tie-break, SNR reliability check — documented in RFC 0001 §Decision table) — worth preserving exactly before any future GPU offload
This spike gates confidence in three things the RFC assumes but has not validated:
- Coding agents can write correct, reviewable Rust (compiler-as-safety-net hypothesis)
- The same Rust binary produces byte-identical offsets on Mac M2, Mac M3, and Windows/NVIDIA
- Cargo toolchain + cross-compile story is workable for our team in practice
Acceptance criteria
Happy path
Given synced episode fixture files (two audio tracks from any shipped episode)
When the Rust binary is run with the same inputs as AudioSyncer.js
Then the computed offset matches the JS output to within ±1 sample (≤ 0.02 ms at 48 kHz), on Mac M2, Mac M3, and the Windows/NVIDIA machine
Given the Rust implementation compiled and run on all three target machines
When each machine processes the same fixture
Then all three produce identical offsets (bit-for-bit, since FFT is deterministic)
Error path / edge case
Given audio tracks with very low SNR (below the existing SNR reliability check threshold in AudioSyncer.js)
When the Rust binary processes them
Then it returns the same tie-break result or a clearly flagged "low confidence" output — not a silent wrong offset
Out of scope
- GPU offload for the FFT (explicitly deferred in RFC 0001 §Decision table)
- Any other pipeline stage (transcription, rendering, diarization)
- A GUI or interactive preview
- Integration into the existing Node pipeline — this is a standalone binary only
- Replacing the current
scripts/sync/AudioSyncer.js — the JS version keeps running in production
Technical context
Source to port: scripts/sync/AudioSyncer.js — FFT cross-correlation, deterministic tie-break, SNR reliability check. The algorithm is documented in RFC 0001 §Decision table ("Port the algorithm from scripts/sync/AudioSyncer.js … faithfully into Rust; it is tuned, team-owned logic worth preserving exactly").
Target machines per RFC 0001 §Verification approach: Mac M2, Mac M3, Windows with NVIDIA GPU.
Fixture source: any shipped episode's synced-output files in public/sync/output/ — export two audio tracks and use them as test fixtures.
Relevant RFC section: docs/rfcs/0001-native-desktop-rewrite.md §Decision table (AudioSyncer row) and §Verification approach.
Repository location: recommend a separate throw-away repo or a top-level spike/ directory (not wired into the existing Next.js monorepo build) — aligns with RFC 0001 open question on new repo vs subdirectory.
Implementation details
- Extract two representative audio fixture files from a shipped episode (48 kHz, mono WAV or raw PCM); commit them as test fixtures alongside the spike code.
- Create a minimal Cargo workspace (
spike/audio-sync/) with a binary crate. No workspace-level config that bleeds into the existing repo.
- Port the FFT cross-correlation loop from
AudioSyncer.js faithfully: same windowing, same tie-break logic, same SNR threshold. Use the rustfft crate (pure Rust, no native deps, deterministic across platforms).
- Write a CLI entry point:
audio-sync <ref.wav> <target.wav> → prints offset in seconds.
- Write a unit test in the same crate that runs the fixture pair and asserts the offset matches the JS baseline (computed once and committed as a constant).
- Run the binary and test suite on Mac M2 — record output.
- Run on Mac M3 — confirm identical output.
- Run on Windows/NVIDIA — confirm identical output. Document the exact
cargo build + cargo test commands used on each machine.
- Write a short retro note (≤ 1 page, can be a comment on this issue or a
spike/RETRO.md) covering: what the agent-driven Rust loop felt like, what the compiler caught vs. what needed human review, and a go/no-go recommendation for proceeding with RFC 0001 Phase 1.
Additional test scenarios
- Fixture with a known positive offset (target starts later than reference) — assert sign is correct
- Fixture with a known negative offset — assert sign is correct
- Zero-offset fixture (same file as both inputs) — assert offset ≈ 0
- Low-SNR fixture (silence or near-silence) — assert the SNR reliability path triggers
Hard constraints
- Must use
rustfft or another pure-Rust FFT (no C FFmpeg/FFTW binding for this spike — the point is to validate the pure Rust dev loop)
- Output offset must match
AudioSyncer.js to within ±1 sample on all three machines — not "close enough"
- No changes to any file outside
spike/ — this must not touch the existing pipeline
- Spike code does not need to meet Phase 4 test-coverage thresholds; it is throwaway validation, not production code
- Retro note is required before this issue can be closed — the go/no-go recommendation is the primary deliverable
Dependency issues
Depends on #90 being reviewed/approved (RFC 0001 — this spike is a direct response to the review).
Independent of all existing refactor phase branches (refactor/p0-*, refactor/p1-*, etc.).
User story
As a team member evaluating the RFC 0001 rewrite, I want a low-risk, self-contained Rust spike, so that we can validate the agent-driven Rust development loop and cross-hardware output parity before committing to the full rewrite.
Background
In response to Saloni's review comment on #90 — "LGTMT, Thank you for the detailed RFC! But I would think we should do a quick spike with Rust to see if we are ok with the dev of it" — Claude suggested porting the
AudioSyncerFFT cross-correlation function as the ideal candidate:scripts/sync/AudioSyncer.jsto diff againstThis spike gates confidence in three things the RFC assumes but has not validated:
Acceptance criteria
Happy path
Given synced episode fixture files (two audio tracks from any shipped episode)
When the Rust binary is run with the same inputs as
AudioSyncer.jsThen the computed offset matches the JS output to within ±1 sample (≤ 0.02 ms at 48 kHz), on Mac M2, Mac M3, and the Windows/NVIDIA machine
Given the Rust implementation compiled and run on all three target machines
When each machine processes the same fixture
Then all three produce identical offsets (bit-for-bit, since FFT is deterministic)
Error path / edge case
Given audio tracks with very low SNR (below the existing
SNR reliability checkthreshold inAudioSyncer.js)When the Rust binary processes them
Then it returns the same tie-break result or a clearly flagged "low confidence" output — not a silent wrong offset
Out of scope
scripts/sync/AudioSyncer.js— the JS version keeps running in productionTechnical context
Source to port:
scripts/sync/AudioSyncer.js— FFT cross-correlation, deterministic tie-break, SNR reliability check. The algorithm is documented in RFC 0001 §Decision table ("Port the algorithm fromscripts/sync/AudioSyncer.js… faithfully into Rust; it is tuned, team-owned logic worth preserving exactly").Target machines per RFC 0001 §Verification approach: Mac M2, Mac M3, Windows with NVIDIA GPU.
Fixture source: any shipped episode's synced-output files in
public/sync/output/— export two audio tracks and use them as test fixtures.Relevant RFC section:
docs/rfcs/0001-native-desktop-rewrite.md§Decision table (AudioSyncer row) and §Verification approach.Repository location: recommend a separate throw-away repo or a top-level
spike/directory (not wired into the existing Next.js monorepo build) — aligns with RFC 0001 open question on new repo vs subdirectory.Implementation details
spike/audio-sync/) with a binary crate. No workspace-level config that bleeds into the existing repo.AudioSyncer.jsfaithfully: same windowing, same tie-break logic, same SNR threshold. Use therustfftcrate (pure Rust, no native deps, deterministic across platforms).audio-sync <ref.wav> <target.wav>→ prints offset in seconds.cargo build+cargo testcommands used on each machine.spike/RETRO.md) covering: what the agent-driven Rust loop felt like, what the compiler caught vs. what needed human review, and a go/no-go recommendation for proceeding with RFC 0001 Phase 1.Additional test scenarios
Hard constraints
rustfftor another pure-Rust FFT (no C FFmpeg/FFTW binding for this spike — the point is to validate the pure Rust dev loop)AudioSyncer.jsto within ±1 sample on all three machines — not "close enough"spike/— this must not touch the existing pipelineDependency issues
Depends on #90 being reviewed/approved (RFC 0001 — this spike is a direct response to the review).
Independent of all existing refactor phase branches (
refactor/p0-*,refactor/p1-*, etc.).