Finding
end_session (line 209), mark_scrobble_eligible (262), and mark_scrobbled (297) execute single-row UPDATEs by session id and return Ok(()) without checking rows_affected, the same pattern the require_affected sweep fixed elsewhere; a stale/wrong SessionId silently no-ops instead of surfacing NotFound (currently only test-exercised, but public repo-layer contract for future scrobble consumers).
Evidence
crates/apotheke/src/repo/play_history/mod.rs:209,262,297. Surfaced by the 2026-07-03 deep-audit workflow (adversarially verified + Opus-judged).
Why this matters
A stale or wrong session id passed to end_session/mark_scrobble_eligible/mark_scrobbled silently no-ops instead of surfacing NotFound, hiding scrobble-tracking bugs from future consumers of the repo API.
Desired correction
Route the three updates through require_affected() so a zero-row match returns NotFound, consistent with the swept sibling modules.
Done when: the defect's failure mode no longer reproduces and a regression test covers it.
Finding
end_session (line 209), mark_scrobble_eligible (262), and mark_scrobbled (297) execute single-row UPDATEs by session id and return Ok(()) without checking rows_affected, the same pattern the require_affected sweep fixed elsewhere; a stale/wrong SessionId silently no-ops instead of surfacing NotFound (currently only test-exercised, but public repo-layer contract for future scrobble consumers).
Evidence
crates/apotheke/src/repo/play_history/mod.rs:209,262,297. Surfaced by the 2026-07-03 deep-audit workflow (adversarially verified + Opus-judged).Why this matters
A stale or wrong session id passed to end_session/mark_scrobble_eligible/mark_scrobbled silently no-ops instead of surfacing NotFound, hiding scrobble-tracking bugs from future consumers of the repo API.
Desired correction
Route the three updates through require_affected() so a zero-row match returns NotFound, consistent with the swept sibling modules.
Done when: the defect's failure mode no longer reproduces and a regression test covers it.