From 8560e54b69c3c28fa87be1428cebed915bfa1526 Mon Sep 17 00:00:00 2001 From: Dotta Date: Sat, 19 Sep 2026 10:02:58 -0500 Subject: [PATCH] test(runner-e2e): report unexercised review boundaries promptly Co-Authored-By: Paperclip --- tests/runner-e2e/README.md | 5 +++++ tests/runner-e2e/everyday-flow.ts | 3 ++- tests/runner-e2e/everyday-observations.ts | 13 +++++++++++++ tests/runner-e2e/everyday.test.ts | 16 ++++++++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/tests/runner-e2e/README.md b/tests/runner-e2e/README.md index 21a180d96b2..ecd5953029d 100644 --- a/tests/runner-e2e/README.md +++ b/tests/runner-e2e/README.md @@ -791,3 +791,8 @@ Everyday restart and Stop scenarios exempt only their recorded cancellation, graceful-shutdown interruption, or process-loss outcome. A later adapter error on that same run still fails immediately and fails the lifecycle grader. The run ID alone is not an exemption from recovery failures. + +The review-handoff case also requires proof that the parent was blocked before +the review wake. If all tasks finish without that ordering, the harness fails +promptly with an unexercised-boundary diagnostic. Successful work alone does not +prove that this recovery path was tested. diff --git a/tests/runner-e2e/everyday-flow.ts b/tests/runner-e2e/everyday-flow.ts index 17404855784..9b11c328e3c 100644 --- a/tests/runner-e2e/everyday-flow.ts +++ b/tests/runner-e2e/everyday-flow.ts @@ -24,6 +24,7 @@ import { isStoryWorkspaceDeferral, isExpectedStoryInterruption, storyUnexpectedRunFailure, + storyUnexercisedReviewBoundary, storyLifecycleChecks, storyRepliesConsumed, storyHasAgentReply, @@ -693,7 +694,7 @@ export async function runEverydayFlow(input: Input) { ); return failed ? `Review handoff prerequisite failed: ${failed.errorCode}: ${failed.error}` - : undefined; + : storyUnexercisedReviewBoundary(state.issues, state.runs); }, }); const child = boundary.issues.find((issue) => issue.parentId === parent!.id)!; diff --git a/tests/runner-e2e/everyday-observations.ts b/tests/runner-e2e/everyday-observations.ts index 542212278d8..5fb35cee388 100644 --- a/tests/runner-e2e/everyday-observations.ts +++ b/tests/runner-e2e/everyday-observations.ts @@ -229,6 +229,19 @@ export function storyUnexpectedRunFailure(runs: StoryRun[], allowedRunIds: reado ); } +/** Called only after the required review boundary did not match. */ +export function storyUnexercisedReviewBoundary( + issues: StoryIssue[], + runs: StoryRun[], +): string | undefined { + if (issues.length === 0 || runs.length === 0) return; + if (!issues.every((issue) => + issue.status === "done" && !issue.scheduledRetry && !issue.activeRecoveryAction, + )) return; + if (!runs.every((run) => run.status === "succeeded")) return; + return "Review handoff boundary not exercised: all tasks finished without evidence of a blocked parent before the review wake."; +} + export function storyLifecycleChecks(input: { issues: StoryIssue[]; runs: StoryRun[]; diff --git a/tests/runner-e2e/everyday.test.ts b/tests/runner-e2e/everyday.test.ts index b422083b306..6f08592011d 100644 --- a/tests/runner-e2e/everyday.test.ts +++ b/tests/runner-e2e/everyday.test.ts @@ -5,6 +5,7 @@ import { everydayTasks, productionStoryProfile } from "./everyday-cases.js"; import { isStoryWorkspaceDeferral, storyUnexpectedRunFailure, + storyUnexercisedReviewBoundary, storyLifecycleChecks, storyRepliesConsumed, storyHasAgentReply, @@ -54,6 +55,21 @@ describe("everyday workflow grader and review timing", () => { }); }); +describe("unexercised review boundary diagnostics", () => { + const done = { id: "parent", companyId: "company", title: "task", status: "done" }; + const completed = { id: "run", companyId: "company", agentId: "lead", status: "succeeded" }; + it("fails promptly when all work finishes without the required review ordering", () => { + expect(storyUnexercisedReviewBoundary([done], [completed])).toContain("not exercised"); + }); + it("does not preempt in-flight finalization, recovery, or unfinished work", () => { + expect(storyUnexercisedReviewBoundary([done], [{ ...completed, status: "running" }])).toBeUndefined(); + expect(storyUnexercisedReviewBoundary([{ ...done, scheduledRetry: {} }], [completed])).toBeUndefined(); + expect(storyUnexercisedReviewBoundary([{ ...done, activeRecoveryAction: {} }], [completed])).toBeUndefined(); + expect(storyUnexercisedReviewBoundary([{ ...done, status: "blocked" }], [completed])).toBeUndefined(); + expect(storyUnexercisedReviewBoundary([], [])).toBeUndefined(); + }); +}); + describe("multi-round agent review handoff", () => { const child = { id: "child",