Files
buzz/desktop/tests/e2e/exact-key-profile.spec.ts
Logan Johnson 83e5962984 fix(desktop): keep explicit agent profiles bound to their exact key (#7131)
🤖

## Summary

In Buzz Desktop, clicking a message from stopped agent A could open
running agent B—and B's controls—because both shared a persona (an agent
definition). This now opens the author you clicked and only that agent's
own controls, so you can inspect an old message without being redirected
to a different running agent.

An explicit public key—the identifier for one agent—now stays exact
across message authors, members, DMs, deep links and Instances rows,
including stopped, archived and relay-only agents. Local controls come
only from a matching local record for that key. A relay-only A cannot
borrow B's Start/Stop/Edit controls or configuration.

Deliberately opening a **persona** is different: it can still select a
representative that respects archived instances or offer Start when none
remains. The change removes competing historical-persona redirects
rather than adding another identity exception.

### Related issue

Independent base: `main`; no stack parent or child among the
replacements. Extracted from
[#7114](https://github.com/block/buzz/pull/7114), retained as historical
source (`98fe33ec`).

[Behavior
contract](9c4b6523ce/docs/agent-profile-identity.md).
Originating [Buzz
discussion](buzz://message?channel=f7a9536a-1738-4bad-a888-b3ea25010ef1&id=7aa1f0ab23dce514bd8a0221441cf005bf428914621171472b79747c50820848)
· channel `f7a9536a-1738-4bad-a888-b3ea25010ef1`.

### Testing

Synthetic Playwright mock-bridge state. After screenshots exercise this
independent profile extraction (`df6612b1`); no availability or
cloud-marker implementation is included.

#### Before: historical A redirects to running B
Unchanged main product code (`bc006f67`) with the same updated
historical-message fixture fails: clicking Earlier Parity Agent opens
Current Parity Agent and its Stop control.


![01-before-historical-redirect](https://raw.githubusercontent.com/block/buzz/2acd989f6eae9e7bc1ce5ae5eeafcbc1704f605f/pr-7131--01-before-historical-redirect.png)

#### After: historical A opens A
The clicked author remains Earlier Parity Agent, with A's public key and
its own Start control. The current sibling is not substituted.


![02-after-historical-exact](https://raw.githubusercontent.com/block/buzz/2acd989f6eae9e7bc1ce5ae5eeafcbc1704f605f/pr-7131--02-after-historical-exact.png)

#### Exact relay-only A while local sibling B exists
A's public key and owner-scoped profile are visible; no local
Start/Stop/Edit/Add control or sibling definition is borrowed.


![03-exact-relay-with-local-sibling](https://raw.githubusercontent.com/block/buzz/2acd989f6eae9e7bc1ce5ae5eeafcbc1704f605f/pr-7131--03-exact-relay-with-local-sibling.png)

#### Explicit persona navigation may select local B
Deliberately opening the persona selects its local representative, with
B's key and legitimate Stop/Restart/Edit controls.


![04-explicit-local-persona](https://raw.githubusercontent.com/block/buzz/2acd989f6eae9e7bc1ce5ae5eeafcbc1704f605f/pr-7131--04-explicit-local-persona.png)

#### Explicit persona without an instance may offer Start
This is a deliberately opened persona, not a relay-only key turned into
a persona surface.


![05-explicit-persona-without-instance](https://raw.githubusercontent.com/block/buzz/2acd989f6eae9e7bc1ce5ae5eeafcbc1704f605f/pr-7131--05-explicit-persona-without-instance.png)

[Original screenshot
publication](https://github.com/block/buzz/pull/7131#issuecomment-5482310890);
all five immutable image URLs and captions retained here. The final
documentation-only commit does not change this UI. These are synthetic
browser fixtures, not live runtime health evidence.

To check manually, open an old message from stopped A while same-persona
B is running; compare the displayed key and controls. Then open the
persona itself and verify that representative selection still works.

#### Evidence and limitations

**5,793 desktop tests**, **56 profile/archive browser cases**,
type/static/size checks and repository-wide `just ci` passed. The
historical-message regression fails on unchanged main by opening B
instead of A. [Published-head CI
passed](https://github.com/block/buzz/actions/runs/33422207592).

The [advisory security
check](https://github.com/block/buzz/actions/runs/33422240973) timed out
without a result; it is not a passing check. No availability,
cloud-marker, discovery or mention-routing change is included. These
screenshots do not establish remote delivery, agent execution or
termination.

#### Security authorization history (audit, not clearance)

The [security
gate](https://github.com/block/buzz/pull/7131#issuecomment-5482300054)
remains visible and unresolved. Existing authorization-request comments
were posted by `loganj`: [old-head
request](https://github.com/block/buzz/pull/7131#issuecomment-5482311163)
for `df6612b1db5a6f8d128cef955fd66a80b6828cb8` at 2026-08-31 17:55:11
UTC, then [current-head
request](https://github.com/block/buzz/pull/7131#issuecomment-5482320424)
for `9c4b6523ceaef0f3d92906fcdb5d9a3b9ede7e17` at 17:55:57 UTC. The
existing [issue-comment workflow
run](https://github.com/block/buzz/actions/runs/33422240973) ended
cancelled after the previously reported timeout; it did not produce a
completed security review. Latest exact-head Run/Post Codex jobs are
skipped, not security approval. Historical comments remain available at
their original links; consolidating their audit here does not withdraw
authorization or clear the gate. An authorized security workflow owner
must arrange the missing exact-range result.

---------

Signed-off-by: Logan Johnson <loganj@squareup.com>
Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
2026-09-02 16:20:49 -04:00

139 lines
4.3 KiB
TypeScript

import { expect, test } from "@playwright/test";
import { installMockBridge, TEST_IDENTITIES } from "../helpers/bridge";
import { waitForAnimations } from "../helpers/animations";
const REMOTE = TEST_IDENTITIES.charlie.pubkey;
const LOCAL = "d".repeat(64);
const OWNER = "deadbeef".repeat(8);
const PERSONA = "shared-persona";
for (const hasSibling of [false, true]) {
test(`explicit relay-only identity has no local controls (${hasSibling ? "local sibling" : "persona only"})`, async ({
page,
}, testInfo) => {
await installMockBridge(page, {
oaOwnerIsMe: true,
managedAgents: hasSibling
? [
{
pubkey: LOCAL,
name: "Local sibling B",
personaId: PERSONA,
status: "running",
channelNames: ["agents"],
},
]
: [],
personas: [
{
id: PERSONA,
displayName: "Shared persona P",
isActive: true,
systemPrompt: "Local definition, not the remote identity.",
},
],
searchProfiles: [
{
pubkey: REMOTE,
displayName: "Relay agent A",
ownerPubkey: OWNER,
isAgent: true,
},
],
});
await page.goto(`/#/agents?profile=${REMOTE}`);
const panel = page.getByTestId("user-profile-panel");
await expect(panel).toBeVisible();
await expect(page.getByTestId("user-profile-name-row")).toContainText(
"Relay agent A",
);
for (const testId of [
"user-profile-agent-primary-action",
"user-profile-start-agent",
"user-profile-edit-agent",
"user-profile-add-to-channel",
]) {
await expect(page.getByTestId(testId)).toHaveCount(0);
}
await expect(panel).not.toContainText(
"Local definition, not the remote identity.",
);
await waitForAnimations(page);
await panel.screenshot({
path: testInfo.outputPath("exact-relay-identity.png"),
});
// Persona-only navigation remains legitimate and intentionally different.
await page.getByTestId("auxiliary-panel-close").click();
await page.getByTestId(`persona-agent-row-${PERSONA}`).click();
await expect(
page.getByTestId(
hasSibling
? "user-profile-agent-primary-action"
: "user-profile-start-agent",
),
).toBeVisible();
await waitForAnimations(page);
await panel.screenshot({
path: testInfo.outputPath("explicit-persona.png"),
});
});
}
for (const allArchived of [false, true]) {
test(`archived exact key stays navigable (${allArchived ? "all archived" : "live sibling"})`, async ({
page,
}) => {
await installMockBridge(page, {
oaOwnerIsMe: true,
archivedIdentities: allArchived ? [REMOTE, LOCAL] : [REMOTE],
managedAgents: [
{
pubkey: REMOTE,
name: "Archived A",
personaId: PERSONA,
status: "stopped",
channelNames: ["agents"],
},
{
pubkey: LOCAL,
name: "Sibling B",
personaId: PERSONA,
status: "running",
channelNames: ["agents"],
},
],
personas: [
{
id: PERSONA,
displayName: "Shared persona P",
isActive: true,
systemPrompt: "Archive profile fixture.",
},
],
});
await page.goto(`/#/agents?profile=${REMOTE}`);
await expect(page.getByTestId("user-profile-panel")).toBeVisible();
await expect(page.getByTestId("user-profile-archived-flair")).toBeVisible();
await expect(
page.getByTestId("user-profile-agent-primary-action"),
).toHaveAttribute("aria-label", "Start agent");
await expect(page.getByTestId("user-profile-name-row")).toContainText(
"Archived A",
);
// Persona navigation still excludes archived representatives.
await page.getByTestId("auxiliary-panel-close").click();
await page.getByTestId(`persona-agent-row-${PERSONA}`).click();
if (allArchived) {
await expect(page.getByTestId("user-profile-start-agent")).toBeVisible();
await expect(
page.getByTestId("user-profile-agent-primary-action"),
).toHaveCount(0);
} else {
await expect(
page.getByTestId("user-profile-agent-primary-action"),
).toHaveAttribute("aria-label", "Stop");
}
});
}