From 8d4f6da64c06c2a2c4de86f9ac733e3de4a751f6 Mon Sep 17 00:00:00 2001 From: dan-claude-bot Date: Mon, 20 Jul 2026 09:56:47 +0000 Subject: [PATCH] test: pin the at-risk gate's floor at one operator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `if [ "$AT_RISK" -gt 0 ]` could be mutated to `-gt 1` and the whole suite stayed green — a users file that revokes the last remaining operator would have proceeded without asking, which is the single-operator box the gate exists for. Neither neighbouring pin bit: the condition grep pins the gate's trigger (zero users AND a readable ledger), and the deferred-threshold negative only matches a comparison against a $-variable, so a literal floor slipped past both. Pinned as a pattern rather than the literal line, so `${AT_RISK}` or extra spacing does not fail a correct gate while any other floor does; `-ge 1` is accepted as the same statement spelled differently. Closes #78 Co-Authored-By: Claude Opus 4.8 --- test/cli.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/cli.sh b/test/cli.sh index fe12cd5..a556050 100644 --- a/test/cli.sh +++ b/test/cli.sh @@ -1127,6 +1127,24 @@ count_at="$(grep -nF 'AT_RISK=$((AT_RISK + 1))' "$ROOT/commands/users-apply.sh" warn_at="$(grep -nF 'this users file names ZERO users' "$ROOT/commands/users-apply.sh" | head -n1 | cut -d: -f1)" check "users apply: the count is taken before the message quotes it" \ 0 "" test "${count_at:-999999}" -lt "${warn_at:-0}" +# ...and the floor the count is measured against: ONE at-risk operator is +# enough. That is the gate's entire reason for existing — a box with a single +# operator is the common case for a small team, not an edge case — and nothing +# else here pins it. The condition grep above pins the gate's TRIGGER (zero +# users AND a readable ledger), and the deferred-threshold negative below only +# matches a comparison against a $-variable, so `-gt 1` slips past both and +# silently un-gates exactly the box that most needs the question (#78). +# +# Pinned as a PATTERN, not as the literal line: a correct gate respelled +# `${AT_RISK}` or re-spaced is still a correct gate and must not fail, while +# any floor other than "one is enough" must. `-ge 1` is the same statement in +# other words and is accepted for that reason — which is also why the negative +# pin below is left matching $-variables only, rather than being widened to +# literals: widening it would call that legitimate spelling a threshold. +# shellcheck disable=SC2016 +check "users apply: one at-risk operator is enough to gate (#78)" 0 "" \ + grep -qE '^[[:space:]]*if[[:space:]]+\[[[:space:]]+"?\$\{?AT_RISK\}?"?[[:space:]]+(-gt[[:space:]]+0|-ge[[:space:]]+1)[[:space:]]+\][[:space:]]*;[[:space:]]*then[[:space:]]*$' \ + "$ROOT/commands/users-apply.sh" # No terminal and no consent is a REFUSAL, not an assumed yes and not a hang. check "users apply: no TTY and no consent exits 2" 0 "" \ grep -qF 'refusing to revoke every managed operator without --yes' \