Skip to content

fix(vertex): scope replay by client thread - #1335

Closed
Ingwannu wants to merge 1 commit into
devfrom
agent/fix-1312-vertex-thread-scope
Closed

fix(vertex): scope replay by client thread#1335
Ingwannu wants to merge 1 commit into
devfrom
agent/fix-1312-vertex-thread-scope

Conversation

@Ingwannu

@Ingwannu Ingwannu commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • Scope Vertex thought-signature replay to Codex's stable client thread identifier instead of the potentially shared prompt-cache key.
  • Preserve the deterministic fallback for clients that do not send a thread identifier.
  • Add regressions proving shared cache cohorts cannot replay signatures across threads while same-thread continuation still works.

Closes #1312

Verification

  • taskset -c 0-1 bun run typecheck
  • taskset -c 0-1 bun test tests/antigravity-static-catalog.test.ts tests/google-adapter.test.ts tests/google-antigravity-oauth.test.ts tests/google-antigravity-replay.test.ts tests/google-antigravity-wire.test.ts tests/google-empty-content.test.ts tests/google-hardening.test.ts tests/google-models-listing.test.ts tests/google-tool-schema.test.ts tests/google-vertex-http.test.ts tests/google-vertex-stream.test.ts tests/google-vertex-thought-signature.test.ts tests/google-wire-compiler.test.ts tests/vertex-catalog.test.ts (227 pass, 0 fail)
  • git diff --check origin/dev...HEAD

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed. No documentation change is needed because this restores the existing per-thread replay contract.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults. No credential or raw thread identifier is persisted; the replay store continues to hash the namespace key.

Summary by CodeRabbit

  • Bug Fixes
    • Improved Vertex replay session handling by prioritizing the client thread identifier when available.
    • Prevented replay signatures from being incorrectly shared across separate client threads.
    • Preserved deterministic replay behavior for requests without a client thread identifier.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Vertex replay sessions now use the trimmed client thread ID when available and retain the existing fallback otherwise. Tests cover isolation across client threads and deterministic replay for threadless requests.

Changes

Vertex replay session scoping

Layer / File(s) Summary
Update replay session identity
src/adapters/google.ts
vertexReplaySessionId now uses parsed._clientThreadId instead of promptCacheKey, with the existing Antigravity session fallback.
Validate replay isolation and fallback
tests/google-vertex-thought-signature.test.ts
Tests add optional request identifiers and verify isolation across client threads, plus deterministic replay when no client thread is present.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: wibias, lidge-jun

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The implementation and regression tests satisfy issue #1312 by using the trimmed client thread ID with the deterministic fallback.
Out of Scope Changes check ✅ Passed The source and test changes directly support Vertex replay scoping and issue #1312, with no unrelated changes identified.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: scoping Vertex replay by the client thread.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/fix-1312-vertex-thread-scope

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Aug 9, 2026
@Ingwannu
Ingwannu requested review from Wibias and lidge-jun August 9, 2026 04:50
@Ingwannu
Ingwannu marked this pull request as ready for review August 9, 2026 05:01

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/adapters/google.ts`:
- Around line 57-58: Update the thread ID selection near antigravitySessionId so
a trimmed client thread ID is transformed with the same one-way hashing used by
antigravitySessionId before being returned as the replay-session key. Preserve
the existing fallback to antigravitySessionId(parsed) when the client ID is
absent or blank, and ensure vertexReplaySession/applyAntigravityReplay receive
only the hashed value.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b3ca2332-f0e5-4cbd-a25b-0bfbc84ebb06

📥 Commits

Reviewing files that changed from the base of the PR and between 87aeeb7 and 12e07f6.

📒 Files selected for processing (2)
  • src/adapters/google.ts
  • tests/google-vertex-thought-signature.test.ts

Comment thread src/adapters/google.ts
Comment on lines +57 to +58
const threadId = parsed._clientThreadId?.trim();
return threadId || antigravitySessionId(parsed);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Hash the client thread ID before using it as the replay-session key.

Line 58 returns the raw x-codex-parent-thread-id value. vertexReplaySession receives it at Line 454 and passes it to applyAntigravityReplay at Lines 459-463, so the replay cache retains the raw client identifier.

Use the same one-way hash used by antigravitySessionId, and keep the existing fallback for an absent or blank ID.

Proposed fix
 function vertexReplaySessionId(parsed: OcxParsedRequest): string {
   const threadId = parsed._clientThreadId?.trim();
-  return threadId || antigravitySessionId(parsed);
+  if (!threadId) return antigravitySessionId(parsed);
+  const digest = createHash("sha256").update(threadId, "utf8").digest();
+  const masked = digest.readBigUInt64BE(0) & 0x7fffffffffffffffn;
+  return `-${masked.toString()}`;
 }

Based on the PR objective to avoid persisting raw thread identifiers and the supplied replay-session contract.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const threadId = parsed._clientThreadId?.trim();
return threadId || antigravitySessionId(parsed);
const threadId = parsed._clientThreadId?.trim();
if (!threadId) return antigravitySessionId(parsed);
const digest = createHash("sha256").update(threadId, "utf8").digest();
const masked = digest.readBigUInt64BE(0) & 0x7fffffffffffffffn;
return `-${masked.toString()}`;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/adapters/google.ts` around lines 57 - 58, Update the thread ID selection
near antigravitySessionId so a trimmed client thread ID is transformed with the
same one-way hashing used by antigravitySessionId before being returned as the
replay-session key. Preserve the existing fallback to
antigravitySessionId(parsed) when the client ID is absent or blank, and ensure
vertexReplaySession/applyAntigravityReplay receive only the hashed value.

@lidge-jun

Copy link
Copy Markdown
Owner

Landed on dev as e09fe6e, rebased onto the current head with your authorship preserved.

Verified before merge: src/adapters/google.ts:56-58 claimed in its own comment to prefer a thread key but actually returned parsed.options.promptCacheKey?.trim() — a cohort that can be shared across conversations. The real per-thread anchor is populated from x-codex-parent-thread-id at src/server/responses/core.ts:1413-1414, so this two-line change makes the code do what its comment already promised. Full suite green (10243 pass, 0 fail).

Thanks — the test where two different threads share one cache key is the one that actually proves the bug, and keeping antigravitySessionId as the threadless fallback avoided a regression for clients that never send the header.

@lidge-jun lidge-jun closed this Aug 9, 2026
@Wibias
Wibias deleted the agent/fix-1312-vertex-thread-scope branch August 9, 2026 07:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants