Skip to content

fix(claude): strip Claude Code's rotating billing line before Responses instructions - #6634

Merged
lidge-jun merged 1 commit into
devfrom
codex/compat-claude-billing-header
Oct 5, 2026
Merged

lidge-jun merged 1 commit into
devfrom
codex/compat-claude-billing-header

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Oct 5, 2026 •

Copy link
Copy Markdown
Owner

Summary

Claude Code opens its system prompt with x-anthropic-billing-header: cc_version=…; cc_entrypoint=…; cch=…;, and cch changes on every request. When a Claude Code request is translated to a Responses destination (for example meta-muse or an OpenAI model), that line became the first bytes of instructions and also fed the system-derived fallback prompt_cache_key, so the prefix and the key rotated every turn and the upstream prompt cache never hit (reporter measured 0.7% cached vs 96.5% for Codex on the same account).

systemToInstructions now strips that line only at the prompt start: from a string system, or from the first text block of a system array (dropping the block if nothing else is left). The regex is the same start-anchored one the Antigravity adapter already uses (src/adapters/google.ts). Native Anthropic passthrough does not use this translation and keeps the client preamble; the translated Anthropic adapter rebuilds its own identity block and never signs billing text, so no destination depended on the line.

Before: instructions = "x-anthropic-billing-header: …cch=abc;\nYou are Claude Code…" (changes every turn). After: instructions = "You are Claude Code…" and the fallback key is stable across turns. The reporter verified this exact patch: cached tokens went from 0 to ~99% on turns 2–5 on two machines.

Closes #6627

Verification

  • Regression case added to the existing tests/claude-integration/claude-inbound.test.ts: rotating cch on a string system (instructions and fallback key stable), header-only first array block dropped, header-plus-text block stripped, later mention and leading whitespace preserved, header-only system leaves no instructions and no system-derived key.
  • Local: bun run typecheck, bun run structure:check, bun scripts/file-size-ratchet.ts, bun run privacy:scan — all pass.
  • No tests were run locally, per maintainer instruction for this sweep; the regression file runs in hosted CI at this head.
  • Independent plan review (gpt-6.1-sol) confirmed no translated destination needs the line and the test file is uncapped.

Checklist

  • Targets dev
  • Regression test in an existing test file
  • Owning doc updated (structure/clients/claude-desktop.md)
  • No secrets or private data

Summary by CodeRabbit

  • Bug Fixes
    • System prompts beginning with Claude Code’s billing header are now cleaned before being converted to instructions. Empty results are omitted, while later text blocks and other prompt content remain unchanged.

@lidge-jun lidge-jun added the bug Something isn't working label Oct 5, 2026
@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner October 5, 2026 12:57
@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@coderabbitai

coderabbitai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

🧰 Additional context used
📚 Code guidelines (2)
src/AGENTS.md — auto-discovered
structure/AGENTS.md — auto-discovered

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: lidge-jun/opencodex/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 6abba43e-9da4-4106-a2d5-6cc57f98bead
📥 Commits

Reviewing files that changed from the base of the PR and between 3e739d2 and bc9946b.

📒 Files selected for processing (3)
  • src/claude/inbound-content-options.ts
  • structure/clients/claude-desktop.md
  • tests/claude-integration/claude-inbound.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

Claude-to-Responses translation now removes a leading x-anthropic-billing-header: line from string system prompts and the first text block of array prompts. Tests cover header removal, preserved content, and system-derived cache-key behavior. Documentation notes that native Anthropic passthrough is unchanged.

Changes

Claude-to-Responses translation

Layer / File(s) Summary
Strip the header during instruction translation
src/claude/inbound-content-options.ts, tests/claude-integration/claude-inbound.test.ts, structure/clients/claude-desktop.md
systemToInstructions removes a leading billing header from string prompts or the first text block of array prompts. It omits that block if stripping leaves it empty. Tests cover preserved content and cache-key behavior. Documentation distinguishes this translation from native Anthropic passthrough.

Priority: ➖ Normal

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

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to bc994

No actionable merge-blocking risk is identified; the change is ready for normal checks.

Security Architecture Review

Security architecture risk: 🔵 Low · up to bc994

The change removes request-varying metadata before forwarding instructions. Existing controls keep shared cache keys separate from session identity, and no new privilege or access path was identified. Some security coverage remains incomplete.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The affected exposure is existing translated Messages requests carrying a leading billing line, across their configured destinations. The change consolidates otherwise-identical fallback cache cohorts but adds no route, credential, tool authority, or account-selection permission. Native passthrough bypasses normalization.

Security Findings and Attack Paths

  • inferred — The examined attack path—manipulating billing text to consolidate cache keys and thereby acquire another conversation's affinity or replay scope—is not established. Consolidation occurs, but existing consumers explicitly reject shared cohort keys as those identities. This conclusion is limited to the inspected repository controls, not upstream cache internals.

Trust Boundaries and Controls

  • observed — The normalization removes caller-supplied text only at the beginning of the top-level system content. It neither supplies replacement instructions nor derives credentials from the billing value. Metadata-derived cache-key precedence and the separate native-passthrough branch remain intact.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 2 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: removing Claude Code’s rotating billing line before generating Responses instructions.
Linked Issues check ✅ Passed Issue #6627 requires removing the billing line only at the prompt start, from a system string or the first text block in a system array, and dropping an emptied result. `src/claude/inbound-content-opt…
Out of Scope Changes check ✅ Passed The reviewed change summary identifies only the translation implementation, its regression tests, and the Claude Desktop client documentation. Each change supports issue #6627. No unrelated change is …
Full details: Docstring Coverage

Explanation

Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 2 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@lidge-jun

Copy link
Copy Markdown
Owner Author

Maintainer integration (lidge-jun, dev only) — compatibility-bug sweep 2026-10-05.

  • Head: bc9946b
  • CI: Cross-platform CI 37313169599:success; all 22 executed checks passed at this head (platform matrices path-skipped).
  • Review: independent gpt-6.1-sol plan audit PASS (no translated destination depends on the billing line; native passthrough unaffected).
  • No local tests run per maintainer instruction; the regression case runs in hosted CI.

@lidge-jun
lidge-jun merged commit 0889b60 into dev Oct 5, 2026
37 of 38 checks passed
@lidge-jun
lidge-jun deleted the codex/compat-claude-billing-header branch October 5, 2026 13:08
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.

1 participant