Summary
When tracker.handoff_state is configured alongside reactions.review_comments, no pending review reaction is ever enqueued for the issue, so review comments left on the resulting pull request are never observed and no continuation turn is dispatched. The orchestrator logs review comment routing enabled at startup but the reconcile loop has nothing to iterate over.
Root Cause (observed)
In internal/orchestrator/exit.go, the block that enqueues a ReactionKindReview entry into state.PendingReactions is gated on state.Claimed[issueID] still being present:
if params.SCMAdapter != nil && workerResult.WorkspacePath != "" {
if _, stillClaimed := state.Claimed[workerResult.IssueID]; stillClaimed {
// ... read scm.json, build PendingReaction ...
}
}
Earlier in the same function, the handoff branch removes the claim on a successful tracker transition:
case params.HandoffState != "" && issueIsActive:
// ... TransitionIssue succeeded ...
CancelRetry(state, workerResult.IssueID)
delete(state.Claimed, workerResult.IssueID)
The review-reaction block runs after the handoff branch, so when handoff succeeds the claim is already gone and the stillClaimed guard short-circuits enqueueing. No entry is ever added to state.PendingReactions, the review reconcile pass iterates over an empty map, and the SCM adapter is never queried for review threads on the PR.
The same stillClaimed guard is applied to the CI reaction block immediately above, so the same gap affects pending CI status checks under handoff.
Symptoms
- Workflow configures
tracker.handoff_state, reactions.review_comments.provider, and produces a valid .sortie/scm.json with pr_number, owner, repo, branch.
- Initial agent run completes, the issue transitions to the configured handoff state, the PR is opened.
- A reviewer leaves review comments and submits a "Request changes" review on the PR.
- No log line related to review fetching, dispatching, debouncing, or escalation appears at any log level. Only the regular tick lines are emitted.
- No continuation turn is scheduled. The agent never sees the review feedback.
- The same gap applies to CI status reactions when
ci_feedback is configured together with handoff_state.
- Removing
handoff_state from the workflow restores the expected behaviour: the review reaction is enqueued and the reviewer's comments are picked up on the next poll.
Steps to Reproduce
- Configure a workflow with both
tracker.handoff_state (any non-empty active->handoff transition the tracker accepts) and reactions.review_comments.provider: github.
- Configure an
after_run hook that opens or finds a PR and writes .sortie/scm.json with pr_number, owner, repo, branch, sha.
- Run the orchestrator. Confirm the startup log contains
review comment routing enabled.
- Let an issue be picked up, the agent run, and the handoff transition apply. Confirm the log line
handoff transition succeeded, releasing claim.
- On GitHub, leave a review comment on the resulting PR and submit a "Request changes" review.
- Wait longer than
reactions.review_comments.poll_interval_ms.
Expected: a log line indicating the review fetch was performed and, if actionable comments are present, that a review-fix continuation was dispatched.
Actual: only tick completed lines. No review fetch is ever attempted for the issue.
Verification
The bug is fixed when:
- A workflow with both
handoff_state and reactions.review_comments enqueues a pending review reaction after the agent's first successful exit, regardless of whether the handoff transition succeeded.
- After the reviewer leaves actionable review comments on the PR, the SCM adapter is queried within
poll_interval_ms, and a continuation turn is dispatched with review_comments populated in the template context.
- The equivalent path for CI reactions also enqueues a pending CI check when
ci_feedback and handoff_state are configured together.
- A regression test in
internal/orchestrator covers the combination of non-empty HandoffState, successful TransitionIssue, and non-nil SCMAdapter, asserting that a ReactionKindReview entry exists in state.PendingReactions after HandleWorkerExit returns. An equivalent assertion covers CIProvider and ReactionKindCI.
Summary
When
tracker.handoff_stateis configured alongsidereactions.review_comments, no pending review reaction is ever enqueued for the issue, so review comments left on the resulting pull request are never observed and no continuation turn is dispatched. The orchestrator logsreview comment routing enabledat startup but the reconcile loop has nothing to iterate over.Root Cause (observed)
In
internal/orchestrator/exit.go, the block that enqueues aReactionKindReviewentry intostate.PendingReactionsis gated onstate.Claimed[issueID]still being present:Earlier in the same function, the handoff branch removes the claim on a successful tracker transition:
The review-reaction block runs after the handoff branch, so when handoff succeeds the claim is already gone and the
stillClaimedguard short-circuits enqueueing. No entry is ever added tostate.PendingReactions, the review reconcile pass iterates over an empty map, and the SCM adapter is never queried for review threads on the PR.The same
stillClaimedguard is applied to the CI reaction block immediately above, so the same gap affects pending CI status checks under handoff.Symptoms
tracker.handoff_state,reactions.review_comments.provider, and produces a valid.sortie/scm.jsonwithpr_number,owner,repo,branch.ci_feedbackis configured together withhandoff_state.handoff_statefrom the workflow restores the expected behaviour: the review reaction is enqueued and the reviewer's comments are picked up on the next poll.Steps to Reproduce
tracker.handoff_state(any non-empty active->handoff transition the tracker accepts) andreactions.review_comments.provider: github.after_runhook that opens or finds a PR and writes.sortie/scm.jsonwithpr_number,owner,repo,branch,sha.review comment routing enabled.handoff transition succeeded, releasing claim.reactions.review_comments.poll_interval_ms.Expected: a log line indicating the review fetch was performed and, if actionable comments are present, that a review-fix continuation was dispatched.
Actual: only
tick completedlines. No review fetch is ever attempted for the issue.Verification
The bug is fixed when:
handoff_stateandreactions.review_commentsenqueues a pending review reaction after the agent's first successful exit, regardless of whether the handoff transition succeeded.poll_interval_ms, and a continuation turn is dispatched withreview_commentspopulated in the template context.ci_feedbackandhandoff_stateare configured together.internal/orchestratorcovers the combination of non-emptyHandoffState, successfulTransitionIssue, and non-nilSCMAdapter, asserting that aReactionKindReviewentry exists instate.PendingReactionsafterHandleWorkerExitreturns. An equivalent assertion coversCIProviderandReactionKindCI.