Part of #320. Governing: ADR-0008, ADR-0017, SPEC vibes-ai-mixtape-engine, SPEC similar-artists-discovery. All review CONFIRMED.
Requirements
Acceptance Criteria
- Empty-choices LLM response yields a user-visible mixtape-error event, process alive
- Enhancement over a listen with an artist-less track completes
- Regenerated album enrichment includes cover-art commentary when images exist
- DJ with mixtapes is deletable (or cleanly refused), never 500
Branch
feature/339-llm-hardening-mixtape-fixes
PR Convention
PR title references the story; body ends with Closes #339, references the parent epic and governing artifacts above.
🤖 Posted on behalf of @joestump by Claude.
Part of #320. Governing: ADR-0008, ADR-0017, SPEC vibes-ai-mixtape-engine, SPEC similar-artists-discovery. All review CONFIRMED.
Requirements
callOpenAIreturnsresp.Choices[0].Message.Contentwith no length guard, and all three calling handlers spawnGenerateMixtapein bare goroutines with norecover()— an empty-choices 200 response (content filter, proxy passthrough) crashes the server (internal/vibes/generator.go:650; enhancer.go:513 already has the guard). Add the guard ANDrecover()in the spawned goroutines (publish a mixtape-error event on panic)getListeningHistorydereferencest.Edges.Artist.Namewithout the nil check Album gets; Track's artist edge is not Required in the schema (internal/vibes/enhancer.go:385,391)EnrichAlbumsetsdata.HasCoverArt=trueafter the prompt template has already executed, so the{{.HasCoverArt}}branches in album.tmpl never fire — cover-art commentary/dominant colors silently always empty (internal/enrichers/openai/openai.go:583-607)storeSimilarArtistsdeletes all existing rows before inserting, no transaction — an LLM response whose artists match nothing wipes prior data and returns nil (internal/services/similar_artists.go:358-414). Validate matches first, write in a transactionOnDelete: NoAction,_fk=1) → constraint error → 500; DJ undeletable from the UI (internal/handlers/vibes.go:228). Cascade or block-with-messagescheduleform value → ent enum validation error → 500; validate and return 400 with a usable message (vibes.go:354,447)Acceptance Criteria
Branch
feature/339-llm-hardening-mixtape-fixesPR Convention
PR title references the story; body ends with
Closes #339, references the parent epic and governing artifacts above.🤖 Posted on behalf of
@joestumpby Claude.