Skip to content

feat(review): submit REQUEST_CHANGES on substantive FAIL so reviewDecision is authoritative (INV-52, closes #193)#197

Merged
zxkane merged 3 commits into
mainfrom
fix/request-changes-on-fail-193
Jun 8, 2026
Merged

feat(review): submit REQUEST_CHANGES on substantive FAIL so reviewDecision is authoritative (INV-52, closes #193)#197
zxkane merged 3 commits into
mainfrom
fix/request-changes-on-fail-193

Conversation

@kane-coding-agent

Copy link
Copy Markdown
Contributor

Summary

Both halves land together because they share decision-gate.md + the approve/merge flow.

What changed

  • NEW skills/autonomous-dispatcher/scripts/lib-review-request-changes.shsubmit_request_changes <pr> <body>, a best-effort helper (always returns 0; a 403/transient gh failure is logged and swallowed so it can never abort the FAIL route under set -e and strand the issue in reviewing).
  • autonomous-review.sh — wires the helper onto exactly the two substantive FAIL routes: the failed-substantive branch (agent posted Review findings:) and the block-substantive merge-conflict (CONFLICTING) route. It is deliberately NOT wired onto the non-substantive routes (mergeable-UNKNOWN re-queue, agent crash with no verdict) — a transient hold is not a dev-actionable blocking finding, and a standing CHANGES_REQUESTED there would falsely accuse the dev. The existing --approve on PASS is retained; PASS and REQUEST_CHANGES are mutually exclusive branches.
  • A subsequent PASS re-approves the new HEAD, superseding the standing CHANGES_REQUESTED (no permanently-stuck blocking state).
  • Agent-side framing fixed: SKILL.md + references/decision-gate.md re-scope "approve + merge" to the wrapper and explicitly forbid the agent running gh pr review/gh pr merge (the rejected mechanical tool-deny backstop is recorded in INV-52 — the review agent runs headless under --dangerously-skip-permissions, so prompt+wrapper enforcement is the robust path).
  • Pipeline Documentation Authority: new INV-52 in invariants.md; review-agent-flow.md (FAIL/PASS paths + sequence diagram) and state-machine.md (transition rows + reviewDecision note) updated in the same PR.
  • .github/workflows/ci.yml — the new lib added to the shellcheck list.

Invariant numbering

INV-51 was taken by #194 (codex review resume loop, on main); highest committed is INV-51 → this PR is INV-52, per the owner's numbering heads-up on the issue.

Post-install / upgrade

This PR adds scripts/lib-review-request-changes.sh. After merge + npx skills update -g, re-run install-project-hooks.sh on every onboarded project (see CLAUDE.local.md → Post-merge Step 2) or their review wrappers will crash on the missing source (the per-project scripts/ holds per-file symlinks into the user-scope skill; a newly-added file has no symlink until the installer re-runs).

Test Plan

  • Design canvas (docs/designs/request-changes-on-fail.md)
  • Test cases documented (docs/test-cases/request-changes-on-fail.md)
  • New regression test tests/unit/test-autonomous-review-request-changes.sh — 24 assertions: executable submit_request_changes harness (requests-changes-not-approve; non-zero gh → returns 0 + warns; continues past helper under set -e), source-of-truth greps (helper sourced + called on EXACTLY the 2 substantive routes, every call best-effort, PASS still --approve, mutual exclusion, bash -n), and agent-doc greps (no "PASS (approve + merge)"; agent prohibited from gh pr review/merge; INV-52 exists + referenced). Fails before the fix, passes after.
  • Full tests/unit/test-*.sh suite green (97 suites); regression pins (auto-merge-failure, mergeable-gate, multi-agent, verdict-trailer, prompt) hold.
  • shellcheck -S error clean on the new lib + wrapper.
  • code-simplifier + code-reviewer agents run (no findings ≥ High).

Acceptance Criteria

  • A blocking FAIL verdict results in reviewDecision == CHANGES_REQUESTED on the PR.
  • The --request-changes call is best-effort (non-fatal under set -e).
  • A subsequent PASS re-approves the new HEAD (no permanently-stuck CHANGES_REQUESTED).
  • The review AGENT never runs gh pr review --approve/gh pr merge.
  • review-agent-flow.md, decision-gate.md, state-machine.md, invariants.md updated in the same PR.

Closes #193

@kane-review-agent kane-review-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All acceptance criteria verified.

@kane-review-agent kane-review-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All acceptance criteria verified.

zxkane added 2 commits June 8, 2026 12:43
…ent posts verdicts only (INV-52, closes #193)

The review WRAPPER now owns the GitHub-native PR review/merge action on both
sides: it submits `gh pr review --approve` (+ merge) on PASS and, NEW,
`gh pr review --request-changes` on a substantive FAIL so the PR's
`reviewDecision` becomes CHANGES_REQUESTED — authoritative for humans, branch
protection, the dispatcher, and the dev-resume agent (root cause behind #188).
The review AGENT posts a verdict comment only and must never approve/merge
itself (the PR #191 / issue #190 incident, where a self-approve raced the
INV-44 mergeable gate + no-auto-close skip-merge).

- NEW lib-review-request-changes.sh::submit_request_changes — best-effort
  (always returns 0; a 403/transient gh failure is logged, never aborts the
  FAIL route under set -e). Wired onto EXACTLY the two substantive FAIL routes
  (agent-posted findings + CONFLICTING mergeable block); NOT on the
  non-substantive routes (mergeable-UNKNOWN re-queue, agent crash w/ no verdict).
- A subsequent PASS re-approves the new HEAD, superseding the standing
  CHANGES_REQUESTED (no permanently-stuck blocking state).
- Agent-side framing fixed: SKILL.md + decision-gate.md re-scope "approve+merge"
  to the wrapper and explicitly forbid the agent running gh pr review/merge.
- Pipeline docs: new INV-52; review-agent-flow.md FAIL/PASS paths +
  state-machine.md transition rows updated in the same PR.
- ci.yml: lib-review-request-changes.sh added to the shellcheck list.
- Tests: tests/unit/test-autonomous-review-request-changes.sh (24 assertions,
  executable helper harness + source-of-truth greps + agent-doc greps).
@kane-coding-agent kane-coding-agent Bot force-pushed the fix/request-changes-on-fail-193 branch from ba1c439 to fc2dabd Compare June 8, 2026 04:45
…oo (INV-52, #193)

Addresses the #197 codex review finding: the INV-52 acceptance criterion is
route-agnostic ("a blocking FAIL verdict must result in reviewDecision ==
CHANGES_REQUESTED"), but the original diff wired submit_request_changes only
into the agent-findings FAIL branch and the CONFLICTING mergeable block. The
E2E hard-gate failure (INV-46, E2E_GATE == fail, lane rc≠0, produced before the
review fan-out) is ALSO a dev-actionable `failed-substantive` blocking FAIL and
must assert CHANGES_REQUESTED on the PR.

- autonomous-review.sh: add submit_request_changes to the E2E `fail` branch
  (best-effort `|| log`, same shape as the other two substantive sites). The
  E2E `block-nonsubstantive` (evidence-missing) re-queue route deliberately
  does NOT request changes (transient, not a code defect).
- test: TC-RC-SRC-02/04 now require EXACTLY 3 substantive call sites; new
  TC-RC-SRC-04b (E2E-fail requests changes) + TC-RC-SRC-04c (E2E-evidence-missing
  does NOT). 26 assertions, all green.
- docs: INV-52 substantive-route table + sub-rule 2 + producer + cross-ref to
  INV-46; review-agent-flow.md E2E gate block + FAIL-path prose; state-machine.md
  E2E-fail transition row; design + test-case docs. The substantive set is now
  explicitly defined by "the verdict is a real dev-actionable blocking FAIL",
  NOT by which gate produced it.

@kane-review-agent kane-review-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All acceptance criteria verified.

@zxkane zxkane merged commit c132f23 into main Jun 8, 2026
3 checks passed
@zxkane zxkane deleted the fix/request-changes-on-fail-193 branch June 8, 2026 06:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(autonomous-review): submit REQUEST_CHANGES on blocking FAIL verdict so reviewDecision is authoritative

1 participant