Skip to content

Commit 0f69c3c

Browse files
committed
test(permission): cover envelope reuse across reactor retries
Two denies of the same exact call under fresh call ids name the same grant request instead of prompting the parent twice.
1 parent a0c81af commit 0f69c3c

1 file changed

Lines changed: 20 additions & 0 deletions

File tree

‎src/permission/worker-grant-flow.test.ts‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,26 @@ describe("worker grant-request flow: deny → parent replay grant → one retry"
8282
expect(replayAgain.reason).toContain(requestId);
8383
});
8484

85+
test("reactor retry of the same exact call reuses the pending envelope", async () => {
86+
const cwd = mkdtempSync(join(tmpdir(), "worker-grant-dedupe-"));
87+
const parentGate = makeParentGate(cwd, true);
88+
const store = new WorkerGrantStore();
89+
const workerGate = workerPermissionGate(parentGate, {
90+
sessionId: "worker-dedupe",
91+
store,
92+
});
93+
94+
const first = await workerGate.authorizeCall(shellCall("c1", COMMAND));
95+
if (first.effect !== "deny") throw new Error("expected worker deny");
96+
// Reactor retries mint fresh call ids for the same tool + args: the
97+
// deny must name the same grant request, not prompt the parent twice.
98+
const second = await workerGate.authorizeCall(shellCall("c2", COMMAND));
99+
if (second.effect !== "deny") throw new Error("expected worker deny");
100+
expect(extractRequestId(second.reason)).toBe(
101+
extractRequestId(first.reason),
102+
);
103+
});
104+
85105
test("tampered args fall through to a fresh deny; original stays consumed", async () => {
86106
const cwd = mkdtempSync(join(tmpdir(), "worker-grant-tamper-"));
87107
const parentGate = makeParentGate(cwd, true);

0 commit comments

Comments
 (0)