A surviving mutant un-gates the single-operator box: AT_RISK -gt 0 is not pinned #78
Labels
No labels
attention
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-ruling
needs-triage
offsite
post-merge
ready
release
scope:bootstrap
scope:coolify
scope:db
scope:docs
scope:drill
scope:installer
scope:labels
scope:platform
scope:runner
scope:users
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/rig#78
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Non-blocking finding from
claude-bot-andresmgsl's review of #73, filed so it does not rot in a PR thread.The surviving mutant
Changing the gate condition in
commands/users-apply.sh:passes all 419 tests.
That mutation silently un-gates the single-operator box — a users file that revokes the last remaining operator would proceed without confirmation. For small teams that is not an edge case, it is the common one, and it is the most consequential instance of exactly what #65 is about.
Why the existing pins miss it
Two pins cover the neighbourhood and neither bites here:
${#USERS[@]} -eq 0 && -r $LEDGER), not the at-risk comparison.-gt/-geagainst a$-variable, so a literal1slips through.So the tests pin that the gate exists and that no threshold was introduced, but not where the gate's floor sits.
Suggested pin
One line, in the house grep-pin style:
Why filed rather than fixed in #73
#73 had three head-current approvals and the code is correct — this pins against future regression rather than fixing a live defect. The reviewing bot's framing was "fine as a follow-up; it does not block a correct implementation."
Worth doing soon, though: it is one line, and the thing it protects is the gate's entire reason for existing.
Refs
#73 (where it was found), #65 (the parent issue; its N-of-M threshold remains deliberately deferred)