# Multi-platform adapter `.spt` packaging

<!-- [doc->REQ-ADAPTER-MULTIPLATFORM-SPT] -->

## Status

proposed (2026-06-22, v0.13.2)

Depends on the target-triple vocabulary established by ADR-0016 (platform-targeted update sets). Sibling to ADR-0016: that ADR governs spt-core's *own* binary distribution and explicitly deferred adapter inclusion ("adapter updates remain on the adapter ripple-update seam… maintainer tooling may compose adapter updates later"). This ADR is that deferred adapter work.

## Context

An adapter that updates via the `gh_release` avenue is fetched as a single release asset, `adapter.spt` — a tar whose root holds `manifest.toml` + `strings/` + the role binaries, extracted flat into the adapter's `install_dir`, where bare program tokens resolve `<install_dir>/<program>` before `PATH` (REQ-INSTALL-11). That format is **single-platform**: one archive carries one OS's binaries. A cross-platform adapter (e.g. a harness integration shipping a Windows `.exe` and a Linux ELF for its translation/digest/psyche binaries) cannot ship one artifact. This is not hypothetical: claude-spt v0.6.0 hit it (finding **F-014**) and shipped a stopgap — separate `adapter-windows-x86_64.spt` / `adapter-linux-x86_64.spt` assets plus a default `adapter.spt` that is merely a copy of the Windows archive, so a Linux user's flag-free `spt adapter add --release` silently installs Windows binaries.

spt-core's own binary already solves cross-platform distribution with **platform-targeted update sets** (ADR-0016): per-triple *separate* artifacts, one signed set-metadata blob with per-platform digests, and each recipient fetches only its own platform's bytes. That model is bandwidth-optimal at fleet scale but heavier for an adapter author: multiple artifacts plus signed set metadata, for what is often a few kilobytes of binary.

## Decision

Add a **fat multi-platform `.spt`** as the simple default, keeping the per-triple "split" path available for adapters that want it.

- **Layout.** The archive root holds the shared `manifest.toml` + `strings/`. Platform binaries live under **per-target-triple subdirectories** keyed by Rust target triple (ADR-0016's protocol identifiers, e.g. `x86_64-pc-windows-msvc/`, `x86_64-unknown-linux-gnu/`). A legacy single-platform archive keeps its binaries at the root.

  ```
  manifest.toml                         (shared)
  strings/                              (shared)
  x86_64-pc-windows-msvc/   <binaries>
  x86_64-unknown-linux-gnu/ <binaries>
  ```

- **Selection at install/update.** spt-core extracts the shared root **plus only `current_platform()`'s** triple subdir, flattened into `install_dir`. So `<install_dir>/<program>` resolution (REQ-INSTALL-11) is **unchanged** — binaries land at the same flat path they do today; nothing downstream moves. An archive that declares triple subdirs but is missing the recipient's triple yields a typed `NoArtifactForPlatform`, never a silent no-op (mirrors ADR-0016).

- **Naming.** The canonical release asset stays **`adapter.spt`** (no new extension). It may be plain tar or gzipped — `tar -xf` auto-detects — so an author ships either form as one asset. `--asset` becomes **optional**, defaulting to `adapter.spt`, so `spt adapter add --release User/repo` and `spt adapter update` work flag-free.

- **Signing.** A fat `adapter.spt` is **one artifact → one signature**: the adapter's existing `signing_key` Ed25519 over the whole archive (`adapter.spt.sig`), the REQ-UPD-9 single-artifact verify, just over more bytes.

- **The split path.** A large adapter that does not want every node downloading all platforms' bytes publishes **per-platform single-triple archives** (selected via `--asset`, or composed under ADR-0016's signed update-set machinery). This reuses existing mechanisms — there is no second bespoke multi-platform system. Split asset *names* are a packaging concern and may stay public-friendly (e.g. `adapter-linux-x86_64.spt`, as claude-spt v0.6.0 already ships); target triples are the protocol identifiers only for the *internal* subdir keys of the fat archive (ADR-0016).

- **Compatibility.** Forward compat is the existing `min_spt_core_version` gate: a multi-platform adapter sets `min_spt_core_version ≥ 0.13.2`, so an older spt-core (which would extract the triple subdirs flat and fail to resolve `<install_dir>/<program>`) refuses at the gate — readable *before* extract — instead of mis-installing. Back compat is structural and free: a flat archive has no triple subdirs, so new spt-core extracts it exactly as today. (Elaborate legacy/auto-detection beyond "is there a triple subdir?" is unwarranted — there is no installed userbase to migrate.)

## Considered Options

- **Per-triple update-set for adapters (ADR-0016 model as the default)** — consistent with spt-core and bandwidth-optimal, but heavier authoring (multiple artifacts + signed set metadata) and worse small-adapter UX. *Kept as the opt-in "split" path, not the default.*
- **Manifest-declared platform map with suffixed binary names at the root** — invents an adapter-only platform-naming scheme divergent from ADR-0016's triples and mangles binary names. Rejected.
- **Fat multi-platform `.spt` with triple subdirs (chosen)** — one artifact, one signature, one flag-free fetch; flat install layout unchanged; reuses ADR-0016's triple vocabulary; split stays available. Trade-off accepted: a fat archive ships every platform's bytes to every recipient — negligible for the small adapters this targets; large adapters split.
