Client or integration
Codex CLI
Area
Provider adapter
Summary
vertexReplaySessionId() (src/adapters/google.ts:56) keys the Vertex thought-signature replay namespace on parsed.options.promptCacheKey, under a comment that says it does something else:
/** Prefer Codex's stable opaque thread key; retain the existing deterministic fallback for clients
* that omit it. ... */
function vertexReplaySessionId(parsed: OcxParsedRequest): string {
const promptCacheKey = parsed.options.promptCacheKey?.trim();
return promptCacheKey || antigravitySessionId(parsed);
}
promptCacheKey is not a thread key. It is the client-supplied Responses prompt_cache_key, accepted as any string (src/responses/schema.ts, copied at src/responses/parser.ts:661), and this repository elsewhere treats it as explicitly shared across conversations:
src/adapters/cursor/request-builder.ts:227 warns against using a shared prompt_cache_key as a conversation id;
- Claude Desktop cache cohorts are marked as shared in
src/server/responses/core.ts:620 and src/server/claude-messages.ts:701.
So two distinct conversations in the same cache cohort share a Vertex replay namespace, and any client can choose the value.
Relationship to #1297
This is the same class of defect #1297 reported for the Cloud Code Assist path, on a different anchor. #1311 fixed the CCA side by anchoring on _clientThreadId and deliberately not on promptCacheKey; it left this one alone rather than bundling an unrelated path into that fix.
Worth recording how it surfaced: while fixing #1297 I found this function and read its comment as the correct pattern to copy. It is not — the comment describes the right anchor and the code uses a different one. Anyone reading google.ts for guidance will make the same mistake.
Severity
Lower than #1297, and the two failure modes differ in kind:
Sharing is partly mitigated the same way the original CCA comment argued: the replay cache keys signatures on functionCall identity (name + args), so a shared namespace does not by itself misattribute a signature. That mitigation is real but it is not a reason for the anchor to be wrong, and it does not cover a client that chooses the value deliberately.
Suggested fix
Mirror #1311: prefer parsed._clientThreadId (populated from x-codex-parent-thread-id at src/server/responses/core.ts:1413), fall back to the existing deterministic id. Unlike the CCA case this value never leaves the process — it scopes a local replay store rather than going on the wire — so the change carries no provider-visible risk.
If promptCacheKey is kept for some reason I have not seen, the comment should at least stop claiming it is a thread key.
Version
dev at b5d44a534.
Operating system
Not platform-specific.
Client or integration
Codex CLI
Area
Provider adapter
Summary
vertexReplaySessionId()(src/adapters/google.ts:56) keys the Vertex thought-signature replay namespace onparsed.options.promptCacheKey, under a comment that says it does something else:promptCacheKeyis not a thread key. It is the client-supplied Responsesprompt_cache_key, accepted as any string (src/responses/schema.ts, copied atsrc/responses/parser.ts:661), and this repository elsewhere treats it as explicitly shared across conversations:src/adapters/cursor/request-builder.ts:227warns against using a sharedprompt_cache_keyas a conversation id;src/server/responses/core.ts:620andsrc/server/claude-messages.ts:701.So two distinct conversations in the same cache cohort share a Vertex replay namespace, and any client can choose the value.
Relationship to #1297
This is the same class of defect #1297 reported for the Cloud Code Assist path, on a different anchor. #1311 fixed the CCA side by anchoring on
_clientThreadIdand deliberately not onpromptCacheKey; it left this one alone rather than bundling an unrelated path into that fix.Worth recording how it surfaced: while fixing #1297 I found this function and read its comment as the correct pattern to copy. It is not — the comment describes the right anchor and the code uses a different one. Anyone reading
google.tsfor guidance will make the same mistake.Severity
Lower than #1297, and the two failure modes differ in kind:
Sharing is partly mitigated the same way the original CCA comment argued: the replay cache keys signatures on
functionCallidentity (name + args), so a shared namespace does not by itself misattribute a signature. That mitigation is real but it is not a reason for the anchor to be wrong, and it does not cover a client that chooses the value deliberately.Suggested fix
Mirror #1311: prefer
parsed._clientThreadId(populated fromx-codex-parent-thread-idatsrc/server/responses/core.ts:1413), fall back to the existing deterministic id. Unlike the CCA case this value never leaves the process — it scopes a local replay store rather than going on the wire — so the change carries no provider-visible risk.If
promptCacheKeyis kept for some reason I have not seen, the comment should at least stop claiming it is a thread key.Version
devatb5d44a534.Operating system
Not platform-specific.