Skip to content

fix(caller-drift): the exempt probe read one protection system, not both (backend#1681) - #222

Merged
LukasWodka merged 1 commit into
developfrom
fix/1681-exempt-probe-reads-rulesets
Aug 11, 2026
Merged

fix(caller-drift): the exempt probe read one protection system, not both (backend#1681)#222
LukasWodka merged 1 commit into
developfrom
fix/1681-exempt-probe-reads-rulesets

Conversation

@LukasWodka

@LukasWodkaLukasWodka commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

The hole

evaluate_protection's exempt-staleness check was:

ifprobe.classic_present:

A branch protected solely by a ruleset returns 404 from the classic endpoint, so it read as unprotected — and its exemption stayed silently valid. The guard would never notice that a role it believes is out of scope is in fact a real, protected branch.

That is exactly the two-systems defect the 20-line header of read_protection() exists to prevent, sitting in the one place that decides whether an exemption is still true. probe.rulesets is populated by the very same call; it was just never consulted.

Why it survived

The selftest coverage stopped one path short. _ruleset_only already existed — and was only ever pointed at the required path, never at exempt. It now covers both.

The finding also names which layer covers the branch, so a reader isn't sent to re-derive the ruleset story by hand.

Test plan / evidence

checkresult
selftest111 → 117 pass, 0 fail
mutation — restore the old classic_present-only conditionthe new case FAILS (findings=[])
live run, all 20 repos"No drift. Every repo read, every entry matched."

The mutation row is the point: it proves the new test covers the hole rather than passing either way. The live row means closing this costs nothing today — no exemption was actually hiding behind it — and it catches the next one.

Found by the round-2 pipeline audit, backend#1681. Parent epic: backend#1680.


Note

Low Risk
Narrows a guard false negative in offline-tested drift logic; no auth or runtime API behavior beyond more accurate staleness detection.

Overview
Fixes a fail-open in evaluate_protection when inventory marks a branch role as exempt: staleness used to fire only on probe.classic_present, so a branch protected only by a ruleset (classic 404) looked unprotected and the exemption stayed valid.

The exempt probe now treats classic_present or probe.rulesets as protected, and findings say whether coverage is classic protection or a named ruleset. A selftest reuses the existing _ruleset_only stub on the exempt path so ruleset-only protection must report a stale exemption.

Reviewed by Cursor Bugbot for commit 8ca024f. Bugbot is set up for automated code reviews on this repo. Configure here.

…oth (backend#1681)
`evaluate_protection`'s exempt-staleness check was `if probe.classic_present:`.
A branch protected SOLELY by a ruleset returns 404 from the classic endpoint, so
it read as unprotected and its exemption stayed silently valid -- the guard would
never notice that a role it believes is out of scope is in fact a real, protected
branch.
That is the two-systems defect the 20-line header of read_protection() exists to
prevent, sitting in the one place that decides whether an exemption is still
true. `probe.rulesets` is populated by the very same call; it was simply never
consulted. The finding now also names WHICH layer covers the branch, so the
reader is not sent to re-derive it.
The gap survived because the coverage stopped one path short: `_ruleset_only`
already existed in the selftest and was only ever pointed at the `required` path,
never at `exempt`. It is now used for both.
Verified:
* selftest 111 -> 117 pass, 0 fail
* MUTATION: restoring the old `classic_present`-only condition makes the new
case FAIL (findings=[]), so the test genuinely covers the hole rather than
passing either way
* LIVE against all 20 repos: "No drift. Every repo read, every entry matched."
-- no exemption was actually hiding behind this, so closing it costs nothing
today and catches the next one.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@LukasWodkaLukasWodka self-assigned this Aug 11, 2026
@LukasWodka
LukasWodka merged commit fb04691 into developAug 11, 2026
13 checks passed
@LukasWodka
LukasWodka deleted the fix/1681-exempt-probe-reads-rulesets branch August 14, 2026 13:53
Sign up for freeto 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

@LukasWodka