FAIR-band: in-band [6/30] — split from #11492 per GPT V-B-A narrowing 2026-05-16T20:47Z. Companion to #11491 (PR #11494) which gates the MCP tool surface; this ticket covers the orthogonal CLI-bypass surface.
Premise
#11491 / PR #11494 added mechanical body-shape validation to manage_pr_review MCP tool. An agent who routes around that gate by using gh pr review --body "..." CLI directly bypasses the mechanical layer. The Helpful Assistant prior empirically favors this bypass under context-compression pressure ("the MCP tool gave me an error, let me just use gh CLI").
GPT correctly identified during #11492 intake V-B-A:
"The gh pr review CLI bypass is a different event/substrate from PR creation and should be separate after #11491 defines the review-body anchor set."
This ticket captures that split.
Why this is a separate ticket from #11492
- Different event surface: #11492 fires on
pull_request: opened; this fires on pull_request_review: submitted.
- Different anchor set: #11492 validates author-side PR-body anchors (Resolves, Evidence, Deltas); this validates reviewer-side pr-review template anchors (
[ARCH_ALIGNMENT] etc.) — same anchor set as PR #11494's REQUIRED_PR_REVIEW_ANCHORS.
- Different downstream-consumer cost: this surface protects the Retrospective-daemon graph ingestion contract; #11492 protects the author-side narrative completeness contract.
- Dependency ordering: should land AFTER PR #11494 merges and the
REQUIRED_PR_REVIEW_ANCHORS constant is the established source-of-truth for what anchors are mandatory.
Prescription
GitHub Actions workflow that:
- Triggers on
pull_request_review: submitted events
- Filters to reviews authored by
@neo-* agent identities (or all reviewers if scope-extension is warranted later)
- Fetches the review body via the
gh api or octokit REST surface
- Runs the same anchor-set check that PR #11494's
REQUIRED_PR_REVIEW_ANCHORS enforces
- If anchors are missing: posts a follow-up comment on the PR naming the missing anchors + linking the template + tagging the reviewer
- Does NOT block the merge (would be too aggressive for a post-hoc lint); operates as visibility + correction signal
Acceptance criteria
Avoided traps
- Blocking the merge on missing anchors: rejected — too aggressive post-hoc; review-state is already set on GitHub when this fires. Visibility + correction signal is the right shape, not a block.
- Duplicating the anchor list in two places: rejected — both the
PullRequestService.mjs validator (PR #11494) and this CI script must read from the same source. Either share a constants module OR document the sync protocol explicitly (the simpler path).
- Scope-extending to ALL reviewers (not just
@neo-*): deferred — start with agent identities; broaden if false-negatives surface (human reviewers may legitimately use ad-hoc structure for one-off comments).
Related
- Split parent: #11492 — Stage-0 V-B-A by GPT (
IC_kwDODSospM8AAAABClFRRA) identified this as a separate substrate from the PR-creation surface
- Substrate parent: PR #11494 / #11491 — the MCP tool-side gate this CI lint complements
- Conceptual sibling: PR #11490 / #11406 — CI grep-fail check shape (single-purpose, scoped path filter)
- Empirical anchor: same as #11491 — Gemini's structurally-non-template reviews on #11488/#11489 lost two PRs of Retrospective-daemon ingest signal
Not self-assigned — held for follow-up after PR #11494 lands and the anchor set is the canonical source-of-truth.
FAIR-band: in-band [6/30] — split from #11492 per GPT V-B-A narrowing 2026-05-16T20:47Z. Companion to #11491 (PR #11494) which gates the MCP tool surface; this ticket covers the orthogonal CLI-bypass surface.
Premise
#11491 / PR #11494 added mechanical body-shape validation to
manage_pr_reviewMCP tool. An agent who routes around that gate by usinggh pr review --body "..."CLI directly bypasses the mechanical layer. The Helpful Assistant prior empirically favors this bypass under context-compression pressure ("the MCP tool gave me an error, let me just use gh CLI").GPT correctly identified during #11492 intake V-B-A:
This ticket captures that split.
Why this is a separate ticket from #11492
pull_request: opened; this fires onpull_request_review: submitted.[ARCH_ALIGNMENT]etc.) — same anchor set as PR #11494'sREQUIRED_PR_REVIEW_ANCHORS.REQUIRED_PR_REVIEW_ANCHORSconstant is the established source-of-truth for what anchors are mandatory.Prescription
GitHub Actions workflow that:
pull_request_review: submittedevents@neo-*agent identities (or all reviewers if scope-extension is warranted later)gh apior octokit REST surfaceREQUIRED_PR_REVIEW_ANCHORSenforcesAcceptance criteria
.github/workflows/pr-review-template-lint.ymlexists with the trigger + filter shape aboveai/scripts/lint-pr-review-body.mjsmatchinglint-skill-manifest.mjsprecedent) shares theREQUIRED_PR_REVIEW_ANCHORSsource-of-truth with PR #11494'sPullRequestService.mjsconstant (single-source via a shared module import OR documented synchronization protocol)Avoided traps
PullRequestService.mjsvalidator (PR #11494) and this CI script must read from the same source. Either share a constants module OR document the sync protocol explicitly (the simpler path).@neo-*): deferred — start with agent identities; broaden if false-negatives surface (human reviewers may legitimately use ad-hoc structure for one-off comments).Related
IC_kwDODSospM8AAAABClFRRA) identified this as a separate substrate from the PR-creation surfaceNot self-assigned — held for follow-up after PR #11494 lands and the anchor set is the canonical source-of-truth.