Summary
main is red. packages/coding-agent/test/claude-sdk-oauth-binding-lifecycle-security.test.ts still pins the pre-#1749 contract for a provider excursion, so the merge of #1749 (fef17495627b4590fed028c7b7b1ab3a3064993a) left a failing test on main.
The failing case is forgets process binding and invalidates/deletes durable state when selecting a non-Claude provider (around :177-206): it asserts getBinding(sessionId) is undefined, that a { invalidated: true, reason: "model_selected" } ledger entry was appended, and that the sidecar file is gone. #1749 deliberately changed that contract — session-registry-wiring.ts now calls keepBindingThenClose for a provider excursion, so the binding is re-remembered, nothing is appended and no sidecar is deleted.
CI: Test (coding-agent 1/3) fails with AssertionError: expected { …(11) } to be undefined at test/claude-sdk-oauth-binding-lifecycle-security.test.ts:200.
Root cause of the miss
#1749 changed a contract that an existing test asserted, and that test was not in the regression survey: the PR checked claude-sdk-oauth-model-switch.test.ts and claude-sdk-oauth-session-registry-wiring.test.ts and concluded no existing test encoded the destructive behavior. This file does, and it was not part of the enumerated GREEN run either. The lesson is to enumerate tests by the CONTRACT being changed (grep the assertions for the behavior, here the sidecar deletion and the invalidation entry) rather than by the files that look topically related.
Expected
The provider-excursion case asserts the shipped contract: the binding and its sidecar survive, and no invalidation record is appended. The suite keeps proving the other half — durable state IS deleted for a genuine invalidation — through its assistant-rewritten and extensions-removed cases, which are unchanged.
Not a loosening: a binding kept across an excursion is still refused on the way back when identity drifted (identityDrift → model_changed) or when the SDK session id was never confirmed (withoutUnconfirmedResume). The deletion was never the mechanism protecting that.
Scope
In: the one test case and a comment recording why the contract changed.
Out: production behavior — #1749's contract stands.
Summary
mainis red.packages/coding-agent/test/claude-sdk-oauth-binding-lifecycle-security.test.tsstill pins the pre-#1749 contract for a provider excursion, so the merge of #1749 (fef17495627b4590fed028c7b7b1ab3a3064993a) left a failing test onmain.The failing case is
forgets process binding and invalidates/deletes durable state when selecting a non-Claude provider(around:177-206): it assertsgetBinding(sessionId)isundefined, that a{ invalidated: true, reason: "model_selected" }ledger entry was appended, and that the sidecar file is gone. #1749 deliberately changed that contract —session-registry-wiring.tsnow callskeepBindingThenClosefor a provider excursion, so the binding is re-remembered, nothing is appended and no sidecar is deleted.CI:
Test (coding-agent 1/3)fails withAssertionError: expected { …(11) } to be undefinedattest/claude-sdk-oauth-binding-lifecycle-security.test.ts:200.Root cause of the miss
#1749 changed a contract that an existing test asserted, and that test was not in the regression survey: the PR checked
claude-sdk-oauth-model-switch.test.tsandclaude-sdk-oauth-session-registry-wiring.test.tsand concluded no existing test encoded the destructive behavior. This file does, and it was not part of the enumerated GREEN run either. The lesson is to enumerate tests by the CONTRACT being changed (grep the assertions for the behavior, here the sidecar deletion and the invalidation entry) rather than by the files that look topically related.Expected
The provider-excursion case asserts the shipped contract: the binding and its sidecar survive, and no invalidation record is appended. The suite keeps proving the other half — durable state IS deleted for a genuine invalidation — through its assistant-rewritten and extensions-removed cases, which are unchanged.
Not a loosening: a binding kept across an excursion is still refused on the way back when identity drifted (
identityDrift→model_changed) or when the SDK session id was never confirmed (withoutUnconfirmedResume). The deletion was never the mechanism protecting that.Scope
In: the one test case and a comment recording why the contract changed.
Out: production behavior — #1749's contract stands.