Document what Engine DJ does to a converted library - #7
Merged
Conversation
Two findings from measuring a real 3,673-track stick, both previously unwritten down and both easy to mistake for defects. Opening Engine DJ can merge its desktop library onto the stick -------------------------------------------------------------- A convert followed by a clean verify, then Engine DJ opened, then verify again: playlist_count expected=45 actual=48, naming playlists in no rekordbox playlist. Those playlists are real and Engine added them on purpose. Controlled repeat with Engine's desktop database cleared, same conversion both times: 48 playlists with the desktop populated, 45 with it cleared, and in the cleared run not one row changed. So the extras were Engine syncing its own desktop library, not corruption and not something rb2engine wrote — their lastEditTime values predated the conversion, consistent with rows that already existed on the desktop side. Troubleshooting now covers this, including how to tell Engine's rows from ours: we pin lastEditTime to the epoch on every playlist we write, so anything with a real timestamp came from Engine. That discriminator survives Engine reassigning ids, which the id watermark does not. Engine populates currentPlayedIndiciator itself ----------------------------------------------- Diffing a pristine conversion against the same database after Engine had opened and closed it: Information.currentPlayedIndiciator 0 -> 1698144667125441751 was the ONLY change. No schema objects, no pragma changes, and Track, PerformanceData, AlbumArt, Playlist and PlaylistEntity all byte-identical. Recorded next to the pin so the next reader does not have to re-derive it, and so the question "should we write that field too?" has a documented answer: no. Engine sets it on first open, and writing an opaque constant would forfeit byte-identical rebuilds for nothing. Docs and comments only — no behaviour change. 704 tests, ruff + mypy clean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V3aF4y4GdsuJta2bfYUZ8w
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.
Docs and comments only — no behaviour change.
Two things measured on a real 3,673-track stick that were previously undocumented, and both of which look like defects if you don't know about them.
1. Opening Engine DJ can merge its desktop library onto the stick
Convert → clean verify → open Engine DJ → verify again:
naming playlists that exist in no rekordbox playlist. Controlled repeat with Engine's desktop database cleared, identical conversion both times:
So the extras were Engine syncing its own desktop library — a legitimate feature, not corruption and not something rb2engine wrote. Their
lastEditTimevalues predated the conversion, consistent with rows that already existed on the desktop side.verifywas correct to report it. Troubleshooting now explains the cause, gives the one-line SQL to tell Engine's rows from ours, and says plainly: verify right after convert, before launching Engine DJ.The discriminator matters — we pin
lastEditTimeto the epoch on every playlist row we write, so anything with a real timestamp came from Engine. That survives Engine reassigning ids, which the id watermark does not.2. Engine populates
currentPlayedIndiciatoritselfDiffing a pristine conversion against the same database after Engine opened and closed it, across schema, pragmas and every cell (blobs by hash):
That was the only change. No schema objects added, no pragma changes, and
Track,PerformanceData,AlbumArt,Playlist,PlaylistEntityall byte-identical.Recorded next to
_DETERMINISTIC_PLAYED_INDICATORso the question "should we write that field too?" has a documented answer: no. Engine sets it on first open, and writing an opaque constant would forfeit byte-identical rebuilds for nothing.Verification
🤖 Generated with Claude Code
https://claude.ai/code/session_01V3aF4y4GdsuJta2bfYUZ8w