Redeliver an interrupted review comment, and close the issue on completion
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 1m16s

Fixes counterexamples 6 and 7 from specs/orchestrator.qnt, the last two.

6. A crash while the executor answered a review comment lost it: its
   cursor is saved before the work (at most once), and a restart in
   PR_OPEN resumed quietly. Now pr.reviewing marks the comment until
   the executor returns (every way it returns, but not a crash), and
   boot resumes the watch just before it, with a notice. The mark stays
   until it is answered, so a second crash cannot lose it either.
7. 'project complete' left the plan issue open. It now closes it with a
   note, after IDLE is saved, as abandon does (shared helper).

The model marks and redelivers, and closes the issue; scenarios 6 and 7
now expect their properties to hold. A mutant without redelivery fails
scenario 6. All eight properties held together over 300,000 traces.
No xfail reproductions remain.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
This commit is contained in:
dongarandClaude Opus 5.5 committed 2026-09-29 20:30:14 +00:00
1 parent 83a4bd72b5
commit 848bd9f122
4 files changed
+153 -52

No files matched your search

+9 -8
View File
@@ -1,8 +1,8 @@
// Counterexamples found in orchestrator.qnt, written out as short traces.
// Each ends by expecting the property it breaks to be false; once the design
// is fixed, the expectation is flipped and the trace kept as a regression.
// Fixed: 1-4 (replies bind to the revision up when they arrived), 5 (boot
// and publishing adopt an open PR).
// All fixed: 1-4 (replies bind to the revision up when they arrived), 5 (boot
// and publishing adopt an open PR), 6 (redelivered), 7 (issue closed).
//
// Run: quint test specs/orchestrator_scenarios.qnt (runs every *Test)
module orchestrator_scenarios {
@@ -107,18 +107,19 @@ module orchestrator_scenarios {
// 6. A crash while the executor answers a review comment. The comment's
// cursor was saved before the work started (at most once), and a
// restart in PR_OPEN resumes quietly, so the comment is never answered
// and nobody is told.
// restart in PR_OPEN resumed quietly, so it was never answered. Fixed:
// the comment is marked while answered, and delivered again.
run crashDuringAReviewLosesTheCommentTest =
toPrOpen
.then(commentPr).then(pollPr).then(runJob(true)) // the executor starts on it
.then(crash(true))
.expect(s.st == "PR_OPEN" and not(review_comments_answered))
.expect(s.st == "PR_OPEN" and review_comments_answered)
.then(pollPr).then(runJob(true)).then(finishReview("completed"))
.expect(s.answered.size() == 1 and s.reviewing == 0)
// 7. A completed task leaves its plan issue open: 'project complete'
// closes nothing, unlike 'abandon'.
// 7. 'project complete' left the plan issue open. Fixed: it closes it.
run projectCompleteLeavesThePlanIssueOpenTest =
toPrOpen
.then(send("complete")).then(runJob(true))
.expect(s.st == "IDLE" and not(no_open_issue_without_a_task))
.expect(s.st == "IDLE" and no_open_issue_without_a_task)
}