Skip to content

feat(desktop): implement 30178 team catalog backend - #5112

Open
wpfleger96 wants to merge 1 commit into
mainfrom
duncan/team-catalog-backend
Open

feat(desktop): implement 30178 team catalog backend#5112
wpfleger96 wants to merge 1 commit into
mainfrom
duncan/team-catalog-backend

Conversation

@wpfleger96

@wpfleger96 wpfleger96 commented Aug 6, 2026

Copy link
Copy Markdown
Member

Implements the Rust/backend half of 30178 team catalog sharing on the community catalog. No TS callers yet — this is PR 1 of 2; #3995 (stacked here) adds the parse layer, hooks, CommunityCatalogDialog, and e2e tests.

What this adds

Projection builder (team_catalog.rs): build_team_catalog_event/content produces a 30178 event from a team + member definitions. Size contracts: 192 KiB total ceiling, per-field bounds (name 256 B, text 4 KiB, system-prompt 16 KiB, avatar URL 32 KiB for projection fields; https URLs additionally validated at 2,048 bytes). Avatar handling: oversized raster data URLs downscaled to fit; oversized built-in avatars silently omitted; oversized https URLs rejected with a named error.

Share/unshare/tombstone (commands/teams/pending.rs): prepare_team_publication_at retains a signed 30178 head for the flush loop; share state is relay-scoped (one community can share while another does not). refresh_or_retract_shared_head_at rebuilds or tombstones the head immediately on team/member edit — no stale publication until the next boot. Persona-edit path reads only the team's own members, never the full persona store.

Atomic adopt (commands/teams/adopt/): add_team_from_catalog re-fetches and signature-verifies the head from the relay, then plans and commits a multi-entity add across two store writes with byte-exact rollback on any failure (crash window between writes explicitly retained). plan_add resolves full member provenance (owner, d-tag, member-key, projection-hash), reuses exact-match built-in personas, and reactivates deactivated copies on re-add. commit_stores snapshots both stores before writing and restores them on failure.

Startup reconcile (event_sync.rs): reconcile_team_catalog_heads_at walks all retained 30178 heads at boot: republishes heads whose content changed, tombstones heads whose team or member was deleted, skips unshared heads and unchanged content. Multi-team continuation — all shared teams processed in one pass.

Types: TeamRecord and AgentDefinition extended with shared, catalog_source, team_catalog_source fields. All commands registered in lib.rs.

Tests

  • team_catalog/tests.rs (999 lines): projection, size contracts, member-key stability, tombstone rollback, fixture matrix
  • adopt/tests.rs (999 lines): head verification, store planning, provenance, rollback
  • pending/tests.rs (679 lines): share/unshare/tombstone lifecycle, edit refresh/retract, typed outcomes
  • event_sync_team_catalog_tests.rs (436 lines): reconcile scenarios including multi-head continuation
  • 27 shared JSON parity fixtures (tests/fixtures/team_catalog_content/) consumed by both this PR's Rust tests and feat(desktop): add team sharing to community catalog #3995's TS tests

Stack: this PR → #3995

Implements the backend for 30178 team catalog sharing on the community
catalog. No UI callers yet — this PR is the backend half of a two-PR
split; desktop PR #3995 (stacked here) adds the TS parse layer, hooks,
CommunityCatalogDialog, and e2e.

Changes:
- team_catalog.rs: 30178 projection builder + size contracts (32 KiB
  ceiling, per-field bounds, avatar downscaling for raster data URLs);
  build_team_catalog_event/content, team_catalog_content_from_event,
  tombstone_team_catalog_coordinate
- commands/teams/pending.rs: publish/unshare/tombstone commands with
  relay-scoped share state; refresh_or_retract_shared_head_at for
  immediate retraction on member edits that exceed the size contract;
  persona-edit refresh guard so unrelated personas are never embedded
- commands/teams/adopt/: add_team_from_catalog with backend head
  verification + byte-level rollback across both stores; plan_add with
  full member provenance (owner, d-tag, member-key, projection-hash);
  builtin reuse via hint matching; commit_stores atomic writer
- event_sync.rs: reconcile_team_catalog_heads_at startup reconcile;
  republish changed heads, tombstone unrebuildable ones, skip unshared;
  multi-head continuation so a single pass handles all shared teams
- Rust tests: team_catalog/tests.rs (999 lines), adopt/tests.rs (999),
  pending/tests.rs (679), event_sync_team_catalog_tests.rs (436)
- 27 shared JSON parity fixtures (team_catalog_content/)
- Existing TeamRecord + AgentDefinition types extended with sharing
  fields (team_catalog_source, catalog_source, shared flag, etc.)
- All commands registered in lib.rs; dormant until UI PR merges

Stack: this PR -> #3995
Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
@wpfleger96
wpfleger96 requested a review from a team as a code owner August 6, 2026 21:08
@wpfleger96 wpfleger96 changed the title feat(desktop): add 30178 team catalog backend feat(desktop): implement 30178 team catalog backend Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant