#!/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'; SNAPSHOT_NAME='r20quc-pre-0801-084130'
R04_RUN_DIR='/opt/router-ops/state/detached-step-runs/STEP_050M07R20QUC_R04_VM101_CONTROLLED_REBOOT_PROOF/runs/20260801-095239-683471-3469'; [[ "$SELFTEST" == true ]] && R04_RUN_DIR="$BASE/selftest-r04-run"
PVE_HOST='pve-mgts'; 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)"
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"; LIVE_ENV="$RUN_DIR/live-state.env"
CURRENT_PHASE=bootstrap; CORE_CHANGE_COMPLETE=true; ROLLBACK_STATUS=not_allowed_after_core_boot_activation; FAILURE_HANDLED=false; STEP_REPORT_URL=not_published; LATEST_ARCHIVE=not_created; LATEST_ARCHIVE_SHA256=unknown
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"
router_step_workflow_init "$CURRENT" "$EVENTS" preflight independent_extract mandatory_tests r04_evidence_verify live_readonly_verify model_publication methods_publication project_source report_build report_publish archive
kv_read(){ awk -F= -v k="$1" '$1==k{v=substr($0,index($0,"=")+1)} END{print v}' "$2"; }
vm101_script(){ if [[ "$SELFTEST" == true ]]; then cat >/dev/null; cat <<EOS
RESULT=PASS_R20QUC_R05_LIVE_VM101
BOOT_ID=boot-after
HEALTHY_SLOTS=5
RECOVERY_MODE=NORMAL
ACTIVE_GENERATION_ID=$ACTIVE_GENERATION_ID
TOPOLOGY_MODE=NORMAL
TOPOLOGY_PENDING=false
BOOT_READY=true
REFRESH_OWNER_PROCESS_COUNT=1
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
else ssh -o BatchMode=yes -o ConnectTimeout=20 "$PVE_HOST" "ssh -i '$PVE_KEY' -o BatchMode=yes -o ConnectTimeout=20 root@'$VM101_ADDR' 'sh -s'"; fi; }
vm100_script(){ if [[ "$SELFTEST" == true ]]; then cat >/dev/null; echo DIRECT_STATE_ABSENT=true; else ssh -o BatchMode=yes -o ConnectTimeout=20 "$PVE_HOST" "ssh -i '$PVE_KEY' -o BatchMode=yes -o ConnectTimeout=20 root@'$VM100_ADDR' 'sh -s'"; fi; }
pve_script(){ if [[ "$SELFTEST" == true ]]; then cat >/dev/null; printf '%s\n' RESULT=PASS_R20QUC_R05_PVE_LIVE VM_STATUS=running SNAPSHOT_AVAILABLE=true; 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=true; echo CORE_CHANGE_REPEATED=false; echo CONTROLLED_REBOOT_REPEATED=false; echo RUNTIME_IMPACT=false; 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="$(kv_read LATEST_ARCHIVE "$EVIDENCE/latest-archive.log")"; LATEST_ARCHIVE_SHA256="$(kv_read LATEST_ARCHIVE_SHA256 "$EVIDENCE/latest-archive.log")"; fi; return $rc; }
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" || 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; if [[ "$SELFTEST" == true ]]; then mkdir -p "${ROUTER_PUBLIC_ROOT:?}/latest/r20quc-r05-stop"; cp "$REPORT/report.txt" "$ROUTER_PUBLIC_ROOT/latest/r20quc-r05-stop/report.txt"; STEP_REPORT_URL=selftest://r20quc-r05-stop/; return 0; fi; set +e; router_step_publish_payload step050m07r20quc_r05_publication_continuation_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; publish_stop "$phase" "$line" "$rc" "$command" || true; archive_latest || true; write_child STOP_R20QUC_R05_PUBLICATION_CONTINUATION "$rc"; echo RESULT=STOP_R20QUC_R05_PUBLICATION_CONTINUATION; echo "STOP_PHASE=$phase"; echo "STOP_LINE=$line"; echo "STOP_RC=$rc"; printf 'STOP_COMMAND=%q\n' "$command"; echo CORE_CHANGE_COMPLETE=true; echo CORE_CHANGE_REPEATED=false; echo CONTROLLED_REBOOT_REPEATED=false; echo RUNTIME_IMPACT=false; echo "ROLLBACK_STATUS=$ROLLBACK_STATUS"; echo "STEP_REPORT_URL=$STEP_REPORT_URL"; echo "LATEST_ARCHIVE=$LATEST_ARCHIVE"; echo "LATEST_ARCHIVE_SHA256=$LATEST_ARCHIVE_SHA256"; 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"
"$BASE/bin/router-release-contract" verify --root "$BUNDLE_ROOT" --step "$STEP_ID"
grep -Fqx RESULT=STOP_R20QUC_VM101_CONTROLLED_REBOOT_PROOF "$BUNDLE_ROOT/reference/r20quc-r04-stop-report.txt"; grep -Fqx CORE_CHANGE_COMPLETE=true "$BUNDLE_ROOT/reference/r20quc-r04-stop-report.txt"; grep -Fqx STOP_PHASE=methods_publication "$BUNDLE_ROOT/reference/r20quc-r04-stop-report.txt"
router_step_phase_complete preflight r04_public_stop_core_complete_and_read_only_boundary
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"; "$FINAL_ROOT/scripts/apply-vm101-publication-continuation.sh" "$ROUTER_RELEASE_TARGET_PACKAGE_SHA256" "$FINAL_ROOT/$ROUTER_RELEASE_TARGET_PACKAGE_PATH" verify-publication-continuation-input | tee "$EVIDENCE/apply-input-contract.log"; grep -Fqx RESULT=PASS_R20QUC_R05_PUBLICATION_CONTINUATION_INPUT_CONTRACT "$EVIDENCE/apply-input-contract.log"; router_step_phase_complete independent_extract canonical_bundle_and_no_apply_contract_verified
CURRENT_PHASE=mandatory_tests; router_step_phase_begin mandatory_tests
: > "$EVIDENCE/mandatory-tests.log"; while IFS= read -r t; do [[ -n "$t" && "$t" != \#* ]] || continue; echo ">>> $t" >> "$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/$t" >> "$EVIDENCE/mandatory-tests.log" 2>&1; done < "$FINAL_ROOT/tests/mandatory.list"; router_step_phase_complete mandatory_tests exact_pass_and_stop_publication_paths_proven
CURRENT_PHASE=r04_evidence_verify; router_step_phase_begin r04_evidence_verify
for f in child-result.env core-change.env pre-reboot.env post-reboot.env workflow-current.txt workflow-events.tsv vm101-source.env vm101-model.env; do [[ -f "$R04_RUN_DIR/$f" ]]; done
for f in production-boot-proof.log vm100-direct-oracle.log vm101-final.log pve-final.log snapshot.log reboot-request.log boot-id-changed.log live-events.log mandatory-tests.log; do [[ -f "$R04_RUN_DIR/evidence/$f" ]]; done
grep -Fqx RESULT=STOP_R20QUC_VM101_CONTROLLED_REBOOT_PROOF "$R04_RUN_DIR/child-result.env"; grep -Fqx CORE_CHANGE_COMPLETE=true "$R04_RUN_DIR/child-result.env"; grep -Fqx REBOOT_REQUESTED=true "$R04_RUN_DIR/child-result.env"; grep -Fqx RESULT=PASS_R20QUC_PRODUCTION_BOOT_BOUNDARY "$R04_RUN_DIR/evidence/production-boot-proof.log"; grep -Fqx HEALTHY_SLOTS=5 "$R04_RUN_DIR/evidence/production-boot-proof.log"; grep -Fqx TOPOLOGY_MODE=NORMAL "$R04_RUN_DIR/evidence/production-boot-proof.log"; grep -Fqx DIRECT_ORACLE=PASS "$R04_RUN_DIR/evidence/vm100-direct-oracle.log"; grep -Fqx RESULT=PASS_R20QUC_FINAL_VM101 "$R04_RUN_DIR/evidence/vm101-final.log"; grep -Fqx RESULT=PASS_R20QUC_SNAPSHOT_AND_VM_RUNNING "$R04_RUN_DIR/evidence/pve-final.log"; grep -Fqx CORE_CHANGE_COMPLETE=true "$R04_RUN_DIR/core-change.env"; grep -Fqx DISCONNECT_OBSERVED=true "$R04_RUN_DIR/post-reboot.env"
PRE_BOOT_ID="$(kv_read PRE_BOOT_ID "$R04_RUN_DIR/post-reboot.env")"; POST_BOOT_ID="$(kv_read POST_BOOT_ID "$R04_RUN_DIR/post-reboot.env")"; [[ -n "$PRE_BOOT_ID" && -n "$POST_BOOT_ID" && "$PRE_BOOT_ID" != "$POST_BOOT_ID" ]]
R04_SOURCE_URL="$(kv_read VM101_PUBLIC_URL "$R04_RUN_DIR/vm101-source.env")"; R04_MODEL_URL="$(kv_read VM101_MODEL_URL "$R04_RUN_DIR/vm101-model.env")"; [[ -n "$R04_SOURCE_URL" && -n "$R04_MODEL_URL" ]]
printf 'RESULT=PASS_R20QUC_R05_R04_RETAINED_EVIDENCE\nR04_RUN_DIR=%s\nPRE_BOOT_ID=%s\nPOST_BOOT_ID=%s\nR04_SOURCE_URL=%s\nR04_MODEL_URL=%s\n' "$R04_RUN_DIR" "$PRE_BOOT_ID" "$POST_BOOT_ID" "$R04_SOURCE_URL" "$R04_MODEL_URL" | tee "$EVIDENCE/r04-retained-evidence.log"
printf 'VM101_PUBLIC_URL=%s\nVM101_GIT_COMMIT=%s\nVM101_GIT_TREE=%s\nVM101_GIT_FILE_COUNT=%s\n' "$R04_SOURCE_URL" "$VM101_GIT_COMMIT" "$VM101_GIT_TREE" "$VM101_GIT_FILE_COUNT" > "$SOURCE_ENV"; chmod 600 "$SOURCE_ENV"
router_step_phase_complete r04_evidence_verify exact_retained_core_reboot_and_postcheck_evidence_verified
CURRENT_PHASE=live_readonly_verify; router_step_phase_begin live_readonly_verify
vm101_script > "$EVIDENCE/vm101-live-verify.log" <<EOS
set -eu
/usr/local/sbin/router-vm101-git-publish.sh --check
. /usr/local/lib/router-egress-recovery-state.sh; reg_init_state
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 ]
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 ]
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
owner="\$(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 ' ')"; [ "\$owner" = 1 ]; active_refresh="\$(ps w 2>/dev/null | grep '[r]outer-egress-full-pool-refresh.sh' | wc -l | tr -d ' ')"; [ "\$active_refresh" = 0 ]
boot_id="\$(cat /proc/sys/kernel/random/boot_id)"; [ "\$boot_id" = '$POST_BOOT_ID' ]
echo RESULT=PASS_R20QUC_R05_LIVE_VM101; echo BOOT_ID="\$boot_id"; echo HEALTHY_SLOTS="\$healthy"; echo RECOVERY_MODE="\$mode"; echo ACTIVE_GENERATION_ID="\$active"; echo TOPOLOGY_MODE=NORMAL; echo TOPOLOGY_PENDING=false; echo BOOT_READY=true; echo REFRESH_OWNER_PROCESS_COUNT="\$owner"; echo ACTIVE_REFRESH_PROCESS_COUNT="\$active_refresh"
EOS
grep -Fqx RESULT=PASS_R20QUC_R05_LIVE_VM101 "$EVIDENCE/vm101-live-verify.log"; grep -Fqx RESULT=PASS_vm101_GIT_PUBLISH_CHECK "$EVIDENCE/vm101-live-verify.log"; grep -Fqx "GIT_COMMIT=$VM101_GIT_COMMIT" "$EVIDENCE/vm101-live-verify.log"; grep -Fqx "GIT_TREE=$VM101_GIT_TREE" "$EVIDENCE/vm101-live-verify.log"; grep -Fqx "GIT_FILE_COUNT=$VM101_GIT_FILE_COUNT" "$EVIDENCE/vm101-live-verify.log"
vm100_script > "$EVIDENCE/vm100-direct-state.log" <<'EOS'
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"
pve_script > "$EVIDENCE/pve-live-verify.log" <<EOF_PVE
set -Eeuo pipefail
qm status 101 | grep -Fq 'status: running'; grep -Fqx '[$SNAPSHOT_NAME]' /etc/pve/qemu-server/101.conf; echo RESULT=PASS_R20QUC_R05_PVE_LIVE; echo VM_STATUS=running; echo SNAPSHOT_AVAILABLE=true
EOF_PVE
grep -Fqx RESULT=PASS_R20QUC_R05_PVE_LIVE "$EVIDENCE/pve-live-verify.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"
printf 'ACTIVE_GENERATION_ID=%s\nHEALTHY_SLOTS=5\nRECOVERY_MODE=NORMAL\nTOPOLOGY_MODE=NORMAL\nDIRECT_ORACLE=PASS\n' "$ACTIVE_GENERATION_ID" > "$LIVE_ENV"; chmod 600 "$LIVE_ENV"
[[ ! -f "$BASE/selftest-force-stop" ]]
router_step_phase_complete live_readonly_verify normal_fivehealthy_direct_inactive_git_clean_same_postreboot_boot_id
CURRENT_PHASE=model_publication; router_step_phase_begin model_publication
"$FINAL_ROOT/scripts/publish-vm101-model.sh" "$RUN_DIR" "$GIT_ENV" "$LIVE_ENV" "$MODEL_ENV" | tee "$EVIDENCE/model-publication.log"; router_step_phase_complete model_publication current_reboot_proven_model_published
CURRENT_PHASE=methods_publication; router_step_phase_begin methods_publication
"$FINAL_ROOT/scripts/publish-vm101-methods.sh" "$RUN_DIR" "$R04_RUN_DIR" "$FINAL_ROOT" "$GIT_ENV" "$METHODS_ENV" | tee "$EVIDENCE/methods-publication.log"; router_step_phase_complete methods_publication private_env_evidence_published_as_safe_txt
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"; router_step_phase_complete project_source r20qu_completion_checkpoint_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" "$LIVE_ENV" "$R04_RUN_DIR/post-reboot.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 "$R04_RUN_DIR/core-change.env" "$REPORT/core-change.txt"; cp "$R04_RUN_DIR/post-reboot.env" "$REPORT/post-reboot.txt"
router_step_phase_complete report_build final_r20quc_pass_payload_complete
CURRENT_PHASE=report_publish; router_step_phase_begin report_publish
if [[ "$SELFTEST" == true ]]; then mkdir -p "${ROUTER_PUBLIC_ROOT:?}/latest/r20quc-r05-pass"; cp "$REPORT/report.txt" "$ROUTER_PUBLIC_ROOT/latest/r20quc-r05-pass/report.txt"; STEP_REPORT_URL=selftest://r20quc-r05-pass/; else router_step_publish_payload step050m07r20quc_r05_controlled_reboot_publication_continuation "$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.txt" core-change.txt "$REPORT/post-reboot.txt" post-reboot.txt "$REPORT/r04-retained-evidence.log" r04-retained-evidence.log "$REPORT/vm101-live-verify.log" vm101-live-verify.log "$REPORT/vm100-direct-oracle.log" vm100-direct-oracle.log "$REPORT/pve-live-verify.log" pve-live-verify.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 final_r20quc_pass_report_published
CURRENT_PHASE=archive; router_step_phase_begin archive; archive_latest; [[ -f "$LATEST_ARCHIVE" ]]; router_step_phase_complete archive latest_archive_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 NEXT_STEP=R20Q-U_COMPLETE_RESUME_M07_PLAN
