镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

feat(agents): import old Buzz teams from the Teams tab - #985

Merged
wpfleger96 merged 18 commits into
mainfrom
duncan/team-import
Oct 14, 2026
Merged

wpfleger96 merged 18 commits into
mainfrom
duncan/team-import

Conversation

@wpfleger96

@wpfleger96 wpfleger96 commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

🤖 Brings old Buzz teams into the 1.0 app and gives the Teams tab the same layout as Your agents. On Your teams, New team (in the spot New agent takes on Your agents) opens a menu with Create a new team and Import a team. Import an agent, under New agent, lists only old agents; Import a team lists only old teams. Both use one dialog and one import path.

  • Import team imports each member that is not here yet, then saves the team once with its old name and shared instructions and every member now in this community, including members that were imported on their own earlier. Re-importing fills in what is missing: it never duplicates a team or member and never overwrites a name or instructions edited in the new app.
  • Import agent imports only that agent and never touches teams.
  • Teams are matched only by a stable ID, beta-<sha256(oldId\nscope)>, where scope is the signed-in account plus the community (relayPartition). They are never matched by name, so a hand-made team with the same name is left alone. Two accounts on one device that import the same old team get separate teams, and neither import changes the other's members, name or instructions. A deleted imported team is recreated by the next import.
  • The team is read fresh from old Buzz (Installed and Development stores merged) at import time, not taken from the preview, and everything lands in the community and account that were active when the import started. Switching community stops before the next member.
  • Welcome Team (old Buzz is_builtin) is not listed; its members import as ordinary agents.
  • While an import runs, the dialog is busy and can't be closed. A complete import closes it and selects Your teams for a team import, or Your agents for an agent import. Partial results keep the dialog open with a message naming each member that failed (including any old Buzz no longer lists; a member with no name is shown by its short public-key label), and each member already imported into another community, which is left off this community's team. If the team itself fails to save, nothing changes in storage or memory and the message says so by name.
  • A member counts as already here only when it shows in Your agents: in this community and owned by the signed-in account. The agent registry on this device is shared across builds and sign-ins, so a member another account owns is left off the team, even one an earlier import already saved on it, and named in the message as belonging to another account on this device. The preview's "already here" count uses the same rule and updates after a partial import.
  • A team stays listed even when all its members are already here.
  • Your teams uses the same empty-state art tile, card style and grid as Your agents. Each team card shows the team name, up to three member portraits and the member names; clicking it opens the team editor. The editor stays open only while that team still exists or is being created, and leaving the tab closes it.
  • The saved Teams list itself stays device-wide, as on main.

Native side: agent-controller lists old teams with named members and their source store. Members are linked as old Buzz links them: by team_id, or by the name of their persona_team_dir folder matched against the team's source folder (else its ID). Agents no longer carry a team.

@wpfleger96

wpfleger96 commented Oct 13, 2026 •

Copy link
Copy Markdown
Member Author

Read-only source review of team Import at remote-verified head ff72c2c15e6c69df16439bc8648c1e424f6b24f4, pass 1. Two IMPORTANT agreed-contract findings remain; otherwise the implementation follows the approved plan.

IMPORTANT — Correctness: the committed fixture retains a known real team name

crates/agent-controller/testdata/old-buzz-teams/teams.json:15 uses Sietch Tabr, which the approved plan identifies as the team name in the real old Buzz stores. The assignment requires these fixtures to contain no real names, keys, prompts or paths. This is an identifiable failure of that fixture requirement, not evidence of a leaked private key. Replace the custom team name with an unrelated synthetic name and update its fixture assertions in port/tests.rs. Public built-in seed values such as builtin-team:welcome should remain: the plan explicitly requires them. I inspected both committed JSON files without opening the real stores; their public keys are repeated-digit placeholders, their relay is .example, and neither file includes a private key or user filesystem path.

IMPORTANT — Correctness: the planned pre-existing same-name team case is not protected

src/features/agents/service.test.ts:536–569 creates the user team only after the imported team already exists. It therefore does not test the required first import when a user-created same-name team already exists. A regression that first looks up the imported ID, then falls back to matching by name would pass these assertions but incorrectly adopt the user's team on that first import.

Add a separate test that creates the same-name user team before the first import, then asserts the user team is exactly unchanged and a distinct expected beta-… team is created with the imported member and old instructions. The production implementation at service.ts:1294–1312 is correct today; this finding is the missing agreed regression case, not a claim that it currently matches by name.

What is solid

  • Fresh team: OldStores::take re-reads the file; app_agent_port calls Ported::new (app_agents.rs:372); that constructor forwards found.team and omits absent teams on serialization. a_ported_agent_carries_its_freshly_read_team exercises the real reader and constructor (739–790). Replacing the constructor's team with None necessarily fails the reported JSON assertion, matching Duncan's red receipt. The service separately tests fresh native data winning over preview data.
  • Failed team save: the real writer runs through service.ts:1320–1324 to store.ts:229–230, before memory changes. The failure test (service.test.ts:646–667) injects at storage.setItem, checks stored bytes and snapshot identity remain unchanged, keeps the agent, and requires the named teamError. Moving snapshot publication before persistence fails that identity assertion, matching the reported receipt. The receipt verifies moving the memory/snapshot update ahead of storage; I have not rerun the mutation independently. The mounted full-page test checks Import remains selected, the card disappears, and recovery copy remains visible.
  • Stable ID plus committed destination, preserving new-app edits, member union, built-in skipping by flag, missing/deleted old teams, and delete-then-import recreation all trace correctly. The start path and existing storage writer are unchanged; there are no team relay writes or added persistent recovery state.
  • main at 0ec0c1adbdceb480e49f218e261d9c38d44d2a3c adds only conversation context to profile props in service.ts; it does not alter this PR's dependencies.
  • The PR is draft with no requested reviewers, uses a conventional title, and its sole commit has Duncan's DCO sign-off. The explicit assignment says no Will trailers; DCO Check passed.

Optional test improvement: the cross-community test's fake native port always returns the first community's relay (service.test.ts:243–249). Make it honor the destination and assert each resulting member identity belongs to its team's community. The current assertions prove the destination-derived IDs, not that full membership invariant. Also add a direct delete-team/recreate assertion for Will's accepted edge case; the implementation is correct by inspection.

No local tests/builds/linters or mutations were run; the two red-then-green receipts were source-checked, not independently re-executed. DCO passed and the six automatic jobs listed at the single CI inspection were still running. Live native import and rendered UI checks remain with Gurney, followed by human acceptance; this is not a shipping approval.

@wpfleger96

Copy link
Copy Markdown
Member Author

Team Import: second source review

All four previous findings are CLOSED; no new source blocker. Reviewed remote-verified head 3d0bc50999cc36e52d016508de6afa9ceb96b77d and the complete incremental diff from ff72c2c15e6c69df16439bc8648c1e424f6b24f4. The fix changes only five test/data files (77 insertions, 43 deletions); production code is unchanged.

  1. IMPORTANT — fixture names: CLOSED. Both old-store fixtures and their Rust/service/page assertions now use the unrelated names Night Shift, Helpers, Alder and Birch. The whitespace-trimming cases remain, and the public built-in Welcome Team seed is unchanged. A case-insensitive whole-word git grep at this exact head found no Sietch, Fremen, Stilgar or Chani in tracked text. The fixtures still use placeholder public keys and .example relays, with no private keys or user filesystem paths observed. I did not open real stores or certify the provenance of every fixture string.
  2. IMPORTANT — first import with a pre-existing same-name team: CLOSED. src/features/agents/service.test.ts:572–586 creates the owner's Night Shift team before importing anyone. The exact two-team assertion requires the original team, including its ID, instructions and membership, to remain unchanged and a separate expected beta-… team to contain the newly imported member. This catches the name-fallback regression that the previous ordering missed. Duncan's reported red-then-green receipt agrees with the assertion; I source-checked it rather than rerunning that mutation.
  3. MINOR — cross-community fake and membership: CLOSED. src/features/agents/service.test.ts:239–256 derives the native identity's relay from the supplied destination. The test at :637–678 still switches the selected community while the first import is in flight, checks both stable team IDs and exact member lists, and now checks each imported identity's corresponding relay. It no longer constructs the second team's member with the first community's relay.
  4. MINOR — delete/recreate regression: CLOSED. src/features/agents/service.test.ts:588–597 imports one member, removes the imported team, then imports another. The exact resulting team requires the stable ID and original text but only the new member; it protects the accepted no-backfill behavior.

The protected Rust construction/serialization and storage-before-memory failure tests remain intact. The full-page partial-success assertions change only their synthetic names. No new behavior, abstraction, recovery state or production scope was introduced. The incremental git diff --check is clean.

Evidence limits: no local tests, builds, linters or mutations executed, and no repository files changed. At the single hosted-check inspection, DCO Check succeeded; that response listed no other checks, so I am not claiming complete CI success. This clears the source findings, not the live Import workflow or readiness to merge. Independent live verification and human acceptance remain separate gates.

— Thufir

@wpfleger96 wpfleger96 changed the title feat(agents): import old Buzz teams with their agents feat(agents): import old Buzz teams from the Import tab Oct 13, 2026
@wpfleger96
wpfleger96 marked this pull request as ready for review October 13, 2026 20:09
@wpfleger96
wpfleger96 requested a review from a team as a code owner October 13, 2026 20:09

@kalvinnchau kalvinnchau left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Source review found two issues: legacy directory-backed team membership is omitted, and the preview counts identities from other communities as already here. Please address these before merging. No tests or app execution performed.

Comment thread crates/agent-controller/src/port.rs Resolved
Comment thread src/bundled/agents/AgentsPage.tsx Resolved

@kalvinnchau kalvinnchau left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Two issues remain: re-import can retain another account's team members, and partial imports leave the preview count stale. Please address these before merging. Source review only.

Comment thread src/features/agents/service.ts Resolved
Comment thread src/bundled/agents/AgentsPage.tsx Resolved
@wpfleger96
wpfleger96 force-pushed the duncan/team-import branch 2 times, most recently from 6d84fec to e3655b2 Compare October 14, 2026 21:58
@wpfleger96 wpfleger96 changed the title feat(agents): import old Buzz teams from the Import tab feat(agents): import old Buzz teams from Import an agent Oct 14, 2026

@kalvinnchau kalvinnchau left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Reviewed the latest head. Prior findings are resolved, including account-scoped imported teams and A → B → A regression coverage. No remaining actionable findings. Source review only; tests and runtime behavior were not exercised.

Duncan added 17 commits October 14, 2026 18:26
An agent imported from old Buzz now joins its old team in the community it was imported into, creating the team on its first member. The team is read again at import and keyed to the committed community; a failed team save keeps the agent and says so on the Import tab.

Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
Fixtures and tests no longer reuse names from a real old Buzz setup. New cases pin that a same-name team made before any import is never adopted and that a deleted imported team is recreated, and the fake native now makes each agent in the community it was given.

Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
Will's model: the Import tab lists old teams and old agents separately. Import team brings every member not here yet, then saves the team once with every member in the community it started in; Import agent never touches teams. Native lists teams with named members built before old Buzz's pubkey merge, so importing re-reads the same merged roster it previewed.

Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
…t's owner

Members old Buzz no longer lists fail by name before any import, and blank names show as a short npub. Result messages name the team as saved, and a failed save names the agents that came.

Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
…ey label

Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
The native registry is shared by every build and sign-in on the machine, so a member counted as already here by public key and community alone could be another owner's agent: hidden in Yours, unrunnable, and its import skipped. A member now joins as already here only when it shows in Yours; one owned by another account is left off and named, and the preview counts only agents in Yours.

Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
Classifying members through the live binding put the captured owner's own agent in elsewhere once another owner signed in mid-import. One partition check against the captured binding now decides yours, foreign and elsewhere; the preview uses the selected binding.

Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
An earlier import's copy of the team is keyed by old team and community, not owner, so its members were merged back unchecked and another account's agent stayed on a team the result reported as kept out.

Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
Import dropped the imported agents from its list but left the team's "already here" count as it was before the import.

Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
Import's per-community count of members already here, which fixed this, needed page and service coverage.

Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
Old Buzz also links an agent to a team by its persona_team_dir folder name, matched against the team's source folder or ID. Import read only team_id, so folder-linked teams came without members and mixed teams lost them.

Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
The early return for an import with no successful members ran before the saved team's filtered roster was written, so another account's agent stayed on it while the result reported it kept out.

Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
Main moved Import into a dialog from New agent. The rebase left port without
its closing onPendingChange(false), which would keep the dialog unclosable
after a failed single import; restore it and mark team imports pending too.

Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
The imported team ID hashed only the old team and community, so a second
account importing the same old team took over the first account's saved
team. Hash the owner-plus-community scope instead.

Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
Team import was only reachable from New agent, so people looking on Your teams could not find it. New team now offers create and import, Import a team shows only teams, and teams render as cards in the agent grid.

Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
The lifted edit id outlived the editor's draft across tab switches, and an id whose team vanished hid New team. The editor now opens only for a new or still-saved team, and leaving Teams clears it.

Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
@wpfleger96 wpfleger96 changed the title feat(agents): import old Buzz teams from Import an agent feat(agents): import old Buzz teams from the Teams tab Oct 14, 2026
@wpfleger96
wpfleger96 merged commit e10c4ee into main Oct 14, 2026
59 of 61 checks passed
@wpfleger96
wpfleger96 deleted the duncan/team-import branch October 14, 2026 23:14
johnmatthewtennant added a commit that referenced this pull request Oct 15, 2026
…-drag

* origin/main: (34 commits)
  fix(channels): resolve template agents from ready inventory (#922)
  [buzz-app] Fit uploaded videos to the relay's 4K envelope and name video rejections (#1129)
  feat(github): reveal the PR comment a link points at (#947)
  fix(messages): stop WebKit freeze from muted composer video previews (#1143)
  test(browser): fix route-unroute and virtua-hold webkit flakes (#1149)
  test(browser): let dnd-kit see its first resize before text shrinks (#1150)
  fix(previews): keep a hovered preview through scroll anchoring (#1138)
  Unify owned agent profile panels (#1083)
  feat(agents): import old Buzz teams from the Teams tab (#985)
  Mark Me chats as personal in the session description for remote agents (#1058)
  feat(messages): optional way to open buzz message links in a thread tab (#1113)
  Distinguish thread originals and tighten conversation spacing (#929)
  fix(buzz-mcp): page channel reads past the relay limit (#1131)
  fix(inbox): show a session's top-level timeline as one conversation (#1094)
  feat: reorder sidebar groups by dragging their headers (#1118)
  fix(avatars): request the cached relay thumbnail at every avatar site (#1054)
  fix(messages): soften quote styling and tighten spacing (#1098)
  fix(emoji): shrink and raise inline custom emoji (#1097)
  fix: follow host theme in media review chrome (#1117)
  Highlight an already-open thread tab when reopening it (#1050)
  ...

Signed-off-by: John Tennant <jtennant@block.xyz>
Co-authored-by: Claude Worker <f425b86c3b780d43f8d9cf1802429d04dd985bf92eac44fca9468b5ad3887c5e@buzz.block.builderlab.xyz>

# Conflicts:
#	src/features/channel-navigation/ChannelSidebarDnd.tsx
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.

2 participants