#!/usr/bin/env bash
set -Eeuo pipefail
umask 077
export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
export PYTHONDONTWRITEBYTECODE=1

BASE="${ROUTER_OPS_BASE:-/opt/router-ops}"
INCOMING="${ROUTER_STEP_INCOMING:-/home/ops/incoming}"
SELFTEST="${ROUTER_EXACT_WORKER_SELFTEST:-false}"
BUNDLE_ROOT="${BUNDLE_ROOT:?bundle root required}"
BUNDLE_ZIP="${BUNDLE_ZIP:?bundle zip required}"
BUNDLE_SHA256="${EXPECTED_BUNDLE_SHA256:?bundle sha required}"
RUN_DIR="${ROUTER_DETACHED_RUN_DIR:?run dir required}"
CHILD_RESULT="${ROUTER_DETACHED_CHILD_RESULT:-$RUN_DIR/child-result.env}"
[[ -x "$BASE/bin/router-release-contract" && -x "$BASE/bin/router-zip-contract" ]]
eval "$("$BASE/bin/router-release-contract" env --root "$BUNDLE_ROOT")"

STEP_ID="$ROUTER_RELEASE_STEP_ID"
REVISION="$ROUTER_RELEASE_REVISION"
VM101_GIT_COMMIT='ac678d1b3164e0201d221967fa131e354a211881'
VM101_GIT_TREE='0d00ec84743795ff4dde671e42ac3e77241591ef'
VM101_GIT_FILE_COUNT='58'
ACTIVE_GENERATION_ID='r20c-20260730-205427-3926'
PVE_HOST='pve-mgts'
VMID='101'
VM100_ADDR='10.71.100.1'
VM101_ADDR='10.71.100.2'
PVE_KEY='/root/.ssh/pve_to_openwrt_mgts_ed25519'
TS="$(date -u +%Y%m%d-%H%M%S)"
STEP_START_EPOCH="$(date +%s)"
SNAPSHOT_NAME="r20quc-pre-$(date -u +%m%d-%H%M%S)"

EVIDENCE="$RUN_DIR/evidence"
REPORT="$RUN_DIR/report"
PAYLOAD="$RUN_DIR/public-payload"
CURRENT="$RUN_DIR/workflow-current.txt"
EVENTS="$RUN_DIR/workflow-events.tsv"
FINAL_ENV="$RUN_DIR/final-result.env"
FINAL_EXTRACT="$RUN_DIR/independent-final-extract"
FINAL_ROOT="$FINAL_EXTRACT/$STEP_ID"
GIT_ENV="$RUN_DIR/vm101-git.env"
SOURCE_ENV="$RUN_DIR/vm101-source.env"
MODEL_ENV="$RUN_DIR/vm101-model.env"
METHODS_ENV="$RUN_DIR/vm101-methods.env"
PROJECT_ENV="$RUN_DIR/project-source.env"
CORE_ENV="$RUN_DIR/core-change.env"
SNAPSHOT_ENV="$RUN_DIR/snapshot.env"
PRE_ENV="$RUN_DIR/pre-reboot.env"
POST_ENV="$RUN_DIR/post-reboot.env"

CURRENT_PHASE=bootstrap
CORE_CHANGE_COMPLETE=false
CORE_CHANGE_POINT='production_boot_ready_anchor_five_healthy_routes'
SNAPSHOT_CREATED=false
REBOOT_REQUESTED=false
ROLLBACK_STATUS=not_needed
FAILURE_HANDLED=false
STEP_REPORT_URL=not_published
LATEST_ARCHIVE=not_created
LATEST_ARCHIVE_SHA256=unknown
VM101_PUBLIC_URL=not_published
VM101_MODEL_URL=not_published
VM101_METHODS_URL=not_published
PROJECT_SOURCE_POST_URL=not_published

mkdir -p "$EVIDENCE" "$REPORT" "$PAYLOAD"
chmod 700 "$EVIDENCE" "$REPORT" "$PAYLOAD"
source "$BASE/lib/router-step-workflow.sh"
source "$BASE/lib/router-direct-state-oracle.sh"
source "$BASE/lib/router-runtime-transition.sh"
TRANSITION_STATE="$RUN_DIR/runtime-transition.env"
router_runtime_transition_init "$TRANSITION_STATE"
router_step_workflow_init "$CURRENT" "$EVENTS" \
  preflight independent_extract mandatory_tests remote_readonly_preflight snapshot \
  reboot reconnect production_boot_verify post_core_verify source_publication \
  model_publication methods_publication project_source report_build report_publish archive

kv_read() {
  local key="$1" file="$2"
  awk -F= -v k="$key" '$1==k{v=substr($0,index($0,"=")+1)} END{print v}' "$file"
}

event_emit() {
  local name="$1"
  printf 'EVENT=%s\n' "$name"
  printf '%s\t%s\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" "$name" >> "$EVIDENCE/live-events.log"
}

progress_emit() {
  local extra="${1:-}"
  local now elapsed
  now="$(date +%s)"; elapsed=$((now - STEP_START_EPOCH))
  printf 'PROGRESS_R20QUC=elapsed=%s phase=%s snapshot=%s reboot=%s core=%s %s\n' \
    "$elapsed" "$CURRENT_PHASE" "$SNAPSHOT_CREATED" "$REBOOT_REQUESTED" "$CORE_CHANGE_COMPLETE" "$extra"
}

selftest_query() {
  sed -n 's/^# SELFTEST_QUERY=//p' | head -n1
}

vm101_script() {
  if [[ "$SELFTEST" == true ]]; then
    local body query state_dir
    body="$(cat)"
    query="$(printf '%s\n' "$body" | selftest_query)"
    state_dir="$BASE/selftest-vm101-state"
    mkdir -p "$state_dir"
    case "$query" in
      PREFLIGHT)
        cat <<EOS
RESULT=PASS_R20QUC_PREFLIGHT
BOOT_ID=boot-before
UPTIME_SEC=86400
PERSIST_STATE_SHA256=prestatehash
RUNTIME_STATE_SHA256=prestatehash
RECOVERY_MODE=NORMAL
ACTIVE_GENERATION_ID=$ACTIVE_GENERATION_ID
READY_PRESENT=false
HEALTHY_SLOTS=5
ACTIVE_REFRESH_PROCESS_COUNT=0
RESULT=PASS_vm101_GIT_PUBLISH_CHECK
GIT_COMMIT=$VM101_GIT_COMMIT
GIT_TREE=$VM101_GIT_TREE
GIT_FILE_COUNT=$VM101_GIT_FILE_COUNT
EOS
        ;;
      REMOTE_SYNTAX)
        echo RESULT=PASS_R20QUC_REMOTE_BUSYBOX_SYNTAX
        ;;
      BOOT_ID)
        if [[ -f "$state_dir/rebooted" ]]; then echo boot-after; else echo boot-before; fi
        ;;
      POST_BOOT_OBSERVE)
        [[ -f "$state_dir/rebooted" ]] || return 75
        cat <<EOS
RESULT=PASS_R20QUC_PRODUCTION_BOOT_BOUNDARY
BOOT_ID=boot-after
UPTIME_SEC=42
PERSIST_STATE_SHA256=prestatehash
RUNTIME_STATE_SHA256=prestatehash
RECOVERY_MODE=NORMAL
ACTIVE_GENERATION_ID=$ACTIVE_GENERATION_ID
RUNTIME_ANCHOR_REAL=/var/lib/router-egress-recovery/generations/staging/$ACTIVE_GENERATION_ID
RUNTIME_ANCHOR_BOOT_RECONSTRUCTED=true
RUNTIME_ANCHOR_BOOT_SOURCE=current_uci_network
RUNTIME_ANCHOR_CREATED_AT_EPOCH=200
BOOT_READY_COMPLETED_AT_EPOCH=210
BOOT_READY_SERVICE_ORDER=router-wgpay-topology-delivery router-egress-zero-healthy-bootstrap router-egress-health-repair router-egress-full-pool-refresh-retry
FIVE_VPN_LINKS_READY=true
ROUTE_TABLES_READY=true
HEALTHY_SLOTS=5
TOPOLOGY_MODE=NORMAL
TOPOLOGY_PENDING=false
PROVIDER_DIRECT_POLICY=disabled_until_proven
REFRESH_OWNER_PROCESS_COUNT=1
REFRESH_OWNER_TICK_RESULT=NOOP_R20QUB_REFRESH_OWNER_NORMAL
BOOT_HANDOFF_LOG_PASS=true
RESULT=PASS_R20QUC_PRODUCTION_BOOT_BOUNDARY
EOS
        ;;
      FINAL_VM101)
        cat <<EOS
RESULT=PASS_vm101_GIT_PUBLISH_CHECK
GIT_COMMIT=$VM101_GIT_COMMIT
GIT_TREE=$VM101_GIT_TREE
GIT_FILE_COUNT=$VM101_GIT_FILE_COUNT
RESULT=PASS_R20QUC_FINAL_VM101
HEALTHY_SLOTS=5
RECOVERY_MODE=NORMAL
TOPOLOGY_MODE=NORMAL
TOPOLOGY_PENDING=false
BOOT_READY=true
REFRESH_OWNER_PROCESS_COUNT=1
ACTIVE_REFRESH_PROCESS_COUNT=0
EOS
        ;;
      ROLLBACK_HEALTH)
        echo RESULT=PASS_R20QUC_ROLLBACK_HEALTH
        echo HEALTHY_SLOTS=5
        ;;
      *)
        echo "RESULT=STOP_R20QUC_SELFTEST_UNKNOWN_VM101_QUERY"
        echo "QUERY=$query"
        return 90
        ;;
    esac
  else
    ssh -o BatchMode=yes -o ConnectTimeout=20 "$PVE_HOST" \
      "ssh -i '$PVE_KEY' -o BatchMode=yes -o ConnectTimeout=15 root@'$VM101_ADDR' 'sh -s'"
  fi
}

vm100_script() {
  if [[ "$SELFTEST" == true ]]; then
    local body query
    body="$(cat)"; query="$(printf '%s\n' "$body" | selftest_query)"
    case "$query" in
      DIRECT_STATE) echo DIRECT_STATE_ABSENT=true ;;
      *) echo RESULT=STOP_R20QUC_SELFTEST_UNKNOWN_VM100_QUERY; return 90 ;;
    esac
  else
    ssh -o BatchMode=yes -o ConnectTimeout=20 "$PVE_HOST" \
      "ssh -i '$PVE_KEY' -o BatchMode=yes -o ConnectTimeout=15 root@'$VM100_ADDR' 'sh -s'"
  fi
}

pve_script() {
  if [[ "$SELFTEST" == true ]]; then
    local body query state_dir
    body="$(cat)"; query="$(printf '%s\n' "$body" | selftest_query)"
    state_dir="$BASE/selftest-vm101-state"; mkdir -p "$state_dir"
    case "$query" in
      SNAPSHOT)
        touch "$state_dir/snapshot"
        echo SNAPSHOT_EXISTED_BEFORE=false
        echo QM_SNAPSHOT_RC=0
        echo SNAPSHOT_EXACT_CONFIG_SECTION=true
        echo RESULT=PASS_R20QUC_SNAPSHOT
        ;;
      REBOOT)
        [[ -f "$state_dir/snapshot" ]]
        touch "$state_dir/rebooted"
        echo RESULT=PASS_R20QUC_REBOOT_REQUESTED
        ;;
      SNAPSHOT_STATUS)
        echo RESULT=PASS_R20QUC_SNAPSHOT_AND_VM_RUNNING
        ;;
      ROLLBACK)
        touch "$state_dir/rollback"
        echo RESULT=PASS_R20QUC_PRECORE_SNAPSHOT_ROLLBACK
        ;;
      *) echo RESULT=STOP_R20QUC_SELFTEST_UNKNOWN_PVE_QUERY; return 90 ;;
    esac
  else
    ssh -o BatchMode=yes -o ConnectTimeout=20 "$PVE_HOST" 'bash -s'
  fi
}

write_child() {
  local result="$1" rc="$2" tmp="${CHILD_RESULT}.tmp.$$"
  {
    echo "RUNNER_STEP_RESULT=$([[ $rc -eq 0 ]] && echo PASS || echo STOP)"
    echo "RESULT=$result"
    echo "REVISION=$REVISION"
    echo "RUN_DIR=$RUN_DIR"
    echo "STEP_REPORT_URL=$STEP_REPORT_URL"
    echo "LATEST_ARCHIVE=$LATEST_ARCHIVE"
    echo "LATEST_ARCHIVE_SHA256=$LATEST_ARCHIVE_SHA256"
    echo "CORE_CHANGE_COMPLETE=$CORE_CHANGE_COMPLETE"
    echo "CORE_CHANGE_POINT=$CORE_CHANGE_POINT"
    echo "SNAPSHOT_NAME=$SNAPSHOT_NAME"
    echo "SNAPSHOT_CREATED=$SNAPSHOT_CREATED"
    echo "REBOOT_REQUESTED=$REBOOT_REQUESTED"
    echo "ROLLBACK_STATUS=$ROLLBACK_STATUS"
    echo "CHILD_RC=$rc"
  } > "$tmp"
  chmod 600 "$tmp"; mv -f "$tmp" "$CHILD_RESULT"
}

archive_latest() {
  set +e
  router_step_archive_latest_python "$BASE" "$INCOMING" "$TS" > "$EVIDENCE/latest-archive.log" 2>&1
  local rc=$?
  set -e
  cat "$EVIDENCE/latest-archive.log" || true
  if [[ $rc -eq 0 ]]; then
    LATEST_ARCHIVE="$(awk -F= '$1=="LATEST_ARCHIVE"{print substr($0,index($0,"=")+1)}' "$EVIDENCE/latest-archive.log" | tail -n1)"
    LATEST_ARCHIVE_SHA256="$(awk -F= '$1=="LATEST_ARCHIVE_SHA256"{print $2}' "$EVIDENCE/latest-archive.log" | tail -n1)"
  fi
  return "$rc"
}

wait_rollback_health() {
  local deadline now rc
  deadline=$(( $(date +%s) + 300 ))
  while true; do
    set +e
    vm101_script > "$EVIDENCE/rollback-health.latest.log" 2>&1 <<'EOS'
# SELFTEST_QUERY=ROLLBACK_HEALTH
set -eu
status="$(/usr/local/sbin/router-egress-slots-status.sh)"
healthy="$(printf '%s\n' "$status" | sed -n 's/.*"healthy"[[:space:]]*:[[:space:]]*\([0-9][0-9]*\).*/\1/p' | tail -n1)"
[ "$healthy" = 5 ] || exit 75
echo RESULT=PASS_R20QUC_ROLLBACK_HEALTH
echo HEALTHY_SLOTS="$healthy"
EOS
    rc=$?
    set -e
    if [[ $rc -eq 0 ]] && grep -Fqx RESULT=PASS_R20QUC_ROLLBACK_HEALTH "$EVIDENCE/rollback-health.latest.log"; then
      cp "$EVIDENCE/rollback-health.latest.log" "$EVIDENCE/rollback-health.log"
      return 0
    fi
    now="$(date +%s)"; [[ $now -lt $deadline ]] || return 1
    sleep 5
  done
}

rollback_precore() {
  if [[ "$CORE_CHANGE_COMPLETE" == true ]]; then
    ROLLBACK_STATUS=not_allowed_after_core_boot_activation
    return 0
  fi
  if [[ "$SNAPSHOT_CREATED" != true || "$REBOOT_REQUESTED" != true ]]; then
    ROLLBACK_STATUS=not_needed_before_reboot
    return 0
  fi
  set +e
  pve_script > "$EVIDENCE/rollback.log" 2>&1 <<EOF_PVE
# SELFTEST_QUERY=ROLLBACK
set -Eeuo pipefail
if qm status $VMID | grep -Fq 'status: running'; then
  qm stop $VMID
fi
for i in \$(seq 1 60); do
  qm status $VMID | grep -Fq 'status: stopped' && break
  sleep 2
done
qm status $VMID | grep -Fq 'status: stopped'
qm rollback $VMID '$SNAPSHOT_NAME'
qm start $VMID
echo RESULT=PASS_R20QUC_PRECORE_SNAPSHOT_ROLLBACK
EOF_PVE
  local rc=$?
  set -e
  if [[ $rc -eq 0 ]] && grep -Fqx RESULT=PASS_R20QUC_PRECORE_SNAPSHOT_ROLLBACK "$EVIDENCE/rollback.log" && wait_rollback_health; then
    ROLLBACK_STATUS=PASS_PRECORE_SNAPSHOT_ROLLBACK
  else
    ROLLBACK_STATUS=STOP_PRECORE_SNAPSHOT_ROLLBACK_FAILED
  fi
}

publish_stop() {
  local phase="$1" line="$2" rc="$3" command="$4" source_root="$BUNDLE_ROOT"
  [[ -f "$FINAL_ROOT/scripts/build-stop-report.py" ]] && source_root="$FINAL_ROOT"
  python3 "$source_root/scripts/build-stop-report.py" \
    --step-id "$STEP_ID" --phase "$phase" --line "$line" --rc "$rc" \
    --command "$command" --run-dir "$RUN_DIR" --output "$REPORT" \
    --core "$CORE_CHANGE_COMPLETE" --rollback "$ROLLBACK_STATUS" \
    --snapshot "$SNAPSHOT_NAME" --reboot "$REBOOT_REQUESTED" || true
  cp "$source_root/scripts/run-step.sh" "$REPORT/executed-step.sh" 2>/dev/null || true
  cp "$source_root/release-info.json" "$REPORT/release-info.json" 2>/dev/null || true
  cp "$CURRENT" "$REPORT/workflow-current.txt" 2>/dev/null || true
  cp "$EVENTS" "$REPORT/workflow-events.tsv" 2>/dev/null || true
  cp "$EVIDENCE/"*.log "$REPORT/" 2>/dev/null || true
  if [[ "$SELFTEST" == true ]]; then
    mkdir -p "${ROUTER_PUBLIC_ROOT:?}/latest/r20quc-stop"
    cp "$REPORT/report.txt" "$ROUTER_PUBLIC_ROOT/latest/r20quc-stop/report.txt"
    STEP_REPORT_URL=selftest://r20quc-stop/
    return 0
  fi
  set +e
  router_step_publish_payload step050m07r20quc_vm101_controlled_reboot_proof_stop \
    "$REPORT" "$PAYLOAD" "$CURRENT" "$EVENTS" "$FINAL_ENV" \
    "$REPORT/report.txt" report.txt \
    "$REPORT/facts.json" facts.json \
    "$REPORT/facts-public.html" facts-public.html \
    "$REPORT/verify-public.html" verify-public.html \
    "$REPORT/rollback-public.html" rollback-public.html \
    "$REPORT/executed-step.sh" executed-step.sh \
    "$REPORT/release-info.json" release-info.json \
    "$REPORT/workflow-current.txt" workflow-current.txt \
    "$REPORT/workflow-events.tsv" workflow-events.tsv \
    > "$EVIDENCE/stop-publication.log" 2>&1
  set -e
  [[ -f "$FINAL_ENV" ]] && STEP_REPORT_URL="$(awk -F= '$1=="PUBLIC_URL"{print substr($0,index($0,"=")+1)}' "$FINAL_ENV" | tail -n1)"
}

stop() {
  local rc="$1" line="$2" command="$3" phase="${CURRENT_PHASE:-unknown}"
  trap - ERR
  [[ "$FAILURE_HANDLED" == false ]] || exit "$rc"
  FAILURE_HANDLED=true
  set +e
  router_step_phase_fail "$phase" "line=$line rc=$rc" >/dev/null 2>&1 || true
  rollback_precore
  publish_stop "$phase" "$line" "$rc" "$command" || true
  archive_latest || true
  write_child STOP_R20QUC_VM101_CONTROLLED_REBOOT_PROOF "$rc"
  echo RESULT=STOP_R20QUC_VM101_CONTROLLED_REBOOT_PROOF
  echo "STOP_PHASE=$phase"
  echo "STOP_LINE=$line"
  echo "STOP_RC=$rc"
  printf 'STOP_COMMAND=%q\n' "$command"
  echo STOP_MACHINE_OWNER=VM130_DETACHED_REBOOT_PROOF
  echo "CORE_CHANGE_COMPLETE=$CORE_CHANGE_COMPLETE"
  echo "CORE_CHANGE_POINT=$CORE_CHANGE_POINT"
  echo "ROLLBACK_STATUS=$ROLLBACK_STATUS"
  echo "SNAPSHOT_NAME=$SNAPSHOT_NAME"
  echo "REBOOT_REQUESTED=$REBOOT_REQUESTED"
  echo "STEP_REPORT_URL=$STEP_REPORT_URL"
  echo "LATEST_ARCHIVE=$LATEST_ARCHIVE"
  echo "LATEST_ARCHIVE_SHA256=$LATEST_ARCHIVE_SHA256"
  echo "RUN_DIR=$RUN_DIR"
  exit "$rc"
}
trap 'rc=$?; stop "$rc" "$LINENO" "$BASH_COMMAND"' ERR

CURRENT_PHASE=preflight; router_step_phase_begin preflight
if [[ "$SELFTEST" != true ]]; then
  [[ "$(hostname)" == router-ops && "$(id -u)" -ne 0 ]]
fi
[[ "$(sha256sum "$BUNDLE_ZIP" | awk '{print $1}')" == "$BUNDLE_SHA256" ]]
printf 'BUNDLE_SHA256=%s\n' "$BUNDLE_SHA256" > "$RUN_DIR/bundle.env"; chmod 600 "$RUN_DIR/bundle.env"
[[ ${#SNAPSHOT_NAME} -le 32 && ${#SNAPSHOT_NAME} -le 40 ]]
printf 'SNAPSHOT_NAME=%s\nSNAPSHOT_NAME_LENGTH=%s\n' "$SNAPSHOT_NAME" "${#SNAPSHOT_NAME}" > "$SNAPSHOT_ENV"; chmod 600 "$SNAPSHOT_ENV"
"$BASE/bin/router-release-contract" verify --root "$BUNDLE_ROOT" --step "$STEP_ID"
grep -Fqx RESULT=PASS_R20QUB1_VM101_BOOT_HANDOFF_ISOLATED_PROOF "$BUNDLE_ROOT/reference/r20qub1-r05-report.txt"
grep -Fqx "VM101_GIT_COMMIT=$VM101_GIT_COMMIT" "$BUNDLE_ROOT/reference/r20qub1-r05-report.txt"
router_step_phase_complete preflight authoritative_b1_pass_and_snapshot_name_prechecked

CURRENT_PHASE=independent_extract; router_step_phase_begin independent_extract
rm -rf "$FINAL_EXTRACT"; mkdir -p "$FINAL_EXTRACT"
"$BASE/bin/router-zip-contract" verify --zip "$BUNDLE_ZIP" --root "$STEP_ID" --canonical | tee "$EVIDENCE/zip-verify.log"
"$BASE/bin/router-zip-contract" extract --zip "$BUNDLE_ZIP" --destination "$FINAL_EXTRACT" --root "$STEP_ID" --canonical | tee "$EVIDENCE/zip-extract.log"
(cd "$FINAL_ROOT" && sha256sum -c manifest.sha256) > "$EVIDENCE/final-manifest.log"
"$BASE/bin/router-release-contract" verify --root "$FINAL_ROOT" --step "$STEP_ID"
router_runtime_transition_set "$TRANSITION_STATE" TRANSFER_VERIFIED true
"$FINAL_ROOT/scripts/apply-vm101-controlled-reboot-proof.sh" \
  "$ROUTER_RELEASE_TARGET_PACKAGE_SHA256" \
  "$FINAL_ROOT/$ROUTER_RELEASE_TARGET_PACKAGE_PATH" \
  verify-controlled-reboot-input | tee "$EVIDENCE/apply-input-contract.log"
grep -Fqx RESULT=PASS_R20QUC_CONTROLLED_REBOOT_INPUT_CONTRACT "$EVIDENCE/apply-input-contract.log"
router_step_phase_complete independent_extract canonical_final_zip_verified_and_input_contract_bound

CURRENT_PHASE=mandatory_tests; router_step_phase_begin mandatory_tests
: > "$EVIDENCE/mandatory-tests.log"
while IFS= read -r test_name; do
  [[ -n "$test_name" && "$test_name" != \#* ]] || continue
  echo ">>> $test_name" | tee -a "$EVIDENCE/mandatory-tests.log"
  BUNDLE_ROOT="$FINAL_ROOT" BUNDLE_ZIP="$BUNDLE_ZIP" EXPECTED_BUNDLE_SHA256="$BUNDLE_SHA256" \
    ROUTER_EXACT_WORKER_SELFTEST="$SELFTEST" bash "$FINAL_ROOT/tests/$test_name" \
    >> "$EVIDENCE/mandatory-tests.log" 2>&1
done < "$FINAL_ROOT/tests/mandatory.list"
router_step_phase_complete mandatory_tests exact_pass_precorerollback_postcorestop_proven

CURRENT_PHASE=remote_readonly_preflight; router_step_phase_begin remote_readonly_preflight
vm101_script > "$EVIDENCE/vm101-preflight.log" <<EOS
# SELFTEST_QUERY=PREFLIGHT
set -eu
. /usr/local/lib/router-egress-recovery-state.sh
reg_init_state
reg_state_validate_file /etc/router-egress-recovery/state.kv
reg_state_validate_file /var/lib/router-egress-recovery/state.kv
cmp -s /etc/router-egress-recovery/state.kv /var/lib/router-egress-recovery/state.kv
mode="\$(reg_get_state mode UNKNOWN)"
active="\$(reg_get_state active_generation_id '')"
[ "\$mode" = NORMAL ]
[ "\$active" = '$ACTIVE_GENERATION_ID' ]
/etc/init.d/router-egress-boot-handoff enabled
for service in router-egress-provider-direct router-wgpay-topology-delivery router-egress-zero-healthy-bootstrap router-egress-slots router-egress-health-repair router-egress-full-pool-refresh-retry; do
  if /etc/init.d/"\$service" enabled >/dev/null 2>&1; then echo "UNEXPECTED_ENABLED_SERVICE=\$service"; exit 41; fi
done
grep -Fqx PROVIDER_DIRECT_ENABLED=0 /etc/router-egress-provider-direct.conf
grep -Fqx BOOTSTRAP_CONTROLLER_PROVIDER_DIRECT_ENABLED=0 /etc/router-egress-zero-healthy-bootstrap.conf
status="\$(/usr/local/sbin/router-egress-slots-status.sh)"
healthy="\$(printf '%s\n' "\$status" | sed -n 's/.*"healthy"[[:space:]]*:[[:space:]]*\([0-9][0-9]*\).*/\1/p' | tail -n1)"
[ "\$healthy" = 5 ]
refresh_count="\$(ps w 2>/dev/null | grep '[r]outer-egress-full-pool-refresh.sh' | wc -l | tr -d ' ')"
[ "\$refresh_count" = 0 ]
ready=false; [ -s /var/run/router-egress-boot-handoff.ready ] && ready=true
boot_id="\$(cat /proc/sys/kernel/random/boot_id)"
uptime_sec="\$(cut -d. -f1 /proc/uptime)"
persist_sha="\$(sha256sum /etc/router-egress-recovery/state.kv | awk '{print \$1}')"
runtime_sha="\$(sha256sum /var/lib/router-egress-recovery/state.kv | awk '{print \$1}')"
/usr/local/sbin/router-vm101-git-publish.sh --check
echo RESULT=PASS_R20QUC_PREFLIGHT
echo BOOT_ID="\$boot_id"
echo UPTIME_SEC="\$uptime_sec"
echo PERSIST_STATE_SHA256="\$persist_sha"
echo RUNTIME_STATE_SHA256="\$runtime_sha"
echo RECOVERY_MODE="\$mode"
echo ACTIVE_GENERATION_ID="\$active"
echo READY_PRESENT="\$ready"
echo HEALTHY_SLOTS="\$healthy"
echo ACTIVE_REFRESH_PROCESS_COUNT="\$refresh_count"
EOS
grep -Fqx RESULT=PASS_R20QUC_PREFLIGHT "$EVIDENCE/vm101-preflight.log"
grep -Fqx RESULT=PASS_vm101_GIT_PUBLISH_CHECK "$EVIDENCE/vm101-preflight.log"
grep -Fqx "GIT_COMMIT=$VM101_GIT_COMMIT" "$EVIDENCE/vm101-preflight.log"
grep -Fqx "GIT_TREE=$VM101_GIT_TREE" "$EVIDENCE/vm101-preflight.log"
grep -Fqx "GIT_FILE_COUNT=$VM101_GIT_FILE_COUNT" "$EVIDENCE/vm101-preflight.log"
PRE_BOOT_ID="$(kv_read BOOT_ID "$EVIDENCE/vm101-preflight.log")"
PRE_PERSIST_SHA="$(kv_read PERSIST_STATE_SHA256 "$EVIDENCE/vm101-preflight.log")"
[[ -n "$PRE_BOOT_ID" && -n "$PRE_PERSIST_SHA" ]]
printf 'PRE_BOOT_ID=%s\nPRE_PERSIST_STATE_SHA256=%s\n' "$PRE_BOOT_ID" "$PRE_PERSIST_SHA" > "$PRE_ENV"; chmod 600 "$PRE_ENV"

vm101_script > "$EVIDENCE/remote-busybox-syntax.log" <<'EOS'
# SELFTEST_QUERY=REMOTE_SYNTAX
set -eu
sh -n /etc/init.d/router-egress-boot-handoff
sh -n /usr/local/sbin/router-egress-boot-handoff.sh
sh -n /usr/local/sbin/router-egress-full-pool-refresh-retry.sh
sh -n /usr/local/lib/router-egress-recovery-state.sh
echo RESULT=PASS_R20QUC_REMOTE_BUSYBOX_SYNTAX
EOS
grep -Fqx RESULT=PASS_R20QUC_REMOTE_BUSYBOX_SYNTAX "$EVIDENCE/remote-busybox-syntax.log"
router_runtime_transition_set "$TRANSITION_STATE" PREFLIGHT_COMPLETE true
router_step_phase_complete remote_readonly_preflight exact_commit_normal_fivehealthy_state_and_busybox_syntax

CURRENT_PHASE=snapshot; router_step_phase_begin snapshot
pve_script > "$EVIDENCE/snapshot.log" 2>&1 <<EOF_PVE
# SELFTEST_QUERY=SNAPSHOT
set -Eeuo pipefail
name='$SNAPSHOT_NAME'
config='/etc/pve/qemu-server/${VMID}.conf'
[ \${#name} -le 40 ]
qm status $VMID | grep -Fq 'status: running'
[ -r "\$config" ]
snapshot_config_has() {
  grep -Fqx "[\$name]" "\$config"
}
SNAPSHOT_EXISTED_BEFORE=false
if snapshot_config_has; then
  SNAPSHOT_EXISTED_BEFORE=true
  QM_SNAPSHOT_RC=0
else
  tmp="\$(mktemp)"
  set +e
  qm snapshot $VMID "\$name" --description 'R20Q-U-C controlled reboot proof pre-reboot snapshot' >"\$tmp" 2>&1
  QM_SNAPSHOT_RC=\$?
  set -e
  cat "\$tmp"
  rm -f "\$tmp"
fi
printf 'SNAPSHOT_EXISTED_BEFORE=%s\n' "\$SNAPSHOT_EXISTED_BEFORE"
printf 'QM_SNAPSHOT_RC=%s\n' "\$QM_SNAPSHOT_RC"
if ! snapshot_config_has; then
  echo RESULT=STOP_R20QUC_SNAPSHOT_NOT_PRESENT_AFTER_QM
  exit "\${QM_SNAPSHOT_RC:-84}"
fi
echo SNAPSHOT_EXACT_CONFIG_SECTION=true
echo RESULT=PASS_R20QUC_SNAPSHOT
EOF_PVE
grep -Fqx RESULT=PASS_R20QUC_SNAPSHOT "$EVIDENCE/snapshot.log"
grep -Fqx SNAPSHOT_EXACT_CONFIG_SECTION=true "$EVIDENCE/snapshot.log"
SNAPSHOT_CREATED=true
router_runtime_transition_set "$TRANSITION_STATE" BACKUP_READY true
event_emit SNAPSHOT_CREATED
router_step_phase_complete snapshot snapshot_created_and_exact_config_section_verified_before_reboot

CURRENT_PHASE=reboot; router_step_phase_begin reboot
REBOOT_REQUEST_EPOCH="$(date +%s)"
pve_script > "$EVIDENCE/reboot-request.log" <<EOF_PVE
# SELFTEST_QUERY=REBOOT
set -Eeuo pipefail
qm status $VMID | grep -Fq 'status: running'
qm reboot $VMID
echo RESULT=PASS_R20QUC_REBOOT_REQUESTED
EOF_PVE
grep -Fqx RESULT=PASS_R20QUC_REBOOT_REQUESTED "$EVIDENCE/reboot-request.log"
REBOOT_REQUESTED=true
printf 'REBOOT_REQUEST_EPOCH=%s\n' "$REBOOT_REQUEST_EPOCH" > "$RUN_DIR/reboot.env"; chmod 600 "$RUN_DIR/reboot.env"
event_emit REBOOT_REQUESTED
if [[ -f "$BASE/selftest-force-stop-precore" ]]; then false; fi
router_step_phase_complete reboot reboot_command_accepted

CURRENT_PHASE=reconnect; router_step_phase_begin reconnect
RECONNECT_DEADLINE=$(( $(date +%s) + 300 ))
DISCONNECT_OBSERVED=false
LAST_PROGRESS=0
POST_BOOT_ID=''
while true; do
  set +e
  vm101_script > "$EVIDENCE/boot-id.latest.log" 2>&1 <<'EOS'
# SELFTEST_QUERY=BOOT_ID
cat /proc/sys/kernel/random/boot_id
EOS
  rc=$?
  set -e
  if [[ $rc -ne 0 ]]; then
    if [[ "$DISCONNECT_OBSERVED" == false ]]; then DISCONNECT_OBSERVED=true; event_emit VM101_DISCONNECTED; fi
  else
    candidate="$(tail -n1 "$EVIDENCE/boot-id.latest.log" | tr -d '\r')"
    if [[ -n "$candidate" && "$candidate" != "$PRE_BOOT_ID" ]]; then POST_BOOT_ID="$candidate"; cp "$EVIDENCE/boot-id.latest.log" "$EVIDENCE/boot-id-changed.log"; break; fi
  fi
  now="$(date +%s)"; [[ $now -lt $RECONNECT_DEADLINE ]] || { echo RESULT=STOP_R20QUC_RECONNECT_TIMEOUT; exit 31; }
  if (( now - LAST_PROGRESS >= 10 )); then progress_emit "disconnect_observed=$DISCONNECT_OBSERVED"; LAST_PROGRESS=$now; fi
  sleep 2
done
event_emit VM101_RECONNECTED
event_emit BOOT_ID_CHANGED
printf 'POST_BOOT_ID=%s\nDISCONNECT_OBSERVED=%s\n' "$POST_BOOT_ID" "$DISCONNECT_OBSERVED" > "$POST_ENV"; chmod 600 "$POST_ENV"
router_step_phase_complete reconnect changed_boot_id_and_automatic_reconnect

CURRENT_PHASE=production_boot_verify; router_step_phase_begin production_boot_verify
BOOT_DEADLINE=$(( $(date +%s) + 240 ))
LAST_PROGRESS=0
while true; do
  set +e
  vm101_script > "$EVIDENCE/production-boot.latest.log" 2>&1 <<EOF_VM101
# SELFTEST_QUERY=POST_BOOT_OBSERVE
set -eu
REQ=$REBOOT_REQUEST_EPOCH
. /usr/local/lib/router-egress-recovery-state.sh
. /etc/router-egress-generation.conf
reg_init_state
reg_state_validate_file /etc/router-egress-recovery/state.kv
reg_state_validate_file /var/lib/router-egress-recovery/state.kv
cmp -s /etc/router-egress-recovery/state.kv /var/lib/router-egress-recovery/state.kv
persist_sha="\$(sha256sum /etc/router-egress-recovery/state.kv | awk '{print \$1}')"
runtime_sha="\$(sha256sum /var/lib/router-egress-recovery/state.kv | awk '{print \$1}')"
[ "\$persist_sha" = '$PRE_PERSIST_SHA' ]
mode="\$(reg_get_state mode UNKNOWN)"
active="\$(reg_get_state active_generation_id '')"
[ "\$mode" = NORMAL ]
[ "\$active" = '$ACTIVE_GENERATION_ID' ]
[ -s /var/run/router-egress-boot-handoff.ready ]
ready_gen="\$(sed -n 's/^generation_id=//p' /var/run/router-egress-boot-handoff.ready | tail -n1)"
ready_epoch="\$(sed -n 's/^completed_at_epoch=//p' /var/run/router-egress-boot-handoff.ready | tail -n1)"
service_order="\$(sed -n 's/^service_order=//p' /var/run/router-egress-boot-handoff.ready | tail -n1)"
[ "\$ready_gen" = '$ACTIVE_GENERATION_ID' ]
case "\$ready_epoch" in ''|*[!0-9]*) exit 75;; esac
[ "\$ready_epoch" -ge "\$REQ" ]
[ "\$service_order" = 'router-wgpay-topology-delivery router-egress-zero-healthy-bootstrap router-egress-health-repair router-egress-full-pool-refresh-retry' ]
anchor="\$(readlink -f /var/lib/router-egress-recovery/generations/active 2>/dev/null || true)"
[ -n "\$anchor" ]
[ "\$(basename "\$anchor")" = '$ACTIVE_GENERATION_ID' ]
[ "\$(sed -n 's/^generation_id=//p' "\$anchor/metadata.kv" | tail -n1)" = '$ACTIVE_GENERATION_ID' ]
[ "\$(sed -n 's/^boot_reconstructed=//p' "\$anchor/metadata.kv" | tail -n1)" = true ]
[ "\$(sed -n 's/^boot_source=//p' "\$anchor/metadata.kv" | tail -n1)" = current_uci_network ]
anchor_epoch="\$(sed -n 's/^created_at_epoch=//p' "\$anchor/metadata.kv" | tail -n1)"
case "\$anchor_epoch" in ''|*[!0-9]*) exit 75;; esac
[ "\$anchor_epoch" -ge "\$REQ" ]
for n in 1 2 3 4 5; do
  iface="vpn\$n"; table=\$((200+n)); mark="0x20\$n"
  ip link show dev "\$iface" >/dev/null 2>&1
  endpoint="\$(amneziawg show "\$iface" endpoints 2>/dev/null | awk 'NF>=2{print \$NF;exit}')"
  [ -n "\$endpoint" ] && [ "\$endpoint" != '(none)' ]
  ip route show table "\$table" | grep -Eq "default[[:space:]].*dev[[:space:]]+\$iface"
  ip rule show | grep -E "fwmark \$mark.*lookup \$table|fwmark \$mark/0xffffffff.*lookup \$table" >/dev/null
 done
status="\$(/usr/local/sbin/router-egress-slots-status.sh)"
healthy="\$(printf '%s\n' "\$status" | sed -n 's/.*"healthy"[[:space:]]*:[[:space:]]*\([0-9][0-9]*\).*/\1/p' | tail -n1)"
[ "\$healthy" = 5 ]
[ "\$(sed -n 's/^mode=//p' /etc/router-wgpay-fallback/state.kv | tail -n1)" = NORMAL ]
[ "\$(sed -n 's/^healthy_slots=//p' /etc/router-wgpay-fallback/state.kv | tail -n1)" = 'egress1,egress2,egress3,egress4,egress5' ]
outbox="\$(/usr/local/sbin/router-wgpay-topology-outbox.sh --status)"
printf '%s\n' "\$outbox" | grep -Fqx pending_present=false
grep -Fqx PROVIDER_DIRECT_ENABLED=0 /etc/router-egress-provider-direct.conf
grep -Fqx BOOTSTRAP_CONTROLLER_PROVIDER_DIRECT_ENABLED=0 /etc/router-egress-zero-healthy-bootstrap.conf
count_proc() { ps w 2>/dev/null | grep -F "\$1" | grep -v grep | wc -l | tr -d ' '; }
refresh_owner_count="\$(count_proc '/usr/local/sbin/router-egress-full-pool-refresh-retry.sh --loop')"
[ "\$refresh_owner_count" = 1 ]
[ "\$(count_proc '/usr/local/sbin/router-egress-provider-direct.sh --loop')" = 0 ]
owner_tick="\$(/usr/local/sbin/router-egress-full-pool-refresh-retry.sh --tick)"
printf '%s\n' "\$owner_tick" | grep -Fqx RESULT=NOOP_R20QUB_REFRESH_OWNER_NORMAL
grep -F "result=PASS active_generation_id=$ACTIVE_GENERATION_ID" /var/log/router-egress-boot-handoff.log >/dev/null
boot_id="\$(cat /proc/sys/kernel/random/boot_id)"
uptime_sec="\$(cut -d. -f1 /proc/uptime)"
echo RESULT=PASS_R20QUC_PRODUCTION_BOOT_BOUNDARY
echo BOOT_ID="\$boot_id"
echo UPTIME_SEC="\$uptime_sec"
echo PERSIST_STATE_SHA256="\$persist_sha"
echo RUNTIME_STATE_SHA256="\$runtime_sha"
echo RECOVERY_MODE="\$mode"
echo ACTIVE_GENERATION_ID="\$active"
echo RUNTIME_ANCHOR_REAL="\$anchor"
echo RUNTIME_ANCHOR_BOOT_RECONSTRUCTED=true
echo RUNTIME_ANCHOR_BOOT_SOURCE=current_uci_network
echo RUNTIME_ANCHOR_CREATED_AT_EPOCH="\$anchor_epoch"
echo BOOT_READY_COMPLETED_AT_EPOCH="\$ready_epoch"
echo BOOT_READY_SERVICE_ORDER="\$service_order"
echo FIVE_VPN_LINKS_READY=true
echo ROUTE_TABLES_READY=true
echo HEALTHY_SLOTS="\$healthy"
echo TOPOLOGY_MODE=NORMAL
echo TOPOLOGY_PENDING=false
echo PROVIDER_DIRECT_POLICY=disabled_until_proven
echo REFRESH_OWNER_PROCESS_COUNT="\$refresh_owner_count"
echo REFRESH_OWNER_TICK_RESULT=NOOP_R20QUB_REFRESH_OWNER_NORMAL
echo BOOT_HANDOFF_LOG_PASS=true
EOF_VM101
  rc=$?
  set -e
  if [[ $rc -eq 0 ]] && grep -Fqx RESULT=PASS_R20QUC_PRODUCTION_BOOT_BOUNDARY "$EVIDENCE/production-boot.latest.log"; then
    cp "$EVIDENCE/production-boot.latest.log" "$EVIDENCE/production-boot-proof.log"
    break
  fi
  now="$(date +%s)"; [[ $now -lt $BOOT_DEADLINE ]] || { cat "$EVIDENCE/production-boot.latest.log" >&2 || true; echo RESULT=STOP_R20QUC_PRODUCTION_BOOT_TIMEOUT; exit 32; }
  if (( now - LAST_PROGRESS >= 10 )); then progress_emit "boot_wait_rc=$rc"; LAST_PROGRESS=$now; fi
  sleep 3
done
CORE_CHANGE_COMPLETE=true
router_runtime_transition_set "$TRANSITION_STATE" CORE_CHANGE_COMPLETE true
router_runtime_transition_set "$TRANSITION_STATE" ACTIVATION_COMPLETE true
ROLLBACK_STATUS=not_allowed_after_core_boot_activation
{
  echo CORE_CHANGE_COMPLETE=true
  echo "CORE_CHANGE_POINT=$CORE_CHANGE_POINT"
  echo "CORE_CHANGE_EPOCH=$(date +%s)"
} > "$CORE_ENV"; chmod 600 "$CORE_ENV"
event_emit RUNTIME_ANCHOR_CREATED
event_emit BOOT_READY_MARKER
event_emit FIVE_HEALTHY
event_emit CORE_BOOT_ACTIVATION_COMPLETE
router_step_phase_complete production_boot_verify core_boundary_crossed_immediately_after_ready_anchor_fivehealthy_routes

if [[ -f "$BASE/selftest-force-stop-postcore" ]]; then false; fi
CURRENT_PHASE=post_core_verify; router_step_phase_begin post_core_verify
vm100_script > "$EVIDENCE/vm100-direct-state.log" <<'EOS'
# SELFTEST_QUERY=DIRECT_STATE
set -eu
state=/var/lib/router-wgpay-direct-mode/state.kv
if [ -e "$state" ]; then cat "$state"; else echo DIRECT_STATE_ABSENT=true; fi
EOS
if grep -Fqx DIRECT_STATE_ABSENT=true "$EVIDENCE/vm100-direct-state.log"; then
  rm -f "$EVIDENCE/vm100-direct-state.kv"
else
  cp "$EVIDENCE/vm100-direct-state.log" "$EVIDENCE/vm100-direct-state.kv"
fi
router_direct_state_oracle "$EVIDENCE/vm100-direct-state.kv" | tee "$EVIDENCE/vm100-direct-oracle.log"
grep -Fqx DIRECT_ORACLE=PASS "$EVIDENCE/vm100-direct-oracle.log"
event_emit DIRECT_REMAINS_INACTIVE

vm101_script > "$EVIDENCE/vm101-final.log" <<EOS
# SELFTEST_QUERY=FINAL_VM101
set -eu
/usr/local/sbin/router-vm101-git-publish.sh --check
status="\$(/usr/local/sbin/router-egress-slots-status.sh)"
healthy="\$(printf '%s\n' "\$status" | sed -n 's/.*"healthy"[[:space:]]*:[[:space:]]*\([0-9][0-9]*\).*/\1/p' | tail -n1)"
[ "\$healthy" = 5 ]
. /usr/local/lib/router-egress-recovery-state.sh
reg_init_state
mode="\$(reg_get_state mode UNKNOWN)"
[ "\$mode" = NORMAL ]
[ -s /var/run/router-egress-boot-handoff.ready ]
outbox="\$(/usr/local/sbin/router-wgpay-topology-outbox.sh --status)"
printf '%s\n' "\$outbox" | grep -Fqx pending_present=false
refresh_owner_count="\$(ps w 2>/dev/null | grep -F '/usr/local/sbin/router-egress-full-pool-refresh-retry.sh --loop' | grep -v grep | wc -l | tr -d ' ')"
[ "\$refresh_owner_count" = 1 ]
active_refresh_count="\$(ps w 2>/dev/null | grep '[r]outer-egress-full-pool-refresh.sh' | wc -l | tr -d ' ')"
[ "\$active_refresh_count" = 0 ]
echo RESULT=PASS_R20QUC_FINAL_VM101
echo HEALTHY_SLOTS="\$healthy"
echo RECOVERY_MODE="\$mode"
echo TOPOLOGY_MODE=NORMAL
echo TOPOLOGY_PENDING=false
echo BOOT_READY=true
echo REFRESH_OWNER_PROCESS_COUNT="\$refresh_owner_count"
echo ACTIVE_REFRESH_PROCESS_COUNT="\$active_refresh_count"
EOS
grep -Fqx RESULT=PASS_R20QUC_FINAL_VM101 "$EVIDENCE/vm101-final.log"
grep -Fqx RESULT=PASS_vm101_GIT_PUBLISH_CHECK "$EVIDENCE/vm101-final.log"
grep -Fqx "GIT_COMMIT=$VM101_GIT_COMMIT" "$EVIDENCE/vm101-final.log"
grep -Fqx "GIT_TREE=$VM101_GIT_TREE" "$EVIDENCE/vm101-final.log"
grep -Fqx "GIT_FILE_COUNT=$VM101_GIT_FILE_COUNT" "$EVIDENCE/vm101-final.log"
pve_script > "$EVIDENCE/pve-final.log" <<EOF_PVE
# SELFTEST_QUERY=SNAPSHOT_STATUS
set -Eeuo pipefail
qm status $VMID | grep -Fq 'status: running'
qm listsnapshot $VMID | awk '{print \$2}' | grep -Fxq '$SNAPSHOT_NAME'
echo RESULT=PASS_R20QUC_SNAPSHOT_AND_VM_RUNNING
EOF_PVE
grep -Fqx RESULT=PASS_R20QUC_SNAPSHOT_AND_VM_RUNNING "$EVIDENCE/pve-final.log"
printf 'VM101_GIT_COMMIT=%s\nVM101_GIT_TREE=%s\nVM101_GIT_FILE_COUNT=%s\n' "$VM101_GIT_COMMIT" "$VM101_GIT_TREE" "$VM101_GIT_FILE_COUNT" > "$GIT_ENV"; chmod 600 "$GIT_ENV"
event_emit TOPOLOGY_NORMAL
event_emit GIT_CLEAN
router_step_phase_complete post_core_verify direct_inactive_topology_normal_single_owner_git_clean

CURRENT_PHASE=source_publication; router_step_phase_begin source_publication
if [[ "$SELFTEST" == true ]]; then
  printf '%s\n' 'RESULT=PASS_ROUTER_MACHINE_CLOSE_SAFE' 'VM101_PUBLIC_URL=selftest://vm101-source/' "COMMIT=$VM101_GIT_COMMIT" "TREE=$VM101_GIT_TREE" "GIT_FILE_COUNT=$VM101_GIT_FILE_COUNT" > "$EVIDENCE/vm101-source-publication.log"
else
  "$BASE/bin/router-machine-close-safe" vm101 'STEP_050M07R20QUC: controlled production reboot proof PASS; source unchanged' | tee "$EVIDENCE/vm101-source-publication.log"
fi
VM101_PUBLIC_URL="$(awk -F= '$1=="VM101_PUBLIC_URL"{print substr($0,index($0,"=")+1)}' "$EVIDENCE/vm101-source-publication.log" | tail -n1)"
[[ -n "$VM101_PUBLIC_URL" ]]
grep -Fqx "COMMIT=$VM101_GIT_COMMIT" "$EVIDENCE/vm101-source-publication.log"
grep -Fqx "TREE=$VM101_GIT_TREE" "$EVIDENCE/vm101-source-publication.log"
grep -Fqx "GIT_FILE_COUNT=$VM101_GIT_FILE_COUNT" "$EVIDENCE/vm101-source-publication.log"
printf 'VM101_PUBLIC_URL=%s\nVM101_GIT_COMMIT=%s\nVM101_GIT_TREE=%s\nVM101_GIT_FILE_COUNT=%s\n' "$VM101_PUBLIC_URL" "$VM101_GIT_COMMIT" "$VM101_GIT_TREE" "$VM101_GIT_FILE_COUNT" > "$SOURCE_ENV"; chmod 600 "$SOURCE_ENV"
router_step_phase_complete source_publication fresh_source_snapshot_same_clean_commit

CURRENT_PHASE=model_publication; router_step_phase_begin model_publication
"$FINAL_ROOT/scripts/publish-vm101-model.sh" "$RUN_DIR" "$GIT_ENV" "$MODEL_ENV" | tee "$EVIDENCE/model-publication.log"
VM101_MODEL_URL="$(kv_read VM101_MODEL_URL "$MODEL_ENV")"
router_step_phase_complete model_publication reboot_proven_model_published

CURRENT_PHASE=methods_publication; router_step_phase_begin methods_publication
"$FINAL_ROOT/scripts/publish-vm101-methods.sh" "$RUN_DIR" "$FINAL_ROOT" "$GIT_ENV" "$METHODS_ENV" | tee "$EVIDENCE/methods-publication.log"
VM101_METHODS_URL="$(kv_read VM101_METHODS_URL "$METHODS_ENV")"
router_step_phase_complete methods_publication reboot_proof_methods_published

CURRENT_PHASE=project_source; router_step_phase_begin project_source
"$FINAL_ROOT/scripts/publish-project-source.sh" "$RUN_DIR" "$FINAL_ROOT" "$SOURCE_ENV" "$MODEL_ENV" "$METHODS_ENV" "$PROJECT_ENV" | tee "$EVIDENCE/project-source.log"
PROJECT_SOURCE_POST_URL="$(kv_read PROJECT_SOURCE_POST_URL "$PROJECT_ENV")"
router_step_phase_complete project_source reboot_checkpoint_and_proof_source_published

CURRENT_PHASE=report_build; router_step_phase_begin report_build
python3 "$FINAL_ROOT/scripts/build-report.py" "$RUN_DIR" "$REPORT" "$(cat "$FINAL_ROOT/installer.sha256")" "$GIT_ENV" "$SOURCE_ENV" "$MODEL_ENV" "$METHODS_ENV" "$PROJECT_ENV" "$SNAPSHOT_ENV" "$PRE_ENV" "$POST_ENV"
cp "$FINAL_ROOT/scripts/run-step.sh" "$REPORT/executed-step.sh"
cp "$FINAL_ROOT/release-info.json" "$REPORT/release-info.json"
cp "$FINAL_ROOT/manifest.sha256" "$REPORT/bundle-manifest.sha256"
cp "$CURRENT" "$REPORT/workflow-current.txt"
cp "$EVENTS" "$REPORT/workflow-events.tsv"
cp "$EVIDENCE/"*.log "$REPORT/" 2>/dev/null || true
cp "$CORE_ENV" "$REPORT/core-change.env"
router_step_phase_complete report_build complete_controlled_reboot_pass_payload

CURRENT_PHASE=report_publish; router_step_phase_begin report_publish
if [[ "$SELFTEST" == true ]]; then
  mkdir -p "${ROUTER_PUBLIC_ROOT:?}/latest/r20quc-pass"
  cp "$REPORT/report.txt" "$ROUTER_PUBLIC_ROOT/latest/r20quc-pass/report.txt"
  STEP_REPORT_URL=selftest://r20quc-pass/
else
  router_step_publish_payload step050m07r20quc_vm101_controlled_reboot_proof \
    "$REPORT" "$PAYLOAD" "$CURRENT" "$EVENTS" "$FINAL_ENV" \
    "$REPORT/report.txt" report.txt \
    "$REPORT/facts.json" facts.json \
    "$REPORT/facts-public.html" facts-public.html \
    "$REPORT/verify.txt" verify.txt \
    "$REPORT/verify-public.html" verify-public.html \
    "$REPORT/rollback-public.html" rollback-public.html \
    "$REPORT/executed-step.sh" executed-step.sh \
    "$REPORT/release-info.json" release-info.json \
    "$REPORT/bundle-manifest.sha256" bundle-manifest.sha256 \
    "$REPORT/workflow-current.txt" workflow-current.txt \
    "$REPORT/workflow-events.tsv" workflow-events.tsv \
    "$REPORT/core-change.env" core-change.env \
    "$REPORT/runtime-transition.env" runtime-transition.env \
    "$REPORT/vm101-preflight.log" vm101-preflight.log \
    "$REPORT/snapshot.log" snapshot.log \
    "$REPORT/reboot-request.log" reboot-request.log \
    "$REPORT/boot-id-changed.log" boot-id-changed.log \
    "$REPORT/production-boot-proof.log" production-boot-proof.log \
    "$REPORT/vm100-direct-oracle.log" vm100-direct-oracle.log \
    "$REPORT/vm101-final.log" vm101-final.log \
    "$REPORT/pve-final.log" pve-final.log \
    "$REPORT/live-events.log" live-events.log
  STEP_REPORT_URL="$(awk -F= '$1=="PUBLIC_URL"{print substr($0,index($0,"=")+1)}' "$FINAL_ENV" | tail -n1)"
fi
router_step_phase_complete report_publish controlled_reboot_pass_report_published

CURRENT_PHASE=archive; router_step_phase_begin archive
archive_latest
[[ "$LATEST_ARCHIVE" != not_created && -f "$LATEST_ARCHIVE" ]]
router_step_phase_complete archive one_final_latest_python_zip_created
router_step_workflow_mark_complete
trap - ERR
write_child PASS_R20QUC_VM101_CONTROLLED_REBOOT_PROOF 0
cat "$REPORT/report.txt"
echo "STEP_REPORT_URL=$STEP_REPORT_URL"
echo "LATEST_ARCHIVE=$LATEST_ARCHIVE"
echo "LATEST_ARCHIVE_SHA256=$LATEST_ARCHIVE_SHA256"
echo CORE_CHANGE_COMPLETE=true
