feat(queue): refuse a row's owner as its reviewer at add, set reviewers and assign (row 31, #1508)

Built by rocko (Gate G run), approved by filbert in round 1 (#1508 comment
26629). Manifest 35199daf. Suites green on an index export.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-04 00:16:41 -05:00
co-authored by Claude Opus 5.5
parent 1649f5e2a3
commit bb2fa9704c
5 changed files with 62 additions and 5 deletions
+6
View File
@@ -120,6 +120,8 @@ test("add: defaults for an ordinary seat, privileged extras, refusals", () => {
refused(() => step(d, "add", { ...add, owner: "rocko" }, "dewey", { brief: brief() }), /only a privileged actor may set owner/);
refused(() => step(d, "add", { ...add, reviewers: ["rocko"] }, "dewey", { brief: brief() }), /reviewers/);
refused(() => step(d, "add", { ...add, required: true }, "dewey", { brief: brief() }), /required/);
refused(() => step(d, "add", { ...add, owner: "rocko", reviewers: ["rocko"] }, "sage", { brief: brief() }), /row 12 owner rocko can't be a listed reviewer/);
refused(() => step(d, "add", { ...add, reviewers: ["sage"] }, "sage", { brief: brief() }), /row 12 owner sage can't be a listed reviewer/);
const d2 = step(d, "add", { ...add, owner: "rocko", gateOwner: "filbert", after: [{ id: 9, when: "done" }], reviewers: ["dewey"], required: true }, "sage", { brief: brief() });
const r2 = row(d2, 12);
assert.deepEqual([r2.owner, r2.gateOwner, r2.required, r2.after], ["rocko", "filbert", true, [{ id: 9, when: "done" }]]);
@@ -390,6 +392,9 @@ test("field edits: who may change what", () => {
const set = (id, field, value, reason = null) => ({ id, field, value, reason });
refused(() => step(d, "set", set(11, "piece", "x"), "dewey"), /privileged/);
assert.match(step(d, "set", set(11, "piece", "Renamed"), "sage").log.at(-1).result.receipt, /row 11 piece: Brief template→Renamed$/);
refused(() => step(d, "set", set(9, "reviewers", ["darkwing"]), "sage"), /row 9 owner darkwing can't be a listed reviewer/);
refused(() => step(d, "set", set(9, "reviewers", ["filbert", "darkwing"]), "sage"), /row 9 owner darkwing can't be a listed reviewer/);
assert.deepEqual(row(step(d, "set", set(9, "reviewers", ["dewey"]), "sage"), 9).reviewers, ["dewey"]);
refused(() => step(d, "set", set(9, "after", []), "sage"), /only jason may change after on a required row/);
step(d, "set", set(9, "after", []), "jason");
step(d, "set", set(11, "after", [{ id: 9, when: "done" }]), "sage");
@@ -544,6 +549,7 @@ test("note: owner, listed reviewer or privileged; empty clears", () => {
test("assign moves the claim with the owner; done clears it", () => {
let d = row9Started();
refused(() => step(d, "assign", { id: 9, seat: "dewey" }, "darkwing"), /privileged/);
refused(() => step(d, "assign", { id: 9, seat: "filbert" }, "sage"), /row 9 owner filbert can't be a listed reviewer/);
d = step(d, "assign", { id: 9, seat: "dewey" }, "sage", {}, "assign-row-9-dewey");
assert.deepEqual(row(d, 9).claim, { seat: "dewey", op: "assign-row-9-dewey" });
assert.match(d.log.at(-1).result.receipt, /owner: darkwing→dewey$/);