Summary
Creating more than one agent from the CLI is not reliably possible today. Drafts sent in quick succession are silently dropped — only the first survives — and the sender is told the opposite ("accepted": true). There is no batch path and no queue, so the only working method is one draft per human round-trip.
Use case
An agent (or any script) reviews N things and proposes one managed agent per thing — a fleet of specialist agents created in a single pass. This is a natural fit for buzz agents draft-create: the CLI can generate the display names and system prompts programmatically, and the owner reviews what was proposed.
Owner review is the right design and this issue does not ask to remove it. NIP-OA attestation is what makes the identity trustworthy, and restricted_writes: true on the relay means it can't be waived client-side anyway. The ask is that N drafts survive to be reviewed, however many confirmations that takes.
Bug 1 — drafts sent in succession are silently superseded
Desktop appears to hold a single pending draft. A draft arriving while a review prompt is already open replaces the pending one rather than queuing behind it. The dropped draft is gone: it is not recoverable from the UI, and nothing in the app's data directory records it.
The sender gets no signal. Every draft-create returns:
{"accepted": true, "action": "create", "event_id": "...", "saved": false,
"message": "Draft sent to Buzz Desktop for owner review. Nothing changes until the owner saves it."}
accepted: true is true of the relay event but not of the draft's fate, so a script has no way to detect the loss. Whoever sent the batch believes N drafts are waiting; the owner sees one.
Repro
- From the CLI, send several drafts back-to-back (~1s apart):
for i in 1 2 3 4; do
buzz agents draft-create --channel "$CHANNEL_UUID" \
--display-name "Test Agent $i" --system-prompt "You are test agent $i."
done
- Observe every call returns
accepted: true.
- In Desktop, exactly one review prompt appears — the first one sent. Save it.
- No further prompts appear. Drafts 2–4 are gone.
Observed across three separate bursts (4, then 2, then 2 drafts): one survivor each time, always the first. Sending them one at a time, waiting for each Save before the next, works every time — which is the workaround, at one human round-trip per agent.
Suggested fix
Queue pending drafts rather than replacing the current one, and present them in arrival order. Even a queue with no other change turns an N-agent batch into N clicks instead of N silent losses. Secondarily, draft-create should be able to report that a draft was superseded rather than returning accepted: true unconditionally.
Bug 2 — no documented batch path, and import errors don't identify the parser
Digging through buzz-desktop for a batch route surfaces snapshot import: .agent.json / .agent.png / .team.json / .team.png, backed by preview_agent_snapshot_import / confirm_agent_snapshot_import and preview_team_snapshot_import / confirm_team_snapshot_import. A .team.json holding N members behind a single preview-then-confirm is exactly the shape this use case needs.
Two problems make it unusable from outside the app:
No published schema. The only way to learn the layout is to read struct symbols out of the shipped binary (TeamSnapshot → format, version, team, members; AgentSnapshot → format, version, definition, profile, memory). Nothing in buzz --help mentions snapshots, and there is no CLI command to author or validate one — buzz pack validates persona packs, which are a different, read-only format that cannot create agents.
The error doesn't say which parser rejected the file. Importing a hand-authored file named *.team.json whose top level is {"format": "buzz-team-snapshot", "version": 1, "team": {...}, "members": [...]} produced:
Invalid snapshot JSON: missing field `definition` at line 92 column 1
Line 92 column 1 is the end of the document, and definition is a required field of AgentSnapshot, not of TeamSnapshot — so the file was parsed as a single agent snapshot. The binary carries a distinct Invalid team snapshot JSON: message that did not fire.
Whether that's a dispatch bug or the wrong import affordance being used, the error can't tell you: it names a field without naming the type it belongs to, and it doesn't say which format it expected. A first-time author of a snapshot file has nothing to correct against.
Repro
- Author a file
something.team.json:
{
"format": "buzz-team-snapshot",
"version": 1,
"team": {"name": "...", "description": "...", "instructions": "..."},
"members": [ { "format": "buzz-agent-snapshot", "version": 1,
"definition": {...}, "profile": {...},
"memory": {"level": "none", "entries": []} } ]
}
- Import it in Desktop.
- Observe Invalid snapshot JSON: missing field
definition — an AgentSnapshot field, reported against a team file.
Suggested fix
- Dispatch on the file's own
format value (buzz-agent-snapshot vs buzz-team-snapshot) rather than on the entry point, so a team file imported anywhere is read as a team file.
- Name the expected type in the error: Invalid agent snapshot JSON: missing field
definition beats Invalid snapshot JSON: ....
- Document both snapshot schemas, and expose validation from the CLI —
buzz snapshot validate <path>, mirroring buzz pack validate, would let a script check a file before asking a human to import it.
- Longer term, a batch draft path (
buzz agents draft-create --batch <file>) would make this a first-class CLI capability rather than a file-import workaround.
Environment
- Buzz Desktop / CLI, macOS (Darwin 25.5.0)
- Relay: hosted,
block/buzz 0.2.0, auth_required: true, restricted_writes: true
Summary
Creating more than one agent from the CLI is not reliably possible today. Drafts sent in quick succession are silently dropped — only the first survives — and the sender is told the opposite (
"accepted": true). There is no batch path and no queue, so the only working method is one draft per human round-trip.Use case
An agent (or any script) reviews N things and proposes one managed agent per thing — a fleet of specialist agents created in a single pass. This is a natural fit for
buzz agents draft-create: the CLI can generate the display names and system prompts programmatically, and the owner reviews what was proposed.Owner review is the right design and this issue does not ask to remove it. NIP-OA attestation is what makes the identity trustworthy, and
restricted_writes: trueon the relay means it can't be waived client-side anyway. The ask is that N drafts survive to be reviewed, however many confirmations that takes.Bug 1 — drafts sent in succession are silently superseded
Desktop appears to hold a single pending draft. A draft arriving while a review prompt is already open replaces the pending one rather than queuing behind it. The dropped draft is gone: it is not recoverable from the UI, and nothing in the app's data directory records it.
The sender gets no signal. Every
draft-createreturns:{"accepted": true, "action": "create", "event_id": "...", "saved": false, "message": "Draft sent to Buzz Desktop for owner review. Nothing changes until the owner saves it."}accepted: trueis true of the relay event but not of the draft's fate, so a script has no way to detect the loss. Whoever sent the batch believes N drafts are waiting; the owner sees one.Repro
accepted: true.Observed across three separate bursts (4, then 2, then 2 drafts): one survivor each time, always the first. Sending them one at a time, waiting for each Save before the next, works every time — which is the workaround, at one human round-trip per agent.
Suggested fix
Queue pending drafts rather than replacing the current one, and present them in arrival order. Even a queue with no other change turns an N-agent batch into N clicks instead of N silent losses. Secondarily,
draft-createshould be able to report that a draft was superseded rather than returningaccepted: trueunconditionally.Bug 2 — no documented batch path, and import errors don't identify the parser
Digging through
buzz-desktopfor a batch route surfaces snapshot import:.agent.json/.agent.png/.team.json/.team.png, backed bypreview_agent_snapshot_import/confirm_agent_snapshot_importandpreview_team_snapshot_import/confirm_team_snapshot_import. A.team.jsonholding N members behind a single preview-then-confirm is exactly the shape this use case needs.Two problems make it unusable from outside the app:
No published schema. The only way to learn the layout is to read struct symbols out of the shipped binary (
TeamSnapshot→format,version,team,members;AgentSnapshot→format,version,definition,profile,memory). Nothing inbuzz --helpmentions snapshots, and there is no CLI command to author or validate one —buzz packvalidates persona packs, which are a different, read-only format that cannot create agents.The error doesn't say which parser rejected the file. Importing a hand-authored file named
*.team.jsonwhose top level is{"format": "buzz-team-snapshot", "version": 1, "team": {...}, "members": [...]}produced:Line 92 column 1 is the end of the document, and
definitionis a required field ofAgentSnapshot, not ofTeamSnapshot— so the file was parsed as a single agent snapshot. The binary carries a distinctInvalid team snapshot JSON:message that did not fire.Whether that's a dispatch bug or the wrong import affordance being used, the error can't tell you: it names a field without naming the type it belongs to, and it doesn't say which format it expected. A first-time author of a snapshot file has nothing to correct against.
Repro
something.team.json:{ "format": "buzz-team-snapshot", "version": 1, "team": {"name": "...", "description": "...", "instructions": "..."}, "members": [ { "format": "buzz-agent-snapshot", "version": 1, "definition": {...}, "profile": {...}, "memory": {"level": "none", "entries": []} } ] }definition— anAgentSnapshotfield, reported against a team file.Suggested fix
formatvalue (buzz-agent-snapshotvsbuzz-team-snapshot) rather than on the entry point, so a team file imported anywhere is read as a team file.definitionbeats Invalid snapshot JSON: ....buzz snapshot validate <path>, mirroringbuzz pack validate, would let a script check a file before asking a human to import it.buzz agents draft-create --batch <file>) would make this a first-class CLI capability rather than a file-import workaround.Environment
block/buzz0.2.0,auth_required: true,restricted_writes: true