Skip to content

Snapshot import has no update path: reimport duplicates, and the team it created cannot be deleted #3085

Description

@finwitz

Snapshot import has no update path: reimport duplicates, and the team it created cannot be deleted

Summary

Importing a .team.json snapshot is a one-way operation. There is no way to
update an imported team in place, and no practical way to remove one, so any
change to the source of a snapshot leaves the operator stuck between duplicates
and a manual 27-step cleanup.

Two behaviours combine into the dead end:

  1. Import always mints new agents. confirmAgentSnapshotImport is
    documented as importing "as a brand-new agent with fresh keys", and snapshots
    deliberately strip every lineage field (persona_id, persona_source_version,
    source_team, source_team_persona_slug). Nothing on the wire identifies two
    snapshots as versions of the same agent, so reimport can only duplicate.

  2. Delete refuses while members exist. delete_team_with_cascade cascades
    personas that came from a source_dir, but a JSON-imported team has none, so
    agents_referencing_team is non-empty and the delete hard-fails.

Steps to reproduce

  1. Author a buzz-team-snapshot v1 file with 27 members.
  2. Import it in Desktop. 27 agents are created and joined to a new team.
  3. Change one member's system prompt at the source and reimport.
    → 54 agents. No prompt was updated.
  4. Try to delete the team to start clean.
Cannot delete team "5ff0eeb8-07c6-4c45-9ba6-4cbf57fbbc89": 27 agent(s) still
reference it (Blender Addon Engineer, Economy Designer, Game Audio Engineer,
... 24 more). Delete or reconfigure them first.

The only supported path is deleting 27 agents individually in the UI. There is
no bulk delete, and no buzz agents delete in the CLI. Editing
managed-agents.json by hand would orphan the relay-side kind:30175 persona
heads that delete_team_with_cascade documents as needing NIP-09 tombstones.

Impact

This scales with team size, and team snapshots exist precisely to make large
teams importable in one step. A 27-agent team is 27 manual deletions per
iteration. It also makes snapshots unusable as a distribution format for any
library that changes over time, since consumers can receive a v1 but never a
v2.

Proposed fixes

Three, listed smallest first. They are independent.

1. cascade_members on team delete. An explicit opt-in flag on the delete
command that removes referencing agents and enqueues their tombstones, reusing
the cascade path that already exists for source_dir personas. Keeps the
current refusal as the default. This alone unblocks the reimport workflow.

2. Bulk delete in the UI, and a buzz agents delete subcommand. Precedent:
#2976 asks for buzz repos delete
for the same reason.

3. Optional sourceId on the snapshot, enabling idempotent import. A
stable, caller-supplied identifier that survives export. On import, a matching
sourceId offers update-in-place (definition and profile only, preserving keys,
memory, and channel membership) instead of minting a duplicate. This is the root
fix; 1 and 2 are workarounds for its absence.

sourceId is deliberately not a lineage field of the kind the format already
excludes on privacy grounds: it identifies the source artifact, not the
exporting machine, relay, or account, and it is opt-in per snapshot. Adding it
to v1 as an optional field is backward compatible in both directions, but it is
a wire-format change and worth agreeing on before anyone writes it.

Related

  • #2973 — stale duplicate agents that cannot be archived or removed. Same removal gap, reached from a different direction.
  • #2648 — duplicate agent identities from a second Desktop install.
  • #1725 — orphaned duplicate agent definitions.

Environment

  • Buzz Desktop (macOS), packaged build
  • Snapshots authored externally as buzz-team-snapshot v1

Offer

Happy to open a PR for (1), which looks self-contained in
desktop/src-tauri/src/managed_agents/teams.rs plus the command wrapper and a
confirmation in the delete dialog. Would rather agree the shape of (3) here
before touching the format.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions