Transition voting: rate a blend, adapt that pair's next one - #126
Merged
Merged
Conversation
Thumbs up/down on the transition you just heard. Votes are keyed by the *directional* track pair (A→B is rated separately from B→A — the blend isn't symmetric) and snapshot the settings that actually produced the blend, so a downvote on an already-simplified transition is distinguishable from one on the user's full settings. Repeated downvotes back that pair's blend off a step at a time; upvotes let it climb back. - TransitionVote (@model): plain UUID references rather than SwiftData relationships, so votes survive a track being deleted and re-imported without cascade rules getting involved. - TransitionFeedback.simplificationLevel (ContinuityCore): pure vote-history → level math, unit-tested and Linux-portable like the rest of the DSP//policy code. - TransitionSettings.simplified(level:): progressively drops beatmatching, bass swap, and harmonic mixing, and shortens the blend. - Player+Voting: adaptedTransitionSettings is cached per pair, because the scheduling check runs at 20 Hz and the history lookup is a SwiftData fetch. Cache is invalidated on a new vote and on any settings change. - clearTransitionState drops the votable record: an aborted blend was never fully heard, so there's nothing to rate. - RootView supplies vote history via the same hook pattern as onQueueExhausted; TransitionVoteBar appears in both the compact and sheet Now Playing layouts. Reassembled from work that was split across an unpushed local commit and a stash, then rebased onto main (clearTransitionState needed both the new pitch-settle teardown and the vote teardown). ContinuityCore: 175 tests pass. App target builds for the simulator. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
sanylax0
approved these changes
Jul 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
This is your own WIP, reassembled — please sanity-check the design before merging. The feature was split across two places and neither built on its own:
f7c07ca "Worktree WIP"onmain—TransitionVote,Player+Voting,TransitionVoteBar,TransitionFeedbacktestsstash@{0}onfeat/transition-voting— the stored properties (transitionVoteHistoryStorage,adaptationCache),TransitionSettings.simplified(level:), and the app-layer wiringThat's why
Player+Voting.swiftreferenced three symbols declared nowhere in the repo. The halves are disjoint and compose exactly; together they build and pass. Yourstash@{0}and thefeat/transition-votingbranch are untouched — I usedstash apply, notpop, and worked on a scratch branch.The feature
Thumbs up/down on the transition you just heard. Votes are keyed by the directional track pair (A→B rated separately from B→A — the blend isn't symmetric) and snapshot the settings that actually produced the blend, so a downvote on an already-simplified transition is distinguishable from one on your full settings. Repeated downvotes back that pair's blend off a step at a time; upvotes let it climb back.
TransitionVote(@Model) — plain UUID references rather than SwiftData relationships, so votes survive a track being deleted and re-imported without cascade rules getting involved.TransitionFeedback.simplificationLevel(ContinuityCore) — pure vote-history → level math, unit-tested and Linux-portable like the rest of the policy code.TransitionSettings.simplified(level:)— progressively drops beatmatching, bass swap, harmonic mixing, and shortens the blend.Player+Voting—adaptedTransitionSettingsis cached per pair, because the scheduling check runs at 20 Hz and the history lookup is a SwiftData fetch. Invalidated on a new vote and on any settings change.clearTransitionStatedrops the votable record — an aborted blend was never fully heard, so there's nothing to rate.RootViewsupplies vote history via the same hook pattern asonQueueExhausted;TransitionVoteBarappears in both the compact and sheet Now Playing layouts.Rebase note
One conflict, resolved by keeping both sides:
origin/main(#121) added pitch-settle teardown toclearTransitionState(), and this branch added vote-state teardown to the same function. Both are now there.Testing
TransitionFeedbackTests).🤖 Generated with Claude Code