Gate: declare the intended divergence, and control the classifier
The migration intends ONE decision change: the old engine granted the empty command, because exec:allowlist:git, split to ("git" "") and the "" entry became a permission. Nothing could match it (argv[0] is never ""), so it was unreachable authority and the migration drops it.
Byte-identity would have forced either a failing gate or a corpus with the interesting case quietly removed, and the second is how a differential comes to agree for the wrong reason. So the divergence is declared BY SHAPE, checked FOR DIRECTION, and counted: every difference must be baseline #t becoming migrated #f. A widening of the same shape still reds.
THE CLASSIFIER IS NOW THE INSTRUMENT, not diff, so it gets its own control. A classifier whose patterns were too broad would wave everything through and the gate would report agreement over a transcript full of changes. The gate now plants an UNDECLARED divergence and requires it to be rejected, alongside the existing control that diff can see a difference at all. When a check is repaired by adding a step, the new step is an instrument too.
Also fixes a bug in this gate's own shell: grep -c PRINTS the count and EXITS 1 when the count is zero, so || echo 0 appended a second zero and the integer test received "0n0". It reported a widening that did not exist. || true keeps the printed count and swallows only the status.
And the landing status now asks the question that actually matters: not "has (sigil grant) shipped" but "does THIS manifest resolve it". Those came apart for most of this branch's life.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DYn8wxSdjveEgK9NRxFcNA
scripts/gate-system-grant-migration | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 67 insertions(+), 8 deletions(-)scripts/gate-system-grant-migrationmodified
if [ -s "$SCRATCH/migrated.txt" ] || [ -s "$SCRATCH/baseline.txt" ]; then say "" say "--- instrument state at exit ---" say " baseline decision lines: $(grep -c '^CHK|' "$SCRATCH/baseline.txt" 2>/dev/null || echo 0)" say " migrated decision lines: $(grep -c '^CHK|' "$SCRATCH/migrated.txt" 2>/dev/null || echo 0)" say " baseline decision lines: $(grep -c '^CHK|' "$SCRATCH/baseline.txt" 2>/dev/null || true)" say " migrated decision lines: $(grep -c '^CHK|' "$SCRATCH/migrated.txt" 2>/dev/null || true)" say "--- end ---" fi}[ "$BASE_N" -gt 0 ] || red "the baseline probe produced ZERO decisions; the differential compared nothing"[ "$MIG_N" -eq "$BASE_N" ] || red "the two probes produced different numbers of decisions ($MIG_N vs $BASE_N)"if ! diff -u "$SCRATCH/baseline.txt" "$SCRATCH/migrated.txt" > "$SCRATCH/diff.txt" 2>&1; then say "--- divergence (baseline vs migrated) ---"# A migration may INTEND to change a decision. Byte-identity would then# force either a failing gate or a corpus with the interesting case# quietly removed, and the second is how a differential comes to agree# for the wrong reason. So intended divergences are declared BY SHAPE,# checked FOR DIRECTION, and counted.## The one declared here: the old engine granted the EMPTY command.# `exec:allowlist:git,` split to ("git" "") and the "" entry became a# permission. Nothing could ever match it (argv[0] is never ""), so it# was unreachable authority, and the migration drops it. Every such# difference must be a NARROWING, baseline #t becoming migrated #f.# A widening of the same shape is a defect and still reds.diff -u "$SCRATCH/baseline.txt" "$SCRATCH/migrated.txt" > "$SCRATCH/diff.txt" 2>&1grep -E '^[-+]CHK\|' "$SCRATCH/diff.txt" > "$SCRATCH/diffchk.txt" 2>/dev/null || true# Anything differing that is NOT the declared shape.UNEXPECTED_DIFF="$(grep -E '^[-+]CHK\|' "$SCRATCH/diff.txt" 2>/dev/null \ | grep -vE '^-CHK\|[^|]*\|exec\|""\|#t$' \ | grep -vE '^\+CHK\|[^|]*\|exec\|""\|#f$' || true)"if [ -n "$UNEXPECTED_DIFF" ]; then say "--- UNDECLARED divergence (baseline vs migrated) ---" echo "$UNEXPECTED_DIFF" | head -40 say "--- full diff head ---" head -40 "$SCRATCH/diff.txt" red "the migrated engine DISAGREES with the pre-migration engine" red "the migrated engine DISAGREES with the pre-migration engine outside the declared narrowing"fisay " transcripts identical: $MIG_N decisions agree, 0 disagree"# A differential that agrees is meaningful only if it COULD disagree.NARROWED="$(grep -cE '^\+CHK\|[^|]*\|exec\|""\|#f$' "$SCRATCH/diff.txt" 2>/dev/null || true)"NARROWED="${NARROWED:-0}"WIDENED="$(grep -cE '^\+CHK\|[^|]*\|exec\|""\|#t$' "$SCRATCH/diff.txt" 2>/dev/null || true)"WIDENED="${WIDENED:-0}"[ "$WIDENED" -eq 0 ] || red "a declared-shape divergence WIDENED authority ($WIDENED lines). The allowance covers narrowing only."AGREED=$((MIG_N - NARROWED))say " decisions agreeing: $AGREED of $MIG_N"say " declared narrowings (exec \"\" was granted, now denied): $NARROWED, widenings: 0"# A differential that agrees is meaningful only if it COULD disagree, and# the thing that decides now is the CLASSIFIER above, not `diff`. When a# check is repaired by adding a step, the new step is an instrument too# and arrives with the same defect rate and none of the scrutiny. So both# get a control.## Control 1: `diff` itself can see a difference at all.CTL="$SCRATCH/control.txt"sed 's/^CHK|pty|/CHK|PLANTED|/' "$SCRATCH/migrated.txt" > "$CTL"if diff -q "$SCRATCH/baseline.txt" "$CTL" >/dev/null 2>&1; thenfisay " comparison positive control: an altered transcript IS detected"# Control 2, and this is the one that matters now: an UNDECLARED# divergence must be REJECTED by the classifier. Without this, a# classifier whose patterns were too broad would wave everything through# and the gate would report agreement over a transcript full of changes.CTL2="$SCRATCH/control-undeclared.txt"sed '0,/^CHK|[^|]*|fs-read|/s//CHK|PLANTED-UNDECLARED|fs-read|/' "$SCRATCH/migrated.txt" > "$CTL2"if [ "$(diff -u "$SCRATCH/baseline.txt" "$CTL2" 2>/dev/null | grep -cE '^[-+]CHK\|')" -eq 0 ]; then setup_failed "the undeclared-divergence control did not land: the planted line produced no diff"fiCTL2_LEAK="$(diff -u "$SCRATCH/baseline.txt" "$CTL2" 2>/dev/null | grep -E '^[-+]CHK\|' \ | grep -vE '^-CHK\|[^|]*\|exec\|""\|#t$' \ | grep -vE '^\+CHK\|[^|]*\|exec\|""\|#f$' || true)"[ -n "$CTL2_LEAK" ] || red \ "the classifier is TOO BROAD: a deliberately planted UNDECLARED divergence was accepted as declared. Every difference would pass."say " classifier positive control: an undeclared divergence IS rejected"say "STEP 4/5 existing test-system suite"timeout "$TIMEOUT_S" "$SIGIL" test --redirects "$REDIRECTS" > "$SCRATCH/suite.log" 2>&1SRC=$? TAGS="$(git -C "$MONO" tag --contains "$GRANT_COMMIT" 2>/dev/null | head -3)" if [ -n "$TAGS" ]; then say " (sigil grant) is RELEASED in: $(echo "$TAGS" | tr '\n' ' ')" say " ACTION: set the floor to the release above, then this branch is landable." # Does the declared floor actually name one of those releases? The # question is not "has it shipped" but "does THIS manifest resolve # it", and those came apart for most of this branch's life. if echo "$TAGS" | sed 's/^v//' | grep -qxF "$FLOOR"; then say " => LANDABLE. The declared floor names a release containing (sigil grant)." else say " => NOT LANDABLE YET. The floor \"$FLOOR\" does not name a release that" say " contains (sigil grant). Set it to one of the releases above." fi else say " (sigil grant) landed in monorepo $(git -C "$MONO" rev-parse --short "$GRANT_COMMIT") and is in NO TAG." say " => NOT LANDABLE YET. Consumers resolve caret ranges against TAGS, so"