Persona fold + standalone backfill strand orphaned duplicate agent definitions (duplicate error cards)
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
## Summary
The persona fold and the standalone-agent backfill can each create a definition for the same conceptual persona, stranding an orphaned duplicate. The Agents screen renders the orphan as a second card for the same agent in a permanent error state (red badge), with no hint it's a deletable leftover.
## What the store ends up with
One agent ("Ron Swanson") after both migrations have run:
| record | `slug` | `pubkey` | `persona_id` | created by |
|---|---|---|---|---|
| definition A | `` | empty | — | `backfill_standalone_agents` (migration/backfill.rs — slug = pubkey by design) |
| definition B | `` | empty | — | `fold_personas_into_agent_store` (migration/fold.rs — legacy persona id) |
| instance | — | `` | `` | linked to definition A |
Definition B is referenced by nothing: key-less, instance-less, permanently un-launchable. The UI shows it as a duplicate card with an error badge next to the healthy one.
## Why it happens
- `fold_personas_in_dir` dedupes folded personas by `slug` against the store — correct in isolation.
- `backfill_standalone_agents_in_dir` targets instances with `persona_id: None` and manufactures a NEW definition slugged by the instance's pubkey, without first checking whether a just-folded definition already matches the instance (by name/prompt content). Result: the instance links to the manufactured definition and the folded one is orphaned.
## Recurrence trigger
Anything that resurrects `personas.json` (restoring app data from a backup, or running a pre-fold build against the shared data dir) re-runs the fold and re-imports the UUID definitions — users see duplicates "come back" after cleaning up, which invites destructive app-data wipes.
## Repro
1. Pre-fold data dir: `personas.json` with N custom personas + `managed-agents.json` with N standalone instances (`persona_id: null`).
2. Boot a current build: fold imports N UUID-slugged definitions; backfill manufactures N pubkey-slugged definitions and links the instances to those.
3. Agents screen: every agent appears twice; one card healthy, one erroring.
4. Delete the orphans by hand, restore `personas.json` from any backup, reboot → duplicates return.
## Suggested fixes (any of)
- Backfill: before manufacturing, try to adopt an existing key-less definition matching the instance (name + prompt hash), and link to it instead.
- Boot-time GC (or one-shot migration): drop key-less, non-builtin definitions whose slug no instance references.
- UI: surface orphaned definitions as such ("no instance, from an old import") with a delete affordance instead of a generic error badge.
## Workaround
Quit the app and filter `managed-agents.json`: remove records with empty `pubkey` whose `slug` is not `builtin:*` and is not any instance's `persona_id`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Contributor guide
Research direction
Start with migration/fold.rs and migration/backfill.rs, especially fold_personas_in_dir and backfill_standalone_agents_in_dir. Reproduce the issue with personas.json and managed-agents.json containing matching standalone records, then trace which definitions and links are created. Done means the migration flow no longer leaves duplicate or permanently orphaned definitions, including after personas.json is restored.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100