#!/bin/bash
# Published by setup.utlyze.com/studio. Stock macOS entry point.
set -euo pipefail
umask 077
VERSION='1.4.7'
SHA256='bf179d3ad8d8b99ebaa01702b0f34bdfd1a9e5e31faba7fb0e57f72791dcc2cf'
base_digest() {
  case "$1" in
    "1.0.0") printf '%s\n' '59de8fae9f92e0b8e4020ecd754c108190c28806e647b59cb01b6a1908c300a2 25386';;
    "1.1.0") printf '%s\n' '569a866cf9edebde0975f8fa6ae087707db6f236fceeba1ad64fc7207b8a54f4 27376977';;
    "1.1.1") printf '%s\n' '0ea2c768ce2ff693c3a250d64c08d06226001a096b7b059fedca9944992b2bc4 27377574';;
    "1.1.2") printf '%s\n' '086d1607d393162a7c55322254a7d7c3e1b474ce937d334bbff2c841bcf93577 27378450';;
    "1.1.3") printf '%s\n' '126fea54c148ba2cac794455498af42eaf5cad0b091c0c4f1553b465096f8e36 27378953';;
    "1.1.4") printf '%s\n' '8165314a563075bd3c902bec5a797c4255fd785a4904e87f1d1f511475c064b6 27379535';;
    "1.1.5") printf '%s\n' '243886888b23c47ccc5b7e24e0e9f2db429591de1a9165b7e710badb78e176be 55367169';;
    "1.1.6") printf '%s\n' 'd999a36272743eba5c175c3852fc79327b40974f68a4bda3372e5392de8b6a7e 27373700';;
    *) return 1;;
  esac
}
ARTIFACT="https://setup.utlyze.com/releases/$VERSION/clientai-kit-$VERSION.tar.gz"
TASK_BASE="$HOME/.clientai"
TASK_TMP=""
TASK_KEEPALIVE=""
TASK_AWAKE=""
TASK_LOCK_OWNED=0
TASK_RESUME_RUN=""
cleanup() {
  [ -z "$TASK_KEEPALIVE" ] || kill "$TASK_KEEPALIVE" 2>/dev/null || true
  [ -z "$TASK_AWAKE" ] || kill "$TASK_AWAKE" 2>/dev/null || true
  [ -z "$TASK_TMP" ] || rm -rf "$TASK_TMP"
  if [ "$TASK_LOCK_OWNED" = 1 ]; then rm -f "$TASK_BASE/.studio-entry.lock/pid"; rmdir "$TASK_BASE/.studio-entry.lock" 2>/dev/null || true; fi
}
trap cleanup EXIT
die() { printf 'Studio setup: %s\n' "$1" >&2; exit "${2:-22}"; }
safe_dir() {
  local p="$1"
  while [ "$p" != / ]; do
    [ ! -L "$p" ] || die 'A managed directory is a symlink; preserve it and ask the fleet agent to reconcile.'
    case "$p" in "$TASK_BASE"|"$TASK_BASE"/*)
      if [ -e "$p" ]; then
        [ "$(/usr/bin/stat -f '%u' "$p")" = "$(id -u)" ] || die 'A managed path belongs to another user.'
        local mode="$(/usr/bin/stat -f '%Lp' "$p")"
        [ "$((8#$mode & 022))" = 0 ] || die 'A managed path is writable by another user.'
      fi;;
    esac
    p="$(dirname "$p")"
  done
}

run_approved_bootstrap() {
  # A long package install can outlive the short-lived run token. One retry
  # reclaims the same approved enrollment; it does not replay completed steps.
  local attempt rc http config="$TASK_BASE/enrollment/config.json"
  for attempt in 1 2; do
    if CLIENTAI_EXPECTED_RUN_ID="$TASK_RESUME_RUN" /bin/bash "$TASK_TMP/approved-bootstrap.sh"; then return 0; else rc=$?; fi
    [ "$attempt" = 1 ] && [ "$rc" = 20 ] && [ -f "$config" ] || return "$rc"
    safe_dir "$config"
    [ "$(/usr/bin/stat -f '%u:%Lp' "$config")" = "$(id -u):600" ] || return "$rc"
    TASK_RESUME_RUN="$(/usr/bin/plutil -extract run_id raw -o - "$config")"
    [[ "$TASK_RESUME_RUN" =~ ^run_[A-Za-z0-9_-]{8,64}$ ]] || return "$rc"
    printf 'Authorization: Bearer %s\n' "$(/usr/bin/plutil -extract run_token raw -o - "$config")" > "$TASK_TMP/run-authorization"
    http="$(/usr/bin/curl --silent --show-error --proto '=https' --connect-timeout 20 --max-time 60 \
      -H @"$TASK_TMP/run-authorization" -o "$TASK_TMP/run-status.json" -w '%{http_code}' \
      "https://setup.utlyze.com/v1/runs/$TASK_RESUME_RUN/config")" || return "$rc"
    rm -f "$TASK_TMP/run-authorization"
    [ "$http" = 403 ] && [ "$(/usr/bin/plutil -extract error.code raw -o - "$TASK_TMP/run-status.json" 2>/dev/null)" = AUTH_FORBIDDEN ] || return "$rc"
    printf '%s\n' 'Renewing this approved Mac’s expired installation session and continuing its saved steps.'
  done
}

clt_ready() {
  local selected
  selected="$(/usr/bin/xcode-select -p 2>/dev/null)" || return 1
  [ -x "$selected/usr/bin/clang" ] && /usr/bin/xcrun --find clang >/dev/null 2>&1
}

clt_gui_running() {
  /usr/bin/pgrep -f '^/System/Library/CoreServices/Install Command Line Developer Tools.app/Contents/MacOS/Install Command Line Developer Tools$' >/dev/null 2>&1
}

install_clt_from_catalog() (
  # Apple's on-demand marker is also used by Homebrew's official installer.
  # Never follow a marker symlink or remove a marker created by another run.
  local marker=/tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
  local owned_marker="" label=""
  cleanup_clt_marker() {
    if [ -n "$owned_marker" ] && [ ! -L "$marker" ] && [ -f "$marker" ] &&
       [ "$(/usr/bin/stat -f '%d:%i:%u:%Lp:%z' "$marker")" = "$owned_marker" ]; then
      /bin/rm -f "$marker"
    fi
    return 0
  }
  trap cleanup_clt_marker EXIT
  if [ -e "$marker" ] || [ -L "$marker" ]; then
    [ ! -L "$marker" ] && [ -f "$marker" ] && [ ! -s "$marker" ] || return 1
  else
    ( set -C; umask 077; : > "$marker" ) 2>/dev/null || return 1
    owned_marker="$(/usr/bin/stat -f '%d:%i:%u:%Lp:%z' "$marker")"
  fi
  printf '%s\n' 'Checking Apple for the compatible Command Line Tools package...'
  LC_ALL=C /usr/sbin/softwareupdate --list > "$TASK_TMP/clt-catalog.log" 2>&1 || return 1
  label="$(/usr/bin/sed -nE 's/^[[:space:]]*\* Label: (Command Line Tools for Xcode( [0-9]+(\.[0-9]+)*)?-[0-9]+(\.[0-9]+)*)[[:space:]]*$/\1/p' "$TASK_TMP/clt-catalog.log" | /usr/bin/sort -V | /usr/bin/tail -1)"
  [ -n "$label" ] || return 1
  clt_ready && return 0
  # An open xcode-select dialog does not prove an installation is active.
  # Use Apple's own update service, which arbitrates update work; never stop
  # the GUI or any update daemon to force this installation through.
  # The single exact label comes from Apple's eligible catalog. Never install
  # all updates or pass a catalog value through shell evaluation.
  printf 'Installing %s. Leave this Terminal open.\n' "$label"
  /usr/bin/sudo -n /usr/sbin/softwareupdate --install "$label" || return 1
  [ -x /Library/Developer/CommandLineTools/usr/bin/clang ] || return 1
  /usr/bin/sudo -n /usr/bin/xcode-select --switch /Library/Developer/CommandLineTools || return 1
  clt_ready
)

ensure_command_line_tools() {
  clt_ready && return 0
  printf '\n%s\n' 'Preparing Apple Command Line Tools before continuing setup.'
  if install_clt_from_catalog; then
    printf '%s\n' 'Command Line Tools are ready. Continuing setup.'
    return 0
  fi
  clt_ready && return 0
  if [ -n "${SSH_CONNECTION:-}${SSH_TTY:-}" ]; then
    /usr/bin/tail -20 "$TASK_TMP/clt-catalog.log" >&2 2>/dev/null || true
    die 'Apple command-line tools installation did not complete. Send the error above to the fleet agent; saved enrollment is preserved. This remote setup has not opened another local dialog.' 40
  fi
  clt_gui_running || /usr/bin/xcode-select --install >/dev/null 2>&1 || true
  printf '%s\n' 'Complete the Command Line Tools installation dialog on this Mac if shown.' \
    'Keep this Terminal open. Setup will continue automatically when the tools are ready.'
  local waited=0
  until clt_ready; do
    [ "$waited" -lt 3600 ] || die 'Command Line Tools are still unavailable. Complete their installation and rerun this command; saved enrollment is preserved.' 40
    /bin/sleep 10
    waited=$((waited+10))
    [ "$((waited % 60))" != 0 ] || printf '%s\n' 'Still waiting for Apple Command Line Tools; this setup session remains active.'
  done
  printf '%s\n' 'Command Line Tools are ready. Continuing setup.'
}

authorize_admin() {
  # sudo -v can demand a password when an admin rule and an already granted
  # NOPASSWD fleet rule coexist. Test actual command authorization first.
  /usr/bin/sudo -n true >/dev/null 2>&1 || /usr/bin/sudo -v || \
    die 'Administrator authorization is required. Run this line in Terminal as the signed-in administrator.' 40
}

authorize_mac() {
  printf '\n%s\n' 'Step 1: authorize this Mac. Enter the Mac administrator password if prompted.'
  authorize_admin
  if [ -z "$TASK_KEEPALIVE" ]; then
    ( while kill -0 $$ 2>/dev/null; do /usr/bin/sudo -n true 2>/dev/null || exit; sleep 50; done ) &
    TASK_KEEPALIVE=$!
  fi
  if [ -z "$TASK_AWAKE" ] && [ -x /usr/bin/caffeinate ]; then
    /usr/bin/caffeinate -dimsu -w "$$" >/dev/null 2>&1 &
    TASK_AWAKE=$!
  fi
  if ! /usr/bin/sudo /usr/sbin/systemsetup -getremotelogin 2>/dev/null | /usr/bin/grep -q 'Remote Login: On'; then
    /usr/bin/sudo /usr/sbin/systemsetup -f -setremotelogin on > "$TASK_TMP/remote-login.log" 2>&1 || \
      die 'Enable Remote Login in System Settings > General > Sharing, then run this line again. macOS may require Terminal Full Disk Access.' 40
    /usr/bin/sudo /usr/sbin/systemsetup -getremotelogin 2>/dev/null | /usr/bin/grep -q 'Remote Login: On' || \
      die 'Remote Login was not confirmed. Enable it in System Settings and resume this line.' 40
  fi
  export ENABLE_SCREEN_SHARING=1
  ensure_command_line_tools
}

pair_studio() {
  local root="$TASK_BASE/studio-pairing" hardware machine user host install token request_id stage http state count response
  hardware="$(/usr/sbin/ioreg -rd1 -c IOPlatformExpertDevice | /usr/bin/awk -F '\"' '/\"IOPlatformUUID\"/ {print $(NF-1); exit}')"
  [ -n "$hardware" ] || die 'The Mac hardware identity could not be read.'
  machine="studio-$(printf '%s' "$hardware" | /usr/bin/shasum -a 256 | /usr/bin/cut -c 1-12)"
  user="$(id -un)"
  [[ "$user" =~ ^[a-z_][a-z0-9_-]{0,40}$ ]] || die 'The Mac account name is unsupported.'
  host="$(/usr/bin/awk 'NR==1 {print $1 " " $2}' /etc/ssh/ssh_host_ed25519_key.pub)"
  [[ "$host" =~ ^ssh-ed25519\ [A-Za-z0-9+/]{68}$ ]] || die 'The SSH host public key is unavailable. Enable Remote Login, then resume.' 40
  safe_dir "$root"
  if [ ! -d "$root" ]; then
    stage="$(mktemp -d "$TASK_BASE/.studio-pairing.XXXXXX")"
    install="$(/usr/bin/uuidgen | tr '[:upper:]' '[:lower:]')"
    token="sp_$(/usr/bin/openssl rand -hex 32)"
    request_id="pair_$(printf '%s' "$install" | tr -d '-')"
    printf '{"id":"%s","install_id":"%s","shortname":"%s","user":"%s","host_key":"%s"}\n' "$request_id" "$install" "$machine" "$user" "$host" > "$stage/request.json"
    printf 'Authorization: Bearer %s\n' "$token" > "$stage/authorization"
    chmod 600 "$stage/request.json" "$stage/authorization"
    # Never replace an earlier request. Reruns retain its private token.
    [ ! -e "$root" ] || die 'Another setup created an approval request. Preserve it and rerun.' 40
    mv "$stage" "$root"
    unset token
  fi
  for stage in "$root/request.json" "$root/authorization"; do
    safe_dir "$stage"
    [ -f "$stage" ] && [ "$(/usr/bin/stat -f '%u:%Lp' "$stage")" = "$(id -u):600" ] || die 'Saved approval files require this user and mode 600.'
  done
  request_id="$(/usr/bin/plutil -extract id raw -o - "$root/request.json")"
  install="$(/usr/bin/plutil -extract install_id raw -o - "$root/request.json")"
  [[ "$request_id" =~ ^pair_[0-9a-f]{32}$ ]] && [[ "$install" =~ ^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ ]] || die 'Saved approval identity is invalid.'
  [ "$request_id" = "pair_$(printf '%s' "$install" | tr -d '-')" ] || die 'Saved approval identity differs.'
  [ "$(/usr/bin/plutil -extract shortname raw -o - "$root/request.json")" = "$machine" ] && \
    [ "$(/usr/bin/plutil -extract user raw -o - "$root/request.json")" = "$user" ] && \
    [ "$(/usr/bin/plutil -extract host_key raw -o - "$root/request.json")" = "$host" ] || die 'This saved request belongs to a different Mac identity. Ask Studio Zero to reconcile it.' 40
  /usr/bin/grep -Eq '^Authorization: Bearer sp_[0-9a-f]{64}$' "$root/authorization" || die 'Saved approval credential is invalid.'
  [ "$(/usr/bin/wc -l < "$root/authorization" | tr -d ' ')" = 1 ] || die 'Saved approval credential has extra fields.'
  response="$TASK_TMP/pairing.json"
  http="$(/usr/bin/curl --silent --show-error --proto '=https' --connect-timeout 20 --max-time 60 \
    -H @"$root/authorization" -H 'Content-Type: application/json' --data-binary @"$root/request.json" \
    -o "$response" -w '%{http_code}' https://setup.utlyze.com/v1/studio/pairings)" || die 'Could not request approval. Run the same line again to resume this request.' 20
  [ "$http" = 201 ] || die "Studio approval request returned HTTP $http. The saved request is preserved for the fleet agent." 40
  printf '\n%s\n' "Step 2: waiting for Studio Zero to approve $machine ($user)." \
    "Approval reference: $request_id" \
    'No setup code is needed. Leave this Terminal open; setup continues as soon as this Mac is approved.' \
    'This reference is safe to share with the fleet agent. Do not share the private files in studio-pairing.'
  count=0
  while :; do
    [ "$(/usr/bin/plutil -extract pairing.id raw -o - "$response")" = "$request_id" ] && \
      [ "$(/usr/bin/plutil -extract pairing.install_id raw -o - "$response")" = "$install" ] && \
      [ "$(/usr/bin/plutil -extract pairing.shortname raw -o - "$response")" = "$machine" ] && \
      [ "$(/usr/bin/plutil -extract pairing.user raw -o - "$response")" = "$user" ] && \
      [ "$(/usr/bin/plutil -extract pairing.host_key raw -o - "$response")" = "$host" ] || die 'Approval response identity differs. Preserve this request for repair.' 40
    state="$(/usr/bin/plutil -extract pairing.state raw -o - "$response")"
    case "$state" in
      APPROVED) break;;
      PENDING) ;;
      DENIED|EXPIRED) die "Studio approval is $state. The fleet agent must reconcile this request." 40;;
      *) die 'Studio approval returned an unknown state.' 40;;
    esac
    count=$((count+1)); [ "$count" -le 240 ] || die 'Still waiting for Studio Zero approval. Run this same command to keep waiting on the same request.' 40
    [ "$((count % 4))" != 0 ] || printf '%s\n' "Still waiting for approval of $machine; the installer is running."
    sleep 15
    http="$(/usr/bin/curl --silent --show-error --proto '=https' --connect-timeout 20 --max-time 60 -H @"$root/authorization" \
      -o "$response" -w '%{http_code}' "https://setup.utlyze.com/v1/studio/pairings/$request_id")" || die 'Approval connection interrupted. Rerun the same command; its saved request will resume.' 20
    [ "$http" = 200 ] || die "Approval check returned HTTP $http. Preserve the saved request and rerun after repair." 40
  done
  printf '\n%s\n' 'Step 3: approved. Installing the base software and connecting to the fleet.'
  /usr/bin/curl --fail --silent --show-error --proto '=https' --connect-timeout 20 --max-time 120 -H @"$root/authorization" \
    "https://setup.utlyze.com/v1/studio/pairings/$request_id/bootstrap" -o "$TASK_TMP/approved-bootstrap.sh" || die 'Could not retrieve the approved bootstrap. Run this same command again.' 20
  safe_dir "$TASK_BASE/enrollment/install-id"
  mkdir -p "$TASK_BASE/enrollment"; chmod 700 "$TASK_BASE/enrollment"
  if [ -e "$TASK_BASE/enrollment/install-id" ]; then
    [ -f "$TASK_BASE/enrollment/install-id" ] && [ "$(cat "$TASK_BASE/enrollment/install-id")" = "$install" ] || die 'Existing install identity differs from the approved Mac.' 40
  else
    stage="$(mktemp "$TASK_BASE/enrollment/.install-id.XXXXXX")"
    printf '%s\n' "$install" > "$stage"; chmod 600 "$stage"; mv "$stage" "$TASK_BASE/enrollment/install-id"
  fi
  authorize_admin
  run_approved_bootstrap
}
[ "$(uname -s)" = Darwin ] && [ "$(uname -m)" = arm64 ] || die 'This full Studio release requires an Apple Silicon Mac.'
[ "$(id -u)" != 0 ] || die 'Run this line as the signed-in Mac user, without sudo.'
safe_dir "$TASK_BASE"
mkdir -p "$TASK_BASE"; chmod 700 "$TASK_BASE"
safe_dir "$TASK_BASE/.studio-entry.lock"
if ! mkdir "$TASK_BASE/.studio-entry.lock" 2>/dev/null; then
  safe_dir "$TASK_BASE/.studio-entry.lock/pid"
  TASK_OTHER="$(cat "$TASK_BASE/.studio-entry.lock/pid" 2>/dev/null || true)"
  if [[ "$TASK_OTHER" =~ ^[0-9]+$ ]] && kill -0 "$TASK_OTHER" 2>/dev/null; then
    die "Setup is already running (process $TASK_OTHER). Return to its Terminal; do not start another enrollment." 40
  fi
  [ -n "$TASK_OTHER" ] || die 'A setup lock is incomplete. Ask the fleet agent to reconcile it.' 40
  rm -f "$TASK_BASE/.studio-entry.lock/pid"
  rmdir "$TASK_BASE/.studio-entry.lock" || die 'The prior setup lock contains unexpected files. Preserve it for repair.' 40
  mkdir "$TASK_BASE/.studio-entry.lock" || die 'Another setup started. Return to its Terminal.' 40
fi
TASK_LOCK_OWNED=1
printf '%s\n' "$$" > "$TASK_BASE/.studio-entry.lock/pid"
TASK_TMP="$(mktemp -d "$TASK_BASE/.studio-download.XXXXXX")"

# Resume the existing base enrollment without consuming a second setup code.
# Paired Macs renew their short-lived run authorization through their original
# approval before resuming. Older unpaired enrollments retain their base path.
TASK_STATE="$TASK_BASE/enrollment/state.json"
TASK_CONFIG="$TASK_BASE/enrollment/config.json"
TASK_PROFILE=""
for TASK_PRIVATE in "$TASK_CONFIG" "$TASK_STATE"; do
  safe_dir "$TASK_PRIVATE"
  if [ -e "$TASK_PRIVATE" ]; then
    [ -f "$TASK_PRIVATE" ] && [ "$(/usr/bin/stat -f '%u:%Lp' "$TASK_PRIVATE")" = "$(id -u):600" ] || \
      die 'Saved enrollment files must be owned by this user and mode 600.'
  fi
done
if [ -f "$TASK_CONFIG" ] && [ ! -L "$TASK_CONFIG" ]; then
  TASK_PROFILE="$(/usr/bin/plutil -extract profile raw -o - "$TASK_CONFIG")"
fi
[ "$TASK_PROFILE" != client ] || die 'This Mac has a client enrollment. A fleet agent must explicitly reconcile its identity before full Studio setup.'
TASK_BASE_DONE=0
if [ -e "$TASK_BASE/enrollment" ] || [ -e "$TASK_BASE/releases" ]; then
  if [ ! -f "$TASK_CONFIG" ] || [ ! -f "$TASK_STATE" ]; then
    TASK_PAIR="$TASK_BASE/studio-pairing/request.json"
    safe_dir "$TASK_PAIR"; safe_dir "$TASK_BASE/enrollment/install-id"
    [ -f "$TASK_PAIR" ] && [ "$(/usr/bin/stat -f '%u:%Lp' "$TASK_PAIR")" = "$(id -u):600" ] && \
      [ -f "$TASK_BASE/enrollment/install-id" ] && \
      [ "$(/usr/bin/plutil -extract install_id raw -o - "$TASK_PAIR")" = "$(cat "$TASK_BASE/enrollment/install-id")" ] || \
      die 'Enrollment checkpoint is incomplete. A fleet agent must repair this enrollment; do not request a second code.' 40
    # A paired stage0 interruption resumes the same install, never a new join.
    # A saved config can resume its authenticated base even before state.json.
  fi
fi
if [ -f "$TASK_CONFIG" ] && [ ! -L "$TASK_CONFIG" ]; then
  TASK_STATUS=CONFIGURED
  [ ! -f "$TASK_STATE" ] || TASK_STATUS="$(/usr/bin/plutil -extract state raw -o - "$TASK_STATE")"
  TASK_KIT="$(/usr/bin/plutil -extract kit_version raw -o - "$TASK_CONFIG")"
  case "$TASK_STATUS" in COMPLETE|COMPLETE_WITH_HUMAN_ACTIONS) TASK_BASE_DONE=1;; esac
  if [ "$TASK_BASE_DONE" = 0 ]; then
    case "$TASK_STATUS" in FAILED_TERMINAL|EXPIRED|REVOKED) die 'Base enrollment requires a fresh owner-issued enrollment. Its saved report identifies the exact state.' 40;; esac
    if [ -e "$TASK_BASE/studio-pairing" ]; then
      # A missing/damaged credential must not silently create a new pairing.
      for TASK_PRIVATE in "$TASK_BASE/studio-pairing/request.json" "$TASK_BASE/studio-pairing/authorization" "$TASK_BASE/enrollment/install-id"; do
        safe_dir "$TASK_PRIVATE"
        [ -f "$TASK_PRIVATE" ] && [ "$(/usr/bin/stat -f '%u:%Lp' "$TASK_PRIVATE")" = "$(id -u):600" ] || die 'Saved approval is incomplete. Preserve this enrollment for repair.' 40
      done
      TASK_RESUME_RUN="$(/usr/bin/plutil -extract run_id raw -o - "$TASK_CONFIG")"
      [[ "$TASK_RESUME_RUN" =~ ^run_[A-Za-z0-9_-]{8,64}$ ]] || die 'Saved enrollment run identity is invalid.'
      [ "$(/usr/bin/plutil -extract install_id raw -o - "$TASK_CONFIG")" = "$(cat "$TASK_BASE/enrollment/install-id")" ] || die 'Saved enrollment install identity differs.' 40
      if [ -f "$TASK_STATE" ]; then
        [ "$(/usr/bin/plutil -extract run_id raw -o - "$TASK_STATE")" = "$TASK_RESUME_RUN" ] && \
          [ "$(/usr/bin/plutil -extract install_id raw -o - "$TASK_STATE")" = "$(cat "$TASK_BASE/enrollment/install-id")" ] || die 'Saved checkpoint identity differs.' 40
      fi
      authorize_mac
      pair_studio
    else
      case "$TASK_KIT" in *[!0-9.]*|'') die 'Saved enrollment version is invalid.';; esac
      TASK_BASE_RECORD="$(base_digest "$TASK_KIT")" || die 'This saved base version is not currently signed and promoted. The fleet owner must reconcile the original enrollment.' 40
      read -r TASK_BASE_SHA TASK_BASE_BYTES <<< "$TASK_BASE_RECORD"
      /usr/bin/curl --fail --silent --show-error --location --proto '=https' --proto-redir '=https' \
        --connect-timeout 20 --max-time 300 --max-filesize "$TASK_BASE_BYTES" \
        "https://setup.utlyze.com/releases/$TASK_KIT/clientai-kit-$TASK_KIT.tar.gz" -o "$TASK_TMP/base.tar.gz"
      [ "$(/usr/bin/wc -c < "$TASK_TMP/base.tar.gz" | tr -d ' ')" = "$TASK_BASE_BYTES" ] || die 'Signed base archive size check failed.' 30
      [ "$(/usr/bin/shasum -a 256 "$TASK_TMP/base.tar.gz" | awk '{print $1}')" = "$TASK_BASE_SHA" ] || die 'Signed base archive integrity check failed.' 30
      # Execute a newly extracted authenticated copy. Never execute saved base
      # scripts or overwrite their tree. Keep this path for native resume jobs.
      TASK_BASE_RELEASES="$TASK_BASE/verified-base-releases"
      safe_dir "$TASK_BASE_RELEASES"; mkdir -p "$TASK_BASE_RELEASES"
      TASK_VERIFIED_BASE="$(mktemp -d "$TASK_BASE_RELEASES/$TASK_KIT.XXXXXX")"
      /usr/bin/tar -xzf "$TASK_TMP/base.tar.gz" -C "$TASK_VERIFIED_BASE"
      [ -f "$TASK_VERIFIED_BASE/bootstrap.sh" ] && [ ! -L "$TASK_VERIFIED_BASE/bootstrap.sh" ] || die 'Signed base archive lacks its bootstrap.'
      authorize_mac
      CLIENTAI_KIT_VERSION="$TASK_KIT" /bin/bash "$TASK_VERIFIED_BASE/bootstrap.sh" --enrollment-config "$TASK_CONFIG"
    fi
    TASK_BASE_DONE=1
  fi
fi
if [ "$TASK_BASE_DONE" = 0 ]; then
  authorize_mac
  pair_studio
fi
# A stopped or client enrollment must never advance just because its process
# returned zero. Full setup reports readiness separately from base enrollment.
[ -f "$TASK_STATE" ] && [ ! -L "$TASK_STATE" ] || die 'Base enrollment did not produce its checkpoint.' 40
TASK_STATUS="$(/usr/bin/plutil -extract state raw -o - "$TASK_STATE")"
TASK_PROFILE="$(/usr/bin/plutil -extract profile raw -o - "$TASK_CONFIG")"
case "$TASK_STATUS:$TASK_PROFILE" in COMPLETE:fleet|COMPLETE_WITH_HUMAN_ACTIONS:fleet) ;; *) die 'The fleet base is not ready. Resume its saved enrollment first.' 40;; esac

printf '%s\n' 'Base software is configured. Installing the Studio layer and registering its SSH identity for automatic fleet setup.'
TASK_RELEASES="$TASK_BASE/studio-releases"
TASK_RELEASE="$TASK_RELEASES/$VERSION"
safe_dir "$TASK_RELEASE"; mkdir -p "$TASK_RELEASES"
/usr/bin/curl --fail --silent --show-error --location --proto '=https' --proto-redir '=https' \
  --connect-timeout 20 --max-time 300 "$ARTIFACT" -o "$TASK_TMP/kit.tar.gz"
TASK_ACTUAL="$(/usr/bin/shasum -a 256 "$TASK_TMP/kit.tar.gz" | awk '{print $1}')"
[ "$TASK_ACTUAL" = "$SHA256" ] || die 'Downloaded Studio release failed its pinned SHA-256 check.' 30
TASK_PYTHON=/opt/homebrew/bin/python3.13
[ -x "$TASK_PYTHON" ] || die 'The base Python installation is missing.' 12
# extract.py is included in the launcher itself, so the archive cannot choose
# how it is verified. Only regular allowlisted files are accepted.
"$TASK_PYTHON" - "$TASK_TMP/kit.tar.gz" "$TASK_RELEASE" "$SHA256" <<'PY'
import hashlib,json,os,pathlib,shutil,stat,sys,tarfile,tempfile
archive, dest, expected = pathlib.Path(sys.argv[1]), pathlib.Path(sys.argv[2]), sys.argv[3]
seen={}; payload={}
with tarfile.open(archive,'r:gz') as tar:
    entries=tar.getmembers()
    if len(entries)>200 or sum(x.size for x in entries)>20*1024*1024: raise SystemExit('Oversized release')
    for item in entries:
        name=item.name.removeprefix('./'); p=pathlib.PurePosixPath(name)
        if item.isdir() and name in ('.','studio','studio/tests'): continue
        if not item.isfile() or p.is_absolute() or '..' in p.parts or name in seen: raise SystemExit('Unsafe release member')
        if str(p)!=name or (name not in ('studio.sh','STUDIO.md') and not (name.startswith('studio/') and p.suffix in ('.py','.json','.md'))): raise SystemExit('Unexpected release file')
        data=tar.extractfile(item).read()
        payload[name]=data; seen[name]=hashlib.sha256(data).hexdigest()
for required in ('studio.sh','studio/runner.py','studio/catalog.json','studio/integrations.py','studio/fleet.py','studio/memory_bridge.py'):
    if required not in seen: raise SystemExit('Incomplete release')
if dest.exists():
    if dest.is_symlink() or not dest.is_dir() or dest.stat().st_uid!=os.getuid() or dest.stat().st_mode&0o022: raise SystemExit('Unsafe existing release')
    actual={}
    for p in dest.rglob('*'):
        if p.is_symlink() or p.stat().st_uid!=os.getuid() or p.stat().st_mode&0o022: raise SystemExit('Unsafe existing release member')
        if p.is_file() and p.name!='release.json': actual[str(p.relative_to(dest))]=hashlib.sha256(p.read_bytes()).hexdigest()
    if actual!=seen: raise SystemExit('Existing release differs from the signed archive; preserve it for repair')
    raise SystemExit(0)
staging=pathlib.Path(tempfile.mkdtemp(prefix='.stage-',dir=dest.parent))
try:
    for name,data in payload.items():
        target=staging/name; target.parent.mkdir(parents=True,exist_ok=True,mode=0o700)
        with target.open('xb') as stream: stream.write(data)
        target.chmod(0o700 if name=='studio.sh' else 0o600)
    (staging/'release.json').write_text(json.dumps({'archive_sha256':expected,'files':seen}))
    (staging/'release.json').chmod(0o600)
    os.rename(staging,dest)
finally:
    if staging.exists(): shutil.rmtree(staging)

PY

export PYTHONDONTWRITEBYTECODE=1
TASK_ARGS=(apply)
if [ -f "$TASK_BASE/studio/site.json" ]; then TASK_ARGS+=(--site "$TASK_BASE/studio/site.json"); fi
set +e
/bin/bash "$TASK_RELEASE/studio.sh" "${TASK_ARGS[@]}"
TASK_RESULT=$?
set -e
printf '\n%s\n' "Full Studio report: $TASK_BASE/studio/report.json" \
  "Setup continues automatically after sign-in, login or fleet configuration. Native permissions and account login remain interactive." \
  "Run this same line again whenever you want a fresh current-version check."
exit "$TASK_RESULT"
