Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 179 additions & 0 deletions tools/broadcast-local/schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import { describe, expect, test } from "bun:test";

import {
DEFAULT_LOCAL_BROADCAST_TTL_MS,
detectLocalBroadcastScopeConflicts,
isLocalBroadcastStale,
localBroadcastExpiresAt,
makeLocalBroadcastReceipt,
validateLocalBroadcastEnvelope,
type LocalBroadcastEnvelope,
type LocalBroadcastScopeConflict,
} from "./schema";

const writtenAt = "2026-05-26T22:50:00Z";
Expand Down Expand Up @@ -59,6 +61,183 @@ describe("local broadcast schema", () => {
});
});

test("detects active overlapping scopes across agents", () => {
const vera = {
...validEnvelope(),
id: "vera-20260526T225000Z",
from: "vera" as const,
summary: "Working on B-0213 conflict detection.",
scope: [{ kind: "path" as const, value: "tools/broadcast-local/" }],
};
const otto = {
...validEnvelope(),
id: "otto-20260526T225100Z",
from: "otto" as const,
summary: "Also touching local broadcast tooling.",
scope: [{ kind: "path" as const, value: "tools/broadcast-local/" }],
};
const riven = {
...validEnvelope(),
id: "riven-20260526T225200Z",
from: "riven" as const,
status: "idle" as const,
summary: "Idle receipt only.",
scope: [{ kind: "path" as const, value: "tools/broadcast-local/" }],
};

const expected: readonly LocalBroadcastScopeConflict[] = [
{
scope: { kind: "path", value: "tools/broadcast-local/" },
broadcastIds: ["otto-20260526T225100Z", "vera-20260526T225000Z"],
agents: ["otto", "vera"],
summaries: ["Also touching local broadcast tooling.", "Working on B-0213 conflict detection."],
},
];

expect(detectLocalBroadcastScopeConflicts([vera, otto, riven], new Date("2026-05-26T22:55:00Z"))).toEqual(
expected,
);
expect(detectLocalBroadcastScopeConflicts([riven, otto, vera], new Date("2026-05-26T22:55:00Z"))).toEqual(
expected,
);
});

test("orders multiple conflicts deterministically by scope", () => {
const otto = {
...validEnvelope(),
id: "otto-20260526T225100Z",
from: "otto" as const,
summary: "Touching two local broadcast scopes.",
scope: [
{ kind: "path" as const, value: "tools/broadcast-local/" },
{ kind: "claim" as const, value: "claim/backlog-0213" },
],
};
const vera = {
...validEnvelope(),
id: "vera-20260526T225000Z",
from: "vera" as const,
summary: "Also touching both local broadcast scopes.",
scope: [
{ kind: "path" as const, value: "tools/broadcast-local/" },
{ kind: "claim" as const, value: "claim/backlog-0213" },
],
};
const expected: readonly LocalBroadcastScopeConflict[] = [
{
scope: { kind: "claim", value: "claim/backlog-0213" },
broadcastIds: ["otto-20260526T225100Z", "vera-20260526T225000Z"],
agents: ["otto", "vera"],
summaries: ["Touching two local broadcast scopes.", "Also touching both local broadcast scopes."],
},
{
scope: { kind: "path", value: "tools/broadcast-local/" },
broadcastIds: ["otto-20260526T225100Z", "vera-20260526T225000Z"],
agents: ["otto", "vera"],
summaries: ["Touching two local broadcast scopes.", "Also touching both local broadcast scopes."],
},
];

expect(detectLocalBroadcastScopeConflicts([vera, otto], new Date("2026-05-26T22:55:00Z"))).toEqual(expected);
expect(detectLocalBroadcastScopeConflicts([otto, vera], new Date("2026-05-26T22:55:00Z"))).toEqual(expected);
});

test("reports every pair when three agents overlap on one scope", () => {
const otto = {
...validEnvelope(),
id: "otto-20260526T225100Z",
from: "otto" as const,
summary: "Touching local broadcast tooling from Otto.",
scope: [{ kind: "path" as const, value: "tools/broadcast-local/" }],
};
const riven = {
...validEnvelope(),
id: "riven-20260526T225200Z",
from: "riven" as const,
summary: "Touching local broadcast tooling from Riven.",
scope: [{ kind: "path" as const, value: "tools/broadcast-local/" }],
};
const vera = {
...validEnvelope(),
id: "vera-20260526T225000Z",
from: "vera" as const,
summary: "Touching local broadcast tooling from Vera.",
scope: [{ kind: "path" as const, value: "tools/broadcast-local/" }],
};
const expected: readonly LocalBroadcastScopeConflict[] = [
{
scope: { kind: "path", value: "tools/broadcast-local/" },
broadcastIds: ["otto-20260526T225100Z", "riven-20260526T225200Z"],
agents: ["otto", "riven"],
summaries: ["Touching local broadcast tooling from Otto.", "Touching local broadcast tooling from Riven."],
},
{
scope: { kind: "path", value: "tools/broadcast-local/" },
broadcastIds: ["otto-20260526T225100Z", "vera-20260526T225000Z"],
agents: ["otto", "vera"],
summaries: ["Touching local broadcast tooling from Otto.", "Touching local broadcast tooling from Vera."],
},
{
scope: { kind: "path", value: "tools/broadcast-local/" },
broadcastIds: ["riven-20260526T225200Z", "vera-20260526T225000Z"],
agents: ["riven", "vera"],
summaries: ["Touching local broadcast tooling from Riven.", "Touching local broadcast tooling from Vera."],
},
];

expect(detectLocalBroadcastScopeConflicts([vera, riven, otto], new Date("2026-05-26T22:55:00Z"))).toEqual(
expected,
);
});

test("keeps NUL-bearing scope values exact", () => {
const otto = {
...validEnvelope(),
id: "otto-20260526T225100Z",
from: "otto" as const,
summary: "Touching NUL path A.",
scope: [{ kind: "path" as const, value: "tools/broadcast-local/\0a" }],
};
const vera = {
...validEnvelope(),
id: "vera-20260526T225000Z",
from: "vera" as const,
summary: "Touching NUL path B.",
scope: [{ kind: "path" as const, value: "tools/broadcast-local/\0b" }],
};
const riven = {
...validEnvelope(),
id: "riven-20260526T225200Z",
from: "riven" as const,
summary: "Also touching NUL path A.",
scope: [{ kind: "path" as const, value: "tools/broadcast-local/\0a" }],
};

const expected: readonly LocalBroadcastScopeConflict[] = [
{
scope: { kind: "path", value: "tools/broadcast-local/\0a" },
broadcastIds: ["otto-20260526T225100Z", "riven-20260526T225200Z"],
agents: ["otto", "riven"],
summaries: ["Touching NUL path A.", "Also touching NUL path A."],
},
];

expect(detectLocalBroadcastScopeConflicts([vera, riven, otto], new Date("2026-05-26T22:55:00Z"))).toEqual(
expected,
);
});

test("ignores stale overlapping scopes", () => {
const vera = validEnvelope();
const otto = {
...validEnvelope(),
id: "otto-20260526T225100Z",
from: "otto" as const,
};

expect(detectLocalBroadcastScopeConflicts([vera, otto], new Date("2026-05-26T23:30:00Z"))).toEqual([]);
});

test("validates the required envelope fields", () => {
expect(validateLocalBroadcastEnvelope(validEnvelope()).ok).toBe(true);

Expand Down
87 changes: 87 additions & 0 deletions tools/broadcast-local/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ export interface LocalBroadcastEnvelope {
readonly receipts?: readonly LocalBroadcastReceipt[];
}

export interface LocalBroadcastScopeConflict {
readonly scope: LocalBroadcastScope;
readonly broadcastIds: readonly [string, string];
readonly agents: readonly [LocalBroadcastAgent, LocalBroadcastAgent];
readonly summaries: readonly [string, string];
}

export type LocalBroadcastValidation =
| { readonly ok: true; readonly value: LocalBroadcastEnvelope }
| { readonly ok: false; readonly errors: readonly string[] };
Expand Down Expand Up @@ -120,6 +127,86 @@ export function makeLocalBroadcastReceipt(config: {
};
}

function localBroadcastScopeKey(scope: LocalBroadcastScope): string {
return JSON.stringify([scope.kind, scope.value]);
}

function compareStrings(left: string, right: string): number {
const leftChars = Array.from(left);
const rightChars = Array.from(right);
const length = Math.min(leftChars.length, rightChars.length);

for (let index = 0; index < length; index += 1) {
const leftCodePoint = leftChars[index]?.codePointAt(0) ?? 0;
const rightCodePoint = rightChars[index]?.codePointAt(0) ?? 0;
if (leftCodePoint !== rightCodePoint) {
return leftCodePoint - rightCodePoint;
}
}

return leftChars.length - rightChars.length;
}

function activeConflictCandidates(
envelopes: readonly LocalBroadcastEnvelope[],
now: Date,
): readonly LocalBroadcastEnvelope[] {
return [...envelopes]
.filter((envelope) => envelope.status !== "idle" && !isLocalBroadcastStale(envelope, now))
.sort((left, right) => {
const agentCompare = compareStrings(left.from, right.from);
if (agentCompare !== 0) {
return agentCompare;
}
return compareStrings(left.id, right.id);
});
Comment thread
AceHack marked this conversation as resolved.
}

export function detectLocalBroadcastScopeConflicts(
envelopes: readonly LocalBroadcastEnvelope[],
now: Date = new Date(),
): readonly LocalBroadcastScopeConflict[] {
const ownersByScope = new Map<string, LocalBroadcastEnvelope[]>();
const conflicts: LocalBroadcastScopeConflict[] = [];

for (const envelope of activeConflictCandidates(envelopes, now)) {
const seenInEnvelope = new Set<string>();
const scopes = [...(envelope.scope ?? [])].sort((left, right) =>
compareStrings(localBroadcastScopeKey(left), localBroadcastScopeKey(right)),
);
for (const scope of scopes) {
const key = localBroadcastScopeKey(scope);
if (seenInEnvelope.has(key)) {
continue;
}
seenInEnvelope.add(key);

const owners = ownersByScope.get(key) ?? [];
for (const owner of owners) {
if (owner.from === envelope.from || owner.id === envelope.id) {
continue;
}

conflicts.push({
scope,
broadcastIds: [owner.id, envelope.id],
agents: [owner.from, envelope.from],
summaries: [owner.summary, envelope.summary],
});
}
ownersByScope.set(key, [...owners, envelope]);
}
}

return [...conflicts].sort((left, right) => {
const scopeCompare = compareStrings(localBroadcastScopeKey(left.scope), localBroadcastScopeKey(right.scope));
if (scopeCompare !== 0) {
return scopeCompare;
}
return compareStrings(JSON.stringify(left.broadcastIds), JSON.stringify(right.broadcastIds));
});
}

export function validateLocalBroadcastEnvelope(value: unknown): LocalBroadcastValidation {
const errors: string[] = [];

Expand Down
Loading