fix: make review_reply wait for the next submit - #66
Merged
Conversation
review_reply returned as soon as it had written, which left the agent free to summarise the round to its user and end its turn with nothing subscribed to the next submit. MCP is pull-only, so a submit nobody is waiting for reached no one: the review stalled until the human said "I submitted" by hand. Nothing else was at fault, and the session transcripts say so. The wait that followed such a prompt returned the round in two seconds, so the sidecar, the sequence counters and the notifier had all done their job; and a wait that ran past two minutes came back to the agent as a task notification and the round continued, so the long stdio call is not the fragile part of this loop either. Closing the round and entering the next wait are now the same call, so the gap cannot open. review_wait remains for the first wait after review_start and for resuming after a timeout, and the tool description says not to end the turn on any other outcome. The embedded skill text moves review_progress(idle) ahead of the reply, since the reply no longer returns until the next round. User request: レビュー画面から submit してもエージェントが反応しないこと がある。原因を突き止め、submit が確実に伝わるようにしたい。原因が MCP に あるなら MCP サーバー機能の廃止も選択肢に入れる、という依頼。調査の結果 MCP は原因ではなく、返信後にループへ戻り損ねる一点だったため、ツール設計 で構造的に塞ぐ方針を選んだ。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
README and DESIGN carried the old loop -- reply, then back to review_wait -- which is exactly the shape that let a round close with nobody waiting. They now describe review_reply as the call that replies and waits, and DESIGN keeps the reasoning: the signal was never lost, there was simply often no next wait to deliver it to. GLOSSARY's Feedback entry named review_wait as the only agent call a submit releases; it now names both. User request: 変更に合わせてドキュメントを追随させる。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why this change is necessary
A review would sometimes stop dead the moment it should have continued. The human clicked Submit, the page went quiet, and nothing happened until they typed "I submitted" into the chat by hand — at which point the agent picked the round up instantly, as if it had been there all along.
Session transcripts say exactly where it went. The agent replied, called
review_progress(idle), summarised the round to its user and ended its turn — and from that moment nothing was subscribed to the next submit. MCP is pull-only: a submit nobody is waiting for reaches no one.Everything else was doing its job. The wait that followed a manual "I submitted" returned the round in two seconds, so the sidecar, the sequence counters and the notifier had never lost anything; and a wait that ran past two minutes came back to the agent as a task notification and the round continued, so the long stdio call — the part this repository had flagged as "documented but unverified" — is not the fragile piece either. Retiring the MCP server, which was on the table when this started, would have changed nothing.
Big picture
図のソース / Diagram source (mermaid)
sequenceDiagram autonumber participant H as Human (page) participant S as Server (session) participant A as Agent A->>S: review_start S-->>H: serve the review page A->>S: review_wait Note over S,A: the call blocks until a submit arrives H->>S: Submit (comments) S-->>A: review_wait returns the comments A->>A: edit the document A->>S: review_reply (inline replies) alt before: reply returns at once S-->>A: returns immediately A-->>H: summarise the round, then end the turn H->>S: Submit again Note over S,A: no waiter: the submit reaches no one H->>A: the human says "I submitted" by hand else after (this PR): reply also waits S->>S: record the replies, keep waiting H->>S: Submit again S-->>A: the same review_reply call returns the next round Note over S,A: the loop continues on its own endApproach
review_replynow writes the replies and then waits for the next submit, returning whatreview_waitreturns. Closing a round and entering the next wait are the same call, so the gap cannot open — the fix is structural rather than a matter of instructing the agent more firmly, which is what a pull-only protocol needs.review_waitstays for the first wait afterreview_startand for resuming after a timeout.Alternatives considered and rejected: replacing MCP with another transport (the evidence clears MCP); a Stop hook that refuses to end the turn while a review is open (client-specific, and unnecessary once the tool surface closes the gap); strengthening the skill wording alone (leaves compliance to the model, which is the thing that failed).
One assumption is baked in:
review_replyalways waits, with no escape hatch, because mid-round reporting is whatreview_progressis for. If a case for replying without waiting shows up, a flag can be added later.Design Documents
Review Points
review_progress(idle)beforereview_reply, since the reply no longer returns until the next round.session_endedfrom End Review.