Skip to content

docs: adversarial codebase audit (2026-07-03)#18

Merged
RubenGlez merged 3 commits into
mainfrom
claude/codebase-adversarial-audit-wo8pbw
Jul 3, 2026
Merged

docs: adversarial codebase audit (2026-07-03)#18
RubenGlez merged 3 commits into
mainfrom
claude/codebase-adversarial-audit-wo8pbw

Conversation

@RubenGlez

Copy link
Copy Markdown
Owner

Adds a full adversarial audit at .harness/qa/adversarial-audit-2026-07-03.md: system map, severity-ranked findings (file:line, CONFIRMED/PLAUSIBLE, concrete scenario), design tensions, expectation gaps, and open questions.

Highest-severity findings

  • F1 (P0) — deleting a Library row destroys the user's original filelibrary:deleteSample (electron/main/ipc/library.ts:51-56) unconditionally fs.unlinkSyncs the file; since importFolder registers files in place, removing a Library entry deletes the source on disk.
  • F2 (P0) — 24-bit exports always fail — 24-bit profiles set sampleFmt: 's24' (electron/main/hardware/profiles.ts:26,40) passed as ffmpeg -sample_fmt s24, which is not a valid ffmpeg sample format (s24 isn't a packed sample fmt). Every MPC/Generic-WAV 24-bit export render fails; tests only cover s16.
  • F7 (P1) — export failures report success — Pack export / send-to-pack / import handlers have no catch (src/views/Packs/index.tsx:58-69), so failures (incl. F2) surface as an empty output folder plus a "N files exported" success toast.
  • F3 (P1) — autosave race creates duplicate projects — the first projects:save blocks on full ffmpeg materialization while activeProject stays null, so a second edit fires a second projects:save (useChopAutosave.ts + stores/projects.ts:75-91).
  • F4 (P1) — duplicate library rows/WAVs — overlapping syncProjectChopsToLibrary calls both see "no sample yet" and both insert (services/materializeChops.ts:75-102); no serialization, no UNIQUE index on source_chop_id.
  • F5 (P1) — clearing the last chop is never persisteduseChopAutosave.ts:46 early-returns on zero regions, so "Clear all" reappears on relaunch despite the confirmation dialog.
  • F14 (P1) — startup blocks the window on migration rendersmain/index.ts:249-260 awaits materializeProjectChops() before creating the window; an upgrade with many legacy chops blank-screens through N sequential ffmpeg renders, and a missing source retries forever every launch.
  • F31 (P1) — path traversal + SSRF from the rendererstems:persist/getCached join a renderer-supplied sourceHash into a path with no validation (services/stems.ts:24-30); freesound:download fetches any renderer-supplied URL. Renderer runs under an 'unsafe-eval' CSP.
  • F24 (P1) — Freesound "Import to Library" imports nothing — it only stages and opens the editor, downloads a lossy 128 kbps preview rather than the original, and never stores license/attribution though most CC licenses require it.
  • F18 (P2) — the auto-update module is deadelectron/main/update.ts channels aren't in the IPC contract and nothing invokes them, so users never receive updates despite electron-updater shipping in every build.

Deepest structural tensions: three file lifetimes share one file_path column (drives F1/F21); projection consistency depends on call-sequence rather than the data layer (F3/F4); durable chop state lives in the WaveSurfer widget so trims churn everything. Also flagged: ~10 dead code/channel items, duplicated hardware-profile truth, permanent staging/sources/cache dirs with no GC, and CI never building or exercising the renderer.

Note: .harness/** carries a filter=doctier gitattribute but no doctier filter is configured in this environment, so the report is committed as plaintext (recorded as open question #7).

🤖 Generated with Claude Code

https://claude.ai/code/session_01MgVgoUZPub3bKYkz6J28yn


Generated by Claude Code

claude and others added 3 commits July 3, 2026 12:19
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MgVgoUZPub3bKYkz6J28yn
Resolves the P0–P3 findings from the 2026-07-03 adversarial audit
(F1–F37) except F24's OAuth2 originals download, deferred to a follow-up.

Data & lifetimes:
- F1/T1: track file ownership; deleteSample only unlinks app-owned files
- F9/F10: probe real WAV duration; robust chunk parser (padding, no-data)
- F21/F15: startup GC sweep of orphaned files under managed dirs
- F22: deleting a library sample orphans pads into recovery, not deletion
- F19c/e: stop writing dead regions JSON / pitch/stretch columns

Autosave & projection:
- F3: create-once latch prevents duplicate projects under fast edits
- F4: serialize per-project sync + UNIQUE(source_chop_id)
- F5: persist empty-regions (delete-last-chop / clear-all)
- F12: real 'error' save status

Export/render:
- F2: 24-bit via pcm_s24le (was invalid -sample_fmt s24) + per-profile test
- F6/F7: dedup filenames, allSettled, count actual writes, catch→toast
- F27/F28: ffmpeg timeout+kill, export concurrency cap, region validation

Stems & security:
- F8: per-run token, reject-on-cancel, duration cap
- F31: hash regex for stem paths; Freesound download host allowlist
- F32: local-file:// access gated to userData/DB-known/brokered paths

Startup/import, updates, coherence, observability, docs/CI:
- F14/F16/F17: window-first backfill, async import, ffmpeg+DB preflight
- F18: auto-update wired end-to-end (contract, events, UpdateBanner)
- F13/F19/F20/F23/F26: pad audition uses owned audio; single profile
  source; 16-pad ceiling; dead code removed; platform-correct key labels
- F29/F30: shared logger for swallowed errors; atomic settings write
- F34/F35/F36/F37: Windows path bridge; README contributing; cross-platform
  non-destructive seed with 0-based slots; renderer build in CI
- F11/F33/F24(partial): Freesound error toasts; persist license/author/
  freesound_id, show CC attribution, write credits.txt on export

Claude-Session: https://claude.ai/code/session_01Jk8vYAovj8RiPQSnEBnzGC
The audit doc was committed as cleartext before the doctier clean filter
was active; re-encrypt it so it satisfies the .harness private-doc policy.

Claude-Session: https://claude.ai/code/session_01Jk8vYAovj8RiPQSnEBnzGC
@RubenGlez
RubenGlez merged commit e8c135b into main Jul 3, 2026
2 checks passed
@RubenGlez
RubenGlez deleted the claude/codebase-adversarial-audit-wo8pbw branch July 3, 2026 18:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants