What happened
On 2026-09-27 the criterion-check run's task 06-e2e-criterion-check came back from review round 1 with request-changes (review-06.md). The engine dispatched the implementer for round 2 with this line in the prompt:
This is round 2: address every finding in runs/criterion-check/review-06.md — fix it, or rebut it finding-by-finding in the task file's notes.
That dispatch failed (exit 1). The engine dispatched round 2 again, and this time the prompt had no such line. It named the task and asked for a commit "round 2", with nothing pointing at the review. That retry failed too, so no implementer ever ran round 2 without the pointer. Had it succeeded, it would have worked the task without knowing a review asked for changes.
Cause
After the failed dispatch the task's status is back to pending. The pending branch of the dispatch derivation (packages/orchestrator/src/derive.ts, around line 468) dispatches with round: task.review_rounds + 1 and bounce: null. packages/orchestrator/src/prompts.ts (line 52) adds the review line only when intent.bounce?.kind === 'review'. So a retry at any round above 1 loses the review it is answering.
The log shows the two reasons: round 1 requested changes before the first dispatch, pending with dependencies complete before the retry.
Expected
An implementer dispatched at round N > 1 is always pointed at the review that asked for round N, whether it is the first attempt or a retry after a failure. The latest review for the task with a request-changes verdict is the one to cite.
Test
A derivation test with a task at review_rounds: 1, a request-changes review, and a failed implementer dispatch for round 2. The next dispatch must carry the review as its bounce. The test fails against today's code.
What happened
On 2026-09-27 the
criterion-checkrun's task06-e2e-criterion-checkcame back from review round 1 withrequest-changes(review-06.md). The engine dispatched the implementer for round 2 with this line in the prompt:That dispatch failed (exit 1). The engine dispatched round 2 again, and this time the prompt had no such line. It named the task and asked for a commit "round 2", with nothing pointing at the review. That retry failed too, so no implementer ever ran round 2 without the pointer. Had it succeeded, it would have worked the task without knowing a review asked for changes.
Cause
After the failed dispatch the task's status is back to
pending. Thependingbranch of the dispatch derivation (packages/orchestrator/src/derive.ts, around line 468) dispatches withround: task.review_rounds + 1andbounce: null.packages/orchestrator/src/prompts.ts(line 52) adds the review line only whenintent.bounce?.kind === 'review'. So a retry at any round above 1 loses the review it is answering.The log shows the two reasons:
round 1 requested changesbefore the first dispatch,pending with dependencies completebefore the retry.Expected
An implementer dispatched at round N > 1 is always pointed at the review that asked for round N, whether it is the first attempt or a retry after a failure. The latest review for the task with a
request-changesverdict is the one to cite.Test
A derivation test with a task at
review_rounds: 1, a request-changes review, and a failed implementer dispatch for round 2. The next dispatch must carry the review as its bounce. The test fails against today's code.