fix: the second review pass — DLP failure tail, caps on every wire, native Responses stickiness, finish and refusal mapping - #126
Merged
Conversation
Collaborator
Author
|
Follow-up pass: one more finding held and is fixed as the sixth commit — under outbound DLP the error tail copied the terminal error's message unredacted, so a vendor error quoting request content could carry it past the redaction. The message now goes through the same outbound redaction; e2e pins an email that appears only in the vendor's |
CMGS
force-pushed
the
cut/test-dedup-and-small-cuts
branch
from
September 23, 2026 12:54
bc4230f to
8e123d0
Compare
…r event Under outbound DLP the native frames are replaced by a tail synthesized from the redacted reply, and that tail ended a failed stream with response.completed carrying status failed and no error. The tail now closes with the stream's failure, so the client gets the error event as it does on a live stream.
…Responses The cap rode the request only from the direct Anthropic wire and OpenAI chat; Bedrock InvokeModel and Converse, and a Responses max_output_tokens, went through the shared send path with no cap, so the 16384 default still met the plain account timeout there. The cap now sits on the engine base, which every send path reads.
…ariant The conversation key read only normalized turns; a native Responses request keeps its input in the raw body, so the first turn was split by request id and the reasoning continuation pinned to the requested model. The key now falls back to the input's first user text.
chat_finish turned every finish but length into tool_calls when tool calls were present, so a filtered reply read as a normal tool call on the chat surface and in batch results. Only a normal stop becomes tool_calls.
The reply mapper read only output_text parts and the stream only output_text deltas, so a refusal under structured outputs came back as empty content with a normal finish. A chat client can request structured outputs by sending text.format as an extra, which rides through to the Responses body, so the refusal path is reachable off the native surface too; #117 was closed on the wrong reason. Refusal parts and deltas are now the reply text. Fixes #117
The error tail a redacted native Responses stream ends with copied the terminal error as the engine saw it, while outbound DLP walked only the response. A vendor error that quotes request content carried the quoted text past the redaction. The terminal error's message now goes through the same outbound redaction as the reply.
CMGS
force-pushed
the
fix/codex-round-followups
branch
from
September 23, 2026 13:06
32763a6 to
875145d
Compare
This was referenced Sep 23, 2026
Chat-surface requests served by a Responses model are stored by OpenAI (store defaults to true)
#114
Closed
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.
Summary
Stacked on #125. A second review pass over the final tree (main → #125) raised five actionable items and two ownership/perf notes; a follow-up pass on this branch raised one more. Each was read against the source; the six hold and are fixed here, the two notes are declined with the reason below.
response.failedresponse.completedcarryingstatus: failedand no error (#123 fixed the terminal row, not the client frames)event: error, noresponse.completed, no raw emailmax_output_tokens, went through the shared send path with no cap, so the 16384 default still met the plain account timeout therejp.anthropic.claude-opus-5-5over Bedrock InvokeModel withtimeout_seconds: 20, non-streaming, nomax_tokens, a 1200-word essay: before 408model_timeout_exceptionafter 20 s, after 200 after 39 s with 3730 completion tokensgpt-5.4-minicanaried togpt-5-mini(reasons by default), native/v1/responses, no user id,include: [reasoning.encrypted_content]: before, turn 1 served bygpt-5-miniwith a reasoning item and the replay served bygpt-5.4-mini; after, both turns bygpt-5-minicontent_filterorlengthfinishchat_finishlengthbecametool_callswhen tool calls were present, so a filtered reply read as a normal tool call on the chat surface and in batch resultscontent_filterandmax_tokenssurvive, only a normal stop becomestool_callsresponse.failedmessage comes back as[REDACTED_EMAIL]inside theerroreventresponse_formatdoes not cross to the Responses body, but atext.formatextra rides through like any extra, so structured outputs and their refusal parts are reachable off the native surface; the mapper read onlyoutput_textrefusalpart and aresponse.refusal.deltaland in the reply textDeclined:
record_responses_usageclones the usage object: once per stream at its end, about a hundred bytes, and the native branch must keep the frame it forwards. Moving it means restructuring the completion arm around a shared borrow for a copy that costs less than the frame's parse. Kept.batch_createon the in-memory store scans retained batches on every submit: the path is batch submission only, gated by the key's QPS, over the batches the single-node memory store kept in the last 30 days, and it is the same shape asvideo_job_put. No mechanism added.Verification
git archive | tar -m), passescargo fmt --all -- --check,cargo clippy --workspace --all-targets -- -D warningsandcargo test --workspace; the test count rises 679 → 684.rust:1linux/arm64 container with rustc 1.98.0 at the final commit: fmt ✓, clippy ✓, 684 passed, 0 failed, 4 ignored.chat_finish, and nothing on the DLP-off stream path. No bench: none of these changes a served frame or adds an allocation on the success path.Size
Production code +47 net (+65 −18), tests +180, docs 0. Comment lines in
*.rs: 2 added (one-line docs on the newfirst_user_turnfallback and thedlp_redact_texthelper), 0 removed. Whole-repo non-blank production Rust 26147 → 26193, comment density 8.75% → 8.74%. Per commit (prod net): the DLP failure tail +7, the cap on the engine base +9, the native conversation key +16, the finish rule 0, the refusal text +4, the redacted failure message +12.