LearnNewsExamplesServices
Frontmatter
id11495
titleCI lint for gh-CLI-direct PR review bypass (split from #11492 per GPT V-B-A narrowing)
stateClosed
labels
enhancementaimodel-experience
assignees[]
createdAtMay 16, 2026, 10:55 PM
updatedAtMay 17, 2026, 1:35 AM
githubUrlhttps://github.com/neomjs/neo/issues/11495
authorneo-opus-4-7
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMay 17, 2026, 1:35 AM

CI lint for gh-CLI-direct PR review bypass (split from #11492 per GPT V-B-A narrowing)

Closedenhancementaimodel-experience
neo-opus-4-7
neo-opus-4-7 commented on May 16, 2026, 10:55 PM

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:

  1. Triggers on pull_request_review: submitted events
  2. Filters to reviews authored by @neo-* agent identities (or all reviewers if scope-extension is warranted later)
  3. Fetches the review body via the gh api or octokit REST surface
  4. Runs the same anchor-set check that PR #11494's REQUIRED_PR_REVIEW_ANCHORS enforces
  5. If anchors are missing: posts a follow-up comment on the PR naming the missing anchors + linking the template + tagging the reviewer
  6. Does NOT block the merge (would be too aggressive for a post-hoc lint); operates as visibility + correction signal

Acceptance criteria

  • AC1: Workflow file .github/workflows/pr-review-template-lint.yml exists with the trigger + filter shape above
  • AC2: Workflow script (likely ai/scripts/lint-pr-review-body.mjs matching lint-skill-manifest.mjs precedent) shares the REQUIRED_PR_REVIEW_ANCHORS source-of-truth with PR #11494's PullRequestService.mjs constant (single-source via a shared module import OR documented synchronization protocol)
  • AC3: When a review missing anchors is submitted, the workflow posts a structured follow-up comment naming the missing anchors and linking the template
  • AC4: When a review with all anchors is submitted, the workflow exits silently (no spam on well-formed reviews)
  • AC5: Unit test coverage for the script (anchor-present passes, anchor-missing emits comment)
  • AC6: ADR 0008 / pr-review skill substrate cross-reference noting the layered defense (MCP gate + CI lint)

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.

tobiu closed this issue on May 17, 2026, 1:35 AM