fix(agent): redact row values MySQL inlines into its error line - #7
Merged
Merged
Conversation
A verification pass caught a leak the earlier redaction fix missed. Postgres isolates row data in DETAIL and CONTEXT, so dropping whole segments removes it. MySQL does not: it puts the offending value on the same ERROR line as the reason, so segment filtering never touched it and a user's data went out on the wire. before: Duplicate entry 'alice@example.com' for key 'users.email' after: Duplicate entry '[redacted]' for key 'users.email' Only the quoted value is replaced. Dropping the whole line would take the reason with it, and the identifier after "for key" or "for column" is schema rather than data, so naming the constraint that failed still works. The test that should have caught this carried dave@example.com in its input and only asserted the DETAIL line was hidden, so the suite stayed green while the address shipped. That is the same shape as the original bug: a test asserting something adjacent to the thing that matters. It now asserts the value is gone and the constraint name survives. SECURITY.md stops overclaiming. This is pattern matching against known engine output, it has now been wrong twice, and the page says so and points at standalone mode as the version of the promise that does not depend on us keeping up with database vendors. Also renames the cron example's results file: --json emits pretty-printed objects, so a .jsonl extension promised one-per-line and would break the obvious `tail -1 | jq`.
dabelle
pushed a commit
that referenced
this pull request
Sep 19, 2026
fix(agent): redact row values MySQL inlines into its error line
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.
A verification pass caught a leak the earlier redaction fix missed.
Postgres isolates row data in
DETAILandCONTEXT, so dropping whole segments removes it. MySQL does not: it puts the offending value on the sameERRORline as the reason, so segment filtering never touched it and the value went out on the wire to the control plane, and from there into alert bodies.Only the quoted value is replaced. Dropping the whole line would take the reason with it, and the identifier after
for keyorfor columnis schema rather than data, so naming the constraint that failed still works.The test that should have caught this carried
dave@example.comin its input and only asserted theDETAILline was hidden, so the suite stayed green while the address shipped. Same shape as the original bug: a test asserting something adjacent to the thing that matters. It now asserts the value is gone and the constraint name survives, plus two new cases coveringDuplicate entryandIncorrect … value:.SECURITY.mdstops overclaiming. This is pattern matching against known engine output, it has now been wrong twice, and the page says so and points at standalone mode as the version of the promise that does not depend on us keeping up with database vendors.Also renames the cron example's results file:
--jsonemits pretty-printed objects, so.jsonlpromised one-per-line and would break the obvioustail -1 | jq.