deja::synth — deterministic values a Substitute miss can be answered with - #134
Merged
Merged
Conversation
This was referenced Sep 10, 2026
maverox
added this pull request to stack #142
September 11, 2026 10:20
| let rendered = uuid_v8(&miss(json!({"key": "k1"}))); | ||
|
|
||
| let groups: Vec<&str> = rendered.split('-').collect(); | ||
| assert_eq!(groups.len(), 5, "must be uuid-shaped: {rendered}"); |
| assert_eq!( | ||
| groups.iter().map(|g| g.len()).collect::<Vec<_>>(), | ||
| vec![8, 4, 4, 4, 12], | ||
| "must be uuid-shaped: {rendered}" |
| ); | ||
| assert!( | ||
| rendered.chars().all(|c| c == '-' || c.is_ascii_hexdigit()), | ||
| "must be parseable: {rendered}" |
Comment on lines
+251
to
+252
| "version nibble must be 8 (RFC 9562 custom), NOT 4 or 7 — that is what \ | ||
| makes the synthesized space disjoint from the recorded one: {rendered}" |
| assert_eq!( | ||
| variant & 0b1100, | ||
| 0b1000, | ||
| "variant must be RFC 4122, or the value is not a valid uuid: {rendered}" |
maverox
force-pushed
the
work/synth-helpers
branch
from
September 14, 2026 10:36
0eb33f8 to
66403aa
Compare
maverox
force-pushed
the
work/synth-helpers
branch
from
September 14, 2026 10:43
66403aa to
c3037a4
Compare
maverox
force-pushed
the
work/synth-helpers
branch
from
September 14, 2026 13:38
c3037a4 to
faf3055
Compare
`deja::synth` gives a site the sanctioned way to total the recording's partial function: `uuid_v8`, `id`, `bytes`, `u64` and `monotonic`, each a pure function of the `SubstituteMiss` handed to the miss arm. Every helper hashes the SAME canonical image the lookup key was built from (`hash_value`, now `pub(crate)`: object keys sorted, array order significant). Two calls that address the same recorded entry therefore synthesize the same value by construction rather than by coincidence, and a permuted array -- which misses at every address rank -- synthesizes a different one. Both halves are asserted. Non-collision gets the most attention because it is the property that is easy to skip and expensive to skip. Deja substitutes RESULTS, so a synthesized value flows into downstream ARGS; if a synthesized uuid could equal a recorded one, the next Substitute lookup keyed on it would HIT -- a false resync on fabricated data, silently. So `uuid_v8` draws from RFC 9562's version-8 custom space, which real code (v4, v7) never produces, and `id` carries a reserved prefix. The version and variant nibbles are asserted, not assumed. Helpers are domain-separated from each other, so a site using two of them is not handed the same bits twice under different names, and `bytes` draws one digest per 8-byte block so lengthening a draw extends it rather than rewriting it -- and so a 32-byte draw is not one 8-byte value repeated four times. `monotonic` is named for what it guarantees and documented for what it does not: successive misses at ONE call site advance, two different sites both start from the origin. A miss carries a per-site occurrence and no global counter, and deriving one would mean advancing shared replay state from the miss path, perturbing the very keys the lookup is built on. A caller that needs cross-site ordering has nothing derivable and should return `NoValue`; there is a test asserting the limit so nobody reads a stronger promise into the name. `SubstituteMiss` gains `occurrence` and `correlation_id`, built lazily on the miss branch from the identity the seam already holds and the same ambient correlation fallback the record seam uses. Correlation is safe in the digest: the orchestrator replays the same correlation ids to every candidate, so it separates two requests without separating two candidates -- which is what keeps them comparable past the edge of the tape. Four mutations, four kills, each by a distinct test: no domain separator, uuid stamped v4, occurrence dropped from the digest, one digest for every byte block. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019FmXkygUmueraF9oR4oqwS
maverox
force-pushed
the
work/synth-helpers
branch
from
September 14, 2026 13:57
faf3055 to
1c22a14
Compare
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
deja::synthgives a site the sanctioned way to total the recording's partial function:uuid_v8,id,bytes,u64,monotonic— each a pure function of theSubstituteMisshanded to the miss arm.Keyed the way the lookup is keyed
Every helper hashes the same canonical image the lookup key was built from (
hash_value, nowpub(crate)). So:{"a":1,"b":2}and{"b":2,"a":1}synthesize the same value — they address the same recorded entry.[1,2]and[2,1]synthesize different values — a permuted array misses at every address rank, so it is a different call.Both halves are asserted. This is the property that makes "same query → same value" true by construction rather than by coincidence.
Non-collision, made structural
This is the property that is easy to skip and expensive to skip. Deja substitutes results, so a synthesized value flows into downstream args. If a synthesized uuid could equal a recorded one, the next Substitute lookup keyed on it would HIT — a false resync on fabricated data, silently.
So
uuid_v8draws from RFC 9562's version-8 custom space, which real code (v4, v7) never produces, andidcarries a reserveddeja-synth-prefix. The version and variant nibbles are asserted, not assumed.Two things the helpers guarantee about each other
bytesextends rather than rewrites — one digest per 8-byte block, sobytes::<8>is a prefix ofbytes::<32>, and a 32-byte draw is not one 8-byte value repeated four times. The second half needs its own test: without it, a single reused digest passes the extension assertion unchanged.monotonicis named for what it guaranteesSuccessive misses at one call site advance. Two different sites both start from the origin — a miss carries a per-site occurrence and no global counter, and deriving one would mean advancing shared replay state from the miss path, perturbing the very keys the lookup is built on.
A caller that needs cross-site ordering has nothing derivable and should return
NoValue. There is a test asserting that limit, so nobody reads a stronger promise into the name.SubstituteMissgains two fieldsoccurrenceandcorrelation_id, built lazily on the miss branch from the identity the seam already holds and the same ambient correlation fallback the record seam uses.newkeeps its four arguments; the context arrives throughwith_call_context.Correlation is safe in the digest: the orchestrator replays the same correlation ids to every candidate, so including it separates two requests without separating two candidates — which is exactly what keeps them comparable past the edge of the tape.
Evidence
just verifygreen. 12 new tests. Four mutations, four kills, each by a distinct test:the_helpers_are_domain_separated_from_each_other,the_blocks_of_a_byte_draw_differ_from_each_othera_synthesized_uuid_is_in_the_reserved_version_8_spacea_different_miss_synthesizes_a_different_valuethe_blocks_of_a_byte_draw_differ_from_each_other🤖 Generated with Claude Code
https://claude.ai/code/session_019FmXkygUmueraF9oR4oqwS