Capture a query's binds as plain values, without a digest or a key - #254
Merged
Merged
Conversation
The structured bind capture replaced every scalar with a keyed digest and fell back to diesel's debug rendering when no key was installed, so the structure that removes the order-only db divergences worked only once a secret was installed in every recording and replay deployment and kept equal between them. Bind values are now captured as the plain values they are, decoded from the bytes diesel sends to Postgres by type: numbers as numbers, text and host enums as strings, dates and timestamps as ISO text, json and jsonb as documents, arrays as arrays, and anything with no faithful JSON form as its bytes in hex. Binds stay keyed by placeholder, since a bind's position is part of what the statement means. The capture key, its id and the keyless fallback are removed, so structure is the only behaviour and needs no configuration. For statements that return a row the values were already on the recording unmasked, in the returned row. Integer arrays now stay numbers in the order bound, so the scorer keeps their order where it bags other arrays.
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.
#247 captured a query's binds as structure, keyed by placeholder, but replaced every scalar with a keyed digest and fell back to diesel's debug rendering when no key was installed. So the structure, which is what removes the order-only db divergences, worked only once a secret was installed in every recording and replay deployment and kept equal between them. This drops the digest. Bind values are captured as the plain values they are, and structure is the only behaviour, with no configuration.
Acting on this needs fresh recordings, as #247 did: every db call's args change shape, so it can't be validated against a recording that exists today.
What changes
"\x…". It is never guessed at.{"$1": …, "$2": …}, because a bind's position is part of what the statement means. An object is compared and hashed by key, so no rule that forgives array order can make two values traded between placeholders read as the same query.deja_runtime::capture_key(the HMAC,install_capture_key, the key id), itshmac,sha2andhexdependencies, and the keyless fallback.CapturedQuery.bindsis now always present. A capture that fails still records{"capture_failed": step}and no operand.What becomes readable, concretely
Encryptionvalues. That is ciphertext, and a tape holds ciphertext either way.refund.metadata: merchant-supplied JSON, now readable. This is the one to weigh.Secretmasking can't be honoured from the bytes. ASecret'sToSqlwrites its inner value, and diesel's only per-bindDebugpass is crate-private.How this meets the scorer's order rule
HashSet<IntentStatus>and the refund, payout and dispute equivalents, as fields ofWebhookDetails, bound as json through serde) capture as JSON arrays of strings in the set's iteration order:["failed", "succeeded"]. That is the multiset shape, so a reordered set is absorbed and named rather than blocking.a_status_set_captures_as_an_array_of_strings_in_either_orderpins the shape: two orders, the same members, all strings.eq_anyin its queries is over strings or enums.Evidence
deja-diesel/tests/bind_capture.rs:just verify: exit 0, clippy-D warningswith 0 diagnostics, 1,333 Rust tests and 79 web tests passed, 0 failed. It was run before the last four test additions; the crate's own suite was run after them.cargo +1.85.0 checkpasses on the runtime crates.ToSqland Postgres' binary formats, and no hyperswitch column type decoded wrongly rather than hexed. Its test gaps are covered above.