Key reasoning-signature replay on the issuing provider - #364
Merged
Conversation
A signature tagged as belonging to a different provider than the current request must never be replayed, even when the historical turn's bare model string happens to match; a second account on the same provider must still replay. The adapter has no way to express provider-tagged signatures yet, so these cases fail to even compile.
signatureForModel compared only turn.model against the current request's model, but provider is a fixed adapter tag while model is arbitrary catalog/user-supplied text — two distinct backends can declare the same literal model name (proxy aliases, two OpenAI-compatible endpoints both configured as gpt-4o), and the equality check would treat a foreign signature as safe to replay, reproducing the original decrypt-failure bug. ConversationTurn carries no field recording which provider produced it, so provenance now rides inside the signature string itself: capture tags it provider:ciphertext, and replay only unwraps the ciphertext when both the tagged provider and the model match. Keying on provider rather than the per-account source id means a live account switch on the same backend (two ChatGPT accounts through the same Codex service) still preserves reasoning continuity, since the decrypting backend is shared across accounts.
TheGreatAxios
force-pushed
the
cl-5594-signature-provenance
branch
from
August 7, 2026 08:11
4c1d9ff to
40e6c0d
Compare
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
signatureForModelcompared onlyturn.modelagainst the current request's model.provideris a fixed adapter tag butmodelis arbitrary catalog/user-supplied text, so two distinct backends can declare the same literal model name (proxy aliases, two OpenAI-compatible endpoints both configured asgpt-4o). The old check would replay a foreign signature in that case, reproducing the original decrypt-failure 400 the prior fix (CL-4xxx) was meant to prevent.ConversationTurnhas no field for which provider produced a turn, so provenance now rides inside the signature string itself: capture (parseResponse, shared by Codex/Grok/OpenAI-Responses adapters) tags it<provider>:<ciphertext>, and replay (signatureForModel) only unwraps the ciphertext when both the tagged provider and the model match the current request.InferenceSource.id— a live Codex account switch (codex/abk-labs→codex/dirtroad) shares the same decrypting backend, so reasoning continuity across accounts is preserved; a genuine cross-provider model-name collision is now blocked.Net lines
Net-positive (mostly comments explaining the provenance scheme + two new provider params threaded through the three Responses adapters + test coverage). No code was removable here — the bug is a missing check, not a redundant one.
Test plan
tests/unit/codex-responses-adapter.test.ts, commitddedba7) confirming the adapter had no way to express provider-tagged signatures; fix landed in the following commit (4c1d9ff).turn.modelmatches the current request's model.sourceId) on the same provider still replays the signature — account-switch continuity preserved.bun run typecheck— cleanbun run build— cleanbun run test— 3985 pass, 0 fail