Skip to content
Merged
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
68 changes: 68 additions & 0 deletions lib/daemon/__tests__/gate-owner-notify-trace.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* Pins today's owner derivation and notify-bridge filtering for a
* worker-opened gate (RT-162 finding 4: refuted).
*/
import { describe, expect, test } from "bun:test";
import { deriveOwner } from "../handlers/gate.ts";
import { parseEventBridgeRules, startNotifyBridge } from "../../notify-bridge.ts";
import type { NotificationEvent } from "../../state/notifier-store.ts";

function fakeBus(): {
onBroadcast(fn: (type: string, data: unknown) => void): () => void;
emit(type: string, data: unknown): Promise<void>;
} {
const subs = new Set<(type: string, data: unknown) => void>();
return {
onBroadcast(fn) {
subs.add(fn);
return () => { subs.delete(fn); };
},
async emit(type, data) {
for (const fn of [...subs]) fn(type, data);
await new Promise((r) => setTimeout(r, 0));
await new Promise((r) => setTimeout(r, 0));
},
};
}

describe("RT-162 finding 4 mechanism", () => {
test("a hook-shaped gate:open on a herd subject derives owner human today", () => {
// The hook's message spells `rt gate open --subject herd:.../job` with
// no origin, so deriveOwner sees no runId and falls back to human.
expect(deriveOwner(undefined, () => null)).toBe("human");
expect(deriveOwner({ presentation: "wait" }, () => "herd:h1")).toBe("human");
});

test("an owner:human bridge rule delivers a human-owned gate and skips a herd-owned one, blind to subject", async () => {
const rules = parseEventBridgeRules(
[{ pattern: "gate/opened/*", category: "gate", title: "t", message: "m", owner: "human" }],
() => {},
);
const bus = fakeBus();
const delivered: NotificationEvent[] = [];

startNotifyBridge({
onBroadcast: bus.onBroadcast,
rules: () => rules,
enqueue: (e) => { delivered.push(e); },
paneFocused: async () => false,
});

// A worker's hook-followed gate:open on its herd subject: derived owner
// "human" (per the test above), subject is the herd job's own subject.
await bus.emit("event", {
id: "1",
topic: "gate/opened/g1",
payload: { owner: "human", subject: "herd:h1/job" },
emittedAt: 1,
});
await bus.emit("event", {
id: "2",
topic: "gate/opened/g2",
payload: { owner: "herd:h1", subject: "herd:h1/job" },
emittedAt: 2,
});

expect(delivered.map((e) => e.id)).toEqual(["1"]);
});
});
Loading