Files
PaperClipAI/server/src/__tests__/issue-dependency-restore-wake-policy.test.ts
T
8d9d2f9ddf fix(recovery): preserve deliberate stops and dependency waits
Preserve deliberate assignee blocks and operator stops during dependency and run-release recovery. Attribute native waits to their bound owner. Ignore unrelated edits and shared-workspace exports from another issue. Continue after genuine dependency changes while preserving independently authorized user input.

Keep the original contributor's implementation and review history. Add native ownership, unrelated-edit, later readiness, and shared-workspace regressions. The shared-workspace loop was reproduced before the fix.

Co-Authored-By: Devin Foley <devin@paperclip.ing>
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-15 00:18:23 -07:00

46 lines
1.9 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { shouldWakeOnRestoredBlockedDependency } from "../services/issue-dependency-wakeups.js";
const base = {
previousStatus: "in_progress",
nextStatus: "blocked",
previousAssigneeAgentId: "agent-1",
nextAssigneeAgentId: "agent-1",
blockerSetEdited: false,
actorType: "user",
actorAgentId: null,
};
describe("shouldWakeOnRestoredBlockedDependency", () => {
it("wakes the assignee when the board blocks an issue whose blockers are already resolved", () => {
expect(shouldWakeOnRestoredBlockedDependency(base)).toBe(true);
});
it("does not wake the assignee agent that blocked its own issue (re-block loop regression)", () => {
expect(shouldWakeOnRestoredBlockedDependency({ ...base, actorType: "agent", actorAgentId: "agent-1" })).toBe(false);
expect(
shouldWakeOnRestoredBlockedDependency({ ...base, actorType: "agent", actorAgentId: "agent-1", blockerSetEdited: true }),
).toBe(false);
});
it("still wakes when another agent blocks the issue or the assignee changes", () => {
expect(shouldWakeOnRestoredBlockedDependency({ ...base, actorType: "agent", actorAgentId: "agent-2" })).toBe(true);
expect(
shouldWakeOnRestoredBlockedDependency({
...base,
actorType: "agent",
actorAgentId: "agent-2",
previousAssigneeAgentId: "agent-1",
nextAssigneeAgentId: "agent-2",
}),
).toBe(true);
});
it("keeps the existing gates: already blocked with no edit, not blocked, or unassigned", () => {
expect(shouldWakeOnRestoredBlockedDependency({ ...base, previousStatus: "blocked" })).toBe(false);
expect(shouldWakeOnRestoredBlockedDependency({ ...base, previousStatus: "blocked", blockerSetEdited: true })).toBe(true);
expect(shouldWakeOnRestoredBlockedDependency({ ...base, nextStatus: "todo" })).toBe(false);
expect(shouldWakeOnRestoredBlockedDependency({ ...base, nextAssigneeAgentId: null })).toBe(false);
});
});