Skip to content

test(claude-sdk-oauth): pin the provider-excursion contract shipped in #1749 - #1753

Merged
code-yeongyu merged 2 commits into
mainfrom
fix/1751-binding-lifecycle-security-contract
Sep 16, 2026
Merged

code-yeongyu merged 2 commits into
mainfrom
fix/1751-binding-lifecycle-security-contract

Conversation

@code-yeongyu

@code-yeongyu code-yeongyu commented Sep 16, 2026

Copy link
Copy Markdown
Owner

Fixes #1752

Summary

main went red when #1749 merged: this suite still asserted the contract #1749 deliberately replaced.

claude-sdk-oauth-binding-lifecycle-security.test.ts asserted that selecting a non-Claude provider forgets the binding, appends { invalidated: true, reason: "model_selected" } and deletes the sidecar. #1749 made a provider excursion non-destructive (session-registry-wiring.ts now calls keepBindingThenClose), so all three assertions inverted. The case now pins the shipped contract and carries a comment naming #1747 so the next reader knows why it changed.

Why this is not a loosening

The suite's security property is that durable state does not linger after a GENUINE invalidation, and that half stays pinned by the unchanged assistant-rewritten and extensions-removed cases in the same file. A binding kept across an excursion is still refused on the way back by identityDrift (model_changed) and by withoutUnconfirmedResume for an unconfirmed SDK session id — sidecar deletion was never what protected that.

Root cause of the miss, recorded so it is not repeated

#1749's regression survey enumerated files that looked topically related (claude-sdk-oauth-model-switch.test.ts, claude-sdk-oauth-session-registry-wiring.test.ts) and concluded nothing encoded the destructive behavior. The right enumeration is by CONTRACT: grep the assertions for the behavior being changed — here bindingSidecarPath plus invalidated: true — which finds this file immediately. Its GREEN run also did not include it.

Verification

CI on this PR is the gate: Test (coding-agent 1/3) currently fails on main at test/claude-sdk-oauth-binding-lifecycle-security.test.ts:200 with AssertionError: expected { …(11) } to be undefined, and must pass here.


Summary by cubic

Pins the claude-sdk-oauth binding-lifecycle test to the provider-excursion contract shipped in #1749, fixing the red build on main (#1752).

The test previously expected that selecting a non-Claude provider forgets the binding, appends { invalidated: true, reason: "model_selected" }, and deletes the sidecar. #1749 made a provider excursion non-destructive, so those assertions now invert: the binding and sidecar persist. The binding is asserted by presence rather than its injected id, since keepBindingThenClose re-remembers it from the live session entry with that entry's own sdkSessionId. The security property is unchanged — genuine invalidation still deletes durable state, and a drifted binding is refused on return via identityDrift / withoutUnconfirmedResume.

Written for commit 487d3af. Summary will update on new commits.

Review in cubic

…injected id

keepBindingThenClose re-remembers the binding from the live session entry, so
it carries the entry sdkSessionId rather than the value the test injected. The
security property is that durable state survives the excursion; the reattach
prefix is pinned by the #1747 regression suite.
@code-yeongyu
code-yeongyu merged commit c68ec4d into main Sep 16, 2026
26 checks passed
@code-yeongyu
code-yeongyu deleted the fix/1751-binding-lifecycle-security-contract branch September 16, 2026 05:21
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.

main is red: binding-lifecycle security test still pins the pre-#1749 provider-excursion contract

1 participant