Skip to content

Mid-iteration agent fallback dispatches into a sandbox lacking the new agent's credentials -> provider 401 - #526

Merged
AdamFrisby merged 1 commit into
mainfrom
codeybox/03e2a3a1
Sep 18, 2026
Merged

AdamFrisby merged 1 commit into
mainfrom
codeybox/03e2a3a1

Conversation

@AdamFrisby

Copy link
Copy Markdown
Owner

Automated via CodeyBox — work item 03e2a3a111b244d19f083d5ced6d2153

Initiated by CodeyBox operator


Co-Authored-By: CodeyBox noreply@codeybox.invalid
🤖 Generated with CodeyBox

Work item a09d2275: a phase entered under agent A and switched to agent B
mid-iteration executed B without B's credentials. Direct credential
variables are baked into the sandbox spec at creation, the reusable sandbox
kept serving A's baked environment after the swap, and the resulting
provider 401 was misreported as 'agent requires re-authentication'.

- New AgentRunnerSwitchGate: the single seam for every post-creation runner
  switch. AssessSwitch re-validates the incoming runner against its own
  credential (agent match + runner's own environment classification);
  ScopeSandbox + CollectCredentialEnvironmentScope + ValidateCredentialScope
  carry the conflict-resolver credential-scoping mechanism unchanged;
  ToPostSwapInfrastructureFailure reclassifies a first-attempt post-swap 401
  as infrastructure with the 401 evidence preserved.
- Quota-fallback path: each fallback candidate is bound, credential-resolved
  and gate-assessed before selection; unmaterialisable candidates are refused
  (logged, added to tried keys, no dispatch) and an all-refused field keeps
  the original failure. Every successful swap arms a one-attempt guard that
  converts a post-swap AgentAuthRequiredException to infrastructure, and
  surrenders the warm reusable sandbox so the retry provisions a fresh
  sandbox from the incoming member's spec. Genuine expiry with no preceding
  swap still fails as auth-required.
- Conflict-resolver path: candidates are partitioned through the same gate;
  refused candidates are named on the attempt trail and never dispatch, and
  the sandbox scoping now flows through the shared helper. Null-credential
  candidates remain dispatchable on both paths (ambient auth + runtime auth
  detection own that outcome).
- Tests: 11 new AgentRunnerSwitchTests cover gate allow/refuse/secret-safety,
  end-to-end swap credential materialisation (per-attempt sandbox specs),
  refusal with original failure preserved and no dispatch, post-swap 401 as
  infrastructure, no-swap auth still auth-required, and both resolver-path
  behaviours.

Verification: dotnet build --no-incremental /warnaserror clean;
full dotnet test suite green (13360 passed in CodeyBox.Tests);
gitleaks clean. semgrep is not installed in this environment (no pip), so
that scan could not be run.

CodeyBox-Prompt-Revision: 1
Co-Authored-By: CodeyBox <noreply@codeybox.invalid>
@AdamFrisby
AdamFrisby merged commit e7c6b6d into main Sep 18, 2026
@AdamFrisby
AdamFrisby deleted the codeybox/03e2a3a1 branch September 18, 2026 08:54
AdamFrisby pushed a commit that referenced this pull request Sep 18, 2026
Hand-landed: the branch's five upstream push attempts were exhausted against a
base that had moved, leaving the item stuck at "manual resolution required".

All nine conflicts were additive collisions in the shared adapter-registration
surface — main registers cmd/continue/qwen, this branch registers
dotnet-opencode, in the same files (AgentKind.cs, Program.cs,
AgentClassesConfigBuilder.cs, CodeyBox.Api.csproj, CodeyBox.slnx, the tests
csproj, InVmSmokeProbeBuildStepsTests.cs, and two docs). Resolved as keep-both.

Three conflict boundaries split mid-construct, where git kept a trailing line
shared by both sides as context: CmdAgentRunner's closing argument, a pair of
QuotaFailureDetector lambdas merged into one body, and two test methods that
lost their closing braces and [Fact]. Each was restored so both sides'
registrations stand independently.

Verified before landing: build 0 warnings / 0 errors; full suite 13,548 passed,
0 failed, 25 skipped; gitleaks over 1,039 commits with the repo config, no
leaks; runner registrations 19 -> 20 and AgentKinds 21 -> 22, with the only
removals being comment rewrites (DefaultRunTimeoutSeconds unchanged at 5400).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WAeyeWMSM6LNdfgEvwWqEd
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.

1 participant