#!/usr/bin/env bash
set -euo pipefail

fail() {
  echo "error: $*" >&2
  exit 1
}

assert_file() {
  [[ -f "$1" ]] || fail "expected file missing: $1"
}

assert_executable() {
  [[ -x "$1" ]] || fail "expected executable file: $1"
}

assert_log_contains() {
  local needle="$1"
  local file="$2"
  grep -F -- "${needle}" "${file}" >/dev/null || fail "expected ${file} to contain: ${needle}"
}

assert_log_excludes() {
  local needle="$1"
  local file="$2"
  if grep -F -- "${needle}" "${file}" >/dev/null; then
    fail "expected ${file} not to contain: ${needle}"
  fi
}

assert_log_before() {
  local first="$1"
  local second="$2"
  local file="$3"
  local first_line
  local second_line
  first_line="$(grep -nF -- "${first}" "${file}" | head -1 | cut -d: -f1)"
  second_line="$(grep -nF -- "${second}" "${file}" | head -1 | cut -d: -f1)"
  [[ -n "${first_line}" && -n "${second_line}" && "${first_line}" -lt "${second_line}" ]] ||
    fail "expected ${file} to contain ${first} before ${second}"
}

TEST_DIR="$(mktemp -d)"
trap 'rm -rf "${TEST_DIR}"' EXIT

FAKE_BIN="${TEST_DIR}/bin"
mkdir -p "${FAKE_BIN}"
cat > "${FAKE_BIN}/npm" <<'EOF_NPM'
#!/usr/bin/env bash
set -euo pipefail
if [[ "${1:-}" == "pack" ]]; then
  package_ref="$2"
  package_name="${package_ref%@*}"
  case "${package_name}" in
    opencode-windows-arm64|opencode-windows-x64) binary_name="opencode.exe"; magic='\x4d\x5a\x00\x00' ;;
    opencode-darwin-arm64|opencode-darwin-x64) binary_name="opencode"; magic='\xcf\xfa\xed\xfe' ;;
    *) echo "unexpected package: ${package_name}" >&2; exit 1 ;;
  esac
  work_dir="$(mktemp -d)"
  mkdir -p "${work_dir}/package/bin"
  printf "${magic}fake %s\n" "${package_name}" > "${work_dir}/package/bin/${binary_name}"
  chmod 0755 "${work_dir}/package/bin/${binary_name}"
  tar -czf "${package_name}.tgz" -C "${work_dir}" package
  rm -rf "${work_dir}"
  exit 0
fi

[[ "${1:-}" == "run" ]] || {
  echo "unexpected npm command: $*" >&2
  exit 1
}
printf 'npm cwd=%s env_version=%s package_version=%s args=%s\n' \
  "${PWD}" \
  "${AGENTTEAM_DESKTOP_VERSION:-}" \
  "${npm_package_version:-}" \
  "${*:2}" >> "${AGENTTEAM_TEST_BUILD_LOG}"
EOF_NPM
chmod +x "${FAKE_BIN}/npm"

cat > "${FAKE_BIN}/signtool.exe" <<'EOF_SIGNTOOL'
#!/usr/bin/env bash
exit 0
EOF_SIGNTOOL
chmod +x "${FAKE_BIN}/signtool.exe"

cat > "${FAKE_BIN}/npx" <<'EOF_NPX'
#!/usr/bin/env bash
set -euo pipefail
[[ "${1:-}" == "electron-builder" ]] || { echo "unexpected npx command: $*" >&2; exit 1; }
printf 'npx cwd=%s env_version=%s package_version=%s args=%s\n' \
  "${PWD}" \
  "${AGENTTEAM_DESKTOP_VERSION:-}" \
  "${npm_package_version:-}" \
  "${*:2}" >> "${AGENTTEAM_TEST_BUILD_LOG}"
printf 'npx electron_mirror=%s builder_binaries_mirror=%s\n' \
  "${ELECTRON_MIRROR:-}" \
  "${ELECTRON_BUILDER_BINARIES_MIRROR:-}" >> "${AGENTTEAM_TEST_BUILD_LOG}"
if [[ -n "${AGENTTEAM_TEST_RELEASE_EVENT_LOG:-}" ]]; then
  printf 'builder %s\n' "${*:2}" >> "${AGENTTEAM_TEST_RELEASE_EVENT_LOG}"
fi
if [[ -n "${AGENTTEAM_TEST_BUILDER_FIXTURE:-}" ]]; then
  builder="${AGENTTEAM_TEST_BUILDER_FIXTURE}/electron/dist/builder"
  version="${AGENTTEAM_DESKTOP_VERSION}"
  if [[ "$*" == *"--mac dmg"* && "$*" == *"--arm64"* ]]; then
    printf 'arm64 dmg\n' > "${builder}/AgentTeam-${version}-mac-arm64.dmg"
    mkdir -p "${builder}/mac-arm64/AgentTeam.app"
  elif [[ "$*" == *"--mac zip"* && "$*" == *"--arm64"* && "$*" == *"--prepackaged"* ]]; then
    printf 'arm64 zip\n' > "${builder}/AgentTeam-${version}-mac-arm64.zip"
    printf 'arm64 zip blockmap\n' > "${builder}/AgentTeam-${version}-mac-arm64.zip.blockmap"
    cat > "${builder}/latest-mac.yml" <<YAML
version: ${version}
files:
  - url: AgentTeam-${version}-mac-arm64.zip
    sha512: arm64
path: AgentTeam-${version}-mac-arm64.zip
sha512: arm64
YAML
  elif [[ "$*" == *"--mac dmg"* && "$*" == *"--x64"* ]]; then
    printf 'x64 dmg\n' > "${builder}/AgentTeam-${version}-mac-x64.dmg"
    mkdir -p "${builder}/mac/AgentTeam.app"
  elif [[ "$*" == *"--mac zip"* && "$*" == *"--x64"* && "$*" == *"--prepackaged"* ]]; then
    printf 'x64 zip\n' > "${builder}/AgentTeam-${version}-mac-x64.zip"
    printf 'x64 zip blockmap\n' > "${builder}/AgentTeam-${version}-mac-x64.zip.blockmap"
    cat > "${builder}/latest-mac.yml" <<YAML
version: ${version}
files:
  - url: AgentTeam-${version}-mac-x64.zip
    sha512: x64
path: AgentTeam-${version}-mac-x64.zip
sha512: x64
YAML
  elif [[ "$*" == *"--win"* && "$*" == *"--arm64"* ]]; then
    printf 'windows arm64\n' > "${builder}/AgentTeam-${version}-win-arm64.exe"
    cat > "${builder}/latest.yml" <<YAML
version: ${version}
files:
  - url: AgentTeam-${version}-win-arm64.exe
    sha512: windows-arm64
path: AgentTeam-${version}-win-arm64.exe
sha512: windows-arm64
YAML
  elif [[ "$*" == *"--win"* && "$*" == *"--x64"* ]]; then
    printf 'windows x64\n' > "${builder}/AgentTeam-${version}-win-x64.exe"
    cat > "${builder}/latest.yml" <<YAML
version: ${version}
files:
  - url: AgentTeam-${version}-win-x64.exe
    sha512: windows-x64
path: AgentTeam-${version}-win-x64.exe
sha512: windows-x64
YAML
  fi
fi
EOF_NPX
chmod +x "${FAKE_BIN}/npx"
cat > "${FAKE_BIN}/curl" <<'EOF_CURL'
#!/usr/bin/env bash
set -euo pipefail
out=""
url=""
probe=0
write_status=0
while [[ $# -gt 0 ]]; do
  case "$1" in
    -o) out="$2"; shift 2 ;;
    -w) write_status=1; shift 2 ;;
    --range) probe=1; shift 2 ;;
    -I|-fI|-fsI|-fsIL) probe=1; shift ;;
    --retry|--connect-timeout|--max-time) shift 2 ;;
    -*) shift ;;
    *) url="$1"; shift ;;
  esac
done

if [[ "${url}" == "https://models.dev/api.json" ]]; then
  [[ -n "${out}" ]] || exit 1
  if [[ -n "${AGENTTEAM_TEST_MODELS_FETCH_LOG:-}" ]]; then
    printf 'fetch\n' >> "${AGENTTEAM_TEST_MODELS_FETCH_LOG}"
  fi
  printf '{"openai":{"id":"openai","name":"OpenAI","env":[],"models":{}}}\n' > "${out}"
  exit 0
fi
if [[ "${probe}" -eq 1 ]]; then
  exit 0
fi
if [[ -n "${out}" ]]; then
  if [[ "${AGENTTEAM_TEST_PUBLIC_METADATA_MISMATCH:-0}" == "1" &&
        "${url}" == "https://static.test.agentteam/agentteam/releases/desktop/latest-mac.yml" ]]; then
    printf '%s\n' 'mismatched public metadata' > "${out}"
    exit 0
  fi
  if [[ "${url}" == https://static.test.agentteam/agentteam/releases/desktop/* ||
        "${url}" == https://test-bucket.ks3-cn-beijing.ksyuncs.com/agentteam/releases/desktop/* ]]; then
    relative="${url#*/agentteam/releases/desktop/}"
    published="${AGENTTEAM_TEST_PUBLISHED_DIR}/agentteam/releases/desktop/${relative}"
    if [[ "${AGENTTEAM_TEST_PUBLIC_VERSION_MISSING:-0}" == "1" &&
          "${url}" == https://static.test.agentteam/agentteam/releases/desktop/v*.json ]]; then
      exit 1
    fi
    if [[ -f "${published}" ]]; then
      cp "${published}" "${out}"
      exit 0
    fi
    [[ "${url}" == https://static.test.agentteam/* ]] && exit 1
  fi
  case "${url}" in
    */agentteam/releases/daemon/index.json)
      printf '%s\n' '{"product":"agentteam-daemon","versions":[{"version":"v9.9.9","manifest_url":"https://static.test.agentteam/agentteam/releases/daemon/v9.9.9.json","published_at":"2026-07-24T00:00:00Z"}],"stable_version":"v9.9.9"}' > "${out}"
      ;;
    */agentteam/releases/desktop/index.json)
      printf '%s\n' '{"product":"agentteam-daemon","versions":[{"version":"v1.1.4","manifest_url":"https://static.test.agentteam/agentteam/releases/desktop/v1.1.4.json","published_at":"2026-07-24T00:00:00Z"}],"stable_version":"v1.1.3"}' > "${out}"
      ;;
    *)
      printf '%s\n' '{"versions":[],"stable_version":""}' > "${out}"
      ;;
  esac
  exit 0
fi
case "${url}" in
  https://test-bucket.ks3-cn-beijing.ksyuncs.com/agentteam/desktop/v9.9.11/SHA256SUMS.txt)
    cat <<'EOF_SUMS'
oldwin  AgentTeam-9.9.11-win-x64.exe
polluted  agentteam_9.9.11_darwin_arm64.tar.gz
EOF_SUMS
    ;;
  https://test-bucket.ks3-cn-beijing.ksyuncs.com/agentteam/desktop/v9.9.12/SHA256SUMS.txt)
    cat <<'EOF_SUMS'
oldmacarm  AgentTeam-v9.9.12-darwin-arm64.dmg
oldmacarmdmgmap  AgentTeam-9.9.12-mac-arm64.dmg.blockmap
oldmacarmzip  AgentTeam-9.9.12-mac-arm64.zip
oldmacarmzipmap  AgentTeam-9.9.12-mac-arm64.zip.blockmap
oldmacx64  AgentTeam-v9.9.12-darwin-amd64.dmg
oldmacx64dmgmap  AgentTeam-9.9.12-mac-x64.dmg.blockmap
oldmacx64zip  AgentTeam-9.9.12-mac-x64.zip
oldmacx64zipmap  AgentTeam-9.9.12-mac-x64.zip.blockmap
polluted  AgentTeam-9.9.12-win-arm64.exe
EOF_SUMS
    ;;
  https://test-bucket.ks3-cn-beijing.ksyuncs.com/agentteam/client/v9.9.10/agentteam_9.9.10_checksums.txt)
    cat <<'EOF_SUMS'
linuxamd  agentteam_9.9.10_linux_amd64.tar.gz
linuxarm  agentteam_9.9.10_linux_arm64.tar.gz
EOF_SUMS
    ;;
  https://test-bucket.ks3-cn-beijing.ksyuncs.com/agentteam/desktop/v9.9.10/SHA256SUMS.txt)
    cat <<'EOF_SUMS'
1111111111111111111111111111111111111111111111111111111111111111  AgentTeam-v9.9.10-darwin-arm64.dmg
2222222222222222222222222222222222222222222222222222222222222222  AgentTeam-9.9.10-mac-arm64.zip
2222222222222222222222222222222222222222222222222222222222222223  AgentTeam-9.9.10-mac-arm64.zip.blockmap
3333333333333333333333333333333333333333333333333333333333333333  AgentTeam-v9.9.10-darwin-amd64.dmg
4444444444444444444444444444444444444444444444444444444444444444  AgentTeam-9.9.10-mac-x64.zip
4444444444444444444444444444444444444444444444444444444444444445  AgentTeam-9.9.10-mac-x64.zip.blockmap
5555555555555555555555555555555555555555555555555555555555555554  AgentTeam_Windows_arm64_v9.9.10.exe
5555555555555555555555555555555555555555555555555555555555555555  AgentTeam_Windows_x64_v9.9.10.exe
EOF_SUMS
    ;;
  https://test-bucket.ks3-cn-beijing.ksyuncs.com/agentteam/desktop/v9.9.10-rc.1/SHA256SUMS.txt)
    cat <<'EOF_SUMS'
1111111111111111111111111111111111111111111111111111111111111111  AgentTeam-v9.9.10-rc.1-darwin-arm64.dmg
2222222222222222222222222222222222222222222222222222222222222222  AgentTeam-v9.9.10-rc.1-darwin-amd64.dmg
3333333333333333333333333333333333333333333333333333333333333332  AgentTeam_Windows_arm64_v9.9.10-rc.1.exe
3333333333333333333333333333333333333333333333333333333333333333  AgentTeam_Windows_x64_v9.9.10-rc.1.exe
EOF_SUMS
    ;;
  https://test-bucket.ks3-cn-beijing.ksyuncs.com/agentteam/desktop/v9.9.14/SHA256SUMS.txt)
    if [[ "${write_status}" -eq 1 ]]; then printf '500'; else echo "server error" >&2; fi
    exit 1
    ;;
  *) exit 0 ;;
esac
EOF_CURL
chmod +x "${FAKE_BIN}/curl"

cat > "${FAKE_BIN}/ks3util" <<'EOF_KS3'
#!/usr/bin/env bash
set -euo pipefail
printf '%s\n' "$*" >> "${AGENTTEAM_TEST_UPLOAD_LOG}"
args=("$@")
source_file="${args[${#args[@]}-2]}"
destination="${args[${#args[@]}-1]}"
if [[ -n "${AGENTTEAM_TEST_PUBLISHED_DIR:-}" &&
      "${destination}" == ks3://test-bucket/agentteam/releases/desktop/* ]]; then
  relative="${destination#ks3://test-bucket/}"
  target="${AGENTTEAM_TEST_PUBLISHED_DIR}/${relative}"
  mkdir -p "$(dirname "${target}")"
  cp "${source_file}" "${target}"
fi
EOF_KS3
chmod +x "${FAKE_BIN}/ks3util"

cat > "${FAKE_BIN}/xcrun" <<'EOF_XCRUN'
#!/usr/bin/env bash
set -euo pipefail
printf '%s\n' "$*" >> "${AGENTTEAM_TEST_NOTARY_LOG}"
if [[ -n "${AGENTTEAM_TEST_RELEASE_EVENT_LOG:-}" ]]; then
  printf 'xcrun %s\n' "$*" >> "${AGENTTEAM_TEST_RELEASE_EVENT_LOG}"
fi
[[ "${1:-}" == "notarytool" ]] || exit 0
case "${2:-}" in
  submit) printf '{"id":"submission-%s"}\n' "$(basename "${3}")" ;;
  info)
    submission_id="${3}"
    count_file="${AGENTTEAM_TEST_NOTARY_LOG}.${submission_id//[^A-Za-z0-9_.-]/_}.count"
    count="$(cat "${count_file}" 2>/dev/null || printf 0)"
    count=$((count + 1))
    printf '%s\n' "${count}" > "${count_file}"
    if [[ "${submission_id}" == "${AGENTTEAM_TEST_NOTARY_NEVER_ACCEPT_ID:-}" ]]; then
      printf '{"id":"%s","status":"In Progress"}\n' "${submission_id}"
    elif [[ "${submission_id}" == "${AGENTTEAM_TEST_NOTARY_INVALID_ID:-}" ]]; then
      printf '{"id":"%s","status":"Invalid"}\n' "${submission_id}"
    elif [[ "${count}" -eq 1 ]]; then
      echo "temporary query failure" >&2; exit 1
    else
      [[ "${count}" -eq 2 ]] && status="In Progress" || status="Accepted"
      printf '{"id":"%s","status":"%s"}\n' "${submission_id}" "${status}"
    fi
    ;;
  log) printf '{"id":"%s","issues":[{"message":"invalid test payload"}]}\n' "${3}" ;;
esac
EOF_XCRUN
chmod +x "${FAKE_BIN}/xcrun"
for command in codesign spctl; do
  cat > "${FAKE_BIN}/${command}" <<'EOF_SECURITY_TOOL'
#!/usr/bin/env bash
set -euo pipefail
printf '%s %s\n' "$(basename "$0")" "$*" >> "${AGENTTEAM_TEST_NOTARY_LOG}"
EOF_SECURITY_TOOL
  chmod +x "${FAKE_BIN}/${command}"
done
PATH="${FAKE_BIN}:${PATH}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=manual-owner-client-assets.lib.sh
source "${SCRIPT_DIR}/manual-owner-client-assets.lib.sh"

# shellcheck source=manual-owner-client-assets-runtime.test.sh
source "${SCRIPT_DIR}/manual-owner-client-assets-runtime.test.sh"

reset_fake_builder_artifacts() {
  local root="$1"
  local builder="${root}/electron/dist/builder"
  rm -rf "${builder}"
  mkdir -p "${builder}"
}

run_builder_and_upload_tests() {
  local root="${TEST_DIR}/release-root"
  local build_log="${TEST_DIR}/build.log"
  local upload_log="${TEST_DIR}/upload.log"
  mkdir -p "${root}/electron" "${root}/release"
  printf '{}\n' > "${root}/electron/package.json"
  mkdir -p "${root}/electron/build"
  printf 'icns\n' > "${root}/electron/build/icon.icns"
  printf 'ico\n' > "${root}/electron/build/icon.ico"
  ln -s "${SCRIPT_DIR}/../electron/node_modules" "${root}/electron/node_modules"
  printf '#!/usr/bin/env bash\nexit 0\n' > "${root}/release/managed-opencode-validate.sh"
  chmod +x "${root}/release/managed-opencode-validate.sh"
  reset_fake_builder_artifacts "${root}"

  ROOT_DIR="${root}"
  KS3UTIL_BIN="ks3util"
  AGENTTEAM_TEST_BUILD_LOG="${build_log}"
  AGENTTEAM_TEST_UPLOAD_LOG="${upload_log}"
  AGENTTEAM_TEST_BUILDER_FIXTURE="${root}"
  AGENTTEAM_MACOS_INSTALLER_OUT_DIR="${TEST_DIR}/mac-output"
  AGENTTEAM_WINDOWS_INSTALLER_OUT_DIR="${TEST_DIR}/win-output"
  AGENTTEAM_KS3_BUCKET="test-bucket"
  AGENTTEAM_DESKTOP_ASSET_PREFIX="agentteam/desktop"
  AGENTTEAM_MANAGED_OPENCODE_VERSION="9.9.9"
  AGENTTEAM_MANAGED_OPENCODE_DARWIN_ARM64_SOURCE="${TEST_DIR}/mac-arm64-opencode"
  AGENTTEAM_MANAGED_OPENCODE_DARWIN_AMD64_SOURCE="${TEST_DIR}/mac-x64-opencode"
  AGENTTEAM_MANAGED_OPENCODE_WINDOWS_ARM64_SOURCE="${TEST_DIR}/win-arm64-opencode.exe"
  AGENTTEAM_MANAGED_OPENCODE_WINDOWS_AMD64_SOURCE="${TEST_DIR}/win-x64-opencode.exe"
  AGENTTEAM_MANAGED_OPENCODE_MODELS_SOURCE="${TEST_DIR}/models.json"
  printf '\xcf\xfa\xed\xfe' > "${AGENTTEAM_MANAGED_OPENCODE_DARWIN_ARM64_SOURCE}"
  printf '\xcf\xfa\xed\xfe' > "${AGENTTEAM_MANAGED_OPENCODE_DARWIN_AMD64_SOURCE}"
  printf '\x4d\x5a\x00\x00' > "${AGENTTEAM_MANAGED_OPENCODE_WINDOWS_ARM64_SOURCE}"
  printf '\x4d\x5a\x00\x00' > "${AGENTTEAM_MANAGED_OPENCODE_WINDOWS_AMD64_SOURCE}"
  printf '{}\n' > "${AGENTTEAM_MANAGED_OPENCODE_MODELS_SOURCE}"
  chmod +x "${AGENTTEAM_MANAGED_OPENCODE_DARWIN_ARM64_SOURCE}" \
    "${AGENTTEAM_MANAGED_OPENCODE_DARWIN_AMD64_SOURCE}" \
    "${AGENTTEAM_MANAGED_OPENCODE_WINDOWS_ARM64_SOURCE}" \
    "${AGENTTEAM_MANAGED_OPENCODE_WINDOWS_AMD64_SOURCE}"
  export AGENTTEAM_TEST_BUILD_LOG AGENTTEAM_TEST_UPLOAD_LOG AGENTTEAM_TEST_BUILDER_FIXTURE \
    AGENTTEAM_MACOS_INSTALLER_OUT_DIR AGENTTEAM_WINDOWS_INSTALLER_OUT_DIR \
    AGENTTEAM_KS3_BUCKET AGENTTEAM_DESKTOP_ASSET_PREFIX \
    AGENTTEAM_MANAGED_OPENCODE_VERSION AGENTTEAM_MANAGED_OPENCODE_DARWIN_ARM64_SOURCE \
    AGENTTEAM_MANAGED_OPENCODE_DARWIN_AMD64_SOURCE AGENTTEAM_MANAGED_OPENCODE_WINDOWS_ARM64_SOURCE \
    AGENTTEAM_MANAGED_OPENCODE_WINDOWS_AMD64_SOURCE \
    AGENTTEAM_MANAGED_OPENCODE_MODELS_SOURCE

  CSC_LINK=/tmp/stale-signing.p12
  CSC_KEY_PASSWORD=stale-password
  CSC_IDENTITY_AUTO_DISCOVERY=true
  AGENTTEAM_MACOS_CODESIGN=0
  AGENTTEAM_MACOS_NOTARIZE=0
  prepare_macos_builder_signing_env
  [[ "${AGENTTEAM_MACOS_ADHOC_SIGN}" == 1 && "${CSC_NAME}" == - ]] ||
    fail "macOS smoke builds must select one explicit ad-hoc signing owner"
  [[ -z "${CSC_LINK:-}" && -z "${CSC_KEY_PASSWORD:-}" ]] ||
    fail "macOS smoke builds must clear stale certificate signing inputs"
  [[ "${CSC_IDENTITY_AUTO_DISCOVERY}" == false ]] ||
    fail "macOS smoke builds must disable signing identity auto-discovery"

  init_manual_owner_client_assets v9.9.11
  : > "${build_log}"
  build_macos_assets >/dev/null
  assert_log_contains "npm cwd=${root}/electron env_version=9.9.11 package_version=9.9.11 args=build:electron" "${build_log}"
  assert_log_contains "npx cwd=${root}/electron env_version=9.9.11 package_version=9.9.11 args=--mac dmg --arm64 --config.mac.identity=- --config.mac.entitlements=build/entitlements.mac.adhoc.plist --config.mac.entitlementsInherit=build/entitlements.mac.adhoc.plist --config.dmg.sign=false --publish never --config.extraMetadata.version=9.9.11" "${build_log}"
  assert_log_contains "npx cwd=${root}/electron env_version=9.9.11 package_version=9.9.11 args=--mac zip --arm64 --prepackaged ${MAC_ARM64_BUILDER_APP} --config.mac.identity=- --config.mac.entitlements=build/entitlements.mac.adhoc.plist --config.mac.entitlementsInherit=build/entitlements.mac.adhoc.plist --config.dmg.sign=false --publish never --config.extraMetadata.version=9.9.11" "${build_log}"
  assert_log_contains "npx cwd=${root}/electron env_version=9.9.11 package_version=9.9.11 args=--mac dmg --x64 --config.mac.identity=- --config.mac.entitlements=build/entitlements.mac.adhoc.plist --config.mac.entitlementsInherit=build/entitlements.mac.adhoc.plist --config.dmg.sign=false --publish never --config.extraMetadata.version=9.9.11" "${build_log}"
  assert_log_contains "npx cwd=${root}/electron env_version=9.9.11 package_version=9.9.11 args=--mac zip --x64 --prepackaged ${MAC_X64_BUILDER_APP} --config.mac.identity=- --config.mac.entitlements=build/entitlements.mac.adhoc.plist --config.mac.entitlementsInherit=build/entitlements.mac.adhoc.plist --config.dmg.sign=false --publish never --config.extraMetadata.version=9.9.11" "${build_log}"
  assert_log_before "args=--mac dmg --x64" "args=--mac zip --arm64 --prepackaged" "${build_log}"
  assert_log_before "args=--mac dmg --x64" "args=--mac zip --x64 --prepackaged" "${build_log}"
  assert_log_excludes "darwin-runtime" "${build_log}"
  assert_file "${MAC_ARM64_DMG}"
  assert_file "${MAC_ARM64_ZIP}"
  assert_file "${MAC_ARM64_ZIP_BLOCKMAP}"
  assert_file "${MAC_X64_DMG}"
  assert_file "${MAC_X64_ZIP}"
  assert_file "${MAC_X64_ZIP_BLOCKMAP}"
  assert_file "${MAC_UPDATER_METADATA}"
  [[ ! -e "${BUILDER_OUTPUT_DIR}/AgentTeam-9.9.11-mac-arm64.dmg.blockmap" &&
     ! -e "${BUILDER_OUTPUT_DIR}/AgentTeam-9.9.11-mac-x64.dmg.blockmap" ]] ||
    fail "macOS DMG builds must not emit pre-notarization blockmaps"
  assert_log_contains "AgentTeam-v9.9.11-darwin-arm64.dmg" "${MAC_CHECKSUM_FILE}"
  assert_log_contains "AgentTeam-v9.9.11-darwin-amd64.dmg" "${MAC_CHECKSUM_FILE}"
  assert_log_excludes ".zip" "${MAC_CHECKSUM_FILE}"
  assert_log_excludes ".blockmap" "${MAC_CHECKSUM_FILE}"
  (
    cd "${root}/electron"
    node --input-type=module - "${MAC_UPDATER_METADATA}" <<'EOF_NODE'
import fs from "node:fs"
import yaml from "js-yaml"

const doc = yaml.load(fs.readFileSync(process.argv[2], "utf8"))
if (String(doc.version) !== "9.9.11") throw new Error("unexpected updater version")
const zipURLs = new Set(doc.files.filter((item) => item.url.endsWith(".zip")).map((item) => item.url))
  for (const expected of [
    "https://static.pingcap.com/agentteam/desktop/AgentTeam-9.9.11-mac-arm64.zip",
    "https://static.pingcap.com/agentteam/desktop/AgentTeam-9.9.11-mac-x64.zip",
  ]) {
  if (!zipURLs.has(expected)) throw new Error(`missing updater URL: ${expected}`)
}
if (zipURLs.size !== 2) throw new Error(`unexpected updater ZIP count: ${zipURLs.size}`)
EOF_NODE
  )
  export AGENTTEAM_MACOS_CODESIGN=1 AGENTTEAM_MACOS_NOTARIZE=1 \
    AGENTTEAM_MACOS_CODESIGN_IDENTITY='Developer ID Application: AgentTeam Test' \
    AGENTTEAM_MACOS_NOTARY_PROFILE=agentteam-notary AGENTTEAM_MACOS_NOTARY_TIMEOUT_SECONDS=3 \
    AGENTTEAM_MACOS_NOTARY_POLL_INTERVAL_SECONDS=1 \
    AGENTTEAM_TEST_NOTARY_LOG="${TEST_DIR}/formal-notary.log" \
    AGENTTEAM_TEST_RELEASE_EVENT_LOG="${TEST_DIR}/formal-release-events.log"
  : > "${AGENTTEAM_TEST_NOTARY_LOG}"; : > "${AGENTTEAM_TEST_RELEASE_EVENT_LOG}"
  reset_fake_builder_artifacts "${root}"
  sleep() { :; }
  build_macos_assets >/dev/null 2>&1
  unset -f sleep
  assert_log_before "xcrun stapler staple ${MAC_ARM64_BUILDER_APP}" "builder --mac zip --arm64 --prepackaged ${MAC_ARM64_BUILDER_APP}" "${AGENTTEAM_TEST_RELEASE_EVENT_LOG}"
  assert_log_before "xcrun stapler validate ${MAC_ARM64_BUILDER_APP}" "builder --mac zip --arm64 --prepackaged ${MAC_ARM64_BUILDER_APP}" "${AGENTTEAM_TEST_RELEASE_EVENT_LOG}"
  assert_log_before "xcrun stapler staple ${MAC_X64_BUILDER_APP}" "builder --mac zip --x64 --prepackaged ${MAC_X64_BUILDER_APP}" "${AGENTTEAM_TEST_RELEASE_EVENT_LOG}"
  assert_log_before "xcrun stapler validate ${MAC_X64_BUILDER_APP}" "builder --mac zip --x64 --prepackaged ${MAC_X64_BUILDER_APP}" "${AGENTTEAM_TEST_RELEASE_EVENT_LOG}"
  export AGENTTEAM_MACOS_CODESIGN=0 AGENTTEAM_MACOS_NOTARIZE=0
  unset AGENTTEAM_MACOS_CODESIGN_IDENTITY AGENTTEAM_MACOS_NOTARY_PROFILE \
    AGENTTEAM_MACOS_NOTARY_TIMEOUT_SECONDS AGENTTEAM_MACOS_NOTARY_POLL_INTERVAL_SECONDS \
    AGENTTEAM_TEST_RELEASE_EVENT_LOG
  : > "${upload_log}"
  upload_macos_assets >/dev/null
  assert_log_contains "AgentTeam-v9.9.11-darwin-arm64.dmg" "${upload_log}"
  assert_log_contains "AgentTeam-9.9.11-mac-x64.zip" "${upload_log}"
  assert_log_contains "AgentTeam-9.9.11-mac-x64.zip.blockmap" "${upload_log}"
  assert_log_excludes ".dmg.blockmap" "${upload_log}"
  assert_log_contains "latest-mac.yml ks3://test-bucket/agentteam/releases/desktop/v9.9.11/latest-mac.yml" "${upload_log}"
  assert_log_excludes "ks3://test-bucket/agentteam/releases/desktop/latest-mac.yml" "${upload_log}"
  assert_log_excludes "install.sh" "${upload_log}"
  assert_log_excludes "darwin_arm64.tar.gz" "${upload_log}"
  assert_log_contains "AgentTeam-9.9.11-win-x64.exe" "${MAC_RELEASE_CHECKSUM_FILE}"
  assert_log_excludes ".dmg.blockmap" "${MAC_RELEASE_CHECKSUM_FILE}"
  rm "${root}/electron/build/icon.icns"
  if (build_macos_assets >/dev/null 2>&1); then
    fail "macOS release must fail closed without the branded application icon"
  fi
  printf 'icns\n' > "${root}/electron/build/icon.icns"
  reset_fake_builder_artifacts "${root}"
  init_manual_owner_client_assets v9.9.12
  : > "${build_log}"
  AGENTTEAM_WINDOWS_SIGN=1
  AGENTTEAM_WINDOWS_SIGN_CERT_SHA1=ABCDEF
  AGENTTEAM_WINDOWS_SIGN_TIMESTAMP_URL=https://timestamp.example
  build_windows_installer_assets >/dev/null
  assert_log_contains "npx cwd=${root}/electron env_version=9.9.12 package_version=9.9.12 args=--win nsis --arm64 --config.win.signtoolOptions.certificateSha1=ABCDEF --config.win.signtoolOptions.rfc3161TimeStampServer=https://timestamp.example --config.forceCodeSigning=true --publish never --config.extraMetadata.version=9.9.12" "${build_log}"
  assert_log_contains "npx cwd=${root}/electron env_version=9.9.12 package_version=9.9.12 args=--win nsis --x64 --config.win.signtoolOptions.certificateSha1=ABCDEF --config.win.signtoolOptions.rfc3161TimeStampServer=https://timestamp.example --config.forceCodeSigning=true --publish never --config.extraMetadata.version=9.9.12" "${build_log}"
  assert_file "${WIN_ARM64_INSTALLER}"
  assert_file "${WIN_X64_INSTALLER}"
  assert_file "${WIN_UPDATER_METADATA}"
  rm "${root}/electron/build/icon.ico"
  if (build_windows_installer_assets >/dev/null 2>&1); then
    fail "Windows release must fail closed without the branded application icon"
  fi
  printf 'ico\n' > "${root}/electron/build/icon.ico"
  CSC_IDENTITY_AUTO_DISCOVERY=true
  unset AGENTTEAM_WINDOWS_SIGNTOOL SIGNTOOL_PATH
  prepare_windows_builder_signing_env
  [[ "${CSC_IDENTITY_AUTO_DISCOVERY}" == false ]] ||
    fail "Windows signing must use explicit electron-builder certificate configuration"
  [[ "${SIGNTOOL_PATH}" == *signtool.exe ]] ||
    fail "Windows signing must discover and export an SDK signtool"
  AGENTTEAM_WINDOWS_SIGN=0
  unset AGENTTEAM_WINDOWS_SIGN_CERT_SHA1 AGENTTEAM_WINDOWS_SIGN_TIMESTAMP_URL
  : > "${upload_log}"
  upload_windows_installer_assets >/dev/null
  assert_log_contains "AgentTeam-9.9.12-win-arm64.exe" "${upload_log}"
  assert_log_contains "AgentTeam-9.9.12-win-x64.exe" "${upload_log}"
  assert_log_contains "latest.yml ks3://test-bucket/agentteam/releases/desktop/v9.9.12/latest.yml" "${upload_log}"
  assert_log_excludes "ks3://test-bucket/agentteam/releases/desktop/latest.yml" "${upload_log}"
  assert_log_contains "AgentTeam-v9.9.12-darwin-arm64.dmg" "${WIN_CHECKSUM_FILE}"
  assert_log_contains "AgentTeam_Windows_arm64_v9.9.12.exe" "${WIN_CHECKSUM_FILE}"
  assert_log_excludes ".dmg.blockmap" "${WIN_CHECKSUM_FILE}"

  reset_fake_builder_artifacts "${root}"
  init_manual_owner_client_assets v9.9.13-rc.1
  build_macos_assets >/dev/null
  build_windows_installer_assets >/dev/null
  : > "${upload_log}"
  upload_macos_assets >/dev/null
  upload_windows_installer_assets >/dev/null
  assert_log_contains "latest-mac.yml ks3://test-bucket/agentteam/releases/desktop/v9.9.13-rc.1/latest-mac.yml" "${upload_log}"
  assert_log_contains "latest.yml ks3://test-bucket/agentteam/releases/desktop/v9.9.13-rc.1/latest.yml" "${upload_log}"
  assert_log_excludes "ks3://test-bucket/agentteam/releases/desktop/latest-mac.yml" "${upload_log}"
  assert_log_excludes "ks3://test-bucket/agentteam/releases/desktop/latest.yml" "${upload_log}"
}

write_fake_manifest_generator() {
  local path="$1"
  cat > "${path}" <<'EOF_MANIFEST'
#!/usr/bin/env bash
set -euo pipefail
mkdir -p "${AGENTTEAM_MANIFEST_OUT_DIR}"
cat > "${AGENTTEAM_MANIFEST_OUT_DIR}/${AGENTTEAM_RELEASE_TAG}.json" <<JSON
{
  "schema_version": "1",
  "product": "legacy",
  "version": "${AGENTTEAM_RELEASE_TAG}",
  "published_at": "2026-07-25T00:00:00Z",
  "manifest_url": "${AGENTTEAM_MANIFEST_BASE_URL}/${AGENTTEAM_RELEASE_TAG}.json",
  "client": {
    "install_script": "${AGENTTEAM_PUBLIC_DOWNLOAD_BASE_URL}/${KS3_CLIENT_PREFIX}/install.sh",
    "checksums": "${AGENTTEAM_PUBLIC_DOWNLOAD_BASE_URL}/${KS3_CLIENT_PREFIX}/${AGENTTEAM_RELEASE_TAG}/${AGENTTEAM_CLIENT_CHECKSUM}",
    "artifacts": [
      {"os":"linux","arch":"amd64","url":"${AGENTTEAM_PUBLIC_DOWNLOAD_BASE_URL}/${KS3_CLIENT_PREFIX}/${AGENTTEAM_RELEASE_TAG}/${AGENTTEAM_CLIENT_AMD64_ARCHIVE}"},
      {"os":"linux","arch":"arm64","url":"${AGENTTEAM_PUBLIC_DOWNLOAD_BASE_URL}/${KS3_CLIENT_PREFIX}/${AGENTTEAM_RELEASE_TAG}/${AGENTTEAM_CLIENT_ARM64_ARCHIVE}"}
    ],
    "assets": [
      {"platform":"linux-amd64","purpose":"runtime","kind":"tarball","url":"${AGENTTEAM_PUBLIC_DOWNLOAD_BASE_URL}/${KS3_CLIENT_PREFIX}/${AGENTTEAM_RELEASE_TAG}/${AGENTTEAM_CLIENT_AMD64_ARCHIVE}"},
      {"platform":"linux-arm64","purpose":"runtime","kind":"tarball","url":"${AGENTTEAM_PUBLIC_DOWNLOAD_BASE_URL}/${KS3_CLIENT_PREFIX}/${AGENTTEAM_RELEASE_TAG}/${AGENTTEAM_CLIENT_ARM64_ARCHIVE}"},
      {"platform":"darwin-arm64","purpose":"runtime","kind":"tarball","url":"legacy-darwin.tar.gz"},
      {"platform":"windows-arm64","purpose":"installer","kind":"exe","url":"legacy-arm64.exe"}
    ]
  },
  "server": {
    "bundle": "${AGENTTEAM_PUBLIC_DOWNLOAD_BASE_URL}/${KS3_SERVER_PREFIX}/${AGENTTEAM_RELEASE_TAG}/${AGENTTEAM_SERVER_BUNDLE}",
    "checksums": "${AGENTTEAM_PUBLIC_DOWNLOAD_BASE_URL}/${KS3_SERVER_PREFIX}/${AGENTTEAM_RELEASE_TAG}/${AGENTTEAM_SERVER_CHECKSUM}"
  }
}
JSON
existing_versions="$(jq -c '.versions // []' "${AGENTTEAM_MANIFEST_EXISTING_INDEX}")"
stable_version="$(jq -r '.stable_version // empty' "${AGENTTEAM_MANIFEST_EXISTING_INDEX}")"
if [[ "${AGENTTEAM_RELEASE_TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
  stable_version="${AGENTTEAM_RELEASE_TAG}"
fi
jq -n \
  --arg version "${AGENTTEAM_RELEASE_TAG}" \
  --arg published_at "2026-07-25T00:00:00Z" \
  --arg manifest_url "${AGENTTEAM_MANIFEST_BASE_URL}/${AGENTTEAM_RELEASE_TAG}.json" \
  --arg stable_version "${stable_version}" \
  --argjson existing "${existing_versions}" \
  '{
    product:"legacy", stable_version:$stable_version, updated_at:$published_at,
    versions: ([{version:$version,published_at:$published_at,manifest_url:$manifest_url}] + ($existing | map(select(.version != $version))))
  }' > "${AGENTTEAM_MANIFEST_OUT_DIR}/index.json"
EOF_MANIFEST
  chmod +x "${path}"
}

run_desktop_manifest_tests() {
  local root="${TEST_DIR}/manifest-root"
  local upload_log="${TEST_DIR}/manifest-upload.log"
  mkdir -p "${root}"
  write_fake_manifest_generator "${root}/generate-manifests.sh"

  ROOT_DIR="${root}"
  KS3UTIL_BIN="ks3util"
  AGENTTEAM_TEST_UPLOAD_LOG="${upload_log}"
  AGENTTEAM_KS3_BUCKET="test-bucket"
  AGENTTEAM_KS3_CLIENT_PREFIX="agentteam/client"
  AGENTTEAM_KS3_SERVER_PREFIX="agentteam/server"
  AGENTTEAM_DESKTOP_ASSET_PREFIX="agentteam/desktop"
  AGENTTEAM_MANIFEST_DESKTOP_PREFIX="agentteam/releases/desktop"
  AGENTTEAM_MANIFEST_WORK_DIR="${TEST_DIR}/manifests"
  AGENTTEAM_TEST_PUBLISHED_DIR="${TEST_DIR}/published"
  AGENTTEAM_PUBLIC_DOWNLOAD_BASE_URL="https://static.test.agentteam"
  AGENTTEAM_GENERATE_MANIFEST_SCRIPT="${root}/generate-manifests.sh"
  export AGENTTEAM_TEST_UPLOAD_LOG AGENTTEAM_TEST_PUBLISHED_DIR AGENTTEAM_KS3_BUCKET AGENTTEAM_KS3_CLIENT_PREFIX \
    AGENTTEAM_KS3_SERVER_PREFIX AGENTTEAM_DESKTOP_ASSET_PREFIX AGENTTEAM_MANIFEST_DESKTOP_PREFIX AGENTTEAM_MANIFEST_WORK_DIR \
    AGENTTEAM_PUBLIC_DOWNLOAD_BASE_URL AGENTTEAM_GENERATE_MANIFEST_SCRIPT

  init_manual_owner_client_assets v9.9.10
  AGENTTEAM_TEST_PUBLIC_VERSION_MISSING=1
  AGENTTEAM_TEST_PUBLIC_METADATA_MISMATCH=1
  export AGENTTEAM_TEST_PUBLIC_VERSION_MISSING AGENTTEAM_TEST_PUBLIC_METADATA_MISMATCH
  regenerate_and_upload_manifests >/dev/null
  activate_root_updater_metadata
  assert_log_before "v9.9.10.json" "index.json" "${upload_log}"
  assert_log_before "index.json" "stable.json" "${upload_log}"
  assert_log_before "agentteam/releases/desktop/stable.json" "agentteam/releases/desktop/latest-mac.yml" "${upload_log}"
  assert_log_contains "ks3://test-bucket/agentteam/releases/desktop/latest-mac.yml" "${upload_log}"
  assert_log_contains "ks3://test-bucket/agentteam/releases/desktop/latest.yml" "${upload_log}"
  local uploads_before_verify
  uploads_before_verify="$(wc -l < "${upload_log}")"
  if (verify_published_release_metadata >/dev/null 2>&1); then
    fail "CDN verification must reject stale public metadata after the origin upload finishes"
  fi
  unset AGENTTEAM_TEST_PUBLIC_VERSION_MISSING AGENTTEAM_TEST_PUBLIC_METADATA_MISMATCH
  verify_published_release_metadata
  [[ "$(wc -l < "${upload_log}")" -eq "${uploads_before_verify}" ]] ||
    fail "CDN verification must not upload release metadata"

  local refresh_urls="${TEST_DIR}/stable-refresh-urls"
  release_metadata_refresh_urls > "${refresh_urls}"
  [[ "$(wc -l < "${refresh_urls}")" -eq 5 ]] || fail "stable publish must print five CDN refresh URLs"
  assert_log_contains "https://static.test.agentteam/agentteam/releases/desktop/v9.9.10.json" "${refresh_urls}"
  assert_log_contains "https://static.test.agentteam/agentteam/releases/desktop/index.json" "${refresh_urls}"
  assert_log_contains "https://static.test.agentteam/agentteam/releases/desktop/stable.json" "${refresh_urls}"
  assert_log_contains "https://static.test.agentteam/agentteam/releases/desktop/latest-mac.yml" "${refresh_urls}"
  assert_log_contains "https://static.test.agentteam/agentteam/releases/desktop/latest.yml" "${refresh_urls}"

  local desktop="${AGENTTEAM_MANIFEST_WORK_DIR}/desktop/v9.9.10.json"
  jq -e '
    .product == "agentteam-desktop" and
    .version == "v9.9.10" and
    (.client.install_script | endswith("/agentteam/client/install.sh")) and
    .client.checksums == "https://static.test.agentteam/agentteam/client/v9.9.10/agentteam_9.9.10_checksums.txt" and
    (.client.artifacts == null) and
    (.server == null) and
    ([.client.assets[].platform] | sort) == ["darwin-amd64","darwin-arm64","linux-amd64","linux-arm64","windows-amd64","windows-arm64"] and
    ([.client.assets[] | select(.platform | startswith("linux-")) | .purpose] | unique) == ["runtime"] and
    ([.client.assets[] | select((.platform | startswith("darwin-")) or (.platform | startswith("windows-"))) | .purpose] | unique) == ["installer"] and
    all(.client.assets[]; (.checksums | type) == "string") and
    ([.client.updater_metadata[].platform] | sort) == ["darwin","windows"] and
    ([.client.updater_metadata[].version] | unique) == ["v9.9.10"] and
    all(.client.updater_metadata[]; .url | contains("/agentteam/releases/desktop/v9.9.10/"))
  ' "${desktop}" >/dev/null || fail "desktop manifest must contain the six-package matrix and updater metadata"

  local invalid_desktop="${TEST_DIR}/invalid-desktop"
  mkdir -p "${invalid_desktop}"
  cp "${desktop}" "${invalid_desktop}/v9.9.10.json"
  cp "${AGENTTEAM_MANIFEST_WORK_DIR}/desktop/index.json" "${invalid_desktop}/index.json"
  cp "${AGENTTEAM_MANIFEST_WORK_DIR}/desktop/stable.json" "${invalid_desktop}/stable.json"
  jq 'del(.client.assets[] | select(.platform == "windows-arm64"))' \
    "${invalid_desktop}/v9.9.10.json" > "${invalid_desktop}/tmp.json"
  mv "${invalid_desktop}/tmp.json" "${invalid_desktop}/v9.9.10.json"
  if (validate_desktop_manifest "${invalid_desktop}" >/dev/null 2>&1); then
    fail "desktop manifest must require all six packages"
  fi

  local invalid_checksum="${TEST_DIR}/invalid-desktop-checksum"
  mkdir -p "${invalid_checksum}"
  cp "${desktop}" "${invalid_checksum}/v9.9.10.json"
  cp "${AGENTTEAM_MANIFEST_WORK_DIR}/desktop/index.json" "${invalid_checksum}/index.json"
  cp "${AGENTTEAM_MANIFEST_WORK_DIR}/desktop/stable.json" "${invalid_checksum}/stable.json"
  jq '.client.checksums = "https://static.test.agentteam/agentteam/desktop/v9.9.10/SHA256SUMS.txt"' \
    "${invalid_checksum}/v9.9.10.json" > "${invalid_checksum}/tmp.json"
  mv "${invalid_checksum}/tmp.json" "${invalid_checksum}/v9.9.10.json"
  if (validate_desktop_manifest "${invalid_checksum}" >/dev/null 2>&1); then
    fail "desktop manifest top-level checksum must match the Linux runtime assets"
  fi

  for file in \
    "${AGENTTEAM_MANIFEST_WORK_DIR}/desktop/index.json" \
    "${AGENTTEAM_MANIFEST_WORK_DIR}/desktop/stable.json"; do
    jq -e . "${file}" >/dev/null || fail "invalid JSON: ${file}"
  done
  [[ "$(jq -r '.stable_version' "${AGENTTEAM_MANIFEST_WORK_DIR}/desktop/index.json")" == "v9.9.10" ]] || fail "desktop index version drift"
  [[ "$(jq -r '.current_version' "${AGENTTEAM_MANIFEST_WORK_DIR}/desktop/stable.json")" == "v9.9.10" ]] || fail "desktop stable version drift"
  [[ "$(jq -r '[.versions[].version] | index("v1.1.4") != null' "${AGENTTEAM_MANIFEST_WORK_DIR}/desktop/index.json")" == "true" ]] || fail "desktop index dropped legacy history"
  [[ "$(jq -r '.versions[] | select(.version == "v1.1.4") | .product' "${AGENTTEAM_MANIFEST_WORK_DIR}/desktop/index.json")" == "agentteam-daemon" ]] || fail "desktop index lost legacy product ownership"
  [[ "$(jq -r '.versions[] | select(.version == "v9.9.10") | .product' "${AGENTTEAM_MANIFEST_WORK_DIR}/desktop/index.json")" == "agentteam-desktop" ]] || fail "desktop index did not mark the canonical release product"
  assert_log_excludes "agentteam/releases/daemon" "${upload_log}"
  AGENTTEAM_MANIFEST_WORK_DIR="${TEST_DIR}/manifests-rc"
  export AGENTTEAM_MANIFEST_WORK_DIR
  : > "${upload_log}"
  init_manual_owner_client_assets v9.9.10-rc.1
  regenerate_and_upload_manifests >/dev/null
  activate_root_updater_metadata
  [[ ! -e "${AGENTTEAM_MANIFEST_WORK_DIR}/desktop/stable.json" ]] || fail "desktop RC must not write stable.json"
  [[ "$(jq -r '.stable_version' "${AGENTTEAM_MANIFEST_WORK_DIR}/desktop/index.json")" == "v9.9.10" ]] || fail "desktop RC advanced stable version"
  assert_log_excludes "stable.json" "${upload_log}"
  assert_log_excludes "ks3://test-bucket/agentteam/releases/desktop/latest-mac.yml" "${upload_log}"
  assert_log_excludes "ks3://test-bucket/agentteam/releases/desktop/latest.yml" "${upload_log}"
  local rc_refresh_urls="${TEST_DIR}/rc-refresh-urls"
  release_metadata_refresh_urls > "${rc_refresh_urls}"
  [[ "$(wc -l < "${rc_refresh_urls}")" -eq 2 ]] || fail "RC publish must print two CDN refresh URLs"
  assert_log_contains "https://static.test.agentteam/agentteam/releases/desktop/v9.9.10-rc.1.json" "${rc_refresh_urls}"
  assert_log_contains "https://static.test.agentteam/agentteam/releases/desktop/index.json" "${rc_refresh_urls}"
  assert_log_excludes "stable.json" "${rc_refresh_urls}"
  assert_log_excludes "latest-mac.yml" "${rc_refresh_urls}"
  assert_log_excludes "latest.yml" "${rc_refresh_urls}"
}

run_entrypoint_contract_tests() {
  local retired
  assert_log_contains 'build_macos_assets' "${SCRIPT_DIR}/build-macos-assets.sh"
  assert_log_contains 'build_windows_installer_assets' "${SCRIPT_DIR}/build-windows-installers.sh"
  assert_log_contains 'npx electron-builder "${builder_args[@]}"' "${SCRIPT_DIR}/manual-owner-client-assets.lib.sh"
  assert_log_contains 'notarize_macos_dmgs \' "${SCRIPT_DIR}/manual-owner-client-assets.lib.sh"
  assert_log_contains 'macOS unsigned or unnotarized packages are local-only' "${SCRIPT_DIR}/build-macos-assets.sh"
  if AGENTTEAM_MACOS_CODESIGN=0 AGENTTEAM_MACOS_NOTARIZE=0 \
    bash "${SCRIPT_DIR}/build-macos-assets.sh" v9.9.9 >/dev/null 2>&1; then
    fail "macOS release entrypoint must reject unsigned upload-capable builds"
  fi
  if AGENTTEAM_MACOS_CODESIGN=1 AGENTTEAM_MACOS_NOTARIZE=0 \
    bash "${SCRIPT_DIR}/build-macos-assets.sh" v9.9.9 >/dev/null 2>&1; then
    fail "macOS release entrypoint must reject unnotarized upload-capable builds"
  fi
  assert_log_contains 'npx electron_mirror=https://npmmirror.com/mirrors/electron/ builder_binaries_mirror=https://npmmirror.com/mirrors/electron-builder-binaries/' "${AGENTTEAM_TEST_BUILD_LOG}"
  assert_log_excludes 'WebView2' "${SCRIPT_DIR}/build-windows-installers.sh"
  assert_log_excludes 'installer/win' "${SCRIPT_DIR}/build-windows-installers.sh"
  if rg -n -i 'webview2|AgentTeamLauncher|installer\.nsi' \
    "${SCRIPT_DIR}/build-macos-assets.sh" \
    "${SCRIPT_DIR}/build-windows-installers.sh" \
    "${SCRIPT_DIR}/manual-owner-client-assets.lib.sh" \
    "${SCRIPT_DIR}/publish-release-manifests.sh" >/dev/null; then
    fail "release-owned scripts/docs still reference a retired Wails/WebView2 installer path"
  fi
  for retired in \
    "${SCRIPT_DIR}/../installer/mac/build.sh" \
    "${SCRIPT_DIR}/../installer/win/build.sh" \
    "${SCRIPT_DIR}/../installer/win/installer.nsi" \
    "${SCRIPT_DIR}/../installer/win/launcher" \
    "${SCRIPT_DIR}/../installer/win/cmd"; do
    [[ ! -e "${retired}" ]] || fail "retired custom installer path still exists: ${retired}"
  done
}
run_macos_notary_lifecycle_tests() {
  local arm64_dmg="${TEST_DIR}/AgentTeam-arm64.dmg" arm64_app="${TEST_DIR}/AgentTeam-arm64.app"
  local x64_dmg="${TEST_DIR}/AgentTeam-x64.dmg" x64_app="${TEST_DIR}/AgentTeam-x64.app"
  local lifecycle_output="${TEST_DIR}/notary-lifecycle.out"
  export AGENTTEAM_TEST_NOTARY_LOG="${TEST_DIR}/notary.log" AGENTTEAM_MACOS_NOTARIZE=1 \
    AGENTTEAM_MACOS_NOTARY_PROFILE=agentteam-notary AGENTTEAM_MACOS_NOTARY_TIMEOUT_SECONDS=3 \
    AGENTTEAM_MACOS_NOTARY_POLL_INTERVAL_SECONDS=1
  for dmg in "${arm64_dmg}" "${x64_dmg}"; do printf 'dmg\n' > "${dmg}"; done
  mkdir -p "${arm64_app}" "${x64_app}"
  sleep() { :; }
  notarize_macos_dmgs "${arm64_dmg}" "${arm64_app}" "${x64_dmg}" "${x64_app}" 2>"${lifecycle_output}"
  unset -f sleep
  [[ "$(grep -c '^notarytool submit ' "${AGENTTEAM_TEST_NOTARY_LOG}")" -eq 2 ]] || fail "macOS notarization must submit each DMG exactly once"
  [[ "$(grep -c '^notarytool info ' "${AGENTTEAM_TEST_NOTARY_LOG}")" -eq 6 ]] || fail "macOS notarization must retry status queries without resubmitting"
  assert_log_contains "notarytool submit ${arm64_dmg}" "${AGENTTEAM_TEST_NOTARY_LOG}"
  assert_log_contains "--no-wait --output-format json" "${AGENTTEAM_TEST_NOTARY_LOG}"
  assert_log_contains "submitted AgentTeam-arm64.dmg for notarization: submission-AgentTeam-arm64.dmg" "${lifecycle_output}"
  assert_log_contains "submitted AgentTeam-x64.dmg for notarization: submission-AgentTeam-x64.dmg" "${lifecycle_output}"
  assert_log_before "notarytool submit ${x64_dmg}" "notarytool info submission-AgentTeam-arm64.dmg" "${AGENTTEAM_TEST_NOTARY_LOG}"
  local invalid_arm64_dmg="${TEST_DIR}/AgentTeam-invalid-arm64.dmg" invalid_arm64_app="${TEST_DIR}/AgentTeam-invalid-arm64.app"
  local invalid_x64_dmg="${TEST_DIR}/AgentTeam-invalid-x64.dmg" invalid_x64_app="${TEST_DIR}/AgentTeam-invalid-x64.app" invalid_output="${TEST_DIR}/notary-invalid.out"
  for dmg in "${invalid_arm64_dmg}" "${invalid_x64_dmg}"; do printf 'dmg\n' > "${dmg}"; done
  mkdir -p "${invalid_arm64_app}" "${invalid_x64_app}"
  : > "${AGENTTEAM_TEST_NOTARY_LOG}"
  export AGENTTEAM_TEST_NOTARY_INVALID_ID="submission-$(basename "${invalid_arm64_dmg}")"
  if (sleep() { :; }; notarize_macos_dmgs \
    "${invalid_arm64_dmg}" "${invalid_arm64_app}" \
    "${invalid_x64_dmg}" "${invalid_x64_app}") >"${invalid_output}" 2>&1; then
    fail "Invalid macOS notarization must fail closed"
  fi
  [[ "$(grep -c '^notarytool submit ' "${AGENTTEAM_TEST_NOTARY_LOG}")" -eq 2 ]] || fail "Invalid macOS notarization must not prevent the second initial submission"
  assert_log_contains "notarytool log ${AGENTTEAM_TEST_NOTARY_INVALID_ID}" "${AGENTTEAM_TEST_NOTARY_LOG}"
  assert_log_contains "invalid test payload" "${invalid_output}"
  unset AGENTTEAM_TEST_NOTARY_INVALID_ID
  local timeout_arm64_dmg="${TEST_DIR}/AgentTeam-timeout-arm64.dmg" timeout_arm64_app="${TEST_DIR}/AgentTeam-timeout-arm64.app"
  local timeout_x64_dmg="${TEST_DIR}/AgentTeam-timeout-x64.dmg" timeout_x64_app="${TEST_DIR}/AgentTeam-timeout-x64.app" timeout_output="${TEST_DIR}/notary-timeout.out"
  for dmg in "${timeout_arm64_dmg}" "${timeout_x64_dmg}"; do printf 'dmg\n' > "${dmg}"; done
  mkdir -p "${timeout_arm64_app}" "${timeout_x64_app}"
  : > "${AGENTTEAM_TEST_NOTARY_LOG}"
  export AGENTTEAM_TEST_NOTARY_NEVER_ACCEPT_ID="submission-$(basename "${timeout_arm64_dmg}")"
  AGENTTEAM_MACOS_NOTARY_TIMEOUT_SECONDS=2
  if (sleep() { :; }; notarize_macos_dmgs "${timeout_arm64_dmg}" "${timeout_arm64_app}" \
    "${timeout_x64_dmg}" "${timeout_x64_app}") >"${timeout_output}" 2>&1; then fail "non-terminal macOS notarization must time out"; fi
  [[ "$(grep -c '^notarytool submit ' "${AGENTTEAM_TEST_NOTARY_LOG}")" -eq 2 ]] || fail "macOS notarization timeout must not resubmit either DMG"
  [[ "$(grep -c '^notarytool info ' "${AGENTTEAM_TEST_NOTARY_LOG}")" -eq 3 ]] || fail "macOS notarization timeout must poll through the configured deadline"
  assert_log_contains "timed out after 2s" "${timeout_output}"
  assert_log_excludes "stapler staple" "${AGENTTEAM_TEST_NOTARY_LOG}"
  unset AGENTTEAM_TEST_NOTARY_NEVER_ACCEPT_ID
  AGENTTEAM_MACOS_NOTARIZE=0
}
run_managed_runtime_tests
run_builder_and_upload_tests
run_desktop_manifest_tests
run_entrypoint_contract_tests
run_macos_notary_lifecycle_tests
echo "manual-owner-client-assets Electron release tests passed"
