Provider protocol: `launch.command` is the inner ACP agent, not the process to exec — a conformant provider can ship silently inert agents
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
## Summary
Writing a third-party `buzz-backend-*` provider, I shipped a deploy that Buzz
reported as fully successful — `backend_agent_id` returned, `last_error: null`,
worktree created, process alive — and which produced a **completely inert
agent**. Nothing was connected to the relay.
The cause: I exec'd `launch.command` as the process to run. It is actually the
ACP agent that runs *under* `buzz-acp`; the harness is what authenticates to the
relay, listens for mentions, and drives the agent over stdio. A provider is
responsible for running the harness and passing the inner agent through
`BUZZ_ACP_AGENT_COMMAND` / `BUZZ_ACP_AGENT_ARGS`.
That is a reasonable contract. The problem is that nothing states it, and
nothing can catch getting it wrong.
## Why the docs didn't prevent it
`docs/remote-agents.md` §Launch data describes the field as:
```
"launch": {
"command": str, // command NAME (e.g. "goose"), never a host path
"args": [str], // normalized args, definition fallback applied
```
Read on its own, `command` + `args` reads unambiguously as *the thing to
execute*. The spec does say elsewhere that `agent_command`/`agent_args` are
"the ACP agent under the harness", but the `deploy` contract never states that
the provider must supply the harness, and §Launch data — the section a provider
author works from — doesn't mention `buzz-acp` at all.
## Why no test catches it
Every `deploy-*.request.json` fixture in
`crates/buzz-backend-kubernetes/tests/fixtures/provider-wire/` carries **no
launch command at all** — `deploy-no-owner`, `deploy-relay-mesh`,
`deploy-relay-mesh-padded`, `deploy-tag-image` have neither `launch` nor
`agent_command`. That is correct for the Kubernetes binding, whose container
image `ENTRYPOINT` is the harness (§K8s Entrypoint). `deploy-full-launch` does
carry `launch`, but is only asserted structurally.
So a provider can pass the entire golden-fixture suite, satisfy [L2]
conformance as written, and still deploy agents that never connect. The layer
the bug lives in is the one the fixtures cannot reach.
## Symptoms, so others can recognise it
Two runtimes, two different signatures, one cause:
- **goose** — `goose acp` blocks on stdin, so the process lingers. `ps` shows a
healthy agent, the worktree/pod looks fine, and it never responds to anything.
- **buzz-agent** — exits immediately with nothing driving it, so its terminal
disappears and it looks like a crash with no error.
In both cases Buzz's own view is a successful deploy: `backend_agent_id` set,
`last_error: null`. There is no failure to surface, because from the provider
protocol's perspective nothing failed.
## Suggested fixes
Any one of these would have prevented it, roughly in order of preference:
1. **Have `launch` carry the resolved harness invocation** — e.g. a
`harness_command` field, or make `command`/`args` the full command to exec
with the inner agent already expressed in `env`. Then providers cannot get
it wrong, which is consistent with the stated rationale for the `launch`
block ("A provider MUST NOT reimplement that derivation").
2. **State it in §Launch data**: the provider runs the harness; `launch.command`
and `launch.args` go to `BUZZ_ACP_AGENT_COMMAND` / `BUZZ_ACP_AGENT_ARGS`
(comma-delimited).
3. **Add a fixture** whose expected behaviour exercises the harness layer, so
[L2] conformance means something here.
## Context
Found while building an out-of-tree provider that runs Buzz agents in
[Orca](https://stably.ai) worktrees. Happy to send a docs PR for (2) if that is
useful.
Verified against `main` at `07a3c76`.
Contributor guide
Assessment
This issue has not been assessed yet.