diff --git a/history/fp-driver-d2-99df52c3.sh b/fp-driver-d2.sh index 487c9d1e..684a0536 100644 --- a/history/fp-driver-d2-99df52c3.sh +++ b/fp-driver-d2.sh @@ -135,6 +135,10 @@ H="$SP/fp-home-d2" # isolated SPT_HOME, THIS experiment only. D2 # nothing here reads, writes or removes r10's home. EXE="$W/target/release/spt.exe" # THE EXECUTABLE r10 ALREADY BUILT. Nothing here builds. EXE_SHA='72d309011415b419aabfdb0b4065df1183bfd0069a9f95b5779da62e43349b10' +# THE CAPTURE SCRIPT IS A SUBJECT TOO (doyle LIRX7EUS). The elevated leg runs BOTH the product +# and this script, and every document this run reasons about is whatever THIS file produced. +# An acknowledgment that measures only the executable proves the leg can see one of the two. +CAPTURE_SHA='a0e7afbee4dce9f310ade9704c199b3b759715c06da7e033d286beb7cfda8c06' PORT=29470 # never 5470 GUARD_PORT=5470 # the production port this run must not disturb SUBJECT_SHA='85f84d738fa702f35c83910f314aae17849d125c' @@ -678,7 +682,12 @@ removal_check() { # TAG -> sets REMOVAL_CHECK record "REMOVAL_CHECK=UNREADABLE_PROBE_UNPINNED measured=$psha pinned=$RULE_PROBE_SHA256 - evidence from an unpinned instrument is not evidence." return fi - pwsh -NoProfile -File "$RULE_PROBE" -Names "$RULE_TAILNET","$RULE_LAN" -ControlName "$CONTROL_RULE" > "$out" 2>&1 + # ONE DELIMITED TOKEN, AND THE PROBE IS TOLD HOW MANY TO EXPECT. Measured 2026-09-13: + # powershell.exe -File collapses `-Names "a","b"` into the single string "a,b", and + # `-Names "a" "b"` binds "b" to the NEXT parameter instead. Both forms silently delivered ONE + # name. The probe now parses the token itself and REFUSES (exit 7) when the parsed count is + # not the expected one, so a binding regression is a refusal rather than a smaller sample. + pwsh -NoProfile -File "$RULE_PROBE" -NamesCsv "$RULE_TAILNET,$RULE_LAN" -ExpectNames 2 -ControlName "$CONTROL_RULE" > "$out" 2>&1 rc=$? exits "rule_probe_${tag}_EXIT=$rc" if [ "$rc" -ne 0 ]; then @@ -720,12 +729,12 @@ removal_check() { # TAG -> sets REMOVAL_CHECK fi if [ "$persist_present" -eq 0 ] && [ "$active_present" -gt 0 ]; then REMOVAL_CHECK=ACTIVESTORE_RESIDUE - record "REMOVAL_CHECK=ACTIVESTORE_RESIDUE active_present=$active_present - the persistent rule is gone and the LIVE one is not. The host is still admitting on it: PENDING/review, and nothing is retried." + record "REMOVAL_CHECK=ACTIVESTORE_RESIDUE active_present=$active_present - the persistent rule is gone and a rule of that name is still in the LIVE store. Whether anything is being admitted through it is NOT established here (this reads names, not effective admission): PENDING/review, and nothing is retried." return fi if [ "$absent" -gt 0 ]; then REMOVAL_CHECK=PARTIAL - record "REMOVAL_CHECK=PARTIAL absent=$absent present=$present - one owned name was removed and another was not. A half-removal is open admission, not a partial success: PENDING/review, and NO second dispatch is issued." + record "REMOVAL_CHECK=PARTIAL absent=$absent present=$present - one owned name is absent and another is present. Read with the pre-teardown state and the remover's exit, that is a half-removal; on its own it does not establish that THIS invocation removed anything. Either way it is not a success: PENDING/review, and NO second dispatch is issued." return fi REMOVAL_CHECK=FAILED @@ -1320,8 +1329,15 @@ cleanup() { pwsh -NoProfile -File "$BIN/census.ps1" -Tag cleanup-teardown-post -OutDir "$R" >> "$R/census.log" 2>&1 local c_rc=$? exits "census_cleanup_teardown_post_EXIT=$c_rc" - local verdict=0 absent=0 valid=0 - grep -q 'LAN_FIREWALL_CLEAN' "$HO_OUT" 2>/dev/null && verdict=1 + # THE REVIEWED REMOVER SUCCEEDS SILENTLY (doyle 2026-09-13). The previous conjunction + # required the product's LAN_FIREWALL_CLEAN line, which belonged to the `serve lan --stop` + # verb this integration replaced. The reviewed payload prints NOTHING on success -- it + # removes, re-reads both stores, and throws if anything remains -- so requiring that marker + # made a successful removal unverifiable and every clean run PENDING. Removed rather than + # manufactured: a marker this driver invents would prove only that the driver can write it. + # WHAT REMAINS REQUIRED is what can actually be measured: the remover's own native exit, a + # census that succeeded, and the independent per-name, per-store absence reading. + local absent=0 valid=0 grep -q 'tag=cleanup-teardown-post .* subj_group=0 subj_29470=0' "$R/census.log" && absent=1 grep -q 'tag=cleanup-teardown-post .* valid=YES' "$R/census.log" && valid=1 # INDEPENDENT POST-REMOVAL CHECK (doyle 2026-09-13). Everything above is either the @@ -1331,13 +1347,13 @@ cleanup() { # emptied PersistentStore while leaving ActiveStore residue, could pass both. This probe # addresses each owned name by InstanceID in EACH store and is the reading that decides. removal_check post-teardown - record "TEARDOWN_CHECK receipt_exit=$t_rc census_exit=$c_rc clean_verdict=$verdict named_rules_absent=$absent census_valid=$valid independent_removal=$REMOVAL_CHECK" - if [ "$t_rc" -eq 0 ] && [ "$c_rc" -eq 0 ] && [ "$verdict" -eq 1 ] && [ "$absent" -eq 1 ] && [ "$valid" -eq 1 ] && [ "$REMOVAL_CHECK" = CONFIRMED ]; then - record "TEARDOWN_VERIFIED — zero teardown exit AND a successful census AND the product's own LAN_FIREWALL_CLEAN verdict AND the owned named rules measured ABSENT by an INDEPENDENT per-name, per-store probe" + record "TEARDOWN_CHECK receipt_exit=$t_rc census_exit=$c_rc named_rules_absent=$absent census_valid=$valid independent_removal=$REMOVAL_CHECK (the remover succeeds SILENTLY; there is no success marker to require)" + if [ "$t_rc" -eq 0 ] && [ "$c_rc" -eq 0 ] && [ "$absent" -eq 1 ] && [ "$valid" -eq 1 ] && [ "$REMOVAL_CHECK" = CONFIRMED ]; then + record "TEARDOWN_VERIFIED — zero remover exit AND a successful census AND the owned named rules measured ABSENT by an INDEPENDENT per-name, per-store probe" CLEANUP_VERDICT=VERIFIED else CLEANUP_VERDICT=PENDING - cfail "TEARDOWN NOT VERIFIED (receipt_exit=$t_rc census_exit=$c_rc clean_verdict=$verdict absent=$absent census_valid=$valid independent_removal=$REMOVAL_CHECK). Owned rules MAY REMAIN; removal is PENDING/review and is NOT retried. The state marker is left set deliberately." + cfail "TEARDOWN NOT VERIFIED (receipt_exit=$t_rc census_exit=$c_rc absent=$absent census_valid=$valid independent_removal=$REMOVAL_CHECK). Owned rules MAY REMAIN; removal is PENDING/review and is NOT retried. The state marker is left set deliberately." fi else cfail "no verified teardown receipt; bootstrap-owned rules MAY REMAIN. State markers left in $ST deliberately." @@ -2017,8 +2033,8 @@ record "PRE_SETUP_ABSENCE measured: both owned names absent — [$PRE_SETUP_ABSE # into preparation, where a mismatch costs no experimental time. prep_check prepared-acknowledgment handoff_request prepare \ - "ACKNOWLEDGE ONLY -- RUN NOTHING. Confirm you are prepared to execute the setup leg and that you have started nothing yet, and report the sha256 of the pinned executable AS YOU MEASURE IT NOW." \ - "ACKNOWLEDGEMENT ONLY. Do not run the product. Reply in the receipt with the three tokens: PREPARED, NOT_STARTED, and executable_sha256=" + "ACKNOWLEDGE ONLY -- RUN NOTHING. Confirm you are prepared to execute the setup leg and that you have started nothing yet, and report the sha256 of BOTH subjects this leg would run, AS YOU MEASURE THEM NOW: the pinned executable and the capture script." \ + "ACKNOWLEDGEMENT ONLY. Do not run the product. Reply in the receipt with the four tokens: PREPARED, NOT_STARTED, executable_sha256=, and capture_sha256=" PREPARED_ACK="$HO_RECEIPT" # NOT `if ! handoff_await trial`: that exact line is the anchor of an assembly-time correction # applied to the RETAINED setup wait, and the assembler asserts it appears exactly once. Same @@ -2028,11 +2044,37 @@ ack_missing='' grep -q "PREPARED" "$PREPARED_ACK" 2>/dev/null || ack_missing="$ack_missing PREPARED" grep -q "NOT_STARTED" "$PREPARED_ACK" 2>/dev/null || ack_missing="$ack_missing NOT_STARTED" grep -q "executable_sha256=$EXE_SHA" "$PREPARED_ACK" 2>/dev/null || ack_missing="$ack_missing executable_sha256=$EXE_SHA" +# BOTH SUBJECTS, NOT ONE (doyle LIRX7EUS). The leg runs the product AND the capture script, and the +# documents this run reasons about are whatever the capture script produced. An acknowledgment that +# measured only the executable proved the leg could see half of what it is about to run. +grep -q "capture_sha256=$CAPTURE_SHA" "$PREPARED_ACK" 2>/dev/null || ack_missing="$ack_missing capture_sha256=$CAPTURE_SHA" if [ -n "$ack_missing" ]; then record "PREPARED_ACK_CONTENTS: [$(tr -d '\r' < "$PREPARED_ACK" 2>/dev/null | tr "\n" " ")]" die "the acknowledgment is missing:$ack_missing. An unverified acknowledgment opens no window -- a receipt that cannot state the subject it measured is not evidence that the executor is looking at this run." fi -record "PREPARED_ACK_VERIFIED - the executor reports PREPARED and NOT_STARTED and measured the pinned executable as $EXE_SHA" +record "PREPARED_ACK_VERIFIED - the executor reports PREPARED and NOT_STARTED and measured BOTH subjects: executable $EXE_SHA and capture script $CAPTURE_SHA" +record "PREPARED_IS_NOT_AUTHORIZATION - readiness says the leg CAN act; it does not say this run MAY. The window stays shut until a separate, run-bound GO authorization is verified below." + +# READINESS IS NOT AUTHORIZATION (doyle LIRX7EUS). The predecessor ran PREPARED and then called +# go() on the next line: verifying that the executor was READY opened the experimental window by +# itself, so a leg that answered a preparation question had, without being asked, started a 300s +# clock on the host. THE TWO ARE NOW SEPARATE ACTS. This second request asks for an AUTHORIZATION, +# it carries its own nonce, and the receipt must quote that nonce back -- so an authorization is +# bound to THIS run and THIS request and cannot be a stale or reused token from another. +prep_check go-authorization +handoff_request go-authorization \ + "AUTHORIZE ONLY -- RUN NOTHING. This is not a readiness question; you have already answered that. Authorize the experimental window to OPEN for this run, knowing the 300s activity clock starts when it does." \ + "AUTHORIZATION ONLY. Do not run the product. Reply in the receipt with BOTH tokens: GO_AUTHORIZED and the nonce of THIS request, quoted exactly." +GO_ACK="$HO_RECEIPT"; GO_ACK_NONCE="$HO_NONCE" +handoff_await trial || die "no GO authorization within the preparation budget. The experimental window is NEVER OPENED: readiness alone does not open it, nothing was dispatched, and there is nothing to tear down." +go_missing='' +grep -q "GO_AUTHORIZED" "$GO_ACK" 2>/dev/null || go_missing="$go_missing GO_AUTHORIZED" +grep -q "$GO_ACK_NONCE" "$GO_ACK" 2>/dev/null || go_missing="$go_missing nonce=$GO_ACK_NONCE" +if [ -n "$go_missing" ]; then + record "GO_ACK_CONTENTS: [$(tr -d '\r' < "$GO_ACK" 2>/dev/null | tr "\n" " ")]" + die "the GO authorization is missing:$go_missing. An authorization that cannot quote the nonce of the request it answers is not bound to this run, and this window does not open on it." +fi +record "GO_AUTHORIZED_VERIFIED nonce=$GO_ACK_NONCE - a separate, run-bound authorization, distinct from the readiness acknowledgment" # THE REMOVAL INSTRUMENT IS REQUIRED BEFORE THE WINDOW OPENS (doyle 2026-09-13). # A run that cannot remove what it is about to create must never create it. The predecessor @@ -2048,7 +2090,7 @@ if ! teardown_pin_verify pre-go; then fi # THE WINDOW OPENS HERE AND NOWHERE ELSE. -go "prepared acknowledgment verified and the reviewed removal instrument verified" +go "GO authorization verified (run-bound), both subject hashes measured by the executor, and the reviewed removal instrument verified" abort_check deadline_check elevated-setup