fix(responses): validate stateful requests and include projections - #1480
Open
pjb157 wants to merge 3 commits into
Open
fix(responses): validate stateful requests and include projections#1480pjb157 wants to merge 3 commits into
pjb157 wants to merge 3 commits into
Conversation
Deploying control-layer with
|
| Latest commit: |
9f856be
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://0d26c256.control-layer.pages.dev |
| Branch Preview URL: | https://peter-fix-zdr-responses-vali.control-layer.pages.dev |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR tightens contract validation for the OpenAI Responses API in dwctl’s inference middleware and makes previous_response_id hydration resilient to partially-shaped stored response objects, especially in zero-data-retention (ZDR) scenarios.
Changes:
- Added early 400s for unsupported
includevalues and forprevious_response_idwhen ZDR is enabled, ensuring validation happens before lifecycle/storage access. - Updated hydration to deserialize only the stored
outputitems (instead of requiring a fully schema-valid stored response object), preventing avoidable 5xx errors. - Added regression tests covering ZDR continuation rejection and unsupported
includerejection, plus a unit test for partial stored-response hydration.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
dwctl/src/test/responses.rs |
Adds integration tests asserting contract 400s for ZDR stateful continuation and unsupported include, and verifies no lifecycle rows are created. |
dwctl/src/inference/translation/responses/hydrate.rs |
Hydrates from stored output only (tolerant to partial stored shapes) and adds a focused unit test for the new behavior. |
dwctl/src/inference/middleware.rs |
Introduces early request validation for include and ZDR previous_response_id, plus a helper for consistent 400 JSON error responses. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
sejori
approved these changes
Aug 14, 2026
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
previous_response_idreasoning.encrypted_contentmessage.output_text.logprobsin blocking and streaming Responses outputincludevalues with a structured 400 instead of accepting a silent no-opincludeschema from a scalar to an arrayRoot cause
The Responses request shape accepted extension fields through its flattened extra object, while the active translator did not fully model the
includecontract. Stateful hydration also tried to parse the persisted partial retrieval object as a complete response, converting absent stored content into an internal error.Encrypted reasoning replay needs a durable client-carried sealing-key lifecycle that is separate from the one-time ZDR response key. The previous implementation draft reused a long-lived application secret, which introduced an undeclared durable content-decryption capability. This PR removes that path and fails safely until the lifecycle and security contract are designed.
Follow-up: #1489
User impact
Callers now get actionable 4xx errors for unavailable stateful capabilities rather than a silent no-op or internal error. Supported logprob projection and plaintext reasoning replay continue to work.
Verification
cargo fmt --all -- --checkcargo test -p dwctl --lib -j 1 inference::translation::responses::— 63 passedcargo test -p dwctl --lib -j 1 test::responses:: -- --test-threads=1— 13 passedjust lint rustwas attempted but is currently blocked outside this diff by generated SQLx optionality mismatches infusillade-arsenal/src/postgres.rs