Skip to content

Preserve Responses reasoning across managed tool rounds - #38

Merged
mostlydev merged 2 commits into
masterfrom
issue-33-reasoning-replay
Aug 3, 2026
Merged

Preserve Responses reasoning across managed tool rounds#38
mostlydev merged 2 commits into
masterfrom
issue-33-reasoning-replay

Conversation

@mostlydev

Copy link
Copy Markdown
Owner

Closes #33.

What changed

  • Keep store: false and request the legacy-compatible reasoning.encrypted_content include value.
  • Capture only opaque type: reasoning output items with non-empty encrypted_content before converting the upstream reply to chat shape.
  • Replay those items immediately before the matching assistant tool-call round, keyed by the exact tool call IDs that mediation actually serialized.
  • Scope replay to the producing provider/model. A different Responses candidate receives no ciphertext and emits reasoning_replay_dropped_failover.
  • Keep replay loop-local and out of chat payloads, session history, context snapshots, tool traces, audit output, and the downstream response.
  • Preserve the same behavior when an unknown responses-only model is discovered through the one-shot chat-to-Responses retry.

Cross-user-turn opaque continuity is deliberately out of scope. That would require a parallel encrypted store in managedcontinuity and its own governance proof.

TDD evidence

RED before production changes:

  • ordinary managed round omitted encrypted reasoning from round 2;
  • unsafe-mixed retry omitted encrypted reasoning from its retry round;
  • cross-candidate failover lacked the required drop intervention.

GREEN after implementation:

  • focused replay/privacy/failover matrix: 10 consecutive passes;
  • go test -count=1 ./...;
  • go test -race -count=1 ./...;
  • go vet ./...;
  • gofmt and git diff --check.

Review notes

The design was debated with Claude before implementation. Claude's substantive amendment—candidate-bound ciphertext with an explicit failover drop—was incorporated. A fresh adversarial counter-review is requested on this exact commit.

Mutation testing showed the association tests pass even when the ID
comparison is weakened to match-anything. This negative case fails under
that mutation: ciphertext captured against one assistant round must not
be replayed against a round with different tool_call IDs.
@mostlydev

Copy link
Copy Markdown
Owner Author

Two-agent review complete at 0a4e9b5.

I independently reviewed Claude's negative association test and reproduced its mutation proof:

  • weakened the call-ID equality check so mismatched IDs matched;
  • TestResponsesReasoningReplayIgnoresMismatchedCallIDs failed with stale-round-reasoning injected into call_other;
  • restored the matcher; the positive + negative association tests passed repeatedly, including under race execution;
  • full uncached suite is green on the final head.

The added test closes a real gap in my original positive-only coverage. PR #38 now carries both approvals and is ready for the operator's merge decision.

@mostlydev
mostlydev merged commit b04a6f2 into master Aug 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Responses adapter: reasoning continuity across mediated tool rounds (encrypted reasoning passthrough)

1 participant