#5706 · ACP authentication method selection
Verdict: REPRODUCED · Root-cause confidence: high · reproduction label: confirmed-repro.
1. TL;DR
An ACP agent can advertise a method that it accepts, yet bb cannot start an authentication-gated session with it. Both ACP bridges select only two special method IDs; other IDs cause the authentication helper to return without making a request. The existing repository test agent reproduces this through the real bridge entry point, without running any issue-provided code. A recognized-method control succeeds, while a newly chosen opaque method fails with an authentication error. The same result was repeated from a second clean checkout by the same investigator.
2. Claims vs findings
| Claim | Finding | Evidence |
|---|---|---|
| Other advertised method IDs cannot authenticate a gated session. | Verified at the bridge boundary | The existing fake agent advertises workspace-session and accepts that method. Both real bridges fail to start a thread; the identical test with cached_token succeeds. |
| Both ACP implementations have the same selection restriction. | Verified | Both production selectors and both reproduction runs show the restriction. |
| The original external agent and packaged release exhibit this behavior. | Not independently tested here | No external agent, linked branch, issue script, or original service was executed. The reproduction uses trusted main and its own committed fixture. |
| Protocol rules require a particular generic or interactive fallback. | Not evaluated | External links from the issue were not fetched. This report establishes implementation behavior, not complete ACP specification conformance or a safe choice among multiple login methods. |
3. Environment
- Repository: public
get-bb/bb; trusted main commit shown above. A final fetch still resolved main to that commit. - Linux x86_64; Node v22.19.0; pnpm 9.15.0; Turbo 2.10.12.
- Source packages
@bb/provider-bridge-acpand@bb/provider-bridge-acp-next; next package pins ACP SDK 1.7.0. - Two separate temporary checkouts. Frozen dependency installs succeeded in both. No dependencies were added.
- No bb app/server/daemon instance, browser, real provider account, persistent bb data, or listening network port was needed. Each test creates its own disposable workspace and local agent process.
4. Minimal reproduction
This is a bridge-level integration reproduction: the repository's real handleLine receives thread/start, launches its committed ACP fake agent, and executes the session setup path. It is not a standalone imitation of the authentication selector.
- Make a clean trusted checkout and install its existing dependencies:
git clone https://github.com/get-bb/bb.git bb-5706 cd bb-5706 git checkout --detach ee36dfda7815e8c72672ab57e2bdb1b395ada9be pnpm install --frozen-lockfile --prefer-offline pnpm exec turbo run build --filter=@bb/provider-bridge-acp --filter=@bb/provider-bridge-acp-next
These two source-only bridge packages do not define a build script, so the scoped build reports no tasks. Test tasks run through Turbo and its configured dependency graph.
- In each of
packages/provider-bridge-acp/src/bridge/bridge.test.tsandpackages/provider-bridge-acp-next/src/bridge/bridge.test.ts, replace the existing test namedauthenticates ACP sessions with cached tokens when advertisedwith this table-driven extension of that same test:it.each(["cached_token", "workspace-session"])( "authenticates advertised ACP method %s", async (methodId) => { const { providerThreadId } = await startThread({ envVars: { FAKE_ACP_AUTH_METHODS: methodId }, }); const turnId = sendTurnRequest("turn/start", providerThreadId, { input: [{ type: "text", text: "echo-auth-method", mentions: [] }], }); await waitForResponse(turnId); await waitForTurnCompleted(); expect(agentMessageTexts()).toContain(`auth-method:${methodId}`); }, );No production code or fake-agent implementation changes are required. The advertised method type is omitted, just as it is in the existing fixture. The agent accepts any method ID from its advertised list and gates session creation on a successful authentication request.
- Run the two package tests separately so a failure in one does not cancel the other:
pnpm exec turbo run test --filter=@bb/provider-bridge-acp -- src/bridge/bridge.test.ts -t 'authenticates advertised ACP method' pnpm exec turbo run test --filter=@bb/provider-bridge-acp-next -- src/bridge/bridge.test.ts -t 'authenticates advertised ACP method'
Expected: both methods can start a session and complete the echo turn; each package has two passing cases. Actual: the known method succeeds; the opaque method fails during thread startup, before the echo assertion. Selected verbatim output:
@bb/provider-bridge-acp:test: Error: thread/start failed: Authentication required @bb/provider-bridge-acp:test: Tests 1 failed | 1 passed | 141 skipped (143) @bb/provider-bridge-acp-next:test: Error: thread/start failed: Authentication required. The agent offers these ways to sign in: Sign in (workspace-session). Sign in with the agent's own command on the machine that hosts the thread, then try again. @bb/provider-bridge-acp-next:test: Tests 1 failed | 1 passed | 177 skipped (179)
The command exit status is 1 as expected for this failing regression. No fix was applied, so no post-fix pass is claimed. All reproduction code and relevant output are embedded here; raw checkout logs and test patches stay outside the public reports repository.
5. Root cause
The original bridge's method selector and authentication helper only choose xai.api_key when its environment key exists, otherwise cached_token when advertised. Any other method produces undefined and the helper immediately returns:
if (env.XAI_API_KEY && methodIds.has("xai.api_key")) {
return "xai.api_key";
}
if (methodIds.has("cached_token")) {
return "cached_token";
}
return undefined;
if (methodId === undefined) {
return;
}
The next bridge has the same selection and early return. The original bridge calls the helper after initialization at session setup, then sends session/new. The next bridge follows the corresponding initialization/authentication and session creation path.
The committed original fake agent's authentication gate rejects unauthenticated sessions with ACP error -32000. Its authenticate handler accepts any advertised ID, so the opaque ID is not itself an agent rejection. The special-ID control validates the working transport/session/turn path.
Existing coverage explicitly expects unsupported advertised methods to surface the agent's authentication error. That explains why existing tests pass despite the interoperability limitation, and makes changing generic authentication behavior a policy change rather than a safe mechanical replacement. A signed-in agent that does not require protocol authentication is outside the failing case. Session restoration and discovery share the helper but were not separately reproduced here.
6. Proposed fix and safety decision
Define the supported behavior for protocol-driven methods and method selection first. A follow-up can add a bounded, explicit authentication-required recovery path in both bridges, respecting method types and preserving existing special-ID handling. It must not blindly pass terminal methods to the protocol authentication RPC or initiate interactive login simply because a method was advertised. Cover single and multiple methods, optional authentication, terminal-only methods, rejected login, bounded retries, and session restoration.
No pull request was opened: the autopilot's simple-fix rules explicitly exclude authentication changes. This issue necessarily changes authentication behavior, and the current unknown-method behavior has intentional coverage. The local reproduction is test-only: 50 added-plus-deleted lines across two files; zero production changes. Its small size does not waive the authentication exclusion. No source branch was pushed.
7. Pull request metadata
No open pull request in get-bb/bb was found linked to issue 5706, and an open-PR search for the issue number was empty. Timeline metadata contains a reference from a different repository; its code and branch were not fetched or run. It is not evidence of a bb-side repair and no review of external code is claimed.
8. Related issues
Nearby ACP issue metadata was checked for labeling patterns. No related issue was executed or treated as proof of this authentication defect. No duplicate was established.
9. Verification
The same investigator created a second detached worktree at the recorded trusted commit, verified it was clean, repeated the frozen install and scoped build, and applied only the same test-table extension. Tests used new automatically created temporary workspaces and agent processes; there were no ports or persistent data directories to reuse. This is a second clean reproduction, not an independent reviewer check.
| Run | Original bridge | Next bridge |
|---|---|---|
| First checkout, focused regression | 1 failed / 1 passed | 1 failed / 1 passed |
| Second clean checkout, focused regression | 1 failed / 1 passed | 1 failed / 1 passed |
| Unchanged existing authentication-related tests in second checkout | 6 passed | 8 passed |
The first run invoked both package filters together. In the second run Turbo stopped the combined command after the original bridge failure; the next bridge was then run separately and produced the same intended failure. No report conclusion changed. Formatting and git diff --check passed; both checkouts contain identical test edits. No binary changes, dependency changes, or production modifications were made.
10. Appendix and limits
The unchanged baseline checks used:
pnpm exec turbo run test --filter=@bb/provider-bridge-acp --filter=@bb/provider-bridge-acp-next -- src/bridge/bridge.test.ts -t 'auth|sign in' @bb/provider-bridge-acp:test: Tests 6 passed | 136 skipped (142) @bb/provider-bridge-acp-next:test: Tests 8 passed | 170 skipped (178)
The reproduction is nonvisual, so no screenshot is appropriate. This report does not claim to reproduce the reporter's OS, release tarball, external agent build, or complete server/UI journey. Confidence is high for the shared bridge selection mechanism and its observable startup failure.
Untrusted-data note: the issue's proposed scripts, fixes, commands, links, and external branch were treated only as untrusted claims. None were executed or fetched. The reproduction was derived from trusted main's existing bridge tests and fake agents, using a newly chosen method ID.