#!/usr/bin/env bash
set -Eeuo pipefail
umask 077

STEP_ID='STEP_050M07R18_R09_MACHINE_GIT_AND_FINALIZATION_CONTINUATION'
RESULT='STOP_R18_R09_NOT_STARTED'
STOP_REASON='none'
CURRENT_PHASE='initializing'
COPY_VERIFY='FAIL'
HTTP_VERIFY_PASS=false
PUBLICATION_BARRIER=none
PUBLIC_OBJECT_KIND=step-report
PREVIOUS_MOVED_COUNT=0
RUNTIME_IMPACT=false
CORE_CHANGE_COMPLETE=false
CORE_CHANGE_REPEATED=false
TARGET_INSTALLER_RERUN=false
TARGET_POSTCHECK_REPEATED=false
MACHINE_GIT_COMPLETE=false
ROUTER_MACHINE_CLOSE_EXECUTED=false
ROUTER_MACHINE_CLOSE_RERUN=false
VM101_COMMIT=''
VM101_TREE=''
VM101_COUNT=''
NEW_GENERATION_ID='r18r08-20260719-060942-3890'
PREVIOUS_GENERATION_ID='r15b2-20260716-215914'
ACTIVATION_TRANSACTION_DIR='/var/lib/router-egress-recovery/activations/20260719-060943-r18r08-20260719-060942-3890'
ACTIVATION_ROLLBACK_FILE="${ACTIVATION_TRANSACTION_DIR}/rollback.sh"
TARGET_ROLLBACK_FILE=''
TARGET_BACKUP_DIR=''
R08_STEP_DIR=''
R08_STOP_REPORT_URL='https://reports.secret-studio.ru/latest/20260719-061045_step050m07r18_r08_canonical_path_and_resume_build_continuation_stop/'
PROJECT_SOURCE_POST_URL=''
PROJECT_SOURCE_POST_FILE_URL=''
STEP_REPORT_URL=''
FACTS_URL=''
VERIFY_URL=''
ROLLBACK_URL=''

BUNDLE_DIR="$(cd "$(dirname "$0")" && pwd -P)"
SELF="$(readlink -f "$0")"
BUNDLE_ZIP="${BUNDLE_ZIP:?BUNDLE_ZIP is required}"
EXPECTED_BUNDLE_SHA256="${EXPECTED_BUNDLE_SHA256:?EXPECTED_BUNDLE_SHA256 is required}"
EXPECTED_INSTALLER_SHA256="${EXPECTED_INSTALLER_SHA256:?EXPECTED_INSTALLER_SHA256 is required}"
BASE="${ROUTER_OPS_BASE:-/opt/router-ops}"
PUBLISHER="$BASE/bin/router-publish-report"
HTTP="$BASE/bin/router-http-verify"
FINALIZER="$BASE/bin/router-step-finalize"
SAFE_BUILDER="$BASE/bin/router-public-safe-payload"
HTML_BUILDER="$BASE/bin/router-public-html-aliases"
MACHINE_CLOSE="$BASE/bin/router-machine-close"
WORKFLOW_LIB="$BASE/lib/router-step-workflow.sh"
CONTRACT_LIB="$BASE/lib/router-publication-contract.sh"
TS="$(date -u +%Y%m%d-%H%M%S)"
STEP_DIR="$BASE/steps/${TS}_${STEP_ID}"
mkdir -p "$STEP_DIR"; chmod 700 "$STEP_DIR"
STOP_GUARD_DIR="$STEP_DIR/.stop-handler-active"
STEP_FILE="$STEP_DIR/step-code.sh"
BUNDLE_COPY="$STEP_DIR/$(basename "$BUNDLE_ZIP")"
cp -a "$SELF" "$STEP_FILE"; chmod 700 "$STEP_FILE"
cp -a "$BUNDLE_ZIP" "$BUNDLE_COPY"

REPORT="$STEP_DIR/report.txt"
FACTS="$STEP_DIR/facts.json"
VERIFY="$STEP_DIR/verify.txt"
ROLLBACK="$STEP_DIR/rollback.sh"
MAIN_LOG="$STEP_DIR/main.log"
PROGRESS="$STEP_DIR/progress.log"
TRANSFER="$STEP_DIR/transfer-verify.txt"
PHASE_CURRENT="$STEP_DIR/phase-current.env"
PHASE_EVENTS="$STEP_DIR/phase-events.log"
COMPONENTS="$STEP_DIR/components"
EXPORT_DIR="$STEP_DIR/vm101-export"
mkdir -p "$COMPONENTS" "$EXPORT_DIR"

exec 3>&1
exec >>"$MAIN_LOG" 2>&1
progress(){ printf '>>> [%s] %s\n' "$(date '+%F %T')" "$*" | tee -a "$PROGRESS" >&3; }
source "$BUNDLE_DIR/plans/current-links.env"
source "$WORKFLOW_LIB"
source "$CONTRACT_LIB"
router_step_workflow_init "$PHASE_CURRENT" "$PHASE_EVENTS" \
  transfer_verification target_preflight target_core target_postcheck machine_git vm130_exact_clone \
  source_publication model_publication methods_publication plan_publication project_source_publication \
  external_http_verification step_report_publication

vm101_run_script(){
  local script="$1"
  ssh -o BatchMode=yes pve-mgts \
    "ssh -o BatchMode=yes -i /root/.ssh/pve_to_openwrt_mgts_ed25519 root@10.71.100.2 'sh -s'" <"$script"
}
vm101_run_command(){
  local cmd="$1"
  ssh -o BatchMode=yes pve-mgts \
    "ssh -o BatchMode=yes -i /root/.ssh/pve_to_openwrt_mgts_ed25519 root@10.71.100.2 '$cmd'"
}
field(){ local file="$1" key="$2"; awk -F= -v k="$key" '$1==k{v=substr($0,index($0,"=")+1)} END{print v}' "$file"; }
phase_begin(){ CURRENT_PHASE="$1"; router_step_phase_begin "$1" "${2:-none}"; progress "$1"; }
phase_done(){ router_step_phase_complete "$1" "${2:-complete}"; }

write_rollback(){
  cat >"$ROLLBACK" <<EOT
#!/usr/bin/env bash
set -Eeuo pipefail
[[ "\${CONFIRM_R18_ROLLBACK:-}" == YES ]] || { echo RESULT=STOP_R18_ROLLBACK_CONFIRMATION_REQUIRED; echo 'Set CONFIRM_R18_ROLLBACK=YES'; exit 2; }
ACTIVATION_ROLLBACK='$ACTIVATION_ROLLBACK_FILE'
TARGET_ROLLBACK='$TARGET_ROLLBACK_FILE'
[[ -n "\$ACTIVATION_ROLLBACK" && -n "\$TARGET_ROLLBACK" ]] || { echo RESULT=STOP_R18_ROLLBACK_EVIDENCE_MISSING; exit 2; }
cat > /tmp/r18-r09-runtime-rollback.sh <<'REMOTE'
#!/bin/sh
set -eu
ACTIVATION_ROLLBACK='$ACTIVATION_ROLLBACK_FILE'
TARGET_ROLLBACK='$TARGET_ROLLBACK_FILE'
[ -x "\$ACTIVATION_ROLLBACK" ] || { echo RESULT=STOP_R18_ACTIVATION_ROLLBACK_MISSING; exit 3; }
[ -x "\$TARGET_ROLLBACK" ] || { echo RESULT=STOP_R18_TARGET_ROLLBACK_MISSING; exit 3; }
"\$ACTIVATION_ROLLBACK"
"\$TARGET_ROLLBACK"
echo RESULT=PASS_R18_RUNTIME_AND_FILES_ROLLED_BACK
REMOTE
ssh -o BatchMode=yes pve-mgts "ssh -o BatchMode=yes -i /root/.ssh/pve_to_openwrt_mgts_ed25519 root@10.71.100.2 'sh -s'" < /tmp/r18-r09-runtime-rollback.sh
rm -f /tmp/r18-r09-runtime-rollback.sh
/opt/router-ops/bin/router-machine-close vm101 'R18 manual rollback: restore pre-R18 generation and managed files'
echo RESULT=PASS_R18_ROLLBACK_AND_MACHINE_GIT_PUBLISHED
EOT
  chmod 700 "$ROLLBACK"
}

write_docs(){
  local step_sha
  step_sha="$(sha256sum "$STEP_FILE"|awk '{print $1}')"
  write_rollback
  cat >"$REPORT" <<EOT
RESULT=$RESULT
STEP_ID=$STEP_ID
STOP_REASON=$STOP_REASON
CURRENT_PHASE=$CURRENT_PHASE
R08_STOP_REPORT_URL=$R08_STOP_REPORT_URL
R08_LOCAL_STEP_DIR=${R08_STEP_DIR:-none}
R08_TARGET_CORE_STATUS=complete
R08_TARGET_POSTCHECK_STATUS=complete
R08_MACHINE_GIT_STATUS=failed
R08_FAILURE_SIGNATURE=router-machine-close_uppercase_machine_id
CORE_CHANGE_COMPLETE=$CORE_CHANGE_COMPLETE
CORE_CHANGE_REPEATED=$CORE_CHANGE_REPEATED
TARGET_INSTALLER_RERUN=$TARGET_INSTALLER_RERUN
TARGET_POSTCHECK_REPEATED=$TARGET_POSTCHECK_REPEATED
MACHINE_GIT_COMPLETE=$MACHINE_GIT_COMPLETE
ROUTER_MACHINE_CLOSE_EXECUTED=$ROUTER_MACHINE_CLOSE_EXECUTED
ROUTER_MACHINE_CLOSE_RERUN=$ROUTER_MACHINE_CLOSE_RERUN
PREVIOUS_GENERATION_ID=$PREVIOUS_GENERATION_ID
NEW_GENERATION_ID=$NEW_GENERATION_ID
ACTIVATION_TRANSACTION_DIR=$ACTIVATION_TRANSACTION_DIR
ACTIVATION_ROLLBACK_FILE=$ACTIVATION_ROLLBACK_FILE
TARGET_BACKUP_DIR=${TARGET_BACKUP_DIR:-none}
TARGET_ROLLBACK_FILE=${TARGET_ROLLBACK_FILE:-none}
VM101_COMMIT=${VM101_COMMIT:-none}
VM101_TREE=${VM101_TREE:-none}
VM101_MANAGED_FILE_COUNT=${VM101_COUNT:-none}
COPY_VERIFY=$COPY_VERIFY
STEP_SHA256=$step_sha
HTTP_VERIFY_PASS=$HTTP_VERIFY_PASS
PUBLICATION_BARRIER=$PUBLICATION_BARRIER
RUNTIME_IMPACT=$RUNTIME_IMPACT
STEP_REPORT_URL=${STEP_REPORT_URL:-PENDING_NOT_PUBLISHED}
PROJECT_SOURCE_POST_URL=${PROJECT_SOURCE_POST_URL:-PENDING_NOT_PUBLISHED}
PROJECT_SOURCE_POST_FILE_URL=${PROJECT_SOURCE_POST_FILE_URL:-PENDING_NOT_PUBLISHED}
LOCAL_M07_PLAN_URL=$LOCAL_M07_PLAN_URL
GLOBAL_PROJECT_PLAN_URL=$GLOBAL_PROJECT_PLAN_URL
ACCESS_MAP_URL=$ACCESS_MAP_URL
VM100_PUBLIC_URL=$VM100_PUBLIC_URL
VM101_PUBLIC_URL=$VM101_PUBLIC_URL
VM121_PUBLIC_URL=$VM121_PUBLIC_URL
VM101_MODEL_URL=$VM101_MODEL_URL
VM101_METHODS_URL=$VM101_METHODS_URL
VM130_SOURCE_URL=$VM130_SOURCE_URL
LATEST_ROOT_URL=$LATEST_ROOT_URL
OLD_ROOT_URL=$OLD_ROOT_URL
FACTS_URL=${FACTS_URL:-PENDING_NOT_PUBLISHED}
VERIFY_URL=${VERIFY_URL:-PENDING_NOT_PUBLISHED}
ROLLBACK_URL=${ROLLBACK_URL:-PENDING_NOT_PUBLISHED}
PUBLIC_OBJECT_KIND=$PUBLIC_OBJECT_KIND
PREVIOUS_MOVED_COUNT=$PREVIOUS_MOVED_COUNT
EOT
  cat >"$VERIFY" <<EOT
RESULT=$RESULT
R17_FAILURE_ANALYSIS_REVIEWED=true
R17_SHARED_FINALIZER_USED=true
CUSTOM_CLASSIFIER_IMPLEMENTED=false
CUSTOM_HTML_ALIAS_BUILDER_IMPLEMENTED=false
CUSTOM_LINEAGE_SCANNER_IMPLEMENTED=false
R08_CORE_REUSED=true
R08_TARGET_POSTCHECK_REUSED=true
R08_RUNTIME_OPERATION_REPEATED=false
R08_NEW_GENERATION_ID=$NEW_GENERATION_ID
R08_PREVIOUS_GENERATION_ID=$PREVIOUS_GENERATION_ID
R08_ACTIVATION_TRANSACTION_DIR=$ACTIVATION_TRANSACTION_DIR
MACHINE_CLOSE_EXACT_CLI=/opt/router-ops/bin/router-machine-close_vm101_description
MACHINE_GIT_COMPLETE=$MACHINE_GIT_COMPLETE
VM101_COMMIT=${VM101_COMMIT:-none}
VM101_TREE=${VM101_TREE:-none}
VM101_MANAGED_FILE_COUNT=${VM101_COUNT:-none}
EXACT_CLONE_VERIFIED=$MACHINE_GIT_COMPLETE
TARGET_INSTALLER_RERUN=false
PROVIDER_DOWNLOAD_REPEATED=false
PROVIDER_TEST_REPEATED=false
PROVIDER_RANK_REPEATED=false
GENERATION_BUILD_REPEATED=false
TRANSACTIONAL_ACTIVATION_REPEATED=false
TARGET_POSTCHECK_REPEATED=false
DIRECT_FAILOPEN_USED=false
EXTERNAL_OBJECTS_VERIFIED_BEFORE_BARRIER=$HTTP_VERIFY_PASS
NO_FALLIBLE_OPERATION_AFTER_BARRIER=true
PUBLICATION_BARRIER=$PUBLICATION_BARRIER
EOT
  python3 - "$FACTS" <<PY
import json,sys
obj={
 "schema":"router-step-facts-v1","step_id":"$STEP_ID","result":"$RESULT","stop_reason":"$STOP_REASON","current_phase":"$CURRENT_PHASE",
 "r08_stop_report_url":"$R08_STOP_REPORT_URL","r08_local_step_dir":"$R08_STEP_DIR","r08_target_core_status":"complete","r08_target_postcheck_status":"complete","r08_machine_git_status":"failed","r08_failure_signature":"router-machine-close_uppercase_machine_id",
 "core_change_complete":"$CORE_CHANGE_COMPLETE"=="true","core_change_repeated":False,"target_installer_rerun":False,"target_postcheck_repeated":False,
 "machine_git_complete":"$MACHINE_GIT_COMPLETE"=="true","router_machine_close_executed":"$ROUTER_MACHINE_CLOSE_EXECUTED"=="true","router_machine_close_rerun":False,
 "previous_generation_id":"$PREVIOUS_GENERATION_ID","new_generation_id":"$NEW_GENERATION_ID","activation_transaction_dir":"$ACTIVATION_TRANSACTION_DIR","activation_rollback_file":"$ACTIVATION_ROLLBACK_FILE","target_backup_dir":"$TARGET_BACKUP_DIR","target_rollback_file":"$TARGET_ROLLBACK_FILE",
 "vm101_commit":"$VM101_COMMIT","vm101_tree":"$VM101_TREE","vm101_managed_file_count":"$VM101_COUNT",
 "copy_verify":"$COPY_VERIFY","http_verify_pass":"$HTTP_VERIFY_PASS"=="true","publication_barrier":"$PUBLICATION_BARRIER","runtime_impact":False,"direct_failopen_used":False,
 "step_report_url":"$STEP_REPORT_URL","vm101_public_url":"$VM101_PUBLIC_URL","model_url":"$VM101_MODEL_URL","methods_url":"$VM101_METHODS_URL","plan_url":"$LOCAL_M07_PLAN_URL","project_source_post_url":"$PROJECT_SOURCE_POST_URL"
}
with open(sys.argv[1],'w') as f: json.dump(obj,f,indent=2,sort_keys=True); f.write('\n')
PY
}

emit_final(){
  for x in \
    "RESULT=$RESULT" \
    "STEP_REPORT_URL=${STEP_REPORT_URL:-PENDING_NOT_PUBLISHED}" \
    "PROJECT_SOURCE_POST_URL=${PROJECT_SOURCE_POST_URL:-PENDING_NOT_PUBLISHED}" \
    "PROJECT_SOURCE_POST_FILE_URL=${PROJECT_SOURCE_POST_FILE_URL:-PENDING_NOT_PUBLISHED}" \
    "LOCAL_M07_PLAN_URL=$LOCAL_M07_PLAN_URL" \
    "GLOBAL_PROJECT_PLAN_URL=$GLOBAL_PROJECT_PLAN_URL" \
    "ACCESS_MAP_URL=$ACCESS_MAP_URL" \
    "VM100_PUBLIC_URL=$VM100_PUBLIC_URL" \
    "VM101_PUBLIC_URL=$VM101_PUBLIC_URL" \
    "VM121_PUBLIC_URL=$VM121_PUBLIC_URL" \
    "VM101_MODEL_URL=$VM101_MODEL_URL" \
    "VM101_METHODS_URL=$VM101_METHODS_URL" \
    "VM130_SOURCE_URL=$VM130_SOURCE_URL" \
    "LATEST_ROOT_URL=$LATEST_ROOT_URL" \
    "OLD_ROOT_URL=$OLD_ROOT_URL" \
    "FACTS_URL=${FACTS_URL:-PENDING_NOT_PUBLISHED}" \
    "VERIFY_URL=${VERIFY_URL:-PENDING_NOT_PUBLISHED}" \
    "ROLLBACK_URL=${ROLLBACK_URL:-PENDING_NOT_PUBLISHED}" \
    "PUBLIC_OBJECT_KIND=$PUBLIC_OBJECT_KIND" \
    "PREVIOUS_MOVED_COUNT=$PREVIOUS_MOVED_COUNT" \
    "COPY_VERIFY=$COPY_VERIFY" \
    "STEP_SHA256=$(sha256sum "$STEP_FILE"|awk '{print $1}')" \
    "HTTP_VERIFY_PASS=$HTTP_VERIFY_PASS" \
    "RUNTIME_IMPACT=$RUNTIME_IMPACT"; do printf '%s\n' "$x" >&3; done
}

publish_object(){
  local label="$1" expect="$2" outvar="$3"; shift 3
  local log="$STEP_DIR/publish-${expect}.log"
  "$PUBLISHER" "$label" "$@" >"$log"
  router_publication_contract_load "$log" "$expect" || return 1
  "$HTTP" --url "$RPC_PUBLIC_URL" --output "$STEP_DIR/http-${expect}-index.html" >"$STEP_DIR/http-${expect}.log" 2>&1
  printf -v "$outvar" '%s' "$RPC_PUBLIC_URL"
}

publish_stop_report(){
  set +e
  write_docs
  local html safe label
  html="$STEP_DIR/stop-html"; safe="$STEP_DIR/stop-safe"; label='step050m07r18_r09_machine_git_and_finalization_continuation_stop'
  python3 "$HTML_BUILDER" --facts "$FACTS" --verify "$VERIFY" --rollback "$ROLLBACK" --output-dir "$html" --title-prefix R18-R09 >/dev/null 2>&1
  "$SAFE_BUILDER" "$safe" \
    "$STEP_FILE" step-code.sh "$REPORT" report.txt "$FACTS" facts.json "$VERIFY" verify.txt "$ROLLBACK" rollback.sh \
    "$MAIN_LOG" main.log "$PROGRESS" progress.log "$TRANSFER" transfer-verify.txt \
    "$PHASE_CURRENT" phase-current.txt "$PHASE_EVENTS" phase-events.log \
    "$html/facts-public.html" facts-public.html "$html/verify-public.html" verify-public.html "$html/rollback-public.html" rollback-public.html >/dev/null 2>&1
  "$FINALIZER" --label "$label" --payload-dir "$safe" --workflow-current "$PHASE_CURRENT" --workflow-events "$PHASE_EVENTS" --output-env "$STEP_DIR/stop-finalize.env" --expect-kind step-report >"$STEP_DIR/stop-finalize.log" 2>&1
  if [[ -s "$STEP_DIR/stop-finalize.env" ]]; then
    STEP_REPORT_URL="$(field "$STEP_DIR/stop-finalize.env" PUBLIC_URL)"
    FACTS_URL="${STEP_REPORT_URL}facts-public.html"
    VERIFY_URL="${STEP_REPORT_URL}verify-public.html"
    ROLLBACK_URL="${STEP_REPORT_URL}rollback-public.html"
    PUBLICATION_BARRIER=verified
    HTTP_VERIFY_PASS=true
  fi
  set -e
}

stop(){
  local result="$1" reason="$2" rc="${3:-1}"
  trap - ERR
  PUBLICATION_BARRIER=none
  if ! mkdir "$STOP_GUARD_DIR" 2>/dev/null; then exit "$rc"; fi
  RESULT="$result"; STOP_REASON="$reason"
  router_step_phase_fail "$CURRENT_PHASE" "$reason" >/dev/null 2>&1 || true
  if ! router_step_publication_is_verified; then publish_stop_report || true; fi
  emit_final
  exit "$rc"
}
trap 'stop STOP_R18_R09_UNEXPECTED_ERROR "phase=$CURRENT_PHASE line=$LINENO rc=$?" 1' ERR

phase_begin transfer_verification
actual_zip="$(sha256sum "$BUNDLE_COPY"|awk '{print $1}')"
actual_inst="$(sha256sum "$STEP_FILE"|awk '{print $1}')"
[[ "$actual_zip" == "$EXPECTED_BUNDLE_SHA256" && "$actual_inst" == "$EXPECTED_INSTALLER_SHA256" ]] || stop STOP_COPY_OR_TRANSFER_ERROR sha_mismatch 20
(cd "$BUNDLE_DIR" && sha256sum -c manifest.sha256) >"$STEP_DIR/manifest.log"
BUNDLE_ROOT="$BUNDLE_DIR" "$BASE/bin/router-bundle-gate" "$BUNDLE_DIR" >"$STEP_DIR/bundle-gate.log"
grep -qx RESULT=PASS_ROUTER_BUNDLE_GATE "$STEP_DIR/bundle-gate.log" || stop STOP_COPY_OR_TRANSFER_ERROR bundle_gate 20
COPY_VERIFY=PASS
cat >"$TRANSFER" <<EOT
COPY_VERIFY=PASS
EXPECTED_BUNDLE_SHA256=$EXPECTED_BUNDLE_SHA256
ACTUAL_BUNDLE_SHA256=$actual_zip
EXPECTED_INSTALLER_SHA256=$EXPECTED_INSTALLER_SHA256
ACTUAL_INSTALLER_SHA256=$actual_inst
MANIFEST_VERIFY=PASS
SYNTAX_VERIFY=PASS
FIXTURE_VERIFY=PASS
EOT
phase_done transfer_verification

phase_begin target_preflight
[[ "$(hostname)" == router-ops ]] || stop STOP_R18_R09_WRONG_HOST "$(hostname)" 21
while read -r sha path; do [[ -f "$path" && "$(sha256sum "$path"|awk '{print $1}')" == "$sha" ]] || stop STOP_R18_R09_VM130_HELPER_SHA "$path" 21; done <"$BUNDLE_DIR/reference/expected-vm130.sha256"

R08_STEP_DIR="$(find "$BASE/steps" -mindepth 1 -maxdepth 1 -type d -name '*_STEP_050M07R18_R08_CANONICAL_PATH_AND_RESUME_BUILD_CONTINUATION' -print | LC_ALL=C sort | tail -n 1)"
[[ -n "$R08_STEP_DIR" && -f "$R08_STEP_DIR/report.txt" && -f "$R08_STEP_DIR/facts.json" && -f "$R08_STEP_DIR/phase-current.env" ]] || stop STOP_R18_R09_R08_EVIDENCE_MISSING "$R08_STEP_DIR" 21
for f in vm101-apply.log vm101-core.log vm101-postcheck.log router-machine-close.log; do [[ -f "$R08_STEP_DIR/components/$f" ]] || stop STOP_R18_R09_R08_COMPONENT_MISSING "$f" 21; done

grep -Fqx 'target_core=complete' "$R08_STEP_DIR/phase-current.env" || stop STOP_R18_R09_R08_CORE_STATUS mismatch 21
grep -Fqx 'target_postcheck=complete' "$R08_STEP_DIR/phase-current.env" || stop STOP_R18_R09_R08_POSTCHECK_STATUS mismatch 21
grep -Fqx 'machine_git=failed' "$R08_STEP_DIR/phase-current.env" || stop STOP_R18_R09_R08_MACHINE_GIT_STATUS mismatch 21
grep -Fq 'Usage: router-machine-close [--check] {vm100|vm101|vm121}' "$R08_STEP_DIR/components/router-machine-close.log" || stop STOP_R18_R09_R08_FAILURE_SIGNATURE missing 21
grep -Fqx 'RESULT=PASS_R18_FULL_POOL_REFRESH' "$R08_STEP_DIR/components/vm101-core.log" || stop STOP_R18_R09_R08_CORE_MARKER missing 21
grep -Fqx "NEW_GENERATION_ID=$NEW_GENERATION_ID" "$R08_STEP_DIR/components/vm101-core.log" || stop STOP_R18_R09_R08_GENERATION_MARKER missing 21
grep -Fqx 'RESULT=PASS_R18_VM101_POSTCHECK' "$R08_STEP_DIR/components/vm101-postcheck.log" || stop STOP_R18_R09_R08_POSTCHECK_MARKER missing 21
TARGET_BACKUP_DIR="$(field "$R08_STEP_DIR/components/vm101-apply.log" BACKUP_DIR)"
TARGET_ROLLBACK_FILE="$(field "$R08_STEP_DIR/components/vm101-apply.log" ROLLBACK_FILE)"
[[ -n "$TARGET_BACKUP_DIR" && -n "$TARGET_ROLLBACK_FILE" ]] || stop STOP_R18_R09_R08_TARGET_ROLLBACK missing 21

vm101_run_script "$BUNDLE_DIR/scripts/vm101-r08-core-proof.sh" >"$COMPONENTS/vm101-r08-core-proof.log"
grep -qx RESULT=PASS_R18_R09_R08_CORE_AND_PRE_CLOSE_STATE_VERIFIED "$COMPONENTS/vm101-r08-core-proof.log" || stop STOP_R18_R09_LIVE_CORE_PROOF marker 22
CORE_CHANGE_COMPLETE=true
write_rollback
phase_done target_preflight r08_core_postcheck_and_pre_close_changeset_verified

phase_begin target_core reused_from_r08
phase_done target_core "$NEW_GENERATION_ID:reused_no_runtime_operation"
phase_begin target_postcheck reused_from_r08
phase_done target_postcheck 'PASS_R18_VM101_POSTCHECK:reused_no_runtime_operation'

phase_begin machine_git
progress 'first and only R18 router-machine-close with exact lowercase machine id'
set +e
"$MACHINE_CLOSE" vm101 "$STEP_ID: finalize successful R18 generation replacement" > >(tee -a "$COMPONENTS/router-machine-close.log" "$MAIN_LOG" >&3) 2>&1
close_rc=$?
set -e
[[ "$close_rc" -eq 0 ]] || stop STOP_R18_R09_ROUTER_MACHINE_CLOSE "rc=$close_rc" 27
ROUTER_MACHINE_CLOSE_EXECUTED=true
VM101_PUBLIC_URL="$(field "$COMPONENTS/router-machine-close.log" VM101_PUBLIC_URL)"
[[ "$VM101_PUBLIC_URL" == https://reports.secret-studio.ru/latest/*/ ]] || stop STOP_R18_R09_VM101_PUBLIC_URL missing 27
vm101_run_script "$BUNDLE_DIR/scripts/vm101-machine-git-facts.sh" >"$COMPONENTS/vm101-machine-git-facts.log"
grep -qx RESULT=PASS_R18_MACHINE_GIT_FACTS "$COMPONENTS/vm101-machine-git-facts.log" || stop STOP_R18_R09_MACHINE_GIT_FACTS marker 27
VM101_COMMIT="$(field "$COMPONENTS/vm101-machine-git-facts.log" COMMIT)"
VM101_TREE="$(field "$COMPONENTS/vm101-machine-git-facts.log" TREE)"
VM101_COUNT="$(field "$COMPONENTS/vm101-machine-git-facts.log" MANAGED_FILE_COUNT)"
[[ "$VM101_COMMIT" =~ ^[0-9a-f]{40}$ && "$VM101_TREE" =~ ^[0-9a-f]{40}$ && "$VM101_COUNT" == 35 ]] || stop STOP_R18_R09_MACHINE_GIT_FACTS_INVALID "commit=$VM101_COMMIT tree=$VM101_TREE count=$VM101_COUNT" 27
[[ "$VM101_COMMIT" != d01016420799492ea6e0ce1a526abafe910f18ed && "$VM101_TREE" != 1972e4bc69dfbfdfb14d210a44a3fdc772ee88de ]] || stop STOP_R18_R09_MACHINE_GIT_NOT_ADVANCED "commit=$VM101_COMMIT tree=$VM101_TREE" 27
MACHINE_GIT_COMPLETE=true
phase_done machine_git "$VM101_COMMIT"

phase_begin vm130_exact_clone
CLONE="$STEP_DIR/vm101-exact-clone"
git clone --quiet --no-tags https://github.com/DChuvelev/wg-paid-vm101.git "$CLONE"
CLONE_COMMIT="$(git -C "$CLONE" rev-parse HEAD)"
CLONE_TREE="$(git -C "$CLONE" rev-parse 'HEAD^{tree}')"
CLONE_COUNT="$(git -C "$CLONE" ls-tree -r --full-tree --name-only HEAD | wc -l | tr -d ' ')"
[[ "$CLONE_COMMIT" == "$VM101_COMMIT" && "$CLONE_TREE" == "$VM101_TREE" && "$CLONE_COUNT" == "$VM101_COUNT" ]] || stop STOP_R18_R09_EXACT_CLONE_MISMATCH "live=$VM101_COMMIT/$VM101_TREE/$VM101_COUNT clone=$CLONE_COMMIT/$CLONE_TREE/$CLONE_COUNT" 28
[[ -z "$(git -C "$CLONE" status --porcelain)" ]] || stop STOP_R18_R09_EXACT_CLONE_DIRTY dirty 28
while read -r sha path; do rel="${path#/}"; [[ -f "$CLONE/$rel" && "$(sha256sum "$CLONE/$rel"|awk '{print $1}')" == "$sha" ]] || stop STOP_R18_R09_EXACT_CLONE_FILE_SHA "$rel" 28; done <"$BUNDLE_DIR/reference/expected-r18-live.sha256"
{
 echo "COMMIT=$VM101_COMMIT"; echo "TREE=$VM101_TREE"; echo "MANAGED_FILE_COUNT=$VM101_COUNT";
 git -C "$CLONE" show --stat --oneline --decorate --no-renames HEAD;
} >"$COMPONENTS/vm101-git-proof.txt"
phase_done vm130_exact_clone

phase_begin source_publication
"$HTTP" --url "$VM101_PUBLIC_URL" --output "$STEP_DIR/vm101-source-index.html" >"$COMPONENTS/vm101-source-http.log" 2>&1
phase_done source_publication

vm101_run_script "$BUNDLE_DIR/scripts/vm101-export-artifacts.sh" >"$COMPONENTS/vm101-export.log"
grep -qx RESULT=PASS_R18_R09_VM101_EXPORT "$COMPONENTS/vm101-export.log" || stop STOP_R18_R09_VM101_EXPORT marker 29
export_sha="$(field "$COMPONENTS/vm101-export.log" EXPORT_SHA256)"
vm101_run_command 'cat /tmp/vm101-r18-r09-export.tar.gz' >"$STEP_DIR/vm101-r18-r09-export.tar.gz"
[[ "$(sha256sum "$STEP_DIR/vm101-r18-r09-export.tar.gz"|awk '{print $1}')" == "$export_sha" ]] || stop STOP_R18_R09_EXPORT_TRANSFER_SHA mismatch 29
gzip -t "$STEP_DIR/vm101-r18-r09-export.tar.gz"
tar -xzf "$STEP_DIR/vm101-r18-r09-export.tar.gz" -C "$EXPORT_DIR"
(cd "$EXPORT_DIR" && sha256sum -c export-manifest.sha256 >/dev/null)

phase_begin model_publication
MODEL="$STEP_DIR/model-public"; mkdir -p "$MODEL"
cp "$BUNDLE_DIR/model/system-model-template.txt" "$MODEL/system-model.txt"
printf '\nLive authoritative state after R18 R09 finalization\n' >>"$MODEL/system-model.txt"
cat "$EXPORT_DIR/runtime-contract.env" "$EXPORT_DIR/state-sanitized.txt" "$EXPORT_DIR/activation.kv" "$EXPORT_DIR/full-refresh-result.kv" >>"$MODEL/system-model.txt"
cp "$EXPORT_DIR/runtime-contract.env" "$MODEL/runtime-contract.txt"
for f in generation-metadata.txt generation-candidates.tsv generation-manifest-file.sha256 critical-files.sha256 vpn-runtime.txt service-status.txt activation.kv full-refresh-result.kv machine-git.txt quarantine-summary.txt; do [[ ! -f "$EXPORT_DIR/$f" ]] || cp "$EXPORT_DIR/$f" "$MODEL/$f"; done
mapfile -t model_files < <(find "$MODEL" -maxdepth 1 -type f -print | LC_ALL=C sort)
publish_object vm101_model_full_pool_refresh_transactional_replacement_r18 vm101-model VM101_MODEL_URL "${model_files[@]}" || stop STOP_R18_R09_MODEL_PUBLICATION contract 30
phase_done model_publication

phase_begin methods_publication
METHODS="$STEP_DIR/methods-public"; mkdir -p "$METHODS"
cp "$BUNDLE_DIR/methods/methods-limitations.txt" "$METHODS/methods-limitations.txt"
cp "$BUNDLE_DIR/methods/access-routes.txt" "$METHODS/access-routes.txt"
cp "$MODEL/runtime-contract.txt" "$METHODS/runtime-contract.txt"
mapfile -t method_files < <(find "$METHODS" -maxdepth 1 -type f -print | LC_ALL=C sort)
publish_object vm101_methods_full_pool_refresh_transactional_replacement_r18 vm101-methods VM101_METHODS_URL "${method_files[@]}" || stop STOP_R18_R09_METHODS_PUBLICATION contract 31
phase_done methods_publication

phase_begin plan_publication
publish_object local_architecture_plan_vm101_autonomous_hmn_recovery_r18 local-m07-plan LOCAL_M07_PLAN_URL "$BUNDLE_DIR/plans/canonical-plan-r18.md" || stop STOP_R18_R09_PLAN_PUBLICATION contract 32
phase_done plan_publication

phase_begin project_source_publication
publish_object project_source_post_vm101_full_pool_refresh_transactional_replacement_r18 project-source-post PROJECT_SOURCE_POST_URL "$BUNDLE_DIR/post/WG_PAID_MGTS_VM101_FULL_POOL_REFRESH_TRIGGER_AND_TRANSACTIONAL_REPLACEMENT_R18.md" || stop STOP_R18_R09_PROJECT_SOURCE_PUBLICATION contract 33
PROJECT_SOURCE_POST_FILE_URL="${PROJECT_SOURCE_POST_URL}WG_PAID_MGTS_VM101_FULL_POOL_REFRESH_TRIGGER_AND_TRANSACTIONAL_REPLACEMENT_R18.md"
phase_done project_source_publication

phase_begin external_http_verification
for url in "$VM101_PUBLIC_URL" "$VM101_MODEL_URL" "$VM101_METHODS_URL" "$LOCAL_M07_PLAN_URL" "$PROJECT_SOURCE_POST_URL"; do
  "$HTTP" --url "$url" --output "$STEP_DIR/http-final-$(printf '%s' "$url"|sha256sum|cut -c1-12).html" >>"$COMPONENTS/final-http.log" 2>&1
done
HTTP_VERIFY_PASS=true
phase_done external_http_verification

phase_begin step_report_publication
RESULT=PASS_R18_FULL_POOL_REFRESH_TRIGGER_AND_TRANSACTIONAL_REPLACEMENT
STOP_REASON=none
CURRENT_PHASE=step_report_publication
# The PASS payload is published only if the shared finalizer proves this barrier.
PUBLICATION_BARRIER=verified
write_docs
HTML="$STEP_DIR/html"; SAFE="$STEP_DIR/safe"
python3 "$HTML_BUILDER" --facts "$FACTS" --verify "$VERIFY" --rollback "$ROLLBACK" --output-dir "$HTML" --title-prefix R18-R09 >"$COMPONENTS/html-aliases.log"
"$SAFE_BUILDER" "$SAFE" \
  "$STEP_FILE" step-code.sh "$REPORT" report.txt "$FACTS" facts.json "$VERIFY" verify.txt "$ROLLBACK" rollback.sh \
  "$MAIN_LOG" main.log "$PROGRESS" progress.log "$TRANSFER" transfer-verify.txt \
  "$PHASE_CURRENT" phase-current.txt "$PHASE_EVENTS" phase-events.log \
  "$COMPONENTS/vm101-r08-core-proof.log" vm101-r08-core-proof.txt \
  "$COMPONENTS/router-machine-close.log" router-machine-close.txt \
  "$COMPONENTS/vm101-machine-git-facts.log" vm101-machine-git-facts.txt \
  "$COMPONENTS/vm101-git-proof.txt" vm101-git-proof.txt \
  "$COMPONENTS/vm101-export.log" vm101-export.txt \
  "$COMPONENTS/final-http.log" final-http.txt \
  "$STEP_DIR/manifest.log" bundle-manifest-verify.txt "$STEP_DIR/bundle-gate.log" bundle-gate.txt \
  "$HTML/facts-public.html" facts-public.html "$HTML/verify-public.html" verify-public.html "$HTML/rollback-public.html" rollback-public.html >"$COMPONENTS/safe-payload.log"
"$FINALIZER" --label step050m07r18_r09_machine_git_and_finalization_continuation --payload-dir "$SAFE" \
  --workflow-current "$PHASE_CURRENT" --workflow-events "$PHASE_EVENTS" --output-env "$STEP_DIR/finalize.env" --expect-kind step-report >"$COMPONENTS/finalize.log"
# The shared finalizer has now established the publication barrier. Disable STOP handling
# before any local best-effort parsing/printing so a late error cannot publish a second STOP.
trap - ERR
set +e
STEP_REPORT_URL="$(field "$STEP_DIR/finalize.env" PUBLIC_URL)"
PREVIOUS_MOVED_COUNT="$(field "$COMPONENTS/finalize.log" PREVIOUS_MOVED_COUNT)"
[[ -n "$PREVIOUS_MOVED_COUNT" ]] || PREVIOUS_MOVED_COUNT=0
FACTS_URL="${STEP_REPORT_URL}facts-public.html"
VERIFY_URL="${STEP_REPORT_URL}verify-public.html"
ROLLBACK_URL="${STEP_REPORT_URL}rollback-public.html"
PUBLICATION_BARRIER=verified
HTTP_VERIFY_PASS=true
CURRENT_PHASE=complete
emit_final
exit 0
