Skip to content

fix: redact blocked tool outputs from replay state - #4507

Open
seratch wants to merge 7 commits into
mainfrom
fix/redact-blocked-tool-output
Open

fix: redact blocked tool outputs from replay state#4507
seratch wants to merge 7 commits into
mainfrom
fix/redact-blocked-tool-output

Conversation

@seratch

@seratch seratch commented Aug 18, 2026

Copy link
Copy Markdown
Member

This pull request fixes a replay-safety issue for terminal tool output rejected by an output guardrail. Non-streaming final results already waited for output guardrails to complete, and a trip did not return a normal final result; the issue was that rejected terminal tool output could still remain reachable through Session history, RunState, streaming replay state, the tripwire exception, or a subsequent model request. The fix also applies the guardrail verdict to the persistence and replay boundary for the terminal-tool-derived current response: a passing response is saved normally, while a rejected current suffix is sanitized or discarded when it cannot be reconstructed safely.

Solution

  • Delays client-managed Session persistence until the output-guardrail verdict is known.
  • Identifies the rejected current response using trusted turn boundaries and object ownership, without joining historical items by provider or call ID.
  • Reconstructs supported function-call pairs from allowlisted fields and replaces rejected output with provider-valid, data-free payloads.
  • Applies the sanitized current-turn snapshot across SDK-owned replay surfaces while preserving previously accepted history.
  • Removes rejected output aliases from guardrail results and the public tripwire exception.
  • Discards only the rejected current suffix when it contains an unsupported, malformed, or reasoning-bearing variant that cannot be reconstructed safely.

Unaffected existing paths

  • Runs without output guardrails retain their existing execution behavior.
  • Client-managed Session persistence without output guardrails retains its released behavior.
  • HITL interruption and resume without output guardrails retain their released suffix-persistence behavior.
  • Ordinary assistant and max-turn output-guardrail failures preserve their existing output_info, run_data, and guardrail results.
  • When an output guardrail passes, normal Session persistence and backend-error behavior remain unchanged.
  • Previously accepted turns remain available for replay; sanitization or suffix removal applies only to the rejected current response.

Guardrail-specific limitations

These limitations apply only to configurations that use output guardrails:

  • A serialized partial-approval state cannot be resumed with output guardrails when the existing state does not contain enough trusted provenance to identify the current response safely. Structurally provable live state remains supported, and partial-approval resume without output guardrails is unaffected.
  • If a terminal tool side effect completes but the output guardrail raises an exception or the run is cancelled before a verdict is persisted, that completed side effect might not appear in Session history. This follows from applying verdict-before-save specifically to terminal tool output.
  • A server-managed conversation fails closed only when output guardrails are enabled and the SDK cannot guarantee that rejected output is excluded from server-owned history. Server-managed conversations without output guardrails are unaffected.
  • If a rejected terminal response cannot be reconstructed safely, the SDK prioritizes preventing raw-output replay over preserving that current response for later resume.

Out of scope

The following are separate extensions to the output-guardrail persistence and replay contract; they do not remove existing functionality from runs without output guardrails:

  • Retracting streaming deltas that were already delivered.
  • Rolling back external side effects performed by terminal tools.
  • Durable response provenance or a pending/accepted/rejected persistence lifecycle.
  • Complete resume support for ambiguous serialized partial-approval states used with output guardrails.
  • Atomic Session replacement, leases, or compare-and-swap coordination.
  • Migration of legacy serialized states that lack trusted provenance.
  • Physical deletion or at-rest erasure of records already stored by a backend.
  • Mutation of raw objects retained by external application references.
  • Reconstruction or deletion of server-managed conversation history.
  • Redaction of tracing or other telemetry that was already emitted.
  • Complete resumability after every output-guardrail trip, exception, cancellation, or unsupported response variant.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 529b9d1d1d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/run_internal/run_loop.py Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a6f48d34e9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/run_internal/run_loop.py Outdated
Comment thread src/agents/run.py Outdated
@seratch
seratch force-pushed the fix/redact-blocked-tool-output branch 2 times, most recently from 23eea88 to e8cf656 Compare August 18, 2026 22:00

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e8cf6564f3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/run.py
Comment thread src/agents/run_internal/run_loop.py Outdated
Comment thread src/agents/run_internal/blocked_output.py Outdated
@seratch
seratch force-pushed the fix/redact-blocked-tool-output branch from e8cf656 to 2c00703 Compare August 19, 2026 00:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant