ChrisBeWithYouandClaude Fable 5 1784765822 feat(sloppak): project a synthetic Vocals arrangement from vocal_pitch
A sloppak carrying a sung-melody sidecar (`vocal_pitch`, feedpak-spec
7.2) previously had no vocal arrangement identity: the melody was not
selectable in the player, visualizers had nothing to auto-match, and -
critically - a sung run had no honest place to record stats. Posting
against the selected fretted arrangement index would corrupt that
arrangement's best_accuracy/best_score and credit progression to the
wrong instrument; posting an out-of-range index is rejected outright.

Fix: project a synthetic chartless "Vocals" arrangement (type "vocals")
wherever arrangements are enumerated, mirroring the drum-only
placeholder contract:

- load_song(): appended after the arrangement loop so the melody is
  selectable and `matchesArrangement` auto-select can key on it. The
  entry carries no notes - the melody itself stays in the sidecar,
  which vocal visualizers fetch directly. Melody-only paks (no fretted
  arrangements) now load, deriving song length from the last sung
  note's end when the manifest omits a duration; the sidecar read is
  path-confined and fully permissive (a malformed file only costs the
  duration fallback, never the load).
- extract_meta(): the metadata mirror, so the library index and the
  /api/stats arrangement-count validation agree with the player's
  arrangement list.

Both sides suppress the projection when the pak already ships an
explicit vocal arrangement (editor-authored `type`, or a vocal-ish
name); a chartless vocal-NAMED manifest entry suppresses only the
metadata side (it is already counted there) while load_song projects
its playable counterpart, keeping the counts in step.

instrument_for_arrangement() already maps the name to "vocals", so
career/progression attribution works with no further changes.

Tests: 12 new (projection both sides, dedupe by type and by name,
melody-only duration fallback, malformed/escaping sidecar permissive-
ness, count parity load_song vs extract_meta, instrument attribution);
sloppak/stats/progression/arrangement/drum slice green (459 passed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EJ6BDHb3K4ZHUDDAHMtKCV
Signed-off-by: ChrisBeWithYou <chris@rifflarr.local>
2026-07-22 12:00:05 -05:00
2026-06-16 18:47:13 +02:00
2026-06-16 18:47:13 +02:00
2026-06-16 18:47:13 +02:00
2026-06-16 18:47:13 +02:00
2026-06-16 18:47:13 +02:00
2026-06-16 18:47:13 +02:00
2026-06-16 18:47:13 +02:00
2026-07-03 13:41:50 +02:00
S
Description
No description provided
AGPL-3.0
981 MiB
Languages
JavaScript 56.4%
Python 37.1%
HTML 3.2%
CSS 1.2%
TypeScript 1.1%
Other 1%