Fix #2080: brc_confirm returns ok=False on pending_acks rejection - #2083
Merged
Conversation
mcp__brc__confirm previously returned {ok: True, status: "pending_acks"}
when the orchestrator rejected the confirm and the producer did not
transition to CONFIRMED. A glance-level read of `ok` looked like
success and contributed to the documenter wait_loop deadlock on
pipeline issue-1965 (#2064).
ok now means "did the producer transition to CONFIRMED": True for
status=="confirmed", False for "pending_acks". The structured response
(status, message, consensus_reached, signal) is preserved so callers
can branch on the rejection reason without exception handling --
pending_acks is a normal protocol state, not a hard failure.
Updated agent rules and the handler docstring so future agents read
ok correctly and inspect status/message on rejection. The CLI command
already keys on status, not ok, so exit-code parity (0/2/1) is
unchanged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Contributor
There was a problem hiding this comment.
No agent-mode design concerns. This change actually improves agent-mode alignment — it makes the ok flag of an MCP tool response semantically match "did this operation achieve its intent," which is what an agent reads at a glance. The rule update in sandbox/agent-config/rules/orchestrator.md is concise orienting metadata (one sentence pointing at status/message for the rejection reason), not pre-fetched bulk content.
— Authored by egg
This comment has been minimized.
This comment has been minimized.
Contributor
There was a problem hiding this comment.
Approve. Clean, well-scoped fix for the pending_acks mis-read that caused the documenter deadlock on issue-1965.
What I verified
- Semantics match the orchestrator contract. All
pending_acksexit paths inorchestrator/peer_consensus.py:511-595return{"status": "pending_acks", ...}under a successful (success: True) envelope, sobody.get("status") == "pending_acks"is the correct discriminator. The two-valued universe (confirmed|pending_acks) is real — there is no third success state to worry about. - No caller breakage.
cmd_consensus_confirmed(sandbox/egg_lib/orch_cli.py:1702) branches onstatus, notok. Exit codes (0/2/1) preserved —test_cli_parity.py::test_pending_acks_exits_2still asserts rc == 2 with the newok: Falsemock.- Repo-wide grep (
brc_confirm,mcp__brc__confirm) shows only the agent rule, the docs reference table, the tests, and the CLI shim — none keys onok.
- Edge case is unchanged. If the orchestrator returns
success: Truewith nostatuskey at all,pending = False, sook = True, status = "confirmed"— same behavior as before the PR. Not a regression vector. - Asymmetry with sibling handlers is justified.
brc_propose/brc_ack/brc_nackraiseGatewayErroronsuccess: Falsebecause they have no deferred-success state;brc_confirmdoes, so returning structuredok: Falserather than raising is the right call. The PR description argues this explicitly and the reasoning holds. - Docstring + agent rule + tests all updated coherently. The new
oksemantics are documented at every layer where an agent might see them.test_happy_confirmedandtest_pending_acksnow both pinokso a future regression in either direction breaks a test.
Non-blocking notes
sandbox/agent-config/rules/orchestrator.md:44is now ~370 chars on one line. Markdown renders it fine and the agent doesn't care, but if anyone ever wants to wrap it for human readability, the bullet would still work as a multi-line entry.test_pending_ackscould optionally also assertresp["message"]is passed through (it currently is —result.get("message")atbrc.py:256), but the existing coverage is sufficient for the contract being established here.
— Authored by egg
Contributor
|
egg review completed. View run logs 3 previous review(s) hidden. |
jwbron
added a commit
that referenced
this pull request
Apr 25, 2026
…er] (#2088) Update documentation to reflect changes from c2eaea9: - agent-tools.md: clarify that mcp__brc__confirm returns ok=False when the orchestrator rejects the transition (pending_acks), not just on hard errors. Equivalent to CLI exit code 2 vs 0. - concurrent-execution.md: extend the pending_acks note to cover the MCP tool response (ok=False / ok=True) alongside the CLI exit codes. Triggered by: #2083 Authored-by: egg Co-authored-by: jwbron <8340608+jwbron@users.noreply.github.com>
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.
Summary
mcp__brc__confirmnow setsok: Falsewhen the orchestrator rejects the confirm (status == "pending_acks");ok: Trueis reserved for the producer actually transitioning to CONFIRMED.status,message,consensus_reached,signal) is unchanged, so callers can still branch on the rejection reason without exception handling —pending_acksis a normal protocol state, not a hard failure.Why
Per #2080: returning
{ok: True, status: "pending_acks"}made a glance-level read of the response look like success even when the producer's state did not change. On pipelineissue-1965(#2064) the documenter agent followed exactly that mis-read into a 36-minutewait_loopdeadlock.okshould mean "did this operation achieve its intent" — the producer didn't transition, so it didn't.Why not raise
GatewayErrorpending_acksis a legitimate protocol state with actionable reasons (producer_not_fully_acked,global_zero_proposal,stale_acks, etc.). Forcing exception handling for an expected branch would be noisy and unlike the rest of the BRC tool surface that returns structured data. Sibling handlers (brc_propose,brc_ack,brc_nack) raise onsuccess: Falsebecause they have no in-between state —brc_confirmis the only verb with a "deferred" outcome.Caller impact
cmd_consensus_confirmed(sandbox/egg_lib/orch_cli.py:1681-1708), branches onstatus, notok. Exit-code parity (0 confirmed / 2 pending / 1 error) is unchanged.okfrom this handler. The agent rule update (sandbox/agent-config/rules/orchestrator.md) preempts future mis-reads.Test plan
pytest tests/sandbox/egg_agent_tools/— 357 pass, 4 skippedmake lint-python— cleantest_handlers_brc.py::test_happy_confirmedandtest_pending_acksto assert the newoksemanticstest_cli_parity.pymock forpending_acksto reflect the new contract (ok: False)Out of scope
check_brc_progressescalation gap) — independent. This fix is worth doing regardless, since it affects everypending_ackspath, not just the documenter case.Refs: #2064, #2078, #2079, PR #2077.
🤖 Generated with Claude Code