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

STEP_ID="STEP_050M07R16_TRANSACTIONAL_GENERATION_ACTIVATION_R01"
STEP_LABEL="step050m07r16_transactional_generation_activation_r01"
MODEL_LABEL="vm101_model_transactional_generation_activation_r16"
METHODS_LABEL="vm101_methods_transactional_generation_activation_r16"
PLAN_LABEL="local_architecture_plan_vm101_autonomous_hmn_recovery_r16"
POST_LABEL="project_source_post_vm101_generation_activation_r16"
GENERATION_ID="r15b2-20260716-215914"
GENERATION_DIR="/var/lib/router-egress-recovery/generations/staging/$GENERATION_ID"
EXPECTED_VM101_HEAD="acdd5c8dc7990d48d492cc567b0a1506af96a826"
EXPECTED_VM101_TREE="a11117d70e206ddb812076757e1d5003ae76ec5f"

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}"
source "$BUNDLE_DIR/plans/current-links.env"

BASE="${ROUTER_OPS_BASE:-/opt/router-ops}"
BIN="$BASE/bin"; LIB="$BASE/lib"; STATE="$BASE/state"
PUBLISHER="$BIN/router-publish-report"
HTTP_VERIFY="$BIN/router-http-verify"
REINDEX="$BIN/router-public-reindex"
MACHINE_CLOSE="$BIN/router-machine-close"
WORKFLOW_LIB="$LIB/router-step-workflow.sh"
PUBLICATION_LIB="$LIB/router-publication-contract.sh"
LATEST_ROOT_URL="https://reports.secret-studio.ru/latest/"
OLD_ROOT_URL="https://reports.secret-studio.ru/old/"

TS="$(date -u +%Y%m%d-%H%M%S)"
STEP_DIR="$BASE/steps/${TS}_${STEP_ID}"
mkdir -p "$STEP_DIR"; chmod 700 "$STEP_DIR"
STEP_FILE="$STEP_DIR/step-code.sh"; cp -a "$SELF" "$STEP_FILE"; chmod 700 "$STEP_FILE"
BUNDLE_COPY="$STEP_DIR/$(basename "$BUNDLE_ZIP")"; 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_LOG="$STEP_DIR/progress.log"; TRANSFER_VERIFY="$STEP_DIR/transfer-verify.txt"
SYSTEM_MODEL="$STEP_DIR/system-model.txt"; METHODS_LIMIT="$STEP_DIR/methods-limitations.txt"; ACCESS_ROUTES="$STEP_DIR/access-routes.txt"
PHASE_CURRENT="$STEP_DIR/phase-current.txt"; PHASE_EVENTS="$STEP_DIR/phase-events.tsv"
TARGET_PACKAGE="$STEP_DIR/r16-target-package.tar.gz"; TARGET_PACKAGE_SHA=""
REMOTE_ROOT="/tmp/router-r16-$TS"; REMOTE_PACKAGE="/tmp/router-r16-$TS.tar.gz"
TARGET_BASE="/var/lib/router-egress-recovery/steps/$STEP_ID"
TARGET_PREFLIGHT_LOG="$STEP_DIR/target-preflight.log"; TARGET_APPLY_LOG="$STEP_DIR/target-apply.log"; TARGET_POSTCHECK_LOG="$STEP_DIR/target-postcheck.log"
TARGET_EXPORT_LOG="$STEP_DIR/target-export.log"; TARGET_ARTIFACTS_TAR="$STEP_DIR/target-artifacts.tar.gz"; TARGET_ARTIFACTS="$STEP_DIR/target-artifacts"
MACHINE_CLOSE_LOG="$STEP_DIR/router-machine-close.log"; TARGET_POST_GIT_LOG="$STEP_DIR/target-post-machine-git.log"
MODEL_BUILD="$STEP_DIR/model-build"; METHODS_BUILD="$STEP_DIR/methods-build"; PLAN_BUILD="$STEP_DIR/plan-build"; POST_BUILD="$STEP_DIR/project-source-post"
MODEL_PUBLISH_LOG="$STEP_DIR/model-publish.log"; METHODS_PUBLISH_LOG="$STEP_DIR/methods-publish.log"; PLAN_PUBLISH_LOG="$STEP_DIR/plan-publish.log"; POST_PUBLISH_LOG="$STEP_DIR/post-publish.log"
STEP_PAYLOAD="$STEP_DIR/step-report-payload"; STEP_PUBLISH_LOG="$STEP_DIR/step-publish.log"; HTTP_LOG="$STEP_DIR/http-verify.log"
mkdir -p "$TARGET_ARTIFACTS" "$MODEL_BUILD" "$METHODS_BUILD" "$PLAN_BUILD" "$POST_BUILD" "$STEP_PAYLOAD"
chmod 700 "$TARGET_ARTIFACTS" "$MODEL_BUILD" "$METHODS_BUILD" "$PLAN_BUILD" "$POST_BUILD" "$STEP_PAYLOAD"

RESULT="STOP_NOT_STARTED"; STOP_REASON="none"; CURRENT_PHASE="initialization"; COPY_VERIFY="FAIL"; STEP_WAS_NOT_STARTED="true"
CORE_CHANGE_COMPLETE="false"; CORE_CHANGE_REPEATED="false"; TARGET_INSTALLER_RERUN="false"; MACHINE_GIT_COMPLETE="false"
ROUTER_MACHINE_CLOSE_RERUN="false"; SNAPSHOT_CREATED="false"; SNAPSHOT_NAME="R16_PRE_${TS//-/_}"
VM101_RUNTIME_CHANGE="false"; RUNTIME_IMPACT="true"; TRAFFIC_INTERRUPTION="brief_vpn_slot_restarts"
TARGET_PREFLIGHT_PASS="false"; TARGET_CORE_PASS="false"; TARGET_POSTCHECK_PASS="false"; TARGET_ROLLBACK_OK="not_needed"
HTTP_VERIFY_PASS="false"; STEP_REPORT_PUBLICATION_COMPLETE="false"; PROJECT_SOURCE_POST_PUBLICATION_COMPLETE="false"
VM101_GIT_COMMIT=""; VM101_GIT_TREE=""; VM101_GIT_FILE_COUNT=""; ACTIVATOR_SHA256=""; BUILDER_SHA256=""; ACTIVATION_TRANSACTION_DIR=""
STEP_REPORT_URL=""; FACTS_URL=""; VERIFY_URL=""; ROLLBACK_URL=""; STEP_PUBLISHED_DIR=""
PROJECT_SOURCE_POST_URL=""; PROJECT_SOURCE_POST_FILE_URL=""
PUBLIC_OBJECT_KIND=""; PREVIOUS_MOVED_COUNT=""; COLLISION_DEDUPLICATED_COUNT=""; PUBLISHER_RC="unknown"

exec 3>&1
exec >>"$MAIN_LOG" 2>&1
progress(){ printf '>>> [%s] %s\n' "$(date '+%F %T')" "$*" | tee -a "$PROGRESS_LOG" >&3; }

[[ -r "$WORKFLOW_LIB" && -r "$PUBLICATION_LIB" ]] || { echo RESULT=STOP_R16_R15D_LIBRARIES_MISSING >&3; exit 2; }
source "$WORKFLOW_LIB"
source "$PUBLICATION_LIB"
PHASES=(transfer_verification vm130_preflight target_package_build snapshot_preflight target_preflight snapshot_create target_core target_postcheck target_artifact_export machine_git_and_source_publication target_post_machine_git model_build model_publication methods_build methods_publication plan_build plan_publication project_source_post_build project_source_post_publication step_report_preparation step_report_publication external_http_verification final_artifact_sync)
router_step_workflow_init "$PHASE_CURRENT" "$PHASE_EVENTS" "${PHASES[@]}"
phase_begin(){ CURRENT_PHASE="$1"; progress "$1"; router_step_phase_begin "$1"; }
phase_complete(){ router_step_phase_complete "$1"; }

value_from_log(){ local key="$1" file="$2"; awk -F= -v k="$key" '$1==k{print substr($0,index($0,"=")+1)}' "$file" | tail -n1; }

write_rollback_wrapper(){
  if [[ "$CORE_CHANGE_COMPLETE" == true ]]; then
    cat >"$ROLLBACK" <<ROLLBACK_EOF
#!/usr/bin/env bash
set -Eeuo pipefail
TARGET_ROLLBACK='$TARGET_BASE/rollback-target.sh'
SNAPSHOT_NAME='$SNAPSHOT_NAME'
ssh -o BatchMode=yes pve-mgts "ssh -o BatchMode=yes -i /root/.ssh/pve_to_openwrt_mgts_ed25519 root@10.71.100.2 '\$TARGET_ROLLBACK'"
/opt/router-ops/bin/router-machine-close vm101 'ROLLBACK_R16: restore pre-activation VM101 runtime and source profile'
echo RESULT=PASS_R16_ROLLBACK
# Additional manual safety point on Proxmox: VM101 snapshot \$SNAPSHOT_NAME
ROLLBACK_EOF
  elif [[ "$TARGET_ROLLBACK_OK" == true || ( "$VM101_RUNTIME_CHANGE" == false && "$TARGET_ROLLBACK_OK" == not_needed ) ]]; then
    cat >"$ROLLBACK" <<ROLLBACK_EOF
#!/usr/bin/env bash
set -Eeuo pipefail
echo RESULT=PASS_R16_NO_RUNTIME_ROLLBACK_REQUIRED
echo CORE_CHANGE_COMPLETE=$CORE_CHANGE_COMPLETE
echo TARGET_ROLLBACK_OK=$TARGET_ROLLBACK_OK
echo SNAPSHOT_NAME=$SNAPSHOT_NAME
ROLLBACK_EOF
  else
    cat >"$ROLLBACK" <<ROLLBACK_EOF
#!/usr/bin/env bash
set -Eeuo pipefail
echo RESULT=STOP_R16_MANUAL_RECOVERY_REQUIRED
echo CORE_CHANGE_COMPLETE=$CORE_CHANGE_COMPLETE
echo TARGET_ROLLBACK_OK=$TARGET_ROLLBACK_OK
echo SNAPSHOT_NAME=$SNAPSHOT_NAME
echo TARGET_APPLY_LOG=$TARGET_APPLY_LOG
exit 1
ROLLBACK_EOF
  fi
  chmod 700 "$ROLLBACK"
}

vm101_command(){ local cmd="$1"; printf '%s\n' "$cmd" | 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'"; }
vm101_upload(){ local local_file="$1" remote_file="$2"; ssh -o BatchMode=yes pve-mgts "ssh -o BatchMode=yes -i /root/.ssh/pve_to_openwrt_mgts_ed25519 root@10.71.100.2 'cat > $remote_file'" <"$local_file"; }
vm101_download(){ local remote_file="$1" local_file="$2"; ssh -o BatchMode=yes pve-mgts "ssh -o BatchMode=yes -i /root/.ssh/pve_to_openwrt_mgts_ed25519 root@10.71.100.2 'cat $remote_file'" >"$local_file"; }

write_docs(){
  local step_sha; step_sha="$(sha256sum "$STEP_FILE"|awk '{print $1}')"
  write_rollback_wrapper
  cat >"$SYSTEM_MODEL" <<MODEL
STEP_ID=$STEP_ID
SCOPE=VM101 transactional generation activation
GENERATION_ID=$GENERATION_ID
GENERATION_DIR=$GENERATION_DIR
SNAPSHOT_NAME=$SNAPSHOT_NAME
SNAPSHOT_CREATED=$SNAPSHOT_CREATED
ACTIVE_GENERATION_CREATED=$TARGET_CORE_PASS
ACTIVE_SLOT_COUNT=$([ "$TARGET_POSTCHECK_PASS" = true ] && echo 5 || echo 0)
REPAIR_COUNTER_RESET=$([ "$TARGET_POSTCHECK_PASS" = true ] && echo true || echo false)
DIRECT_FAILOPEN_ENABLED=false
TRAFFIC_INTERRUPTION=$TRAFFIC_INTERRUPTION
RUNTIME_IMPACT=true
MODEL
  cat >"$METHODS_LIMIT" <<METHODS
Activation method: immutable staged generation validation; Proxmox pre-snapshot without VM stop; global activation/local-repair locks; complete temporary UCI network build; atomic persistent network replacement; sequential vpn1..vpn5 restart; endpoint, strict ping, route and rule verification; active symlink and repair counter reset only after five-slot proof.
Rollback boundary: before TARGET_CORE PASS every runtime mutation triggers all-five-slot rollback. State/source rollback is committed only after the previous runtime is independently proven restored; otherwise recovery code is retained and the STEP stops with TARGET_ROLLBACK_OK=false. After TARGET_CORE PASS later Machine Git/publication errors STOP without automatic runtime rollback.
Snapshot is an additional manual safety point and is never automatically restored by this STEP.
DIRECT_FAILOPEN_ENABLED=false.
METHODS
  cat >"$ACCESS_ROUTES" <<ACCESS
VM130 -> ssh pve-mgts -> ssh -i /root/.ssh/pve_to_openwrt_mgts_ed25519 root@10.71.100.2
Proxmox snapshot: VMID 101, name $SNAPSHOT_NAME
ACCESS_MAP_URL=$ACCESS_MAP_URL
ACCESS
  python3 - "$FACTS" <<PY
import json,sys
b=lambda x:x=='true'
data={
"step_id":"$STEP_ID","result":"$RESULT","stop_reason":"$STOP_REASON","current_phase":"$CURRENT_PHASE",
"copy_verify":"$COPY_VERIFY","step_sha256":"$step_sha","expected_step_sha256":"$EXPECTED_INSTALLER_SHA256",
"step_was_not_started":b("$STEP_WAS_NOT_STARTED"),"core_change_complete":b("$CORE_CHANGE_COMPLETE"),"core_change_repeated":False,
"target_installer_rerun":False,"machine_git_complete":b("$MACHINE_GIT_COMPLETE"),"router_machine_close_rerun":False,
"generation_id":"$GENERATION_ID","generation_dir":"$GENERATION_DIR","snapshot_name":"$SNAPSHOT_NAME","snapshot_created":b("$SNAPSHOT_CREATED"),
"target_preflight_pass":b("$TARGET_PREFLIGHT_PASS"),"target_core_pass":b("$TARGET_CORE_PASS"),"target_postcheck_pass":b("$TARGET_POSTCHECK_PASS"),
"target_rollback_ok":"$TARGET_ROLLBACK_OK","vm101_runtime_change":b("$VM101_RUNTIME_CHANGE"),"traffic_interruption":"$TRAFFIC_INTERRUPTION","runtime_impact":True,
"vm101_git_commit":"$VM101_GIT_COMMIT","vm101_git_tree":"$VM101_GIT_TREE","vm101_git_file_count":"$VM101_GIT_FILE_COUNT",
"activator_sha256":"$ACTIVATOR_SHA256","builder_sha256":"$BUILDER_SHA256","activation_transaction_dir":"$ACTIVATION_TRANSACTION_DIR",
"step_report_url":"$STEP_REPORT_URL","project_source_post_url":"$PROJECT_SOURCE_POST_URL","project_source_post_file_url":"$PROJECT_SOURCE_POST_FILE_URL",
"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",
"step_report_publication_complete":b("$STEP_REPORT_PUBLICATION_COMPLETE"),"project_source_post_publication_complete":b("$PROJECT_SOURCE_POST_PUBLICATION_COMPLETE"),
"http_verify_pass":b("$HTTP_VERIFY_PASS"),"public_object_kind":"$PUBLIC_OBJECT_KIND","previous_moved_count":"$PREVIOUS_MOVED_COUNT","collision_deduplicated_count":"$COLLISION_DEDUPLICATED_COUNT"
}
json.dump(data,open(sys.argv[1],'w'),ensure_ascii=False,indent=2,sort_keys=True); open(sys.argv[1],'a').write('\n')
PY
  cat >"$VERIFY" <<VERIFY_EOF
RESULT=$RESULT
CURRENT_PHASE=$CURRENT_PHASE
COPY_VERIFY=$COPY_VERIFY
STEP_SHA256=$step_sha
EXPECTED_STEP_SHA256=$EXPECTED_INSTALLER_SHA256
SNAPSHOT_NAME=$SNAPSHOT_NAME
SNAPSHOT_CREATED=$SNAPSHOT_CREATED
TARGET_PREFLIGHT_PASS=$TARGET_PREFLIGHT_PASS
TARGET_CORE_PASS=$TARGET_CORE_PASS
TARGET_POSTCHECK_PASS=$TARGET_POSTCHECK_PASS
CORE_CHANGE_COMPLETE=$CORE_CHANGE_COMPLETE
CORE_CHANGE_REPEATED=false
TARGET_INSTALLER_RERUN=false
MACHINE_GIT_COMPLETE=$MACHINE_GIT_COMPLETE
ROUTER_MACHINE_CLOSE_RERUN=false
GENERATION_ID=$GENERATION_ID
ACTIVE_GENERATION_CREATED=$TARGET_CORE_PASS
ACTIVE_SLOT_COUNT=$([ "$TARGET_POSTCHECK_PASS" = true ] && echo 5 || echo 0)
REPAIR_COUNTER_RESET=$([ "$TARGET_POSTCHECK_PASS" = true ] && echo true || echo false)
VM101_GIT_COMMIT=$VM101_GIT_COMMIT
VM101_GIT_TREE=$VM101_GIT_TREE
VM101_GIT_FILE_COUNT=$VM101_GIT_FILE_COUNT
ACTIVATOR_SHA256=$ACTIVATOR_SHA256
BUILDER_SHA256=$BUILDER_SHA256
AUTHORIZATION_CONSUMED=$TARGET_CORE_PASS
HTTP_VERIFY_PASS=$HTTP_VERIFY_PASS
DIRECT_FAILOPEN_ENABLED=false
TRAFFIC_INTERRUPTION=$TRAFFIC_INTERRUPTION
RUNTIME_IMPACT=true
VERIFY_EOF
  cat >"$REPORT" <<REPORT_EOF
RESULT=$RESULT
STEP_ID=$STEP_ID
STOP_REASON=$STOP_REASON
CURRENT_PHASE=$CURRENT_PHASE
GENERATION_ID=$GENERATION_ID
GENERATION_DIR=$GENERATION_DIR
SNAPSHOT_NAME=$SNAPSHOT_NAME
SNAPSHOT_CREATED=$SNAPSHOT_CREATED
TARGET_PREFLIGHT_PASS=$TARGET_PREFLIGHT_PASS
TARGET_CORE_PASS=$TARGET_CORE_PASS
TARGET_POSTCHECK_PASS=$TARGET_POSTCHECK_PASS
TARGET_ROLLBACK_OK=$TARGET_ROLLBACK_OK
CORE_CHANGE_COMPLETE=$CORE_CHANGE_COMPLETE
CORE_CHANGE_REPEATED=false
TARGET_INSTALLER_RERUN=false
MACHINE_GIT_COMPLETE=$MACHINE_GIT_COMPLETE
ROUTER_MACHINE_CLOSE_RERUN=false
ACTIVE_GENERATION_CREATED=$TARGET_CORE_PASS
ACTIVE_SLOT_COUNT=$([ "$TARGET_POSTCHECK_PASS" = true ] && echo 5 || echo 0)
REPAIR_COUNTER_RESET=$([ "$TARGET_POSTCHECK_PASS" = true ] && echo true || echo false)
DIRECT_FAILOPEN_ENABLED=false
TRAFFIC_INTERRUPTION=$TRAFFIC_INTERRUPTION
RUNTIME_IMPACT=true
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}
HTTP_VERIFY_PASS=$HTTP_VERIFY_PASS
REPORT_EOF
}

print_final(){
  local step_sha; step_sha="$(sha256sum "$STEP_FILE"|awk '{print $1}')"
  cat >&3 <<FINAL
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:-step-report}
PREVIOUS_MOVED_COUNT=${PREVIOUS_MOVED_COUNT:-unknown}
COLLISION_DEDUPLICATED_COUNT=${COLLISION_DEDUPLICATED_COUNT:-unknown}
SNAPSHOT_NAME=$SNAPSHOT_NAME
SNAPSHOT_CREATED=$SNAPSHOT_CREATED
COPY_VERIFY=$COPY_VERIFY
STEP_SHA256=$step_sha
HTTP_VERIFY_PASS=$HTTP_VERIFY_PASS
TRAFFIC_INTERRUPTION=$TRAFFIC_INTERRUPTION
RUNTIME_IMPACT=true
FINAL
}

publish_stop_report_best_effort(){
  local stop_payload="$STEP_DIR/stop-report-payload" stop_log="$STEP_DIR/stop-publish.log" stop_rc
  [[ -x "$PUBLISHER" ]] || return 1
  write_docs
  rm -rf "$stop_payload"; mkdir -p "$stop_payload"; chmod 700 "$stop_payload"
  while IFS= read -r -d '' f; do cp -a "$f" "$stop_payload/$(basename "$f")"; done < <(find "$STEP_DIR" -maxdepth 1 -type f -print0)
  set +e
  "$PUBLISHER" "$STEP_LABEL" "$stop_payload"/* >"$stop_log" 2>&1
  stop_rc=$?
  set -e
  cat "$stop_log"
  router_publication_contract_load "$stop_log" step-report || return 1
  [[ "$stop_rc" -eq 0 || "$RPC_PUBLICATION_COMMITTED" == true ]] || return 1
  STEP_PUBLISHED_DIR="$RPC_PUBLISHED_DIR"; STEP_REPORT_URL="$RPC_PUBLIC_URL"
  PUBLIC_OBJECT_KIND="$RPC_PUBLIC_OBJECT_KIND"; PREVIOUS_MOVED_COUNT="$RPC_PREVIOUS_MOVED_COUNT"; COLLISION_DEDUPLICATED_COUNT="$RPC_COLLISION_DEDUPLICATED_COUNT"
  FACTS_URL="${STEP_REPORT_URL}facts.json"; VERIFY_URL="${STEP_REPORT_URL}verify.txt"; ROLLBACK_URL="${STEP_REPORT_URL}rollback.sh"
  STEP_REPORT_PUBLICATION_COMPLETE=true
  write_docs
  if [[ -d "$STEP_PUBLISHED_DIR" ]]; then
    for f in "$REPORT" "$FACTS" "$VERIFY" "$ROLLBACK" "$stop_log"; do
      [[ -f "$f" ]] || continue
      cp -a "$f" "$STEP_PUBLISHED_DIR/$(basename "$f").tmp.$$"
      chmod 644 "$STEP_PUBLISHED_DIR/$(basename "$f").tmp.$$" 2>/dev/null || true
      mv -f "$STEP_PUBLISHED_DIR/$(basename "$f").tmp.$$" "$STEP_PUBLISHED_DIR/$(basename "$f")"
    done
    "$REINDEX" >/dev/null 2>&1 || true
  fi
  if [[ -x "$HTTP_VERIFY" ]]; then
    if "$HTTP_VERIFY" --url "$FACTS_URL" --output "$STEP_DIR/http-stop-facts.json" --sha256 "$(sha256sum "$FACTS"|awk '{print $1}')" >>"$HTTP_LOG" 2>&1       && "$HTTP_VERIFY" --url "$VERIFY_URL" --output "$STEP_DIR/http-stop-verify.txt" --sha256 "$(sha256sum "$VERIFY"|awk '{print $1}')" >>"$HTTP_LOG" 2>&1; then
      HTTP_VERIFY_PASS=true
      write_docs
      for f in "$REPORT" "$FACTS" "$VERIFY"; do
        [[ -d "$STEP_PUBLISHED_DIR" && -f "$f" ]] || continue
        cp -a "$f" "$STEP_PUBLISHED_DIR/$(basename "$f").tmp.$$"
        chmod 644 "$STEP_PUBLISHED_DIR/$(basename "$f").tmp.$$" 2>/dev/null || true
        mv -f "$STEP_PUBLISHED_DIR/$(basename "$f").tmp.$$" "$STEP_PUBLISHED_DIR/$(basename "$f")"
      done
      "$REINDEX" >/dev/null 2>&1 || true
    fi
  fi
  return 0
}

stop_step(){
  local result="$1" reason="${2:-unspecified}"
  RESULT="$result"; STOP_REASON="$reason"; router_step_phase_fail "$CURRENT_PHASE" "$reason" || true
  write_docs
  trap - ERR
  set +e
  publish_stop_report_best_effort || true
  write_docs
  print_final
  exit 1
}
on_err(){
  local rc=$? line=$1
  if router_step_workflow_is_complete; then return 0; fi
  stop_step STOP_R16_UNEXPECTED_ERROR "phase=$CURRENT_PHASE line=$line rc=$rc"
}
trap 'on_err $LINENO' ERR

publish_object(){
  local label="$1" kind="$2" log="$3"; shift 3
  set +e; "$PUBLISHER" "$label" "$@" >"$log" 2>&1; local rc=$?; set -e
  cat "$log"
  router_publication_contract_load "$log" "$kind" || return 1
  [[ "$rc" -eq 0 || "$RPC_PUBLICATION_COMMITTED" == true ]]
}

phase_begin transfer_verification
ACTUAL_BUNDLE_SHA="$(sha256sum "$BUNDLE_ZIP"|awk '{print $1}')"; ACTUAL_INSTALLER_SHA="$(sha256sum "$SELF"|awk '{print $1}')"
[[ "$ACTUAL_BUNDLE_SHA" == "$EXPECTED_BUNDLE_SHA256" ]] || stop_step STOP_COPY_OR_TRANSFER_ERROR zip_sha
[[ "$ACTUAL_INSTALLER_SHA" == "$EXPECTED_INSTALLER_SHA256" ]] || stop_step STOP_COPY_OR_TRANSFER_ERROR installer_sha
(cd "$BUNDLE_DIR" && sha256sum -c manifest.sha256 >/dev/null) || stop_step STOP_COPY_OR_TRANSFER_ERROR manifest
cat >"$TRANSFER_VERIFY" <<TRANSFER
EXPECTED_BUNDLE_SHA256=$EXPECTED_BUNDLE_SHA256
ACTUAL_BUNDLE_SHA256=$ACTUAL_BUNDLE_SHA
EXPECTED_INSTALLER_SHA256=$EXPECTED_INSTALLER_SHA256
ACTUAL_INSTALLER_SHA256=$ACTUAL_INSTALLER_SHA
COPY_VERIFY=PASS
STEP_SHA256=$ACTUAL_INSTALLER_SHA
TRANSFER
COPY_VERIFY=PASS; STEP_WAS_NOT_STARTED=false
phase_complete transfer_verification

phase_begin vm130_preflight
[[ "$(hostname)" == router-ops ]] || stop_step STOP_R16_VM130_HOSTNAME "hostname=$(hostname)"
for c in bash sh ssh tar gzip sha256sum python3 git curl find awk sed grep install readlink; do command -v "$c" >/dev/null || stop_step STOP_R16_VM130_COMMAND_MISSING "$c"; done
[[ "$(sha256sum "$PUBLISHER"|awk '{print $1}')" == a4977d5bd3b6f31c38d514afcae4f0850dfa44fd7e5477991fef5476d324f029 ]] || stop_step STOP_R16_PUBLISHER_SHA
[[ "$(sha256sum "$HTTP_VERIFY"|awk '{print $1}')" == b81a8db5878c04f1259eba829c8636cce17e38cc3f44e0fb82137178d0501776 ]] || stop_step STOP_R16_HTTP_VERIFY_SHA
[[ "$(sha256sum "$WORKFLOW_LIB"|awk '{print $1}')" == 985e35997ff3c150f76208e2a2934bfaa37c5f0762063e1beea378f521f72a0f ]] || stop_step STOP_R16_WORKFLOW_LIB_SHA
[[ "$(sha256sum "$MACHINE_CLOSE"|awk '{print $1}')" == 939cecd23799216474e1f906b831b9e42b61571ed3a3b153bee114e10dfa96a9 ]] || stop_step STOP_R16_MACHINE_CLOSE_SHA
ssh -o BatchMode=yes pve-mgts true
vm101_command true
phase_complete vm130_preflight

phase_begin target_package_build
( cd "$BUNDLE_DIR" && tar -czf "$TARGET_PACKAGE" payload/vm101 scripts/vm101 tests/fixture-validator.sh )
gzip -t "$TARGET_PACKAGE"; TARGET_PACKAGE_SHA="$(sha256sum "$TARGET_PACKAGE"|awk '{print $1}')"
phase_complete target_package_build

phase_begin snapshot_preflight
test "${#SNAPSHOT_NAME}" -le 40 || stop_step STOP_R16_SNAPSHOT_NAME_TOO_LONG "length=${#SNAPSHOT_NAME}"
test "${#SNAPSHOT_NAME}" -le 32 || stop_step STOP_R16_SNAPSHOT_NAME_NOT_PREFERRED "length=${#SNAPSHOT_NAME}"
ssh -o BatchMode=yes pve-mgts "test \"\$(qm status 101 | awk '{print \$2}')\" = running; ! qm listsnapshot 101 | awk '{print \$2}' | grep -Fx '$SNAPSHOT_NAME'"
phase_complete snapshot_preflight

phase_begin target_preflight
vm101_command "rm -rf '$REMOTE_ROOT' '$REMOTE_PACKAGE'; mkdir -p '$REMOTE_ROOT' '$TARGET_BASE'"
vm101_upload "$TARGET_PACKAGE" "$REMOTE_PACKAGE"
REMOTE_SHA="$(vm101_command "sha256sum '$REMOTE_PACKAGE' | cut -d ' ' -f1")"
[[ "$REMOTE_SHA" == "$TARGET_PACKAGE_SHA" ]] || stop_step STOP_R16_TARGET_PACKAGE_SHA
vm101_command "tar -xzf '$REMOTE_PACKAGE' -C '$REMOTE_ROOT'"
set +e; vm101_command "sh '$REMOTE_ROOT/scripts/vm101/vm101-preflight.sh' '$TARGET_BASE/preflight'" >"$TARGET_PREFLIGHT_LOG" 2>&1; rc=$?; set -e
cat "$TARGET_PREFLIGHT_LOG"; [[ "$rc" -eq 0 ]] || stop_step STOP_R16_TARGET_PREFLIGHT_FAILED "rc=$rc"
grep -qx RESULT=PASS_R16_TARGET_PREFLIGHT "$TARGET_PREFLIGHT_LOG" || stop_step STOP_R16_TARGET_PREFLIGHT_MARKER
TARGET_PREFLIGHT_PASS=true
phase_complete target_preflight

phase_begin snapshot_create
ssh -o BatchMode=yes pve-mgts "qm snapshot 101 '$SNAPSHOT_NAME' --description '$STEP_ID pre-activation safety snapshot'"
ssh -o BatchMode=yes pve-mgts "qm listsnapshot 101 | awk '{print \$2}' | grep -Fx '$SNAPSHOT_NAME'; test \"\$(qm status 101 | awk '{print \$2}')\" = running"
SNAPSHOT_CREATED=true
phase_complete snapshot_create

phase_begin target_core
set +e; vm101_command "sh '$REMOTE_ROOT/scripts/vm101/vm101-apply.sh' '$REMOTE_ROOT' '$TARGET_BASE'" >"$TARGET_APPLY_LOG" 2>&1; rc=$?; set -e
cat "$TARGET_APPLY_LOG"
if [[ "$rc" -ne 0 ]]; then
  TARGET_ROLLBACK_OK="$(value_from_log ROLLBACK_OK "$TARGET_APPLY_LOG")"; [[ -n "$TARGET_ROLLBACK_OK" ]] || TARGET_ROLLBACK_OK=unknown
  stop_step STOP_R16_TARGET_CORE_FAILED "rc=$rc rollback=$TARGET_ROLLBACK_OK"
fi
grep -qx RESULT=PASS_R16_TARGET_CORE "$TARGET_APPLY_LOG" || stop_step STOP_R16_TARGET_CORE_MARKER
TARGET_CORE_PASS=true; CORE_CHANGE_COMPLETE=true; VM101_RUNTIME_CHANGE=true; TARGET_ROLLBACK_OK=not_needed
ACTIVATOR_SHA256="$(value_from_log ACTIVATOR_SHA256 "$TARGET_APPLY_LOG")"; BUILDER_SHA256="$(value_from_log BUILDER_SHA256 "$TARGET_APPLY_LOG")"; ACTIVATION_TRANSACTION_DIR="$(value_from_log ACTIVATION_TRANSACTION_DIR "$TARGET_APPLY_LOG")"
phase_complete target_core

phase_begin target_postcheck
set +e; vm101_command "sh '$REMOTE_ROOT/scripts/vm101/vm101-postcheck.sh' '$TARGET_BASE'" >"$TARGET_POSTCHECK_LOG" 2>&1; rc=$?; set -e
cat "$TARGET_POSTCHECK_LOG"; [[ "$rc" -eq 0 ]] || stop_step STOP_R16_TARGET_POSTCHECK_FAILED "rc=$rc core_complete=true_no_auto_rollback"
grep -qx RESULT=PASS_R16_TARGET_POSTCHECK "$TARGET_POSTCHECK_LOG" || stop_step STOP_R16_TARGET_POSTCHECK_MARKER
TARGET_POSTCHECK_PASS=true
phase_complete target_postcheck

phase_begin target_artifact_export
set +e; vm101_command "sh '$REMOTE_ROOT/scripts/vm101/vm101-export.sh' '$TARGET_BASE' '$TARGET_BASE/export.tar.gz'" >"$TARGET_EXPORT_LOG" 2>&1; rc=$?; set -e
cat "$TARGET_EXPORT_LOG"; [[ "$rc" -eq 0 ]] || stop_step STOP_R16_TARGET_EXPORT_FAILED "rc=$rc"
vm101_download "$TARGET_BASE/export.tar.gz" "$TARGET_ARTIFACTS_TAR"
gzip -t "$TARGET_ARTIFACTS_TAR"; tar -xzf "$TARGET_ARTIFACTS_TAR" -C "$TARGET_ARTIFACTS"
phase_complete target_artifact_export

phase_begin machine_git_and_source_publication
set +e; "$MACHINE_CLOSE" vm101 "$STEP_ID: transactional activation of $GENERATION_ID" >"$MACHINE_CLOSE_LOG" 2>&1; rc=$?; set -e
cat "$MACHINE_CLOSE_LOG"; [[ "$rc" -eq 0 ]] || stop_step STOP_R16_MACHINE_CLOSE_FAILED "rc=$rc"
grep -qx RESULT=PASS_ROUTER_MACHINE_CLOSE "$MACHINE_CLOSE_LOG" || stop_step STOP_R16_MACHINE_CLOSE_MARKER
VM101_GIT_COMMIT="$(value_from_log COMMIT "$MACHINE_CLOSE_LOG")"; VM101_GIT_TREE="$(value_from_log TREE "$MACHINE_CLOSE_LOG")"; VM101_GIT_FILE_COUNT="$(value_from_log GIT_FILE_COUNT "$MACHINE_CLOSE_LOG")"; VM101_PUBLIC_URL="$(value_from_log VM101_PUBLIC_URL "$MACHINE_CLOSE_LOG")"
[[ "$VM101_GIT_COMMIT" =~ ^[0-9a-f]{40}$ && "$VM101_GIT_TREE" =~ ^[0-9a-f]{40}$ && "$VM101_GIT_FILE_COUNT" =~ ^[0-9]+$ && "$VM101_PUBLIC_URL" == https://*/*/ ]] || stop_step STOP_R16_MACHINE_CLOSE_FIELDS
MACHINE_GIT_COMPLETE=true
phase_complete machine_git_and_source_publication

phase_begin target_post_machine_git
set +e; vm101_command "sh '$REMOTE_ROOT/scripts/vm101/vm101-post-machine-git.sh' '$VM101_GIT_COMMIT' '$VM101_GIT_TREE' '$VM101_GIT_FILE_COUNT'" >"$TARGET_POST_GIT_LOG" 2>&1; rc=$?; set -e
cat "$TARGET_POST_GIT_LOG"; [[ "$rc" -eq 0 ]] || stop_step STOP_R16_TARGET_POST_GIT_FAILED "rc=$rc"
grep -qx RESULT=PASS_R16_POST_MACHINE_GIT "$TARGET_POST_GIT_LOG" || stop_step STOP_R16_TARGET_POST_GIT_MARKER
phase_complete target_post_machine_git

phase_begin model_build
cp -a "$TARGET_ARTIFACTS"/* "$MODEL_BUILD/"
cat >"$MODEL_BUILD/README.md" <<MODEL_MD
# VM101 current model — R16 transactional generation activation

- Generation: `$GENERATION_ID`
- Active link: `/var/lib/router-egress-recovery/generations/active` -> `$GENERATION_DIR`
- Active slots: 5
- Endpoints match immutable generation candidates: PASS
- Tables/rules 201–205: PASS
- Strict health: PASS
- Repair counter: 0
- Health repair service: running
- Direct failopen: disabled
- Activator: `/usr/local/sbin/router-egress-generation-activate`
- Activator SHA256: `$ACTIVATOR_SHA256`
- Builder SHA256: `$BUILDER_SHA256`
- Automatic activation gate: disabled; activation used a consumed single-use authorization
- VM101 Git commit: `$VM101_GIT_COMMIT`
- Proxmox safety snapshot: `$SNAPSHOT_NAME`
MODEL_MD
phase_complete model_build

phase_begin model_publication
publish_object "$MODEL_LABEL" vm101-model "$MODEL_PUBLISH_LOG" "$MODEL_BUILD"/* || stop_step STOP_R16_MODEL_PUBLICATION
VM101_MODEL_URL="$RPC_PUBLIC_URL"
phase_complete model_publication

phase_begin methods_build
cp -a "$TARGET_ARTIFACTS/activation-output.txt" "$METHODS_BUILD/"
cp -a "$TARGET_ARTIFACTS/rollback-target.sh" "$METHODS_BUILD/rollback-target.sh.reference"
cat >"$METHODS_BUILD/README.md" <<METHODS_MD
# VM101 methods — R16 transactional activation

R16 validates the immutable staging generation immediately before core. It builds a complete UCI network file off-line, atomically installs it, restarts vpn1..vpn5 sequentially under activation and local-repair locks, and verifies every endpoint, strict probe, table and rule.

The active symlink and repair counter reset occur only after all five slots pass. A single-use authorization bound to the generation manifest is consumed before runtime mutation. Automatic activation remains disabled. Any failure before the PASS boundary restores the previous network, recovery state, repair counter and absence of active generation. The Proxmox snapshot is retained as a manual safety point and is not automatically restored.

Late Machine Git/publication failures after target core PASS do not trigger runtime rollback. Continuation starts at the first incomplete R15D phase.
METHODS_MD
phase_complete methods_build

phase_begin methods_publication
publish_object "$METHODS_LABEL" vm101-methods "$METHODS_PUBLISH_LOG" "$METHODS_BUILD"/* || stop_step STOP_R16_METHODS_PUBLICATION
VM101_METHODS_URL="$RPC_PUBLIC_URL"
phase_complete methods_publication

phase_begin plan_build
cp -a "$BUNDLE_DIR/reference/canonical-plan.md" "$PLAN_BUILD/canonical-plan.md"
cat >"$PLAN_BUILD/R16_PROGRESS.md" <<PLAN_MD
# R16 progress — transactional generation activation

`PASS_R16_TRANSACTIONAL_GENERATION_ACTIVATION`

Completed:

- staged generation `$GENERATION_ID` validated again;
- Proxmox safety snapshot `$SNAPSHOT_NAME` created without stopping VM101;
- five new HideMyName configurations activated all-or-nothing;
- endpoints, strict health, tables and rules verified;
- active generation symlink committed only after complete proof;
- `repair_events_since_full_refresh=0` only after complete proof;
- activation implementation published through Machine Git;
- direct failopen remained disabled;
- automatic activation remained disabled and the R16 authorization was consumed;
- generation builder was made compatible with an existing active generation so the next pool can still be staged.

Next architectural work: integrate the same activator into autonomous full-pool-refresh orchestration and test forced rollback plus reboot persistence as separate controlled STEP(s).
PLAN_MD
phase_complete plan_build

phase_begin plan_publication
publish_object "$PLAN_LABEL" local-architecture-plan "$PLAN_PUBLISH_LOG" "$PLAN_BUILD"/* || stop_step STOP_R16_PLAN_PUBLICATION
LOCAL_M07_PLAN_URL="$RPC_PUBLIC_URL"
phase_complete plan_publication

phase_begin project_source_post_build
POST_FILE="$POST_BUILD/WG_PAID_MGTS_VM101_TRANSACTIONAL_GENERATION_ACTIVATION_R16.md"
cat >"$POST_FILE" <<POST_MD
# WG Paid / MGTS — R16 transactional activation of VM101 generation

Date: $(date -u '+%Y-%m-%d %H:%M:%S UTC')  
STEP: `$STEP_ID`  
Result: `PASS_R16_TRANSACTIONAL_GENERATION_ACTIVATION`

## What changed

The validated staging generation `$GENERATION_ID`, authorized by a consumed single-use manifest-bound authorization, became the active five-slot VM101 generation. R16 installed the durable activator, prepared the complete UCI network configuration away from production, switched vpn1..vpn5 under locks and verified endpoint identity, strict external connectivity, tables 201–205 and fwmark rules.

## Transaction boundary

Before complete proof, any failure restores the previous network, recovery state and repair counter. The active symlink is created only after all five slots pass. The repair counter is reset only after the same proof. After target core PASS, publication errors do not automatically roll back a healthy runtime.

## Safety

- Proxmox snapshot: `$SNAPSHOT_NAME`
- VM was not stopped for snapshot creation.
- Direct failopen remained disabled.
- Automatic activation remained disabled.
- The builder remains able to stage a future generation while this one is active.
- Brief interruption was limited to sequential restarts of vpn1..vpn5.
- Manual rollback remains available on VM101 and in the STEP report.

## Authoritative state

- Generation: `$GENERATION_ID`
- VM101 commit: `$VM101_GIT_COMMIT`
- VM101 tree: `$VM101_GIT_TREE`
- VM101 files: `$VM101_GIT_FILE_COUNT`
- VM101 source: $VM101_PUBLIC_URL
- Current model: $VM101_MODEL_URL
- Current methods: $VM101_METHODS_URL
- Current local plan: $LOCAL_M07_PLAN_URL

## Next work

Use the R16 activator inside autonomous full-refresh orchestration, then execute controlled rollback and reboot-persistence testing before enabling the complete state machine path.
POST_MD
POST_SHA="$(sha256sum "$POST_FILE"|awk '{print $1}')"
printf '{"result":"PASS_R16_PROJECT_SOURCE_POST_BUILT","step_id":"%s","sha256":"%s","runtime_impact":true}\n' "$STEP_ID" "$POST_SHA" >"$POST_BUILD/facts.json"
printf 'POST_SHA256=%s\nRUNTIME_IMPACT=true\n' "$POST_SHA" >"$POST_BUILD/verify.txt"
phase_complete project_source_post_build

phase_begin project_source_post_publication
publish_object "$POST_LABEL" project-source-post "$POST_PUBLISH_LOG" "$POST_BUILD"/* || stop_step STOP_R16_PROJECT_SOURCE_POST_PUBLICATION
PROJECT_SOURCE_POST_URL="$RPC_PUBLIC_URL"; PROJECT_SOURCE_POST_FILE_URL="${PROJECT_SOURCE_POST_URL}$(basename "$POST_FILE")"; PROJECT_SOURCE_POST_PUBLICATION_COMPLETE=true
phase_complete project_source_post_publication

write_rollback_wrapper

phase_begin step_report_preparation
RESULT=PASS_R16_TRANSACTIONAL_GENERATION_ACTIVATION; STOP_REASON=none; write_docs
rm -rf "$STEP_PAYLOAD"; mkdir -p "$STEP_PAYLOAD"
for f in "$STEP_FILE" "$REPORT" "$FACTS" "$VERIFY" "$ROLLBACK" "$MAIN_LOG" "$PROGRESS_LOG" "$TRANSFER_VERIFY" "$SYSTEM_MODEL" "$METHODS_LIMIT" "$ACCESS_ROUTES" "$PHASE_CURRENT" "$PHASE_EVENTS" "$TARGET_PREFLIGHT_LOG" "$TARGET_APPLY_LOG" "$TARGET_POSTCHECK_LOG" "$TARGET_EXPORT_LOG" "$MACHINE_CLOSE_LOG" "$TARGET_POST_GIT_LOG" "$TARGET_ARTIFACTS_TAR" "$MODEL_PUBLISH_LOG" "$METHODS_PUBLISH_LOG" "$PLAN_PUBLISH_LOG" "$POST_PUBLISH_LOG"; do [[ -f "$f" ]] && cp -a "$f" "$STEP_PAYLOAD/$(basename "$f")"; done
cp -a "$POST_FILE" "$STEP_PAYLOAD/"
phase_complete step_report_preparation

phase_begin step_report_publication
set +e; "$PUBLISHER" "$STEP_LABEL" "$STEP_PAYLOAD"/* >"$STEP_PUBLISH_LOG" 2>&1; PUBLISHER_RC=$?; set -e
cat "$STEP_PUBLISH_LOG"; router_publication_contract_load "$STEP_PUBLISH_LOG" step-report || stop_step STOP_R16_STEP_REPORT_PUBLICATION_CONTRACT "rc=$PUBLISHER_RC"
STEP_PUBLISHED_DIR="$RPC_PUBLISHED_DIR"; STEP_REPORT_URL="$RPC_PUBLIC_URL"; PUBLIC_OBJECT_KIND="$RPC_PUBLIC_OBJECT_KIND"; PREVIOUS_MOVED_COUNT="$RPC_PREVIOUS_MOVED_COUNT"; COLLISION_DEDUPLICATED_COUNT="$RPC_COLLISION_DEDUPLICATED_COUNT"
FACTS_URL="${STEP_REPORT_URL}facts.json"; VERIFY_URL="${STEP_REPORT_URL}verify.txt"; ROLLBACK_URL="${STEP_REPORT_URL}rollback.sh"
[[ "$PUBLISHER_RC" -eq 0 || "$RPC_PUBLICATION_COMMITTED" == true ]] || stop_step STOP_R16_STEP_REPORT_PUBLICATION_FAILED "rc=$PUBLISHER_RC"
STEP_REPORT_PUBLICATION_COMPLETE=true
phase_complete step_report_publication

phase_begin external_http_verification
: >"$HTTP_LOG"
"$HTTP_VERIFY" --url "$STEP_REPORT_URL" --output "$STEP_DIR/http-step-index.html" >>"$HTTP_LOG" 2>&1
"$HTTP_VERIFY" --url "${STEP_REPORT_URL}step-code.sh" --output "$STEP_DIR/http-step-code.sh" --sha256 "$EXPECTED_INSTALLER_SHA256" >>"$HTTP_LOG" 2>&1
"$HTTP_VERIFY" --url "$PROJECT_SOURCE_POST_FILE_URL" --output "$STEP_DIR/http-project-source-post.md" --sha256 "$(sha256sum "$POST_FILE"|awk '{print $1}')" >>"$HTTP_LOG" 2>&1
"$HTTP_VERIFY" --url "$VM101_PUBLIC_URL" --output "$STEP_DIR/http-vm101-source-index.html" >>"$HTTP_LOG" 2>&1
"$HTTP_VERIFY" --url "$VM101_MODEL_URL" --output "$STEP_DIR/http-model-index.html" >>"$HTTP_LOG" 2>&1
"$HTTP_VERIFY" --url "$VM101_METHODS_URL" --output "$STEP_DIR/http-methods-index.html" >>"$HTTP_LOG" 2>&1
"$HTTP_VERIFY" --url "$LOCAL_M07_PLAN_URL" --output "$STEP_DIR/http-plan-index.html" >>"$HTTP_LOG" 2>&1
HTTP_VERIFY_PASS=true
phase_complete external_http_verification

phase_begin final_artifact_sync
CURRENT_PHASE=complete; RESULT=PASS_R16_TRANSACTIONAL_GENERATION_ACTIVATION; STOP_REASON=none; write_docs
for f in "$REPORT" "$FACTS" "$VERIFY"; do cp -a "$f" "$STEP_PUBLISHED_DIR/$(basename "$f").tmp.$$"; chmod 644 "$STEP_PUBLISHED_DIR/$(basename "$f").tmp.$$"; mv -f "$STEP_PUBLISHED_DIR/$(basename "$f").tmp.$$" "$STEP_PUBLISHED_DIR/$(basename "$f")"; done
"$REINDEX" >/dev/null
"$HTTP_VERIFY" --url "$FACTS_URL" --output "$STEP_DIR/http-final-facts.json" --sha256 "$(sha256sum "$FACTS"|awk '{print $1}')" >>"$HTTP_LOG" 2>&1
"$HTTP_VERIFY" --url "$VERIFY_URL" --output "$STEP_DIR/http-final-verify.txt" --sha256 "$(sha256sum "$VERIFY"|awk '{print $1}')" >>"$HTTP_LOG" 2>&1
phase_complete final_artifact_sync
router_step_workflow_mark_complete
trap - ERR
set +e
print_final
exit 0
