defaults guard: a SHIP review receipt on the head passes; a new setting that defaults off is free
Leo's rule change of 2026-10-21 for the defaults guard: a default change no longer waits for a teammate's approving review.
What changes in scripts/ci/defaults_guard.py
- A setting this PR adds whose default is off (false, null,
off,never,none,disabledor empty) keeps what everyone had before the setting existed, so it passes on its own. It still shows in the list and the sticky comment. - Any other default change passes with an independent review receipt on the head. That is a PR comment or review whose first line is
Review (<reviewer>): SHIP at <full head sha>. It must come from an OWNER, MEMBER or COLLABORATOR user (not a bot) and must not be a self-review. The newest verdict that names the head decides, so a later BLOCK beats an earlier SHIP. A push needs a new receipt. The grammar matchesRECEIPTinscripts/ci/risk_tier.py(#23730); this PR carries its own small copy. - An approving review of the head from a call owner other than the author still passes too.
- The GraphQL query now also reads each comment's and review's author type, association, time and body.
- The check's error is now "Default changes need a review", and it gives the receipt line to post. The sticky comment says the same.
Docs: the workflow header, the owners-file description, the base-autofix comment and docs/ci/cmux-next-tiers.md.
Re-running the check: a receipt posted as a review re-runs the guard through cmux-next-defaults-guard-review.yml. A receipt posted as a plain comment does not re-run it; re-run the check yourself, or the next push does. No workflow logic changed.
Tests (tests/test_defaults_guard.py, 47 tests, all pass locally):
- Receipts: in a comment and in a review body; a wrong commit or a short sha; a later BLOCK; a self-review, an outsider and a bot; a receipt that is not on the first line.
- New-setting exemption: off values pass, on values (
true,ask,every-merge) need a receipt, an existing setting and a new flag are not exempt, and a mixed PR still needs a receipt.
This PR edits the guard's own files, so the guard lists it as a default change. The guard runs from the base, so this PR is judged by the old rule: a call owner's approval.
Agent session: cosmic-gray
🤖 Generated with Claude Code
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Updates the defaults guard so a default change no longer needs a teammate's approving review: an independent SHIP receipt on the head commit passes, and a new setting that defaults to off passes on its own (Leo 2026-10-21).
- A comment or review whose first line is
Review (<reviewer>): SHIP at <full head sha>from an OWNER, MEMBER, or COLLABORATOR user (not a bot, not a self-review) passes; the newest verdict naming the head wins, so a later BLOCK beats an earlier SHIP, and a push needs a new receipt. - A setting the PR adds whose default is off (
false,null,off,never,none,disabled, or empty) keeps everyone's prior behavior and passes without a receipt, though it stays listed. - Approving reviews from call owners other than the author still pass; the error and sticky comment now say "Needs a review" and post the receipt line to use.
- The GraphQL query now reads each comment's and review's author type, association, timestamp, and body; a receipt in a review body re-runs the guard, a receipt in a plain comment does not (re-run the check or wait for the next push).
- Updates the workflow header, owners-file description, base-autofix comment, and
docs/ci/cmux-next-tiers.md, with 47 tests covering receipts and the off-default exemption; the guard runs from the base, so this PR is judged by the old rule.