block / block/buzz

Bulk agent creation: successive drafts are silently dropped, and snapshot import has no documented schema

Open
#3,378 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
32.7k
Forks
4.3k
Avg merge
1d 13h
Merged PRs (30d)
253

Description

## 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:

```json
{"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

1. From the CLI, send several drafts back-to-back (~1s apart):
```bash
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
```
2. Observe every call returns `accepted: true`.
3. In Desktop, exactly **one** review prompt appears — the first one sent. Save it.
4. 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

1. Author a file `something.team.json`:
```json
{
"format": "buzz-team-snapshot",
"version": 1,
"team": {"name": "...", "description": "...", "instructions": "..."},
"members": [ { "format": "buzz-agent-snapshot", "version": 1,
"definition": {...}, "profile": {...},
"memory": {"level": "none", "entries": []} } ]
}
```
2. Import it in Desktop.
3. Observe **Invalid snapshot JSON: missing field `definition`** — an `AgentSnapshot` field, reported against a team file.

### Suggested fix

1. 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.
2. Name the expected type in the error: **Invalid agent snapshot JSON: missing field `definition`** beats **Invalid snapshot JSON: ...**.
3. Document both snapshot schemas, and expose validation from the CLI — `buzz snapshot validate `, mirroring `buzz pack validate`, would let a script check a file before asking a human to import it.
4. Longer term, a batch draft path (`buzz agents draft-create --batch `) 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`

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.