#!/usr/bin/env bash
# require-supported-version.sh  -  turn the update-check "force" signal into an
# exit code (Phase 0 Step 0.6, pipeline-wide supported-version gate).
#
# update-check.sh stays advisory by contract: it always exits 0 and the caller
# decides. This wrapper is that decision for shell callers. It runs the same
# cached check (one shared cache file, so it costs nothing extra) and:
#
#   exit 0  -  the run may proceed (current, merely-behind, offline, or the
#              registry has no `required` floor)
#   exit 3  -  the installed version is BELOW dist-tags.required; the caller
#              must halt and tell the user to run /multi-agent:update
#
# Fail-open is deliberate and load-bearing. A floor is only ever enforced from a
# registry answer we actually received: offline, a blocked registry, a missing
# `required` tag or an undeterminable local version all exit 0. A version gate
# that bricks the pipeline on a flaky network is worse than the drift it guards.
#
# Emergency override: MULTI_AGENT_ALLOW_OUTDATED=1 exits 0 with a loud stderr
# warning. It exists so a broken release cannot strand someone mid-incident; it
# is not a supported way to stay behind, and the caller logs that it was used.
#
# `prefs.global.updateCheck.enabled: false` does NOT disable this gate  -  that
# switch silences the advisory nag. A floor is only published for a release that
# changes a contract, and opting out of it would only fail later and less
# legibly.
#
# stdout on exit 3 (one machine-readable line, then a human block on stderr):
#   force|<local>|<latest>|<required>
#
# Usage:
#   bash pipeline/scripts/require-supported-version.sh || halt
#   bash pipeline/scripts/require-supported-version.sh --local 15.0.0

set -uo pipefail

HERE="$(cd "$(dirname "$0")" && pwd)"
CHECK="$HERE/update-check.sh"
[ -f "$CHECK" ] || CHECK="$HOME/.claude/scripts/update-check.sh"
[ -f "$CHECK" ] || exit 0  # no checker installed -> nothing to enforce

out=$(bash "$CHECK" "$@" 2>/dev/null) || exit 0
case "$out" in
  *"|force") ;;
  *) exit 0 ;;
esac

local_v="${out%%|*}"
rest="${out#*|}"
latest_v="${rest%%|*}"
# Second call is served from the same fresh cache the first one just used.
required_v=$(bash "$CHECK" --print-required "$@" 2>/dev/null | tr -d '[:space:]')
[ -n "$required_v" ] || required_v="$latest_v"

if [ "${MULTI_AGENT_ALLOW_OUTDATED:-}" = "1" ]; then
  printf 'WARNING: MULTI_AGENT_ALLOW_OUTDATED=1 - running v%s below the required floor. Update as soon as this run ends.\n' \
    "$local_v" >&2
  exit 0
fi

printf 'force|%s|%s|%s\n' "$local_v" "$latest_v" "$required_v"
cat >&2 <<MSG

  This release line is required, not optional.
  Installed: v${local_v}   Required: v${required_v} or newer   Latest: v${latest_v}

  Run /multi-agent:update, then start this command again.

MSG
exit 3
