← reports

#3019 · ACP plan capability and mode update gap

Bug Medium Effort: High providers provider-acp open on GitHub 2026-09-03 · base 43e3fc519

Verdict: REPRODUCED · Root-cause confidence: high

1. TL;DR

BB does not offer its plan action for ACP providers. The ACP provider declaration always returns an empty composer action list. The bridge also drops each turn's promptMode option. It classifies ACP mode-change updates as noise and returns no lifecycle delta. Two tests failed in two clean checks at the same trusted commit.

2. Claims vs findings

ClaimStatusEvidence
ACP providers do not get the normal plan action.VerifiedThe declaration returns composerActions: []. The registration test received that empty list.
ACP mode changes do not reach the plan lifecycle.VerifiedThe translator returned an empty delta list for current_mode_update with currentModeId: plan.
An ACP session can declare a plan mode.VerifiedA trusted ACP recording at the base commit contains availableModes with a plan entry.
The current capability contract has a supportsPlan field.RefutedA full tracked-file search found no such field. BB currently gates this function through composerActions.
The same defect occurs in a live OMP account.Not required for the code-path proofThe shared declaration and translator paths fail before agent-specific behavior can correct them. This check did not use a private account.

3. Environment

4. Minimal reproduction

  1. Check out the trusted base commit.
  2. Save the provider registration test as plugins/provider-acp/src/issue-3019-repro.test.ts.
  3. Run this command from plugins/provider-acp.
    pnpm exec vitest run src/issue-3019-repro.test.ts --config vitest.config.ts
  4. Save the mode update test as packages/provider-bridge-acp/src/issue-3019-repro.test.ts.
  5. Run this command from packages/provider-bridge-acp.
    pnpm exec vitest run src/issue-3019-repro.test.ts --config vitest.config.ts

Expected

Provider declaration composer actions: ["plan"]
Mode update translation: one or more lifecycle deltas

Actual

AssertionError: expected [] to include 'plan'
AssertionError: expected [] to not deeply equal []

First-run evidence: first-run.txt.

5. Verification

I created a second clean worktree at the same full base commit. I installed the frozen dependency set there. I copied only the two reproduction tests into that worktree. Both commands failed with the same assertions. I made no report correction after this check.

Second-run evidence: second-run.txt.

6. Root cause

The first gate is the provider declaration. Its string set has no plan copy, and it always returns an empty composer action list. See the ACP strings and the ACP declaration.

The server recognizes plan prompts only when the provider registration has a plan composer action. See the plan command resolver and the prompt-mode resolver.

The ACP bridge has a second gap. Its pending turn type does not keep execution options. The turn/start handler copies the input and request identifiers only. Thus, a received promptMode cannot cause session/set_mode. See the pending turn type and the turn handler.

The session result parser keeps models and config options, but it does not type or use modes. See the session result schema. A trusted ACP recording shows a returned plan mode.

The update parser sends all other update names through a general schema. The visibility table labels current_mode_update as noise. The translator then returns no deltas for it. See the general update schema, the noise classification, and the translator default.

The deeper problem is a timing mismatch. BB declares composer actions before an ACP session starts. ACP gives exact mode support after it creates or loads a session. A capability-faithful fix needs a contract for this later session fact.

7. Proposed fix

  1. Add a provider-neutral session-mode capability to the bridge and timeline contracts.
  2. Parse modes from ACP session start, load, and fork results.
  3. Carry promptMode into each ACP turn and call session/set_mode when supported.
  4. Translate current_mode_update into the provider-neutral lifecycle event.
  5. Keep the plan gate closed when the session does not report a plan mode.

This work needs a product and architecture decision. It changes public capability and lifecycle contracts across the provider plugin, bridge protocol, server, timeline, CLI, and UI. It does not meet the simple-fix rules.

8. Related issues

No related issue was necessary for this reproduction. The defect exists in the shared ACP paths at the trusted base.

9. Appendix

Commands

git fetch git@github.com:get-bb/bb.git main
git checkout 43e3fc519f32081d97bf2f757fd679fc9b9c5695
pnpm install --frozen-lockfile --prefer-offline
pnpm exec turbo run build
pnpm exec vitest run src/issue-3019-repro.test.ts --config vitest.config.ts
git grep -n supportsPlan 43e3fc519f32081d97bf2f757fd679fc9b9c5695

The final search returned no matches. The GitHub metadata check found no open pull request linked to issue 3019.

The issue data was untrusted. I used its statements only as claims to test. I did not fetch or run linked code.