Make no-reviewer review blocks stop saying advisory-only #790

Closed
opened 2026-07-09 09:06:10 +00:00 by coilyco-ops · 2 comments
Member

Problem

A no-reviewer in-container review result is converted to a fail-closed block, but the human-facing text still says the opposite:

review note: ADVISORY-ONLY REVIEW: no reviewer family was available for codex, so the adversarial panel could not run and did NOT gate this diff.
panel BLOCKED: 0/0 passing - do NOT land this diff.
review summary: blocked: ADVISORY-ONLY REVIEW: no reviewer family was available for codex, so the adversarial panel could not run and did NOT gat...
ward: review gate BLOCKED: 0/0 passing (class default); blocked: ADVISORY-ONLY REVIEW: no reviewer family was available for codex, so the adversarial panel could not run and did NOT gat...; landing refused

The gate behavior is correct: no runnable reviewer must fail closed. The regression is the contradictory wording and summary/handoff shape. It tells the worker and human reader that the panel was advisory-only and did not gate the diff, then immediately blocks landing.

Evidence

The pasted run was a Codex worker in /workspace/factory-game-v3 at 2026-07-09 01:48:00.125. All reviewer families were unavailable:

  • codex launch probe failed after printing the Codex startup banner and prompt text.
  • claude smoke test produced no usable output.
  • opencode was not on PATH.
  • goose could not reach the Ollama endpoint.

/substrate/ward shows the source of the contradiction:

  • internal/reviewpanel/panel.go renders advisoryNote as ADVISORY-ONLY REVIEW ... did NOT gate this diff.
  • cmd/ward/agent_review.go then converts GateAdvisory to GateBlock before writing the summary, handoff, panel output, and issue conclusion.
  • reviewSummaryBlocked prefixes that stale advisory note with blocked:.

Expected behavior

When no reviewer can run and ward converts the result to a fail-closed block, every user-visible surface should say the gate blocked because no reviewer was runnable. It should not use ADVISORY-ONLY REVIEW, and it should not say the diff was not gated.

Surfaces to cover:

  • stderr panel note
  • panel BLOCKED text
  • review summary
  • ~/.ward/review-summary.txt
  • WARD-REVIEW / blocked error path
  • issue conclusion comment body

Do

  • Preserve fail-closed behavior for no runnable reviewers.
  • Change the note/summary wording after advisory-to-block conversion so the unavailable panel reads as a block, not an advisory bypass.
  • Add regression coverage for the no-runnable-reviewer path. The test should fail if a blocked result contains ADVISORY-ONLY REVIEW or did NOT gate this diff in the worker-facing summary/output.
  • Update docs/dispatch-review.md only if the public contract needs clarifying.

Acceptance

  • A no-runnable-reviewer review still exits non-zero and refuses landing.
  • The output and summary clearly say the review gate blocked fail-closed because no reviewer family was available.
  • No blocked no-reviewer summary says ADVISORY-ONLY REVIEW or did NOT gate this diff.
  • ward exec test passes.

Dispatch note

Dispatch this with --skip-review because the issue repairs review-gate output and should not be blocked by the broken review gate it is fixing. This follow-up narrows the remaining regression after ward#784.

## Problem A no-reviewer in-container review result is converted to a fail-closed block, but the human-facing text still says the opposite: ```text review note: ADVISORY-ONLY REVIEW: no reviewer family was available for codex, so the adversarial panel could not run and did NOT gate this diff. panel BLOCKED: 0/0 passing - do NOT land this diff. review summary: blocked: ADVISORY-ONLY REVIEW: no reviewer family was available for codex, so the adversarial panel could not run and did NOT gat... ward: review gate BLOCKED: 0/0 passing (class default); blocked: ADVISORY-ONLY REVIEW: no reviewer family was available for codex, so the adversarial panel could not run and did NOT gat...; landing refused ``` The gate behavior is correct: no runnable reviewer must fail closed. The regression is the contradictory wording and summary/handoff shape. It tells the worker and human reader that the panel was advisory-only and did not gate the diff, then immediately blocks landing. ## Evidence The pasted run was a Codex worker in `/workspace/factory-game-v3` at `2026-07-09 01:48:00.125`. All reviewer families were unavailable: * codex launch probe failed after printing the Codex startup banner and prompt text. * claude smoke test produced no usable output. * opencode was not on `PATH`. * goose could not reach the Ollama endpoint. `/substrate/ward` shows the source of the contradiction: * `internal/reviewpanel/panel.go` renders `advisoryNote` as `ADVISORY-ONLY REVIEW ... did NOT gate this diff`. * `cmd/ward/agent_review.go` then converts `GateAdvisory` to `GateBlock` before writing the summary, handoff, panel output, and issue conclusion. * `reviewSummaryBlocked` prefixes that stale advisory note with `blocked:`. ## Expected behavior When no reviewer can run and ward converts the result to a fail-closed block, every user-visible surface should say the gate blocked because no reviewer was runnable. It should not use `ADVISORY-ONLY REVIEW`, and it should not say the diff was not gated. Surfaces to cover: * stderr panel note * `panel BLOCKED` text * `review summary` * `~/.ward/review-summary.txt` * `WARD-REVIEW` / blocked error path * issue conclusion comment body ## Do * Preserve fail-closed behavior for no runnable reviewers. * Change the note/summary wording after advisory-to-block conversion so the unavailable panel reads as a block, not an advisory bypass. * Add regression coverage for the no-runnable-reviewer path. The test should fail if a blocked result contains `ADVISORY-ONLY REVIEW` or `did NOT gate this diff` in the worker-facing summary/output. * Update `docs/dispatch-review.md` only if the public contract needs clarifying. ## Acceptance * A no-runnable-reviewer review still exits non-zero and refuses landing. * The output and summary clearly say the review gate blocked fail-closed because no reviewer family was available. * No blocked no-reviewer summary says `ADVISORY-ONLY REVIEW` or `did NOT gate this diff`. * `ward exec test` passes. ## Dispatch note Dispatch this with `--skip-review` because the issue repairs review-gate output and should not be blocked by the broken review gate it is fixing. This follow-up narrows the remaining regression after ward#784.
Author
Member

🔒 Reserved by ward agent --harness codex — container engineer-codex-ward-790 on host kais-macbook-pro-2.local is carrying this issue (reserved 2026-07-09T09:06:18Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (1h TTL); --force overrides.

Do not comment on or edit this issue to steer the run while it is reserved. The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a new issue, dispatched fresh — that is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494).

run seed context — what this run is carrying (ward#609)
  • Resolved: coilyco-flight-deck/ward#790 · branch issue-790 · harness codex · workflow pr
  • Run: engineer-codex-ward-790 · ward v0.488.0 · dispatched 2026-07-09T09:06:18Z
  • Comment thread: 0 included in the pre-flight read, 0 stripped (ward's own automated comments).

Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.488.0).

— Codex, via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --harness codex` — container `engineer-codex-ward-790` on host `kais-macbook-pro-2.local` is carrying this issue (reserved 2026-07-09T09:06:18Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (1h TTL); `--force` overrides. **Do not comment on or edit this issue to steer the run while it is reserved.** The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a **new issue, dispatched fresh** — that is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494). <details><summary>run seed context — what this run is carrying (ward#609)</summary> - **Resolved:** `coilyco-flight-deck/ward#790` · branch `issue-790` · harness `codex` · workflow `pr` - **Run:** `engineer-codex-ward-790` · ward `v0.488.0` · dispatched `2026-07-09T09:06:18Z` - **Comment thread:** 0 included in the pre-flight read, 0 stripped (ward's own automated comments). Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.488.0). </details> <!-- ward-agent-signature --> — Codex, via `ward agent`
Author
Member

WARD-OUTCOME: done - rewrote no-reviewer block wording and covered the fail-closed surfaces
workflow: pr; review summary: skipped by --skip-review / --no-review-gate

The conversion seam was the right place to fix this. Once I rewrote the advisory fallback at the block boundary, the summary, handoff, panel output, and issue comment all lined up. The only friction was Forgejo PR creation and status polling, which I handled through the API and tasks endpoint. Confidence is high.

WARD-OUTCOME: done - rewrote no-reviewer block wording and covered the fail-closed surfaces workflow: pr; review summary: skipped by --skip-review / --no-review-gate The conversion seam was the right place to fix this. Once I rewrote the advisory fallback at the block boundary, the summary, handoff, panel output, and issue comment all lined up. The only friction was Forgejo PR creation and status polling, which I handled through the API and tasks endpoint. Confidence is high.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
coilyco-flight-deck/ward#790
No description provided.