#!/bin/bash
# FIELD DRIVER — repaired candidate 53d625cd. FOR SOURCE REVIEW ONLY. NOT RUN, NOT GRANTED.
# todlando 2026-09-12. One driver, explicit setup/trial/cleanup transitions.
#
# NO `set -e`. Rationale (doyle): set -e can exit before a failed command is RECORDED and before
# cleanup runs. Every command goes through run_cmd, which captures the exit IMMEDIATELY into a
# variable, records it, and returns it. A trailing echo never stands in for a command's exit.
#
# WHAT CHANGED FROM v3, and why (verified by me in source at 53d625cd, not taken on report):
#   serveverb.rs:180-187 — Lan{bootstrap:false, stop:false} builds ServeRequest::LanStatus. So the
#   v3 timed command `serve lan --port 29470` would have QUERIED A STOPPED LISTENER. Withdrawn.
#   The trial startup is --bootstrap WITH SPT_INSTALL_NO_FIREWALL=1:
#     mutation_permitted() (bootstrap_firewall.rs:19-25) returns Err when that var is set;
#     it gates ONLY request_lan_firewall (serveverb.rs:330) and reconcile_lan_firewall (:486).
#     verify() (:29-37) is NOT gated — so the verify-query leg still runs. Listener up, exactly one
#     verify-query, no elevation prompt, no reconcile.
#   The trial STOP also carries the opt-out: report_lan_cleanup (:376-391) calls is_clean and then,
#   unelevated, request_lan_firewall — which the opt-out refuses, so THE PAIR IS RETAINED. That is
#   what makes an Arm B trial repeatable. The elevated stop in v3, placed right after setup, would
#   have removed the pair before Arm B ran. Withdrawn.
#   Elevated setup and elevated cleanup must EXPLICITLY REMOVE the variable (env -u), or they would
#   refuse their own mutation.

W='C:/Users/decid/Documents/projects/spt-core/.worktrees/304-w2-repr'
SP='C:/Users/decid/AppData/Local/Temp/claude/C--Users-decid-Documents-projects-spt-core/71de7b8b-0f13-494d-8fa4-c01f4a215d10/scratchpad'
H="$SP/fp-home"                      # FRESH isolated home, this experiment only
R="$SP/fp-run"                       # every capture lands here
EXE="$W/target/release/spt.exe"      # RELEASE, produced by debug-rollout --build-current
PORT=29470                           # never 5470
LANE='fp-53d625cd'
SUBJECT_SHA='53d625cd0bd88a04815efdf6c8209a3096bf53e8'
SUBJECT_BLOB='c28874ef6823a7bb522168514ac81c16ddd427d5'   # windows.rs at that sha

mkdir -p "$R"
: > "$R/exits.txt"; : > "$R/timeline.txt"; : > "$R/findings.txt"

stamp()  { printf '%s %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$1" >> "$R/timeline.txt"; }
record() { printf '%s\n' "$1" | tee -a "$R/findings.txt"; }

# run_cmd TAG OUTFILE ERRFILE -- cmd...   Captures the exit immediately; never masked by an echo.
run_cmd() {
  local tag="$1" out="$2" err="$3"; shift 4
  stamp "${tag}_START"
  "$@" > "$out" 2> "$err"
  local rc=$?                                   # captured BEFORE anything else runs
  printf '%s_EXIT=%d\n' "$tag" "$rc" >> "$R/exits.txt"
  stamp "${tag}_END rc=$rc"
  return $rc
}

CLEANUP_DONE=0
cleanup() {                                     # idempotent; runs on every exit path
  [ "$CLEANUP_DONE" -eq 1 ] && return 0
  CLEANUP_DONE=1
  record "CLEANUP_BEGIN"
  # Product cleanup, ELEVATED, opt-out explicitly REMOVED so the mutation is permitted.
  # liam runs this; it is the second and last elevated action.
  run_cmd cleanup_elev "$R/cleanup.out" "$R/cleanup.err" -- \
    env -u SPT_INSTALL_NO_FIREWALL SPT_HOME="$H" "$EXE" serve lan --stop
  pwsh -NoProfile -File "$R/census.ps1" -Tag cleanup-post -OutDir "$R" >> "$R/census.log" 2>&1
  # Isolated daemon under H. OWL_SESSION_ID IS LEFT INTACT — clearing it bypasses a refusal guard
  # and that has NOT been approved. If the stop refuses, the refusal is REPORTED and the process is
  # left in place pending a source-grounded shutdown review. No force-reap.
  run_cmd rig_daemon_stop "$R/rig-daemon-stop.out" "$R/rig-daemon-stop.err" -- \
    env SPT_HOME="$H" "$EXE" daemon stop
  if [ -s "$R/rig-daemon-stop.err" ]; then
    record "RIG_DAEMON_STOP_REFUSED_OR_ERRORED — reported, not forced. See rig-daemon-stop.err"
  fi
  ( cd "$W" && cargo run -p xtask -- pool-release --pool "$W/target" ) > "$R/pool-release.out" 2>&1
  printf 'pool_release_EXIT=%d\n' "$?" >> "$R/exits.txt"
  record "CLEANUP_END"
}
trap cleanup EXIT

die()  { record "HALT: $1"; exit 1; }           # trap runs cleanup
void() { record "VOID: $1 — investigation stops here; no further trial runs"; exit 2; }

# ── S0  CAPACITY AND RUNNER, WITHOUT CARGO (no cargo producer may run before this) ────────────
pwsh -NoProfile -Command '$d=Get-PSDrive C; "FREE_GIB={0:N2} USED_GIB={1:N2}" -f ($d.Free/1GB),($d.Used/1GB)' \
  > "$R/s0-disk.out" 2>&1
printf 's0_disk_EXIT=%d\n' "$?" >> "$R/exits.txt"
free_gib=$(sed -n 's/^FREE_GIB=\([0-9.]*\).*/\1/p' "$R/s0-disk.out")
[ -n "$free_gib" ] || die "capacity probe produced no FREE_GIB row"
awk -v f="$free_gib" 'BEGIN{exit !(f+0 >= 96)}' || die "free $free_gib GiB below the 96 GiB producer-admission floor"
record "CAPACITY free=${free_gib} GiB (divisor 1073741824 — GiB, not decimal GB) floor=96 GiB OK"
# Runner census, two-axis, still no cargo: jobs-level CI read + ancestry-authenticated process census.
gh run list --repo BigscreenVR/spt-bs-releases --limit 5 --json databaseId,headSha,conclusion \
  > "$R/s0-ci.json" 2>&1; printf 's0_ci_EXIT=%d\n' "$?" >> "$R/exits.txt"
pwsh -NoProfile -File "$R/runner-census.ps1" > "$R/s0-runner.txt" 2>&1
printf 's0_runner_EXIT=%d\n' "$?" >> "$R/exits.txt"
grep -q 'RUNNER_WORKER=ABSENT' "$R/s0-runner.txt" || die "Runner.Worker.exe present — box not free"

# ── S0b  SUBJECT IDENTITY ─────────────────────────────────────────────────────────────────────
head_sha=$(git -C "$W" rev-parse HEAD)
[ "$head_sha" = "$SUBJECT_SHA" ] || die "W is at $head_sha, not the subject $SUBJECT_SHA"
dirty=$(git -C "$W" status --porcelain); [ -z "$dirty" ] || die "W is dirty; a dirty tree fabricates provenance"
blob=$(git -C "$W" rev-parse HEAD:crates/spt-daemon/src/bootstrap_firewall/windows.rs)
[ "$blob" = "$SUBJECT_BLOB" ] || die "windows.rs blob $blob != $SUBJECT_BLOB"
record "SUBJECT sha=$head_sha clean blob=$blob"

# ── S0c  SEED SHAPE — exactly ONE record, never the value ─────────────────────────────────────
seed_len=${#SPT_DEBUG_RELEASE_SEED}
seed_shape=BAD
case "${SPT_DEBUG_RELEASE_SEED:-}" in
  ''|*[!0-9a-fA-F]*) seed_shape=BAD ;;
  *) [ "$seed_len" -eq 64 ] && seed_shape=OK ;;
esac
record "SEED_SHAPE=$seed_shape len=$seed_len expect=64hex"     # the ONE record. No value, no expansion.
[ "$seed_shape" = OK ] || die "SPT_DEBUG_RELEASE_SEED is unset or not 64 hex chars (A7's S3 died here: 'seed is hex' panic, xtask/src/main.rs:2717)"

# ── S1  POOL CLAIM, then S2-S5. Every cargo runs with cwd=W and jobs=2. ───────────────────────
export CARGO_BUILD_JOBS=2
( cd "$W" && cargo run -p xtask -- pool-claim --pool "$W/target" --label "$LANE" ) > "$R/s1-pool.out" 2>&1
printf 's1_pool_EXIT=%d\n' "$?" >> "$R/exits.txt"
# --manifest-path does NOT set cwd (doyle). Every cargo above and below is `cd "$W" && cargo ...`.
# Lane-identity enforcement lives in the BUILD, never in pool-claim (IR-42): a SPT_POOL_FOREIGN or
# lane-identity refusal will appear at S3 and is a HALT, not something to predict from the claim.

mkdir -p "$H"
( cd "$W" && cargo run -p xtask -- debug-keygen fp-debug-2026 ) > "$R/s2-keygen.out" 2>&1
printf 's2_keygen_EXIT=%d\n' "$?" >> "$R/exits.txt"
pub=$(sed -n 's/.*--public-key \([0-9a-f]*\).*/\1/p' "$R/s2-keygen.out" | head -1)
[ -n "$pub" ] || die "no public key parsed from debug-keygen output"
( cd "$W" && cargo run -p xtask -- debug-pin --key-id fp-debug-2026 --public-key "$pub" --home "$H" ) \
  > "$R/s2-pin.out" 2>&1
printf 's2_pin_EXIT=%d\n' "$?" >> "$R/exits.txt"

( cd "$W" && cargo run -p xtask -- debug-rollout --key-id fp-debug-2026 --product-version 0.69.0-fp \
    --channel debug --version 1 --build-current --stage-dir "$H/releases" \
    --state "$W/target/fp-rollout-state.json" ) > "$R/s3-rollout.out" 2> "$R/s3-rollout.err"
rc=$?; printf 's3_rollout_EXIT=%d\n' "$rc" >> "$R/exits.txt"
[ "$rc" -eq 0 ] || die "S3 rollout exit $rc — see s3-rollout.err (this is where A7 failed)"
grep -q 'DEBUG_ROLLOUT_STAGED version=1' "$R/s3-rollout.out" || die "S3 produced no STAGED row"

( cd "$W" && cargo run -p xtask -- debug-mark-applied --version 1 --home "$H" ) > "$R/s4-applied.out" 2>&1
rc=$?; printf 's4_applied_EXIT=%d\n' "$rc" >> "$R/exits.txt"
[ "$rc" -eq 0 ] && grep -q 'DEBUG_MARKED_APPLIED version=1' "$R/s4-applied.out" || die "S4 did not mark applied"

# S5 provenance — its own row, measured independently of any product self-report.
[ -f "$EXE" ] || die "no release binary at $EXE"
{ sha256sum "$EXE"; stat -c '%s bytes  mtime=%y  path=%n' "$EXE"; } > "$R/s5-provenance.out" 2>&1
printf 's5_prov_EXIT=%d\n' "$?" >> "$R/exits.txt"
exe_sha=$(awk '{print $1}' "$R/s5-provenance.out" | head -1)
[ -n "$exe_sha" ] || die "no measured sha256 for the built binary"
record "PROVENANCE exe_sha=$exe_sha (compared against, never replaced by, the product's own anchor line)"

# ── S6  RUNNER CENSUS REFRESHED AFTER THE BUILD, BEFORE ARM A ─────────────────────────────────
pwsh -NoProfile -File "$R/runner-census.ps1" > "$R/s6-runner.txt" 2>&1
printf 's6_runner_EXIT=%d\n' "$?" >> "$R/exits.txt"
grep -q 'RUNNER_WORKER=ABSENT' "$R/s6-runner.txt" || die "runner re-occupied during the build"

# ── 5470 PRESERVATION — FIELDS AND LISTENER IDENTITY, NOT A COUNT ─────────────────────────────
# A count is a visibility control only (doyle). preserve5470 records, for every rule carrying 5470:
# Name, Group, Enabled, Direction, Action, Profile, RemoteAddress, Program; AND the listener identity
# on TCP 5470: owning pid, process path, process start time. Compared FIELD BY FIELD.
snapshot_5470() { pwsh -NoProfile -File "$R/preserve5470.ps1" -Tag "$1" -OutDir "$R" ; }
snapshot_5470 baseline || die "5470 baseline snapshot failed"
assert_5470_unchanged() {
  snapshot_5470 "$1" || die "5470 snapshot '$1' failed"
  if ! diff -u "$R/preserve5470-baseline.txt" "$R/preserve5470-$1.txt" > "$R/preserve5470-$1.diff"; then
    die "5470 rule fields or listener identity CHANGED at '$1' — see preserve5470-$1.diff"
  fi
}

# ── TRIAL ─────────────────────────────────────────────────────────────────────────────────────
# ARM = a|b. Startup and stop BOTH carry SPT_INSTALL_NO_FIREWALL=1: unelevated, no reconcile, and
# for arm b the stop RETAINS the pair so the next trial sees the same populated precondition.
trial() {
  local arm="$1" n="$2" errf="$R/$arm-$n.err"
  pwsh -NoProfile -File "$R/census.ps1"     -Tag "$arm-pre-$n"  -OutDir "$R" >> "$R/census.log" 2>&1
  grep -q "tag=$arm-pre-$n .* valid=YES" "$R/census.log" || void "pre-census $arm-$n lacks both positive controls (ctl_5470>=1 and ctl_sptexe>=1)"
  pwsh -NoProfile -File "$R/cpubracket.ps1" -Tag "$arm-pre-$n" >> "$R/cpu-brackets.txt" 2>&1   # OUTSIDE the timed call

  run_cmd "${arm}${n}_serve" "$R/$arm-$n.out" "$errf" -- \
    env SPT_INSTALL_NO_FIREWALL=1 SPT_HOME="$H" "$EXE" serve lan --bootstrap --port "$PORT"
  local serve_rc=$?
  run_cmd "${arm}${n}_stop" "$R/$arm-$n.stop.out" "$R/$arm-$n.stop.err" -- \
    env SPT_INSTALL_NO_FIREWALL=1 SPT_HOME="$H" "$EXE" serve lan --stop
  local stop_rc=$?

  pwsh -NoProfile -File "$R/cpubracket.ps1" -Tag "$arm-post-$n" >> "$R/cpu-brackets.txt" 2>&1
  pwsh -NoProfile -File "$R/census.ps1"     -Tag "$arm-post-$n" -OutDir "$R" >> "$R/census.log" 2>&1
  grep -q "tag=$arm-post-$n .* valid=YES" "$R/census.log" || void "post-census $arm-$n lacks both positive controls"
  assert_5470_unchanged "$arm-post-$n"

  # SUBJECT ROW. grep -c EXITS NONZERO ON ZERO MATCHES (doyle) — it still PRINTS 0, so `|| true`
  # keeps the count and drops the status. A missing file would print nothing, so the file is checked
  # first and the value is asserted numeric before it is compared.
  [ -f "$errf" ] || void "$arm trial $n produced no stderr capture at all"
  local rows; rows=$(grep -c 'leg=verify-query' "$errf" || true)
  case "$rows" in (''|*[!0-9]*) void "row count from $errf is not numeric: '$rows'" ;; esac
  if   [ "$rows" -eq 0 ]; then void "$arm trial $n: subject row ABSENT — the measured path was not reached"
  elif [ "$rows" -gt 1 ]; then void "$arm trial $n: $rows subject rows; multiple rows are NOT interchangeable observations"
  fi
  local row; row=$(grep 'leg=verify-query' "$errf")
  local outcome; outcome=$(printf '%s' "$row" | sed -n 's/.*outcome=\([a-z]*\).*/\1/p')
  case "$outcome" in
    completed|failed|killed) : ;;
    *) void "$arm trial $n: unrecognised outcome field in row: $row" ;;
  esac
  record "TRIAL $arm-$n serve_rc=$serve_rc stop_rc=$stop_rc outcome=$outcome row=[$row]"
  # failed/killed are MEASUREMENTS and are recorded in place. They do not count toward a successful
  # arm and they are NEVER re-rolled: all three scheduled attempts stand as run.
  if [ "$outcome" = failed ]; then record "  failed row, error text: $(cat "$R/$arm-$n.err" | tr '\n' ' ' | cut -c1-400)"; fi
  # Which arm of decide() refused — the representation discriminator, read from the product's own text.
  local face=none
  grep -q 'do not match the admission pair' "$errf"          && face=spec-match
  grep -q 'not Local:' "$errf"                                && face=source-store
  grep -q 'ActiveStore enforcement is'  "$errf"               && face=enforcement
  grep -q 'LAN_FIREWALL_VERIFIED\|LAN admission verified' "$errf" && face=verified
  record "  refusal_face=$face"
}

# ── ARM A — pair ABSENT ───────────────────────────────────────────────────────────────────────
pwsh -NoProfile -File "$R/census.ps1" -Tag a-precondition -OutDir "$R" >> "$R/census.log" 2>&1
grep -q 'tag=a-precondition .* subj_group=0 subj_29470=0' "$R/census.log" \
  || die "ARM A precondition not met: an owned pair is present"
for n in 1 2 3; do trial a "$n"; done

# ── ARM B SETUP — ONE elevated action (liam). Acceptance is POSITIVE, not absence-of-text. ────
run_cmd b_setup_elev "$R/b-setup.out" "$R/b-setup.err" -- \
  env -u SPT_INSTALL_NO_FIREWALL SPT_HOME="$H" "$EXE" serve lan --bootstrap --port "$PORT"
setup_rc=$?
pwsh -NoProfile -File "$R/census.ps1" -Tag b-setup-post -OutDir "$R" >> "$R/census.log" 2>&1
# THREE positive conditions, all required (doyle): a positive product verdict, a zero exit, and a
# pair census showing both halves. Absence of refusal text is NOT acceptance.
verdict_ok=0; grep -q 'LAN_FIREWALL_VERIFIED\|LAN admission verified' "$R/b-setup.out" "$R/b-setup.err" && verdict_ok=1
census_ok=0;  grep -q 'tag=b-setup-post .* subj_group=2 subj_29470=2' "$R/census.log" && census_ok=1
if [ "$setup_rc" -ne 0 ] || [ "$verdict_ok" -ne 1 ] || [ "$census_ok" -ne 1 ]; then
  record "ARM_B_SETUP_NOT_ACCEPTED rc=$setup_rc verdict_ok=$verdict_ok census_ok=$census_ok"
  if grep -q 'ActiveStore enforcement is' "$R/b-setup.err"; then
    record "  DIAGNOSTIC: enforcement refusal. Spec matching passed FOR THAT INVOCATION and nothing"
    record "  more — this does NOT establish the registered successful-reconcile precondition."
    record "  Populated trials HELD. Cleanup runs. No Arm B without a separately reviewed amendment."
  fi
  exit 3                                   # trap -> cleanup
fi
# Retain the pair for Arm B: an UNELEVATED opt-out stop. An elevated stop here would remove it.
run_cmd b_setup_stop "$R/b-setup-stop.out" "$R/b-setup-stop.err" -- \
  env SPT_INSTALL_NO_FIREWALL=1 SPT_HOME="$H" "$EXE" serve lan --stop
pwsh -NoProfile -File "$R/census.ps1" -Tag b-precondition -OutDir "$R" >> "$R/census.log" 2>&1
grep -q 'tag=b-precondition .* subj_group=2 subj_29470=2' "$R/census.log" \
  || die "the opt-out stop did not retain the pair; Arm B's populated precondition is gone"

for n in 1 2 3; do trial b "$n"; done

# ── D1 — SEPARATE SERIALIZED DIAGNOSTIC. Never inside a timed trial, never concurrent. ────────
# The script text is the PRODUCT'S OWN QUERY const, extracted from the pinned blob and composed the
# way script() composes it, then UTF16LE+base64 encoded exactly as encoded() does — not a paraphrase.
# Control: the extracted body must satisfy the amended A2.1 counts, or the extraction is wrong and
# the capture means nothing.
d1_capture() {
  python "$R/d1_render.py" --repo "$W" --blob "$SUBJECT_BLOB" --out "$R/d1-script.b64" \
    > "$R/d1-render.out" 2>&1 || { record "D1 render failed — see d1-render.out"; return 1; }
  grep -q 'PRECHECK Named-Rules=1 PersistentStore=0 Get-NetIPAddress=1 ActiveStore=2' "$R/d1-render.out" \
    || { record "D1 render failed its own pre-check; capture discarded"; return 1; }
  powershell.exe -NoLogo -NoProfile -NonInteractive -EncodedCommand "$(cat "$R/d1-script.b64")" \
    > "$R/d1-snapshot.json" 2> "$R/d1-snapshot.err"
  printf 'd1_EXIT=%d\n' "$?" >> "$R/exits.txt"
  record "D1 captured to d1-snapshot.json — a SEPARATE DIAGNOSTIC INVOCATION. It is NOT the product's"
  record "  failure-time snapshot and cannot say what any timed call saw."
}
d1_capture

record "ALL ARMS COMPLETE"
exit 0
