#!/bin/sh
# Deterministic fixture test for the exact three-target adapter.spt release contract.
set -u
ROOT=$(CDPATH= cd "$(dirname "$0")/.." && pwd)
PACKER="$ROOT/ci/publish/package-adapter.sh"
WRITER="$ROOT/ci/publish/create-adapter-archive.py"
WIN_TRIPLE=x86_64-pc-windows-msvc
GNU_TRIPLE=x86_64-unknown-linux-gnu
MUSL_TRIPLE=x86_64-unknown-linux-musl
SHARED_FILES="omp-spt.mjs package.json skills/commune/SKILL.md skills/knock/SKILL.md skills/role/SKILL.md skills/setup/SKILL.md skills/signoff/SKILL.md"
rc=0
fail() { printf 'FAIL: %s\n' "$1"; rc=1; }
ok() { printf 'ok   %s\n' "$1"; }

for tool in awk chmod cmp cp dirname env grep head mkdir mktemp od rm sed sort tar tr; do
  command -v "$tool" >/dev/null 2>&1 || { echo "FAIL: required tool unavailable: $tool"; exit 1; }
done
PY=""
for cand in "${OMP_SPT_PYTHON:-}" python python3 py; do
  [ -n "$cand" ] || continue
  command -v "$cand" >/dev/null 2>&1 || continue
  PY=$cand
  break
done
[ -n "$PY" ] || { echo "FAIL: Python unavailable"; exit 1; }
if ! sh "$ROOT/tests/manifest-schema.sh"; then
  echo "FAIL: manifest-schema prerequisite failed"
  exit 1
fi

TARGET="$ROOT/tools/omp-spt/target"
mkdir -p "$TARGET" || { echo "FAIL: cannot create fixture parent $TARGET"; exit 1; }
TMP=$(mktemp -d "$TARGET/adapter-archive-fixture.XXXXXX") || { echo "FAIL: mktemp"; exit 1; }
trap 'rm -rf "$TMP"' EXIT INT TERM
REL=${TMP#"$TARGET/"}
[ "$REL" != "$TMP" ] || { echo "FAIL: fixture is not beneath target/"; exit 1; }
WIN_RELSUB="$REL/windows-release"
GNU_RELSUB="$REL/gnu-release"
MUSL_RELSUB="$REL/musl-release"
mkdir -p "$TARGET/$WIN_RELSUB" "$TARGET/$GNU_RELSUB" "$TARGET/$MUSL_RELSUB" \
  || { echo "FAIL: cannot create fixture binary directories"; exit 1; }

# Generate deterministic loader-image fixtures. Each accepted image has a nonzero entry
# point backed by an executable PE section or ELF PT_LOAD. The GNU ELF retains glibc's
# x86_64 PT_INTERP; the musl fixture remains static (no PT_INTERP or DT_NEEDED).
WIN_GOOD="$TMP/windows-good.exe"
GNU_GOOD="$TMP/gnu-good"
MUSL_GOOD="$TMP/musl-good"
WRONG_ARCH="$TMP/aarch64-static"
NEEDED="$TMP/needed-no-interpreter"
WIN_ZERO_ENTRY="$TMP/windows-zero-entry.exe"
WIN_UNMAPPED_ENTRY="$TMP/windows-unmapped-entry.exe"
WIN_NONEXEC_ENTRY="$TMP/windows-nonexec-entry.exe"
WIN_DLL="$TMP/windows-dll.exe"
WIN_SHORT_OPTIONAL="$TMP/windows-short-optional.exe"
WIN_TRUNCATED_SECTIONS="$TMP/windows-truncated-sections.exe"
WIN_BAD_RAW="$TMP/windows-bad-raw.exe"
GNU_ZERO_ENTRY="$TMP/gnu-zero-entry"
GNU_UNMAPPED_ENTRY="$TMP/gnu-unmapped-entry"
GNU_NONEXEC_ENTRY="$TMP/gnu-nonexec-entry"
GNU_BAD_LOAD_SIZE="$TMP/gnu-bad-load-size"
GNU_OOB_LOAD="$TMP/gnu-oob-load"
"$PY" - "$WIN_GOOD" "$GNU_GOOD" "$MUSL_GOOD" "$WRONG_ARCH" "$NEEDED" \
  "$WIN_ZERO_ENTRY" "$WIN_UNMAPPED_ENTRY" "$WIN_NONEXEC_ENTRY" "$WIN_DLL" \
  "$WIN_SHORT_OPTIONAL" "$WIN_TRUNCATED_SECTIONS" "$WIN_BAD_RAW" \
  "$GNU_ZERO_ENTRY" "$GNU_UNMAPPED_ENTRY" "$GNU_NONEXEC_ENTRY" \
  "$GNU_BAD_LOAD_SIZE" "$GNU_OOB_LOAD" <<'PY'
from pathlib import Path
import struct
import sys


PE_OFFSET = 0x80
PE_OPTIONAL_OFFSET = 0x98
PE_SECTION_OFFSET = 0x188
ELF_BASE = 0x400000


def changed(image: bytes, offset: int, fmt: str, value: int) -> bytes:
    changed_image = bytearray(image)
    struct.pack_into(fmt, changed_image, offset, value)
    return bytes(changed_image)


def pe() -> bytes:
    image = bytearray(0x400)
    image[:2] = b"MZ"
    struct.pack_into("<I", image, 0x3C, PE_OFFSET)
    image[PE_OFFSET : PE_OFFSET + 4] = b"PE\0\0"
    struct.pack_into(
        "<HHIIIHH", image, PE_OFFSET + 4, 0x8664, 1, 0, 0, 0, 0xF0, 0x0022
    )

    optional = PE_OPTIONAL_OFFSET
    struct.pack_into("<H", image, optional, 0x20B)
    struct.pack_into("<I", image, optional + 4, 0x200)
    struct.pack_into("<I", image, optional + 16, 0x1000)
    struct.pack_into("<I", image, optional + 20, 0x1000)
    struct.pack_into("<Q", image, optional + 24, 0x140000000)
    struct.pack_into("<II", image, optional + 32, 0x1000, 0x200)
    struct.pack_into("<HH", image, optional + 40, 6, 0)
    struct.pack_into("<HH", image, optional + 48, 6, 0)
    struct.pack_into("<III", image, optional + 56, 0x2000, 0x200, 0)
    struct.pack_into("<HH", image, optional + 68, 3, 0x8160)
    struct.pack_into(
        "<QQQQ", image, optional + 72, 0x100000, 0x1000, 0x100000, 0x1000
    )
    struct.pack_into("<II", image, optional + 104, 0, 16)

    image[PE_SECTION_OFFSET : PE_SECTION_OFFSET + 8] = b".text\0\0\0"
    struct.pack_into(
        "<IIIIIIHHI",
        image,
        PE_SECTION_OFFSET + 8,
        1,
        0x1000,
        0x200,
        0x200,
        0,
        0,
        0,
        0,
        0x60000020,
    )
    image[0x200] = 0xC3
    return bytes(image)


def elf(machine: int, interpreter: str | None) -> bytes:
    encoded_interpreter = (
        b"" if interpreter is None else interpreter.encode("ascii") + b"\0"
    )
    program_count = 1 + (1 if interpreter is not None else 0)
    payload_offset = 64 + program_count * 56
    code = b"\x31\xff\xb8\x3c\0\0\0\x0f\x05".ljust(32, b"\x90")
    file_size = payload_offset + len(encoded_interpreter) + len(code)
    entry_point = ELF_BASE + payload_offset + len(encoded_interpreter)
    ident = b"\x7fELF\x02\x01\x01\0" + b"\0" * 8
    header = struct.pack(
        "<16sHHIQQQIHHHHHH",
        ident,
        2,
        machine,
        1,
        entry_point,
        64,
        0,
        0,
        64,
        56,
        program_count,
        0,
        0,
        0,
    )
    load = struct.pack(
        "<IIQQQQQQ",
        1,
        5,
        0,
        ELF_BASE,
        ELF_BASE,
        file_size,
        file_size,
        0x1000,
    )
    programs = [load]
    if interpreter is not None:
        programs.append(
            struct.pack(
                "<IIQQQQQQ",
                3,
                4,
                payload_offset,
                ELF_BASE + payload_offset,
                ELF_BASE + payload_offset,
                len(encoded_interpreter),
                len(encoded_interpreter),
                1,
            )
        )
    return header + b"".join(programs) + encoded_interpreter + code


def elf_with_needed() -> bytes:
    program_count = 2
    dynamic_offset = 64 + program_count * 56
    dynamic_entries = struct.pack("<qQqQ", 1, 0, 0, 0)
    code = b"\x31\xff\xb8\x3c\0\0\0\x0f\x05".ljust(32, b"\x90")
    file_size = dynamic_offset + len(dynamic_entries) + len(code)
    ident = b"\x7fELF\x02\x01\x01\0" + b"\0" * 8
    header = struct.pack(
        "<16sHHIQQQIHHHHHH",
        ident,
        2,
        62,
        1,
        ELF_BASE + dynamic_offset + len(dynamic_entries),
        64,
        0,
        0,
        64,
        56,
        program_count,
        0,
        0,
        0,
    )
    load = struct.pack(
        "<IIQQQQQQ",
        1,
        5,
        0,
        ELF_BASE,
        ELF_BASE,
        file_size,
        file_size,
        0x1000,
    )
    dynamic = struct.pack(
        "<IIQQQQQQ",
        2,
        4,
        dynamic_offset,
        ELF_BASE + dynamic_offset,
        ELF_BASE + dynamic_offset,
        len(dynamic_entries),
        len(dynamic_entries),
        8,
    )
    return header + load + dynamic + dynamic_entries + code


pe_good = pe()
gnu_good = elf(62, "/lib64/ld-linux-x86-64.so.2")
Path(sys.argv[1]).write_bytes(pe_good)
Path(sys.argv[2]).write_bytes(gnu_good)
Path(sys.argv[3]).write_bytes(elf(62, None))
Path(sys.argv[4]).write_bytes(elf(183, None))
Path(sys.argv[5]).write_bytes(elf_with_needed())
Path(sys.argv[6]).write_bytes(changed(pe_good, PE_OPTIONAL_OFFSET + 16, "<I", 0))
Path(sys.argv[7]).write_bytes(
    changed(pe_good, PE_OPTIONAL_OFFSET + 16, "<I", 0x3000)
)
Path(sys.argv[8]).write_bytes(
    changed(pe_good, PE_SECTION_OFFSET + 36, "<I", 0x40000040)
)
Path(sys.argv[9]).write_bytes(changed(pe_good, PE_OFFSET + 22, "<H", 0x2022))
Path(sys.argv[10]).write_bytes(changed(pe_good, PE_OFFSET + 20, "<H", 111))
Path(sys.argv[11]).write_bytes(pe_good[: PE_SECTION_OFFSET + 39])
Path(sys.argv[12]).write_bytes(
    changed(pe_good, PE_SECTION_OFFSET + 20, "<I", 0x380)
)
Path(sys.argv[13]).write_bytes(changed(gnu_good, 24, "<Q", 0))
Path(sys.argv[14]).write_bytes(changed(gnu_good, 24, "<Q", ELF_BASE + 0x3000))
Path(sys.argv[15]).write_bytes(changed(gnu_good, 68, "<I", 4))
Path(sys.argv[16]).write_bytes(changed(gnu_good, 104, "<Q", len(gnu_good) - 1))
Path(sys.argv[17]).write_bytes(changed(gnu_good, 96, "<Q", len(gnu_good) + 1))
PY
cp "$WIN_GOOD" "$TARGET/$WIN_RELSUB/omp-spt.exe"
cp "$GNU_GOOD" "$TARGET/$GNU_RELSUB/omp-spt"
cp "$MUSL_GOOD" "$TARGET/$MUSL_RELSUB/omp-spt"
chmod 0755 "$TARGET/$GNU_RELSUB/omp-spt" "$TARGET/$MUSL_RELSUB/omp-spt"

expect_packer_failure() {
  name=$1
  expected=$2
  shift 2
  if "$@" >"$TMP/output" 2>&1; then
    fail "$name unexpectedly succeeded"
  elif grep -Fq "$expected" "$TMP/output"; then
    ok "$name fails closed"
  else
    fail "$name failed for the wrong reason: $(cat "$TMP/output")"
  fi
}

expect_windows_binary_failure() {
  name=$1
  expected=$2
  fixture=$3
  cp "$fixture" "$TARGET/$WIN_RELSUB/omp-spt.exe" \
    || { fail "$name could not install fixture"; return; }
  expect_packer_failure "$name" "$expected" \
    env OMP_SPT_WIN_RELSUB="$WIN_RELSUB" OMP_SPT_LINUX_RELSUB="$GNU_RELSUB" \
    OMP_SPT_MUSL_RELSUB="$MUSL_RELSUB" ADAPTER_SPT_OUT="$BASE_OUT" sh "$PACKER" --apply
}

expect_gnu_binary_failure() {
  name=$1
  expected=$2
  fixture=$3
  cp "$fixture" "$TARGET/$GNU_RELSUB/omp-spt" \
    || { fail "$name could not install fixture"; return; }
  chmod 0755 "$TARGET/$GNU_RELSUB/omp-spt"
  expect_packer_failure "$name" "$expected" \
    env OMP_SPT_WIN_RELSUB="$WIN_RELSUB" OMP_SPT_LINUX_RELSUB="$GNU_RELSUB" \
    OMP_SPT_MUSL_RELSUB="$MUSL_RELSUB" ADAPTER_SPT_OUT="$BASE_OUT" sh "$PACKER" --apply
}

BASE_OUT="$TMP/rejected.spt"
expect_packer_failure "missing GNU helper" "MISS" \
  env OMP_SPT_WIN_RELSUB="$WIN_RELSUB" OMP_SPT_LINUX_RELSUB="$REL/missing-gnu-release" \
  OMP_SPT_MUSL_RELSUB="$MUSL_RELSUB" ADAPTER_SPT_OUT="$BASE_OUT" sh "$PACKER" --apply

printf '%s\n' 'not a PE binary' >"$TARGET/$WIN_RELSUB/omp-spt.exe"
expect_packer_failure "malformed Windows helper" "truncated DOS header" \
  env OMP_SPT_WIN_RELSUB="$WIN_RELSUB" OMP_SPT_LINUX_RELSUB="$GNU_RELSUB" \
  OMP_SPT_MUSL_RELSUB="$MUSL_RELSUB" ADAPTER_SPT_OUT="$BASE_OUT" sh "$PACKER" --apply
cp "$WIN_GOOD" "$TARGET/$WIN_RELSUB/omp-spt.exe"

expect_windows_binary_failure "zero-entrypoint PE pseudo-binary" \
  "PE image has zero entry point" "$WIN_ZERO_ENTRY"
expect_windows_binary_failure "PE with unmapped entrypoint" \
  "PE entry point is not mapped by any section" "$WIN_UNMAPPED_ENTRY"
expect_windows_binary_failure "PE with non-executable entry section" \
  "PE entry point is in a non-executable section" "$WIN_NONEXEC_ENTRY"
expect_windows_binary_failure "DLL PE helper" \
  "PE image is marked as a DLL" "$WIN_DLL"
expect_windows_binary_failure "PE with incomplete optional header" \
  "invalid PE32+ optional header size" "$WIN_SHORT_OPTIONAL"
expect_windows_binary_failure "PE with truncated section table" \
  "PE section table is outside the file" "$WIN_TRUNCATED_SECTIONS"
expect_windows_binary_failure "PE with out-of-file raw section" \
  "PE section raw data is outside the file" "$WIN_BAD_RAW"
cp "$WIN_GOOD" "$TARGET/$WIN_RELSUB/omp-spt.exe"

printf '%s\n' 'not an ELF binary' >"$TARGET/$GNU_RELSUB/omp-spt"
expect_packer_failure "malformed GNU helper" "truncated ELF64 header" \
  env OMP_SPT_WIN_RELSUB="$WIN_RELSUB" OMP_SPT_LINUX_RELSUB="$GNU_RELSUB" \
  OMP_SPT_MUSL_RELSUB="$MUSL_RELSUB" ADAPTER_SPT_OUT="$BASE_OUT" sh "$PACKER" --apply
cp "$GNU_GOOD" "$TARGET/$GNU_RELSUB/omp-spt"

expect_gnu_binary_failure "zero-entrypoint ELF pseudo-binary" \
  "ELF image has zero entry point" "$GNU_ZERO_ENTRY"
expect_gnu_binary_failure "ELF with unmapped entrypoint" \
  "ELF entry point is not mapped by a loadable segment" "$GNU_UNMAPPED_ENTRY"
expect_gnu_binary_failure "ELF with non-executable entry segment" \
  "ELF entry point is in a non-executable loadable segment" "$GNU_NONEXEC_ENTRY"
expect_gnu_binary_failure "ELF load with file size above memory size" \
  "ELF64 load segment file size exceeds memory size" "$GNU_BAD_LOAD_SIZE"
expect_gnu_binary_failure "ELF load with out-of-file range" \
  "ELF64 segment is outside the file" "$GNU_OOB_LOAD"
cp "$GNU_GOOD" "$TARGET/$GNU_RELSUB/omp-spt"
chmod 0755 "$TARGET/$GNU_RELSUB/omp-spt"

expect_packer_failure "missing musl helper" "MISS" \
  env OMP_SPT_WIN_RELSUB="$WIN_RELSUB" OMP_SPT_LINUX_RELSUB="$GNU_RELSUB" \
  OMP_SPT_MUSL_RELSUB="$REL/missing-musl-release" ADAPTER_SPT_OUT="$BASE_OUT" \
  sh "$PACKER" --apply

printf '%s\n' 'not an ELF binary' >"$TARGET/$MUSL_RELSUB/omp-spt"
expect_packer_failure "malformed musl helper" "truncated ELF64 header" \
  env OMP_SPT_WIN_RELSUB="$WIN_RELSUB" OMP_SPT_LINUX_RELSUB="$GNU_RELSUB" \
  OMP_SPT_MUSL_RELSUB="$MUSL_RELSUB" ADAPTER_SPT_OUT="$BASE_OUT" sh "$PACKER" --apply

cp "$GNU_GOOD" "$TARGET/$MUSL_RELSUB/omp-spt"
expect_packer_failure "GNU helper mislabeled as musl" "musl target must be static" \
  env OMP_SPT_WIN_RELSUB="$WIN_RELSUB" OMP_SPT_LINUX_RELSUB="$GNU_RELSUB" \
  OMP_SPT_MUSL_RELSUB="$MUSL_RELSUB" ADAPTER_SPT_OUT="$BASE_OUT" sh "$PACKER" --apply

cp "$NEEDED" "$TARGET/$MUSL_RELSUB/omp-spt"
expect_packer_failure "musl helper with DT_NEEDED dependency" "has 1 DT_NEEDED entry" \
  env OMP_SPT_WIN_RELSUB="$WIN_RELSUB" OMP_SPT_LINUX_RELSUB="$GNU_RELSUB" \
  OMP_SPT_MUSL_RELSUB="$MUSL_RELSUB" ADAPTER_SPT_OUT="$BASE_OUT" sh "$PACKER" --apply

cp "$WRONG_ARCH" "$TARGET/$MUSL_RELSUB/omp-spt"
expect_packer_failure "wrong-architecture musl helper" "is not x86_64" \
  env OMP_SPT_WIN_RELSUB="$WIN_RELSUB" OMP_SPT_LINUX_RELSUB="$GNU_RELSUB" \
  OMP_SPT_MUSL_RELSUB="$MUSL_RELSUB" ADAPTER_SPT_OUT="$BASE_OUT" sh "$PACKER" --apply

cp "$MUSL_GOOD" "$TARGET/$MUSL_RELSUB/omp-spt"
chmod 0755 "$TARGET/$MUSL_RELSUB/omp-spt"
COPIED_ROOT="$TMP/copied-root"
mkdir -p "$COPIED_ROOT/ci/manifest" "$COPIED_ROOT/ci/publish"
cp -R "$ROOT/adapter" "$COPIED_ROOT/adapter"
cp "$ROOT/ci/manifest/check-manifest.sh" "$COPIED_ROOT/ci/manifest/check-manifest.sh"
cp "$ROOT/ci/manifest/validate_manifest.py" "$COPIED_ROOT/ci/manifest/validate_manifest.py"
cp "$PACKER" "$COPIED_ROOT/ci/publish/package-adapter.sh"
cp "$WRITER" "$COPIED_ROOT/ci/publish/create-adapter-archive.py"
cp "$ROOT/ci/publish/validate-release-binary.py" \
  "$COPIED_ROOT/ci/publish/validate-release-binary.py"
rm "$COPIED_ROOT/adapter/strings/skills/signoff/SKILL.md"
expect_packer_failure "incomplete canonical shared plugin copy" \
  "required shared plugin file missing" \
  env ADAPTER_SPT_OUT="$BASE_OUT" sh "$COPIED_ROOT/ci/publish/package-adapter.sh" --apply

OUT="$TMP/adapter.spt"
# [unit->REQ-DIST-ADAPTER-RELEASE]
# [unit->REQ-DIST-LINUX-MUSL]
if package_out=$(SOURCE_DATE_EPOCH=123 OMP_SPT_WIN_RELSUB="$WIN_RELSUB" \
   OMP_SPT_LINUX_RELSUB="$GNU_RELSUB" OMP_SPT_MUSL_RELSUB="$MUSL_RELSUB" \
   ADAPTER_SPT_OUT="$OUT" sh "$PACKER" --apply 2>&1); then
  ok "three-target packer --apply succeeds"
else
  fail "packer --apply exited non-zero: $package_out"
  exit "$rc"
fi
[ -f "$OUT" ] || { fail "no archive written at $OUT"; exit "$rc"; }

LIST=$(tar -tzf "$OUT")
NORMALIZED=$(printf '%s\n' "$LIST" | sed 's:/$::' | sort)
EXPECTED=$(printf '%s\n' \
  manifest.toml \
  strings strings/omp-spt.mjs strings/package.json strings/skills \
  strings/skills/commune strings/skills/commune/SKILL.md \
  strings/skills/knock strings/skills/knock/SKILL.md \
  strings/skills/role strings/skills/role/SKILL.md \
  strings/skills/setup strings/skills/setup/SKILL.md \
  strings/skills/signoff strings/skills/signoff/SKILL.md \
  "$WIN_TRIPLE" "$WIN_TRIPLE/omp-spt.exe" \
  "$GNU_TRIPLE" "$GNU_TRIPLE/omp-spt" \
  "$MUSL_TRIPLE" "$MUSL_TRIPLE/omp-spt" | sort)
if [ "$NORMALIZED" = "$EXPECTED" ]; then
  ok "archive has deterministic exact shared and three-target membership"
else
  fail "archive membership mismatch: [$NORMALIZED]"
fi

WIN_MAGIC=$(tar -xOzf "$OUT" "$WIN_TRIPLE/omp-spt.exe" | od -An -tx1 -N4 | tr -d '[:space:]')
case "$WIN_MAGIC" in 4d5a*) ok "Windows archive member retains PE magic" ;; *) fail "Windows member magic=$WIN_MAGIC" ;; esac
for triple in "$GNU_TRIPLE" "$MUSL_TRIPLE"; do
  magic=$(tar -xOzf "$OUT" "$triple/omp-spt" | od -An -tx1 -N4 | tr -d '[:space:]')
  [ "$magic" = "7f454c46" ] && ok "$triple member retains ELF magic" || fail "$triple member magic=$magic"
  mode=$(tar -tvzf "$OUT" "$triple/omp-spt" | awk 'NR == 1 {print $1}')
  [ "$mode" = "-rwxr-xr-x" ] \
    && ok "$triple member has canonical mode 0755 ($mode)" \
    || fail "$triple member mode is not canonical 0755 ($mode)"
done

VERIFY="$TMP/exact-payloads"
mkdir -p "$VERIFY"
assert_exact_payload() {
  source=$1
  member=$2
  extracted="$VERIFY/$member"
  mkdir -p "$(dirname "$extracted")"
  if tar -xOzf "$OUT" "$member" >"$extracted" && cmp -s "$source" "$extracted"; then
    ok "$member exactly matches its release input"
  else
    fail "$member does not exactly match its release input"
  fi
}
assert_exact_payload "$ROOT/adapter/omp-spt.toml" manifest.toml
for rel in $SHARED_FILES; do
  assert_exact_payload "$ROOT/adapter/strings/$rel" "strings/$rel"
done
assert_exact_payload "$TARGET/$WIN_RELSUB/omp-spt.exe" "$WIN_TRIPLE/omp-spt.exe"
assert_exact_payload "$TARGET/$GNU_RELSUB/omp-spt" "$GNU_TRIPLE/omp-spt"
assert_exact_payload "$TARGET/$MUSL_RELSUB/omp-spt" "$MUSL_TRIPLE/omp-spt"

if printf '%s\n' "$NORMALIZED" | grep -qE "^($WIN_TRIPLE|$GNU_TRIPLE|$MUSL_TRIPLE)/(manifest\.toml|strings/)"; then
  fail "shared plugin files are duplicated under a target"
else
  ok "shared plugin files remain root-only"
fi

# The archive writer itself rejects an unintended file under the musl directory rather than
# silently growing the public contract.
WRITER_STAGE="$TMP/writer-stage"
mkdir -p "$WRITER_STAGE/strings" "$WRITER_STAGE/$WIN_TRIPLE" \
  "$WRITER_STAGE/$GNU_TRIPLE" "$WRITER_STAGE/$MUSL_TRIPLE"
cp "$ROOT/adapter/omp-spt.toml" "$WRITER_STAGE/manifest.toml"
for rel in $SHARED_FILES; do
  mkdir -p "$(dirname "$WRITER_STAGE/strings/$rel")"
  cp "$ROOT/adapter/strings/$rel" "$WRITER_STAGE/strings/$rel"
done
cp "$WIN_GOOD" "$WRITER_STAGE/$WIN_TRIPLE/omp-spt.exe"
cp "$GNU_GOOD" "$WRITER_STAGE/$GNU_TRIPLE/omp-spt"
cp "$MUSL_GOOD" "$WRITER_STAGE/$MUSL_TRIPLE/omp-spt"
printf '%s\n' unintended >"$WRITER_STAGE/$MUSL_TRIPLE/debug.txt"
if "$PY" "$WRITER" "$WRITER_STAGE" "$TMP/unintended.spt" \
   "$WIN_TRIPLE" "$GNU_TRIPLE" "$MUSL_TRIPLE" >"$TMP/output" 2>&1; then
  fail "archive writer accepted an unintended musl member"
elif grep -Fq "unexpected staged archive member" "$TMP/output"; then
  ok "archive writer rejects unintended musl members"
else
  fail "archive writer rejected unintended member for wrong reason: $(cat "$TMP/output")"
fi

OUT_AGAIN="$TMP/adapter-again.spt"
if SOURCE_DATE_EPOCH=123 OMP_SPT_WIN_RELSUB="$WIN_RELSUB" \
   OMP_SPT_LINUX_RELSUB="$GNU_RELSUB" OMP_SPT_MUSL_RELSUB="$MUSL_RELSUB" \
   OMP_SPT_ARCHIVE_LINUX_MODE=0777 OMP_SPT_ARCHIVE_MUSL_MODE=0700 \
   ADAPTER_SPT_OUT="$OUT_AGAIN" sh "$PACKER" --apply >/dev/null 2>&1 \
   && cmp -s "$OUT" "$OUT_AGAIN"; then
  ok "release environment cannot vary canonical archive bytes or Linux modes"
else
  fail "release environment varied canonical archive bytes or Linux modes"
fi

plan=$(OMP_SPT_WIN_RELSUB="$WIN_RELSUB" OMP_SPT_LINUX_RELSUB="$GNU_RELSUB" \
  OMP_SPT_MUSL_RELSUB="$MUSL_RELSUB" sh "$PACKER" 2>&1)
echo "$plan" | grep -qE "min_spt_core 0\.(1[3-9]|[2-9][0-9])" \
  && ok "packer advertises a fat-capable manifest floor (>= 0.13.2)" \
  || fail "packer floor advertisement missing/too low; plan=[$plan]"
echo "$plan" | grep -Fq "$MUSL_TRIPLE/omp-spt  [ELF64 x86_64, static]" \
  && ok "dry-run identifies the static musl target" \
  || fail "dry-run omits the static musl contract; plan=[$plan]"
manifest_floor=$(grep -E '^min_spt_core_version' "$ROOT/adapter/omp-spt.toml" | head -1 | sed -E 's/.*"([^"]+)".*/\1/')
case "$plan" in
  *"Needs spt v$manifest_floor+"*) ok "install guidance uses manifest floor v$manifest_floor" ;;
  *) fail "install guidance does not use manifest floor v$manifest_floor; plan=[$plan]" ;;
esac

[ "$rc" -eq 0 ] && echo "PASS: adapter-archive"
exit "$rc"
