fix: embed real timestamp in toV7-derived UUIDs#18
Merged
Conversation
toV7 built fake UUIDv7s — it used the first 48 bits of MD5(key) as the timestamp field and only forced the version nibble to 7, so every derived trace/span ID carried a garbage timestamp (decoding to ~year 5241). Embed a real millisecond timestamp in the first 48 bits while keeping the entropy/node bytes from MD5(key), so IDs stay deterministic (idempotent upserts + duplicate-fire dedup) but now sort chronologically and match the entity's start_time: - trace ID: bucket-aligned ms (keeps both concurrent onPrompt fires on the same timestamp, so the dedup guarantee is unchanged) - span IDs: the message's own transcript timestamp via millisFromISO - parent-span FK reference in onSubagentStop now looks up the parent entry's timestamp so it reproduces the exact ID the parent span was built with Existing IDs are unaffected; only newly generated IDs decode correctly. Adds uuid_test.go and rebuilds all platform binaries. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Problem
toV7()produced fake UUIDv7s. It MD5-hashed the input key and used the first 48 bits of the hash as the timestamp field, only forcing the version nibble to7. So everytoV7-derived ID (trace IDs + all transcript-derived span IDs) carried a random timestamp.A real trace observed via the Opik MCP server:
5de5a0f2-b1f4-7dfb-aef2-9365c5cc45942026-06-09T08:25:29.754Z5241-07-28T00:05:53Z❌ (~3,200 years off)The MD5 hashing itself isn't gratuitous — it makes IDs deterministic, which is what the duplicate-fire dedup guard in
onPromptand idempotent upserts rely on. The fix preserves that.Fix
toV7(key, tsMillis)now embeds a real millisecond timestamp in the first 48 bits and derives only the entropy/node bytes fromMD5(key). Same key + same timestamp → same ID (determinism preserved), but the ID now sorts chronologically and its embedded time matchesstart_time.Callers updated:
bucket*5*1000). Bucket alignment is deliberate: both concurrentonPromptfires share the same bucket, so they still compute an identical ID and the dedup guarantee is unchanged. Trade-off: embedded time can trailstart_timeby up to the ~5s dedup window (exact ms and perfect determinism are mutually exclusive under bucketed dedup).millisFromISO(p.Timestamp), matching each span'sstart_timeexactly.onSubagentStop) — looks up the parent Task entry's timestamp so the reference reproduces the exact ID the parent span was built with. Hoisted an already-present transcript read; no extra I/O on the common path.Notes
src/uuid_test.gocovers: timestamp round-trips through the first 48 bits, version/variant bits, determinism, andmillisFromISOparsing incl. the failure→0fallback.go build,go vet, fullgo test ./...pass; all four platform binaries rebuilt.🤖 Generated with Claude Code