fix(auth): preserve provider-owned credential pools (LAB-100) - #1262
fix(auth): preserve provider-owned credential pools (LAB-100)#1262eddieparc wants to merge 12 commits into
Conversation
Ultraworked with [omo](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
Ultraworked with [omo](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
There was a problem hiding this comment.
All reported issues were addressed
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Ultraworked with [omo](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
|
Cubic의 3개 지적을 모두 검증·수정했습니다.
검증: AI focused 7/7, Claude OAuth adjacent 18/18, changed-file LSP clean, root 현재 작성자 계정은 upstream READ 권한이라 merge/reviewer 요청 권한이 없습니다. Latest-head CI가 모두 통과하면 maintainer merge 부탁드립니다. |
There was a problem hiding this comment.
1 issue found across 4 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/coding-agent/test/suite/claude-sdk-oauth-extension.test.ts">
<violation number="1">
P3: The preflight test was downgraded from two stored logins to a single one, removing the only multi-login `streamSimple` coverage in this suite. The PR targets projected-selected-account resolution and pool preservation across multiple accounts, so reducing the fixture to one account leaves that path with no regression guard; the prior multi-account assertion was replaced rather than fixed.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
Ultraworked with [omo](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
|
Final head
The contributor account has upstream READ permission, and direct merge, auto-merge, reviewer request, and the unauthenticated Orca browser cannot cross that permission boundary. Please merge with a merge commit. |
Ultraworked with [omo](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
Ultraworked with [omo](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
|
Follow-up runtime recovery fix pushed at New evidence:
Root cause of the reported Please rerun CI/review on head |
There was a problem hiding this comment.
2 issues found across 14 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/coding-agent/src/core/agent-session.ts">
<violation number="1" location="packages/coding-agent/src/core/agent-session.ts:2357">
P1: For a provider response whose abort message is exactly `This operation was aborted`, this admission only runs in the asynchronous agent-end processor. The synchronous retry-promise and `willRetry` preflights still reject that message, so callers can observe the turn as settled before the retry starts and extensions receive `willRetry: false`; include the same provider-abort predicate in both preflight paths, preferably through a shared helper.</violation>
</file>
<file name="packages/coding-agent/src/changes.md">
<violation number="1" location="packages/coding-agent/src/changes.md:8">
P3: The changelog says `/fallback restore` "then clears the live fallback state", but restoreFallbackPrimary() restores the model and thinking level without clearing `_retryFallback.activeState`. After the command, getFallbackStatus() still reports the session active and the state survives until a later turn-boundary revert. Either clear the fallback controller state in the restore path or reword the entry.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
| // User/system abort provenance still wins and never replays a cancelled turn. | ||
| const providerOperationAbort = | ||
| msg.stopReason === "aborted" && msg.errorMessage?.trim().toLowerCase() === "this operation was aborted"; | ||
| const retryableError = this._isRetryableError(msg) || providerOperationAbort; |
There was a problem hiding this comment.
P1: For a provider response whose abort message is exactly This operation was aborted, this admission only runs in the asynchronous agent-end processor. The synchronous retry-promise and willRetry preflights still reject that message, so callers can observe the turn as settled before the retry starts and extensions receive willRetry: false; include the same provider-abort predicate in both preflight paths, preferably through a shared helper.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/coding-agent/src/core/agent-session.ts, line 2357:
<comment>For a provider response whose abort message is exactly `This operation was aborted`, this admission only runs in the asynchronous agent-end processor. The synchronous retry-promise and `willRetry` preflights still reject that message, so callers can observe the turn as settled before the retry starts and extensions receive `willRetry: false`; include the same provider-abort predicate in both preflight paths, preferably through a shared helper.</comment>
<file context>
@@ -2349,8 +2349,12 @@ export class AgentSession {
+ // User/system abort provenance still wins and never replays a cancelled turn.
+ const providerOperationAbort =
+ msg.stopReason === "aborted" && msg.errorMessage?.trim().toLowerCase() === "this operation was aborted";
+ const retryableError = this._isRetryableError(msg) || providerOperationAbort;
const hardErrorFallbackEligible = this._isHardErrorFallbackEligible(msg);
const cursorZeroTokenRe = isCursorZeroTokenResourceExhausted(msg);
</file context>
| ### What changed | ||
|
|
||
| - Provider-owned `This operation was aborted` results enter the ordinary turn retry budget, which defaults to three retries, before model fallback. Explicit user aborts remain terminal. | ||
| - `/fallback restore` switches only the current session back to the model and thinking level active before fallback, then clears the live fallback state. |
There was a problem hiding this comment.
P3: The changelog says /fallback restore "then clears the live fallback state", but restoreFallbackPrimary() restores the model and thinking level without clearing _retryFallback.activeState. After the command, getFallbackStatus() still reports the session active and the state survives until a later turn-boundary revert. Either clear the fallback controller state in the restore path or reword the entry.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/coding-agent/src/changes.md, line 8:
<comment>The changelog says `/fallback restore` "then clears the live fallback state", but restoreFallbackPrimary() restores the model and thinking level without clearing `_retryFallback.activeState`. After the command, getFallbackStatus() still reports the session active and the state survives until a later turn-boundary revert. Either clear the fallback controller state in the restore path or reword the entry.</comment>
<file context>
@@ -1,5 +1,27 @@
+### What changed
+
+- Provider-owned `This operation was aborted` results enter the ordinary turn retry budget, which defaults to three retries, before model fallback. Explicit user aborts remain terminal.
+- `/fallback restore` switches only the current session back to the model and thinking level active before fallback, then clears the live fallback state.
+- `ExtensionSessionSettings` exposes the narrow `restoreFallbackPrimary()` action used by the builtin command.
+
</file context>
Ultraworked with [omo](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
Ultraworked with [omo](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
Ultraworked with [omo](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
Ultraworked with [omo](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
|
Final head All 19 required checks passed, including all three coding-agent shards, Changelog gate, Static checks, Cubic, Windows RPC, and GitGuardian. Live production-surface evidence on the original affected 585-message session:
Direct merge is blocked by branch policy and this account lacks auto-merge permission. Please merge PR #1262. |
Ultraworked with [omo](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
|
Definitive head Final runtime correction beyond
The original session had already lost its SDK lineage and grew to a deterministic 2.4MB/612-message cold-seed failure. Its durable plan/Boulder/ledger goal has been migrated to a fresh opus-5 session rather than executing copied transcript fragments. Direct merge remains blocked by branch policy and this account lacks auto-merge permission. Please merge PR #1262. |
|
Superseded by two clean, scoped PRs:
Both replacement branches start from current Closing this mixed PR so the two concerns can be reviewed and merged independently. |
https://linear.app/jgplabs/issue/LAB-100/omo-claude-sdk-oauth-provider-%EB%AF%B8%EC%84%A4%EC%A0%95-fallback-%EC%8B%A4%ED%8C%A8
Summary
login-Nslots from replacing real provider-added accountsEvidence
undefined; GREEN: 9/9[default, login-2]; GREEN: 5/5 with[default, second]bun run check: exit 0LAB100_OKon opus-5 medium andLAB100_FALLBACK_OKon opus-4.8 medium, both exit 0No credentials or auth values are included in this PR.
Summary by cubic
Fixes LAB-100 across provider-owned OAuth persistence and Claude SDK session recovery. OAuth logins now retain real accounts, resumed sessions use selected credentials, and compacted sessions can restart without replaying the full context.
Bug Fixes
login-Nsentinels.accountspool exists.message_end.This operation was abortedresults use the configured turn retry budget before model fallback; user aborts remain terminal.New Features
/fallback restorereturns the current session to the model and thinking level active before fallback without changing global defaults.Written for commit 41aea64. Summary will update on new commits.