Skip to content

feat(implementation): dispatch tagged phase-boundary reviews to quality-gate - #8394

Merged
kyle-sexton merged 24 commits into
mainfrom
feat/8331-phase-boundary-review-dispatch
Oct 19, 2026
Merged

kyle-sexton merged 24 commits into
mainfrom
feat/8331-phase-boundary-review-dispatch

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Oct 19, 2026 •

Copy link
Copy Markdown
Member

Closes #8331

Summary

A plan phase tagged Review: architecture, security, code-design or concurrency now gets that review at its phase boundary, run by /implementation:implement and /implementation:implement-dispatch through /review:quality-gate. An untagged phase gets no review.

Fix

  • New plugins/implementation/skills/implement/context/phase-review.md holds the sequence: invoke /review:quality-gate architecture, security, code-design or slice concurrency with the previous phase-boundary commit as --base, the plan's Quality bar: line when present, --report-only, and --worktree for a worker's worktree, passing no rationale. For a worker branch's first phase, --base is the commit the branch was created from. Then fix inside the phase fence, re-review once with the same --base as the first call (the whole phase diff stays in scope, so a fix that missed its finding still rates it and a regression the fix added rates too), and give the acceptance verdict last.
  • Any CRITICAL on the re-review stops the loop (the original finding, a regression the fix introduced, or a defect the first call missed): it goes to DEVIATIONS.md as a blocking human-decision and is escalated once, never looped.
  • implement/SKILL.md and implement-dispatch/SKILL.md load that file at a tagged boundary, and implement-dispatch carries the full review call.
  • Permission decision: this adds no new grants, and no git -C * allowed-tools rule anywhere. When the session's permission mode denies the review's worktree reads, the run logs the review to DEVIATIONS.md as not run (unverified), the phase-verifier still runs, and Step 5's report lists that phase and tag as not reviewed (decision on #8331).
  • Four eval cases: pb-tagged-phase-reviews-before-commit (review before commit, the review invocation, verifier after review), pb-untagged-phase-no-review, pb-repeated-critical-escalates-once (same finding CRITICAL again), and pb-regression-critical-stops (the fix clears the first CRITICAL but the re-review rates a different one the fix introduced). In both re-review cases, an llm judge checks that the run plans no further fix brief or review; steps addressed to a person do not count.
  • Changelog fragment under .changes/implementation/.

Verification

  • phase-verifier: 9/9 acceptance criteria pass.

  • Paid evals at aa2efee (3 runs per arm, regex graders, all three runs VALID), with plugin vs without: tagged phase 1.0 vs 0.0; untagged phase 1.0 vs 0.5; repeated critical 0.889 vs 0.667. One case each, so the noise report calls n too small for an interval. The repeated-critical miss: one with-arm run planned another fix brief and re-review instead of a blocking human-decision.

  • Paid evals at f84cffe9 (r4, 3 runs per arm, no run errors), with plugin vs without:

    Case With Without Delta
    pb-regression-critical-stops 1.0 0.667 +0.333
    pb-repeated-critical-escalates-once 1.0 0.667 +0.333

    blocking-human-decision (and phase-not-done) stay regex graders. not-a-repeat, no-further-round and no-third-round are now llm judges with explicit pass/fail criteria, because three rounds of regex could not settle these semantic checks. Every with-plugin run passes every grader. Every without run fails only blocking-human-decision. The judges pass the without runs' further-round check because their extra fix and review steps are addressed to a person. That is why the delta is lower than r3's regex grade, which counted those lines against them.

  • bash scripts/check-affected.sh --tests --base origin/main from the worktree after merging current main: 7 passed, 2 skipped (no shell or Python changed) over 29 changed files, rerun at f84cffe.

  • typos over the changed files: clean.

Related

🤖 Generated with Claude Code

kyle-sexton and others added 19 commits October 18, 2026 20:22
Every quality-gate mode takes --worktree, --base, --quality-bar and
--report-only, so an orchestrator can review a phase diff in a worker's
worktree. With a base SHA no pull-request lookup or fetch runs. Adds the
qg-phase-boundary-worktree eval case.

Refs #8327

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The phase-boundary inputs are passed explicitly by an orchestrator, so the
description needs no new trigger phrase.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d grants

Restore the argument-hint to the mode set so it fits the 100-character
budget and matches the lead of the Arguments line; the phase-boundary
flags stay documented in the Arguments line and context/phase-boundary.md.

Remove the allowed-tools entries that put a wildcard before the git
subcommand (git -C * ...). A wildcard there also approves options such as
-c core.fsmonitor=<cmd>, which runs a program, in a skill that reviews
untrusted diffs. Worktree-targeted commands go through normal permission
handling.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Under --base or --worktree, code mode skips the pr-review-toolkit path
for its code-reviewer fallback, and downstream mode skips the remote
downstream_probe layer and treats the floor as report. Under
--report-only the size-crossing loop reads git diff -z instead of a
written path file. Name the modes --quality-bar applies to, pass spec
text to the spec reviewer, and fail the eval grader only on a finding
in admin.js, not on a note that it predates the base.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Name pr and close-out in the --quality-bar row; brief reviewers with
  each mode's own required inputs; restatement dispatches under --base.
- Under --report-only the standards ladder takes its non-interactive rung.
- code skips size crossings under --worktree; define the report-only base.
- Step 0 skips the PR-exists signal with --base; drop restated upstream.
- Eval: fail on any Write, add a no-Edit grader.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
code-reviewer, security-reviewer and architecture-guardian run only the
change-set commands their brief supplies (worktree path and base SHA),
with no gh lookup, fetch or ls-remote; without one, step 2 is unchanged.
phase-boundary.md says the brief replaces that step. criteria mode under
--base or --worktree dispatches a fresh-context review:brief-reviewer
instead of reviewing inline.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Restatement mode now dispatches its batch reviewer under --worktree as
well as --base, so a worktree-only run no longer reviews inline from the
invoking checkout.

The phase-boundary reviewer brief names the worktree's absolute path as
the file-read root, and code-reviewer, security-reviewer and
architecture-guardian resolve every Read, Grep, Glob and listed
untracked path under a supplied worktree. The advisory line no longer
reads as if per-slice passes the plan's rationale.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace the per-command worktree anchoring with one rule: when the brief
supplies a worktree, every command and tool call in the review targets it
(git via git -C, Read/Grep/Glob, untracked paths, and any other command
such as a dependency audit), never the invoking checkout. Stated
identically in code-reviewer, security-reviewer and architecture-guardian,
and in the quality-gate phase-boundary brief for every dispatched
reviewer, review:brief-reviewer included. The downstream probe's
repository root is the worktree path under --worktree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…alternation

typos read the [Ss]earch character class as the misspelling "earch" and
failed lint-repo. (?:search|Search) matches the same strings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The mode loads the consumer's review criteria through the standards
resolution ladder, falls back to small bundled criteria (Duplicated Code,
Shotgun Surgery, Speculative Generality), and dispatches a fresh-context
brief-reviewer. Repetition is CRITICAL only when the diff introduces an
unsynced copy in code, naming the fact and the diverging change; Markdown,
cascades and the prototype bar stay SUGGESTION. A contradicting consumer
standard wins and the report names the overridden default; with no
quality bar the review assumes production and says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Five plugin-eval cases cover the mode's severity rules: an introduced,
unsynced code copy is CRITICAL with the production assumption named; a
declared-registry entry and a file move are not CRITICAL; Markdown
repetition and the prototype bar stay SUGGESTION; a contradicting
docs/standards file produces the override line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The no-critical and repetition-is-suggestion graders now fail only on a
rated finding (a severity table cell, a line that starts with the
severity, a (CRITICAL) or [CRITICAL] label, or Severity: CRITICAL) and
pass a negated mention such as "Not CRITICAL: setup.md is Markdown".
The cascade grader requires the CRITICAL finding to name
FREE_SHIPPING_THRESHOLD or 50, not the word threshold. code-design.md
states that its repetition rule overrides severity.md's "code
duplication" IMPORTANT example.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ty-gate

A plan phase tagged Review: architecture, security, code-design or
concurrency now gets /review:quality-gate architecture, security,
code-design or slice concurrency at its boundary, with the previous
boundary commit as --base, the plan's Quality bar line, --report-only,
--worktree for a worker's worktree, and no rationale. Sequence: review,
fix inside the phase fence, one re-review scoped to the fixed hunks,
then the acceptance verdict last. A repeated CRITICAL goes to
DEVIATIONS.md as a blocking human-decision and escalates once.

The gate's git -C reads run under the permission posture implement-
dispatch already relies on for worker worktrees; no allow rule is
added. A denied review is logged as not run and the phase-verifier
still runs.

Adds three eval cases: tagged phase reviews before the commit, untagged
phase gets no review, repeated CRITICAL escalates once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…raders

The no-third-round and phase-not-done graders treated instead, rather,
stop, leave, left, stays, remains and unmarked as negators, so a wrong
reply such as "Instead of parking, dispatch another fix brief" passed.
Keep only true negators and add both wrong replies as fail samples.
Name the implement Step 4 lead-in exactly in the implement-dispatch
pointer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…spatch

implement-dispatch pointed at implement Step 4 for the tag-to-mode table and
flags, so a dispatch run that did not load implement emitted the gate call
without its mode, --report-only or --quality-bar. It now states the whole
invocation.

Two eval graders misread correct output: review-before-commit anchored on
\A, which the binary's JavaScript engine reads as a literal "A", and
phase-not-done counted a restated plan rule ("before it is marked [DONE]")
as marking the phase.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…one grader

The DEVIATIONS "Plan said" line restates the plan by design, so a
correct reply that quotes a "marked [DONE]" plan rule failed the grader.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton
kyle-sexton marked this pull request as ready for review October 19, 2026 05:12
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-19T05:13:55.056664Z ee39af4 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ee39af47ca

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugins/implementation/skills/implement/context/phase-review.md Outdated
@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

claude-security-review reviewed f84cffe94a08349455c8dec98c09d8096c18805e: 0 finding(s), 0 as inline comments.

No security issues found in the incremental change (f84cffe, since 7f373fb).

The change touches only eval fixtures under plugins/implementation/evals/:

  • It moves three inline regex graders per case into graders/*.md files. The regex patterns are the same as before.
  • It replaces two of the regex graders with LLM-judge rubrics: no-further-round and not-a-repeat in pb-regression-critical-stops, and no-third-round in pb-repeated-critical-escalates-once.
  • It adds sample answers to the samples/*.json files.

None of these files contain executable code, credentials, workflow or permission changes, or network access. The rubrics are static text.

I did not read the instruction exception register. The change touches no CLAUDE.md, AGENTS.md, rules file, skill or agent body, or hook. The removed regexes were test graders, so no guardrail is deleted.

Moving the regexes to files adds no new trust boundary. The no-further-round regex is dropped in favor of an LLM rubric, and the other two keep theirs. Those patterns only ever run on eval outputs, not on untrusted PR input. A ReDoS in an eval-only grader would not cross a trust boundary.

Comment thread plugins/implementation/skills/implement/context/phase-review.md
Comment thread plugins/implementation/skills/implement-dispatch/SKILL.md Outdated
@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

claude-review reviewed f84cffe94a08349455c8dec98c09d8096c18805e: 0 finding(s), 0 as inline comments.

Incremental review of f84cffe (changes since 7f373fb): no findings.

The change moves the grader definitions for pb-regression-critical-stops and pb-repeated-critical-escalates-once out of case.yaml and into graders/*.md. It turns no-further-round, no-third-round and not-a-repeat from regex graders into LLM-judged ones, and extends the sample files.

What I checked by reading, not by running:

  • Grader layout: collect_graders in plugins/evals/skills/validate/scripts/validate-cases.py takes the union of the case.yaml grader list and graders/*.md, so a case.yaml with no graders: key is valid. plugins/architecture/evals/ already uses the graders/*.md layout.
  • Frontmatter: the keys type, arm: both and focus: last_message are inside the validator's allowed sets (GRADER_COMMON, and focus for llm).
  • Regex graders: the moved blocking-human-decision and phase-not-done patterns, flags and match are unchanged from the removed case.yaml entries (checked against the diff).
  • Samples: the validator only warns that LLM-judged samples are not checked, since that needs a paid calibration run. The new samples are consistent with the new judge criteria:
    • "Next step:", "Next,", "should run the review again", "need to re-run", and "Plan:" are in the fail lists.
    • The person-addressed options and remediation lines are in the pass lists.
    • The "not a repeat" and "does not repeat" lines are in the pass list for not-a-repeat.

I did not run validate-cases.py because the sandbox needed approval for it. Nothing here has been executed.

Evidence note (not a code defect): the PR body's table (1.0 vs 0.333 and 1.0 vs 0.444) says the scores were regraded offline with the graders at 7f373fb, which were regex. The head now uses LLM judges for no-further-round, no-third-round and not-a-repeat, and I saw no paid run against them. Those scores are author-claimed and describe a different grader set than the head carries. If the "with vs without" numbers matter for #8331's "difference in the PR body" criterion, refresh them with a run at this head.

The phase-boundary re-review now keeps the first call's --base, so a fix
that missed its finding still rates it and a regression the fix added is
rated too. Any CRITICAL on the re-review stops the loop, not only a
repeat of the same finding. implement-dispatch names the first phase's
base on a fresh worker branch and lists a review the permission mode
denied in Step 5's report.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread plugins/implementation/skills/implement/context/phase-review.md
…en the round grader

Add pb-regression-critical-stops: the fix clears the first call's
CRITICAL but the re-review rates a different one the fix introduced,
which must still stop as a blocking human-decision. The no-third-round
grader now fails any plan for another fix brief or review run, including
"re-run the review", while passing negated lines. phase-review.md says a
CRITICAL matching no first-call finding is never a discovery or a fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread plugins/implementation/evals/pb-repeated-critical-escalates-once/case.yaml Outdated
Comment thread plugins/implementation/evals/pb-regression-critical-stops/case.yaml Outdated
kyle-sexton and others added 2 commits October 19, 2026 01:38
…t grader

An r3 with-plugin run named the CRITICAL as "a line added by fix commit
e81c4f0a", a correct answer the grader rejected. Add that phrasing and a
sample for it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…and anchor not-a-repeat

The round grader's verb branch now needs an imperative or future lead-in
(I'll, will, next:, then, let me, going to) before run, send or dispatch,
so a description such as "run with shell=True, introduced by the fix
commit" passes. not-a-repeat now needs a negated "repeat(s) the first
call / original" and rejects "not a new finding" and "not a regression".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread plugins/implementation/evals/pb-regression-critical-stops/case.yaml Outdated
Comment thread plugins/implementation/evals/pb-regression-critical-stops/case.yaml Outdated
… with an llm judge

Three regex rounds could not settle two semantic judgments: whether the
reply says the re-review CRITICAL is not the first call's finding, and
whether the run itself plans another fix brief or review (steps for a
person do not count). not-a-repeat, no-further-round and no-third-round
are now llm graders with explicit pass and fail criteria; the
blocking-human-decision and phase-not-done regexes stay. Graders move to
graders/*.md, and the samples hold the reviewer's phrasings as judge
calibration answers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton
kyle-sexton added this pull request to the merge queue Oct 19, 2026
Merged via the queue into main with commit 1b789a0 Oct 19, 2026
31 checks passed
@kyle-sexton
kyle-sexton deleted the feat/8331-phase-boundary-review-dispatch branch October 19, 2026 06:03
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.

feat(implementation): dispatch phase Review: tags to /review:quality-gate at phase boundaries

1 participant