Commita67dd0f8Recorded2 Sep 2026Repositorysigil-system

Gate: the landing check was asking the inverted question

Message

sigil: is a MINIMUM with no upper bound, so any runtime at or above it is permitted. To GUARANTEE (sigil grant) is present, the floor must be at least the release that introduced it.

The check asked the opposite: "does the floor permit some release that has it". That answers YES for a floor of 0.20, which permits sigil 0.20.3, which has no grant.sgl at all. A false green in the dangerous direction, and a control caught it: four cases, two of which had to answer no, and 0.20 was one of them.

An earlier version was wrong in the safe direction too, comparing floor to tag by STRING EQUALITY and calling "0.21" not a match for v0.21.0. That failed closed and would only have sent someone to edit a manifest already correct. Both are the same root: comparing text where versions were meant. The floor is now normalised to three components before comparison, because "0.21" and "0.21.0" are the same version and a text sort disagrees.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DYn8wxSdjveEgK9NRxFcNA

Changed
 scripts/gate-system-grant-migration | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)
Diff
scripts/gate-system-grant-migrationmodified
@@ -346,7 +346,34 @@ if [ -d "$MONO/.git" ]; then
346
# Does the declared floor actually name one of those releases? The
347
# question is not "has it shipped" but "does THIS manifest resolve
348
# it", and those came apart for most of this branch's life.
−349
if echo "$TAGS" | sed 's/^v//' | grep -qxF "$FLOOR"; then
+349
# THE `sigil:` FIELD IS A MINIMUM WITH NO UPPER BOUND, not an exact
+350
# pin: e530e14 established that a caret is a range while a bare
+351
# version here is a floor. An earlier version of this check
+352
# compared floor to tag by STRING EQUALITY and reported "0.21" as
+353
# not naming v0.21.0, which is false, since 0.21 means >= 0.21.0.
+354
# It failed CLOSED, so it never licensed a bad merge; it would
+355
# simply have sent someone to edit a manifest already correct.
+356
# AND THE COMPARISON RUNS THE OTHER WAY. `sigil:` is a MINIMUM, so
+357
# any runtime at or above it is permitted. To GUARANTEE the module
+358
# is present, the floor must be at least the release that
+359
# introduced it. Asking "does the floor permit some release that
+360
# has it" is the inverted question and answers YES for a floor of
+361
# 0.20, which permits 0.20.3, which has no grant.sgl. That is a
+362
# false green in the dangerous direction and a control caught it.
+363
#
+364
# Normalise the floor to three components first: "0.21" and
+365
# "0.21.0" are the same version, and a text sort disagrees.
+366
EARLIEST="$(echo "$TAGS" | sed 's/^v//' | sort -V | head -1)"
+367
NFLOOR="$FLOOR"
+368
case "$NFLOOR" in
+369
*.*.*) ;;
+370
*.*) NFLOOR="$NFLOOR.0" ;;
+371
*) NFLOOR="$NFLOOR.0.0" ;;
+372
esac
+373
SATISFIED=no
+374
[ "$(printf '%s\n%s\n' "$NFLOOR" "$EARLIEST" | sort -V | head -1)" = "$EARLIEST" ] && SATISFIED=yes
+375
say " earliest release with it: $EARLIEST; declared floor normalises to $NFLOOR"
+376
if [ "$SATISFIED" = yes ]; then
377
say " => LANDABLE. The declared floor names a release containing (sigil grant)."
378
else
379
say " => NOT LANDABLE YET. The floor \"$FLOOR\" does not name a release that"