Skip to content

Deleting a relay-synced agent definition deletes it account-wide and orphans live agents #3440

Open

Description

@Czaruno

Summary

A second Desktop install can receive an account-scoped agent definition without owning the corresponding local agent keypair. If the resulting bodyless/duplicate entry is deleted on that install, Buzz publishes a kind:5 tombstone for the shared kind:30175 definition. The tombstone is applied on every install, including the machine running the real agent body.

The surviving agent retains its original persona_id, but that definition no longer exists. There is no supported UI path to restore the definition at the old id or relink the agent to a replacement definition, so the live identity becomes orphaned.

This is a destructive second-order failure of #3414 (also related to #2648): the second install can first mint a ghost identity for the already-instantiated definition, then deleting the ghost's entry removes the shared definition rather than only the local duplicate.

Reproduction

  1. On install A, create a definition and start its managed agent.
  2. Sign into the same Buzz account on install B. The account-scoped kind:30175 definition appears, but install B has no local agent record/keypair for install A's kind:30177 identity.
  3. Start or DM the definition on install B. A new keypair/agent identity is minted with the same display name and persona id.
  4. Delete the duplicate/bodyless entry on install B.
  5. Observe a kind:5 targeting the shared kind:30175. The definition disappears on both installs.
  6. Install A's original agent record remains but points to the now-missing persona_id and is reported as orphaned.

Observed evidence

  • Duplicate pubkey prefix 497d45dd… published kind:0 at 2026-07-28T21:51:36Z and 11 kind:9 events through 22:30:25Z, with no kind:30175 of its own.
  • The matching Rimac-Buzz kind:30175 definition was published about 90 seconds earlier at 21:50:08Z.
  • Manual recovery required reinserting the definition rows into managed-agents.json at their original ids and saving from Desktop; replacement kind:30175 events appeared at 00:26:43Z and 00:26:49Z.

Expected behavior

  • A relay-synced definition must not be treated as locally owned deletion authority. Removing it on a secondary install should be local-only and must not publish a kind:5 for the shared kind:30175.
  • Before minting, Desktop should use the retained owner-authored kind:30177 persona_id association to detect an identity that exists on another install. It must not fabricate a runnable local shell without the secret key.
  • If a shared definition is legitimately tombstoned, linked local agent identities should remain runnable as standalone snapshots rather than becoming dangling references.
  • The edit UI should support relinking an orphaned agent to an active definition without changing its pubkey/keypair.

Root causes

  1. Inbound kind:30177 events are retained but no non-runnable identity index is exposed when there is no local record, so creation and mention flows cannot deduplicate by persona_id.
  2. delete_persona publishes a kind:5 for a definition learned from the owner's relay, conflating local cleanup with account-wide deletion authority.
  3. Inbound kind:30175 tombstones remove the definition without first detaching/materializing linked local agents, and the edit API has no persona-link repair operation.

Activity

  1. ben-waymarker commented on Sep 4, 2026

    @ben-waymarker

    Hitting this on a current build (macOS, Buzz Desktop), and the manual recovery described in the issue body no longer applies — persona definitions have since moved out of personas.json into agents/retention/<scope>.db, table persona_events, so there is no definition row left in managed-agents.json to reinsert.

    Sequence on our side: four custom personas (John, Memory Steward, Project Manager, Worker) were orphaned after duplicate/bodyless entries were deleted on a second install. Four kind:5 events signed by the owner key target 30175:<owner>:<uuid> for exactly those four. The kind:30177 instance records and their keypairs are untouched, so all four agents show "This agent's configuration is missing — it may still be syncing or was deleted on another device."

    Two things make this unrecoverable rather than merely broken, and I think they are the parts worth fixing:

    1. Deletions replicate but definitions do not. Querying the relay directly for the owner pubkey:

    filter result
    kinds:[5] all four persona tombstones present
    kinds:[30175] 0 events
    kinds:[30177] 10, with deleted instances correctly absent

    Persona definitions appear to be local-only while persona deletions are published account-wide. So the destructive half of the state syncs and the repairable half does not: every launch re-applies the tombstones against local definitions that are sitting intact on disk, and no local edit can ever win.

    2. There is no UI path to re-save an unresolvable persona. A kind:5 only suppresses events older than itself, so re-saving the definition would permanently outrank it — that is the natural fix. But an agent whose persona_id does not resolve renders under "Unknown agents" with no editable card, and Start does not create a persona. The one action that would repair the state is the one action the UI removes precisely when it is needed.

    Concretely, what would have unblocked us:

    • a way to re-publish/restore a definition at its original id (even just "Restore" on an orphaned agent), or
    • the relink operation already listed under Expected behavior — repointing an orphaned agent to a live definition without changing its pubkey, and
    • either publishing kind:30175 alongside deletions, or scoping deletions to the install that issued them so an unpublished definition cannot be killed account-wide.

    Related: #3414 (the ghost-minting path that creates the deletable duplicate in the first place) and #5705 (rename leaving instances stranded on an old identity). All three land on the same underlying gap — instance identity and definition identity are separately mutable, and only one of them is authoritative on the relay.

    Happy to supply the raw event ids or the relay query if useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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