Fix legacy ID handling: accept occurrence IDs, hash verbatim - #5
Fix legacy ID handling: accept occurrence IDs, hash verbatim#5maximilliangeorge wants to merge 2 commits into
Conversation
Things Cloud histories from early clients contain IDs of the form `<UUID>-YYYYMMDD` for spawned occurrences of repeating tasks. These appear both as object keys and in relationship arrays, and failed ThingsId parsing, so folding the append log aborted with "Corrupt log entry" for affected accounts. Parse the suffixed form by SHA1-hashing the full uppercase string, the same scheme legacy UUIDs use. The suffix stays part of the hashed identity: the occurrence is a distinct entity from its template (which it references via `rt`), so it must not collapse into the template's ID the way the `ACTIONGROUP-` prefix is stripped. Fixes evanpurkhiser#4 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The server's compact-ID migration hashed each legacy ID string exactly as written: histories reference an uppercase-keyed item by base58(SHA1(uppercase string)) and a lowercase-keyed one by base58(SHA1(lowercase string)). Case-normalizing to uppercase before hashing therefore split a lowercase-keyed item from its own later compact-keyed updates - in a real history the orphaned update was the task's trash flag, so a trashed task kept showing up in Today. Hash the verbatim string, making legacy UUID parsing case-sensitive to match, and bump the state-cache version so stale folded caches rebuild. Fixes evanpurkhiser#6 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Pushed a second commit fixing a related legacy-ID bug found right after: trashed items reappearing in Today (#6). The server's compact-ID migration hashed legacy ID strings verbatim (verified against real history data: uppercase-keyed |
|
Did you reverse the things3 app to figure out how they translated these old IDs to new style IDs for compat? |
Fixes #4
Problem
Histories that go back far enough contain IDs of the form
<UUID>-YYYYMMDD(e.g.5F3AE5FB-3FF3-49DE-BF34-91224AACC9FF-20170524), which early Things clients used for spawned occurrences of repeating tasks. They appear both as object keys and in relationship arrays (ts,rt).ThingsId::from_strrejected them, so the first log line containing one failedWireItemdeserialization and every command aborted with:Same class of legacy-ID issue as #3.
Fix
ThingsId::from_strnow recognizes the<UUID>-YYYYMMDDshape and canonicalizes it by SHA1-hashing the full uppercase string — the same scheme legacy UUIDs already use. Unlike theACTIONGROUP-prefix, the date suffix is not stripped: the occurrence is a distinct entity from its template (it references the template viart), so it must hash to its own distinct 16 bytes rather than collapsing into the template's ID.Tests
log_cachefold test seeded with the real-world entry shapeVerified against my real 12MB append log — previously aborted at byte 3224757, now folds cleanly. All unit tests pass; the 6 failing
cli_trycmdsnapshot tests fail identically on cleanmainin my environment, so they're unrelated.🤖 Generated with Claude Code