Compare commits

...
Author SHA1 Message Date
dev-guard fbbfa9e741 test(delivery): cover replies to human aliases 2026-11-04 17:58:34 +00:00
3 changed files with 68 additions and 0 deletions

No files matched your search

+20
View File
@@ -10,6 +10,26 @@ describe("wrapSendBody — pre-release CLI/daemon Item 2 (email-style envelope)"
expect(out).toContain('↩ Reply: rig send driver-3@my-rig "..."');
});
it.each(["human@kernel", "human@host", "human-alice@kernel", "human-alice@host"])(
"gives %s a queue update reply with the existing human-route fields",
(sender) => {
const body = "Please check this.\nKeep the actor unchanged.";
const out = wrapSendBody(sender, "driver@rig", body, { replyToQitem: "qitem-original" });
expect(out).toContain(`From: ${sender}\nTo: driver@rig\n`);
expect(out.split("\n---\n")[1]).toBe(body);
expect(out.split("\n").at(-1)).toBe(`↩ Reply if needed: rig queue create --destination ${sender} --human-intent update --summary "<one line>" --evidence-ref "<path>" --body "..." --verify`);
expect(out).not.toContain(`rig send ${sender}`);
expect(out).not.toContain("--reply-to"); // Slack-thread guidance belongs to registered external addresses.
},
);
it("keeps similarly named real seats on the ordinary reply route", () => {
for (const sender of ["human@my-rig", "humanity@kernel", "dev-human@host", "dev-human@rig@origin-host"]) {
expect(wrapSendBody(sender, "driver@rig", "hi").split("\n").at(-1))
.toBe(`↩ Reply: rig send ${sender} "..."`);
}
});
it("routes an external sender's reply through the durable human queue", () => {
const out = wrapSendBody("decision-maker@external", "driver@rig", "Decision received.");
expect(out).toContain("From: decision-maker@external");
@@ -22,6 +22,26 @@ describe("wrapPaneEnvelope — slice 23 envelope renderer (daemon-side)", () =>
expect(out).toContain('↩ Reply: rig send driver-3@my-rig "..."');
});
it.each(["human@kernel", "human@host", "human-alice@kernel", "human-alice@host"])(
"gives %s a queue update reply with the existing human-route fields",
(sender) => {
const body = "Please check this.\nKeep the actor unchanged.";
const out = wrapPaneEnvelope(sender, "driver@rig", body, { replyToQitem: "qitem-original" });
expect(out).toContain(`From: ${sender}\nTo: driver@rig\n`);
expect(out.split("\n---\n")[1]).toBe(body);
expect(out.split("\n").at(-1)).toBe(`↩ Reply if needed: rig queue create --destination ${sender} --human-intent update --summary "<one line>" --evidence-ref "<path>" --body "..." --verify`);
expect(out).not.toContain(`rig send ${sender}`);
expect(out).not.toContain("--reply-to"); // Slack-thread guidance belongs to registered external addresses.
},
);
it("keeps similarly named real seats on the ordinary reply route", () => {
for (const sender of ["human@my-rig", "humanity@kernel", "dev-human@host", "dev-human@rig@origin-host"]) {
expect(wrapPaneEnvelope(sender, "driver@rig", "hi").split("\n").at(-1))
.toBe(`↩ Reply: rig send ${sender} "..."`);
}
});
it("routes an external sender's reply through the durable human queue", () => {
const out = wrapPaneEnvelope("decision-maker@external", "driver@rig", "Decision received.");
expect(out).toContain("From: decision-maker@external");
@@ -118,6 +118,34 @@ describe("queue wake nudge carries the stored summary", () => {
} finally { await settle(); h.db.close(); }
});
it.each(["human@kernel", "human@host"])("a wake from %s offers a reply accepted by the real queue writer", async (sender) => {
const h = makeHarness();
try {
const row = await h.repo.create({ sourceSession: sender, destinationSession: "dev@rig", body: "Please check the build." });
await vi.waitFor(() => expect(h.calls).toHaveLength(1));
const envelope = h.calls[0]!.text;
expect(envelope).toContain(`From: ${sender}\nTo: dev@rig\n`);
expect(envelopeBody(envelope)).toEqual([`Queue handoff: ${row.qitemId} - check your queue.`]);
const reply = { sourceSession: "dev@rig", destinationSession: sender, humanIntent: "update" as const,
summary: "Build checked", body: "The result is in the proof.", nudge: false };
// Establish the existing route and its required field before checking the generated command.
await expect(h.repo.create(reply)).rejects.toMatchObject({ code: "human_route_fields_required" });
const control = await h.repo.create({ ...reply, evidenceRef: "proof/build.md" });
expect(control.destinationSession).toBe(sender);
expect(control.humanIntent).toBe("update");
const hint = envelope.split("\n").at(-1)!;
expect(hint).toBe(`↩ Reply if needed: rig queue create --destination ${sender} --human-intent update --summary "<one line>" --evidence-ref "<path>" --body "..." --verify`);
// Fill the actual emitted placeholders, then feed those values into the production queue writer.
const command = hint.replace('"<one line>"', '"Build checked"').replace('"<path>"', '"proof/build.md"').replace('"..."', '"The result is in the proof."');
const fields = /--destination (\S+) --human-intent (update) --summary "([^"]+)" --evidence-ref "([^"]+)" --body "([^"]+)" --verify$/.exec(command)!;
expect(fields).not.toBeNull();
const accepted = await h.repo.create({ sourceSession: "dev@rig", destinationSession: fields[1]!,
humanIntent: fields[2] as "update", summary: fields[3]!, evidenceRef: fields[4]!, body: fields[5]!, nudge: false });
expect(accepted).toMatchObject({ sourceSession: "dev@rig", destinationSession: sender,
humanIntent: "update", summary: "Build checked", evidenceRef: "proof/build.md" });
} finally { await settle(); h.db.close(); }
});
it("a seat's message keeps the ordinary reply hint", async () => {
const h = makeHarness();
try {