Skip to content

fix(policy): exempt the release-trigger gate, whose mutation cannot be driven - #949

Merged
wenzowski merged 1 commit into
mainfrom
claude/cloud-1777-mutation-exempt
Sep 12, 2026
Merged

fix(policy): exempt the release-trigger gate, whose mutation cannot be driven#949
wenzowski merged 1 commit into
mainfrom
claude/cloud-1777-mutation-exempt

Conversation

@wenzowski

@wenzowski wenzowski commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

DO-NOT-CLOSE — this completes no row on its own. CLOUD-1777's work landed in #939, which closed it; this is a correction to what that PR landed, and CLOUD-843 is named only as the reason a route was unavailable.

A follow-up to #939, which is merged — a merged pull request cannot track new work.

What landed wrong

#939 added policy/release-trigger-independent.rego with a #MUTANT row and a matching entry in MUTANT_GATES. mutate census accepts that pairing, so it passed the landing-path gate. The mutation can never run.

Measured with the runner rather than reasoned about:

release-trigger-independent no-suite (tests/release-trigger-independent.bats)
::error:: mutate sweep: 175 declared mutation(s) could not be looked at —
          an unresolvable gate or suite is not a pass

mutate resolves a gate's suite as tests/$gate.bats, and shell add refused forbids adding one (CLOUD-843 replaces shell gates rather than growing them). no-suite is could-not-look, not a pass — so the registration was a coverage claim with nothing behind it, in the file whose own subject is a gate that decides nothing.

That is the same defect the admission on the original commit said it was avoiding, one level up. I declared the #MUTANT row, ran the sweep, and the sweep refuted it.

The fix

policy/connector-not-granted.rego already carries a #MUTANT-EXEMPT for exactly this situation with exactly this reason. This follows that precedent, and records that the #MUTANT row was tried first so the next reader does not re-derive it.

What still covers the module is unchanged and named in the exemption:

  • Load-time tier — the module's own six test_ rules: committed shape clean, a trunk push clean, a clock alone refused, the release event alone refused, a non-watching workflow untouched, no workflow answers nothing.
  • Engine tierbatten-check over this repository's committed workflow, exit 0. This is the tier a with input as case cannot reach, because it fabricates the very shape the engine may be unable to produce (here: whether on: survives as a string key rather than YAML 1.1's boolean true).

Verification

  • mise run mutant-census: 140 gates, every one enforced or exempt by a filed row

Not claimed

The 175 could-not-look mutations are a tree-wide property, not this module's: every rego and engine gate in the censused set reports names-no-case or no-suite under mutate sweep, which is why the sweep is off the landing path while the census is on it. Whether that gap is worth closing is its own row, not a question this diff answers.


https://claude.ai/code/session_01Ef4sxymkMdNUktBXVg19LZ

…e driven

The gate landed one commit ago carrying a `#MUTANT` row and a `MUTANT_GATES`
registration. `mutate census` accepts that pairing, so it passed the
landing-path gate — but the mutation can never run. Measured with the runner
rather than reasoned about: `mutate sweep` answers

    release-trigger-independent no-suite (tests/release-trigger-independent.bats)

because `mutate` resolves a gate's suite as `tests/$gate.bats`, and
`shell add refused` forbids adding one. `no-suite` is could-not-look, which is
not a pass — so the registration was a coverage claim with nothing behind it,
in the file whose own subject is a gate that decides nothing.

`policy/connector-not-granted.rego` already carries a `#MUTANT-EXEMPT` for
exactly this, with exactly this reason. This follows that precedent and states
that the `#MUTANT` row was tried first and the sweep is what refuted it, so the
next reader does not re-derive it.

What still covers the module is unchanged and is named in the exemption: its
own six `test_` rules at load time, and `batten-check` over this repository's
committed workflow at the engine tier — the tier a `with input as` case cannot
reach, since it fabricates the shape the engine may be unable to produce.

A follow-up rather than an amendment: CLOUD-1777's pull request is merged, and a
merged pull request cannot track new work.

Refs: CLOUD-1777

Admits: 749595d72b9f52ef1ce9d770ef625112b205a18865c4d4b7cf044dd913c68e31
Admits-rule: protected-mutation
Admits-verdict: path write refused
Admits-subject: policy/release-trigger-independent.rego
Admits-anchor: call:2a42e1b1509fc186f70fe0806c270430995cd45e
Admits-epoch: b5139db4812867d3865de4093819111ebd4fbe4d7786a6f54184bf695b56867f
Admits-author: alec@wenzowski.com
Admits-prev: c450f58d96bcde8dfe52c77e55e4b17187c8510844b9cdc8b99277ffc7e8f87f
Admits-answer-lost: A coverage claim with nothing behind it, in the file whose own subject is a gate that decides nothing. `mutate census` is satisfied by the declaration alone, so the module would pass the landing-path gate while its declared mutation is unrunnable — which is the surviving-mutant shape non-negotiable rule 2 exists to refuse, and precisely the defect my previous admission on this same file said it was avoiding. Measured: 175 declared mutations report could-not-look, and mine is one of them.
Admits-answer-precondition: No surface can express this change: the declaration lives in the module `mutate` reads it from. `mutate sweep` answers `release-trigger-independent no-suite (tests/release-trigger-independent.bats)` — it resolves a gate's suite as `tests/$gate.bats`, and `shell add refused` forbids adding one, so the `#MUTANT` row I declared names a mutation that can never be driven. `policy/connector-not-granted.rego` carries a `#MUTANT-EXEMPT` for exactly this, and the correction is to follow that precedent rather than keep a row the runner reports as could-not-look.
Admits-answer-rejected-route: `config read first` does not apply: the subject is a policy module, and `batten.toml` spells no module's mutation marker. `patch run first` does not apply: `git restore` would discard a file created in this diff rather than correct one declaration in it. Adding `tests/release-trigger-independent.bats` is the route the runner's own message implies and it is refused by `shell add refused`, with no override declared.
@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 0e14282c-e22b-456d-861f-d25b15226dc9

📥 Commits

Reviewing files that changed from the base of the PR and between 2a42e1b and 8b61926.

📒 Files selected for processing (2)
  • mise.toml
  • policy/release-trigger-independent.rego

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The change removes release-trigger-independent from MUTANT_GATES in mise.toml. It replaces the policy’s #MUTANT comment with a #MUTANT-EXEMPT CLOUD-1260 comment. The comment documents that no dedicated Bats suite exists or may be added because the mutation runner resolves suites by gate name and reports no-suite.

Priority: ⬇️ Low

Merge Risk: ⚪ Minimal · up to 8b619

This change only exempts an unrunnable mutation gate while retaining the existing load-time and engine-tier coverage, so no merge-blocking risk remains.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: exempting the release-trigger gate because its mutation cannot be driven.
Description check ✅ Passed The description directly explains the incorrect mutation declaration, the no-suite result, the exemption-based fix, and the verification results.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/cloud-1777-mutation-exempt

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@wenzowski
wenzowski marked this pull request as ready for review September 11, 2026 23:57
@wenzowski

Copy link
Copy Markdown
Contributor Author

/fast-forward

@wenzowski
wenzowski merged commit 8b61926 into main Sep 12, 2026
21 checks passed
@wenzowski
wenzowski deleted the claude/cloud-1777-mutation-exempt branch September 12, 2026 00:08
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.

1 participant