Skip to content

fix(career): gig song selection — full-genre pool, working re-roll, and the venue pack loads#976

Merged
byrongamatos merged 2 commits into
mainfrom
fix/gig-song-selection
Jul 15, 2026
Merged

fix(career): gig song selection — full-genre pool, working re-roll, and the venue pack loads#976
byrongamatos merged 2 commits into
mainfrom
fix/gig-song-selection

Conversation

@byrongamatos

Copy link
Copy Markdown
Contributor

Three tester reports on career gigs, all reproduced.

"Metalcore says 137 songs only shows 1 in the gig list"

The gig pool was built from only two sets: songs played on this passport's instrument, and songs never played at all (filename NOT IN song_stats). A song played on a different instrument's arrangement is in neither — it has a stats row (so the unplayed filler skipped it) and its played bucket is that other instrument's. It could never be gigged.

Reproduced against the real propose logic: a guitar passport with 137 bass-played metalcore songs → 404, zero songs.

"Passport re-roll does not change songs"

A set drawn from that filler was the library's first N in table order, every call. Re-roll re-proposes → identical set. Reproduced: 3 proposals byte-identical.

Both fixed by _unplayed_genre_songs_fill_genre_songs: the pool is now every library song of the genre the set hasn't already picked, shuffled.

"Venue doesn't load when starting song from passport. Loads standard particles."

crowd.setManifest(venue) — what actually loads a venue's pack — is reached only through pushCrowdManifest, called only from the career tab's refresh(). A gig navigates away from that tab, so it never runs. startGig set the venue override but never pushed the manifest, so the venue viz turned on (3D highway) while its crowd/stage pack never loaded. startGig now pushes it.

The first two are reproduced + gated by tests (both fail on pre-fix). The venue-pack fix is a call-graph fact (pushCrowdManifest has one other caller and startGig is not it) but was fixed by static analysis — I could not reproduce the visual symptom locally because this instance had a manifest already applied. On-device confirmation on a real passport gig still owed. Career suite green.

Two tester reports, one root: the gig song pool was built from only two sets —
songs played ON THIS PASSPORT'S INSTRUMENT, and songs never played AT ALL
(`filename NOT IN song_stats`).

A song played on a DIFFERENT instrument's arrangement is in neither: it has a
stats row (so the "unplayed" filler skipped it), and its played bucket is that
other instrument's, not this passport's. It could never be gigged.

- "Metalcore says 137 songs only shows 1 in the gig list" — a library of
  metalcore all played on another instrument. Reproduced: a guitar passport with
  137 bass-played metalcore songs got a 404, zero songs. The "1" the tester saw
  was whatever handful happened to be on-instrument or truly unplayed.

- "Passport re-roll does not change songs" — a set drawn from that filler was the
  library's first N in table ORDER, every call. Re-roll re-proposes, so it
  returned the identical set. Reproduced: 3 proposals, byte-identical.

_unplayed_genre_songs -> _fill_genre_songs: the pool is now every library song of
the genre the set hasn't already picked (a stats row on some other instrument has
no bearing on whether a song can be in THIS gig), and it is shuffled so re-roll
actually re-rolls.

Both reproduced against the real propose logic before the fix and pinned as
regression tests (both fail on the pre-fix routes.py). Full career suite green.
Tester: "Venue doesn't load when starting song from passport. Loads standard
particles."

crowd.setManifest(venue) — the call that actually loads a venue's crowd/stage
pack — is reached ONLY through pushCrowdManifest, and pushCrowdManifest is
called ONLY from refresh(), the career tab's own reload. A gig navigates AWAY
from the career tab to the player, so refresh() never runs during it. startGig
set the venue override and nulled _appliedManifestVenue but never re-pushed, so
the venue visualization turned on (3D highway) while its pack never loaded — the
song played over the bare highway backdrop, or over whatever venue a previous
refresh() had left applied.

startGig now pushes the crowd manifest for the gig venue right after setting the
override, using the career state the booking screen already fetched.

This is a call-graph fact, not a guess (pushCrowdManifest has exactly one other
caller and startGig is not it), but it is fixed by static analysis — I could not
reproduce the user-visible symptom locally because this instance happened to have
a manifest already applied from a prior refresh. On-device confirmation on a real
passport gig is still owed.

Guard test: startGig must push the manifest after setting the override (fails on
the pre-fix source). Career suite green.
@byrongamatos
byrongamatos merged commit 365cec1 into main Jul 15, 2026
5 checks passed
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.

1 participant