feat(hook): opt-in review gate wiring for hook stop (Y-18 Slice 3)#148
Merged
Conversation
Wire the review-gate verdict (computed in Slice 2, #147) into the `basou hook stop` CLI as an opt-in tier. Slices 1 (review record verb, #146) and 2 (review-gate detection, #147) already merged. - `hook stop --require-review`: off by default. When set, a session that shipped substantive code (git push / merge / gh pr create|merge) without recording a review composes a review reminder into the SAME Stop envelope as the capture reminder. A Stop hook emits one response, so --block is a single switch governing the whole envelope's blocking-ness; advisory by default. Without --require-review the review verdict is ignored entirely, so the capture-only output stays byte-identical. - core buildStopHookCommand gains requireReview (--require-review, ordered after --block, before --min-edits; existing commands round-trip unchanged). - hook install --require-review registers that form; hook status reports the active gates (capture vs capture + review) via describeHookMode. The capture and review tiers are independent: a captured-but-unreviewed shipped session still emits the review reminder on its own. Advisory-first staging is intentional; blocking requires --block on top. Adversarial review (codex, review-only): clean on byte-identity, envelope composition, loop guard, flag ordering, and install/status; the two test-gap findings it raised (review-only emission path; capture+review -> capture downgrade) are both covered here. Nothing was blocked. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
takashi-matsuyama
added a commit
that referenced
this pull request
Jun 30, 2026
Bump packages/{basou,core,cli,sdk} to 0.30.0 and finalize the CHANGELOG
section. Bundles two already-merged themes:
- Codex adapter (#149/#150): the Codex context channel (basou refresh
renders orientation into ~/.codex/AGENTS.md) and the basou run codex
launcher (pre-spawn re-render + shell_environment_policy.inherit=all +
codex-adapter source kind).
- Y-18 review enforcement (#146/#147/#148): basou review record, the
review-gate verdict in evaluateStopHook, and the opt-in
hook stop --require-review gate.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Slice 3 (final) of basou review enforcement ([Y-18]): the CLI wiring that renders the review-gate verdict computed in Slice 2. Slices 1 (
review recordverb +review_recordedevent, #146) and 2 (review-gate detection inevaluateStopHook, #147) already merged.This makes the gate user-facing for the first time — as an opt-in, advisory-first tier.
Behavior
basou hook stop --require-review— off by default. When set, a session that shipped substantive code (git push/git merge/gh pr create|mergeafter enough file edits) without recording a review (basou review record) gets a reminder, composed into the same Stop envelope as the capture reminder.--blockis a single switch governing the whole envelope's blocking-ness (advisory by default;--blockmakes itdecision:block).--require-reviewthe review verdict is ignored entirely, so capture-only output is unchanged from main.buildStopHookCommandgainsrequireReview(--require-review, ordered after--block, before--min-edits; existing registered commands round-trip unchanged).hook install --require-reviewregisters that form;hook statusreports active gates (capturevscapture + review) via a newdescribeHookMode.Scope / staging
Advisory-first is intentional (the Y-18 staged release: verb → detection → enforcement).
--require-reviewdefaults to advisory; blocking requires--blockon top. Detection patterns landed in Slice 2 and are unchanged here.Adversarial review (codex, review-only, FIXED CONSTRAINTS injected)
Clean on all design/correctness dimensions: byte-identity (verified the
parts[]composition reduces to the old capture-only path when the flag is absent), envelope composition (capture-only / review-only / both), loop guard, flag ordering / byte-stability, and install/uninstall/status. Nothing blocked. It raised 2 test-gap findings (no production change) — the review-only emission path (MEDIUM) and the capture+review → capture downgrade (LOW) — both are covered by tests added in this PR.Verification
--require-review(composed) /--require-review --block(decision:block) /install --require-review+status(reportscapture + review) / downgrade — all OK🤖 Generated with Claude Code