# Spawn — getting it, and proving it is ours

Spawn is a **workstation command-line binary**, not a container stack. You put it
on whatever machine you want it on — your laptop, a jump host, a machine your
Hivemind server has never heard of and has no authority over. Nothing pushes it
to you, and nothing needs a login to your box.

That shape is deliberate. Hivemind talks to Spawn; it does not install Spawn. If
it did, your Hivemind server would need credentials into every machine you run
Spawn on, and it does not have them and should never have them.

---

## The one thing to get right

Everything below is a way of answering a single question:

> **Are these bytes the ones Seglamater built, or the ones whoever served me the
> download wanted me to have?**

A checksum published next to the file it describes cannot answer it. Neither can
a signature published next to the key that verifies it. Whoever controls the
server controls both halves, and both checks pass. This is a real, open finding
in our own review notes, not a hypothetical.

**The answer is one value that reaches you by a different road than the
download.** For Spawn that value is the SHA-256 fingerprint of our release
signing key:

```
ec005e3643f7baac232925a1a42ef31ac0058cb5ddc2844442e3ffc9b7f1bb93
```

You should have received that same string in your onboarding email. **Compare
the two now.** If they differ, stop and contact `support@seglamater.com` through
a channel you already trust — not a link on this page.

Everything after that comparison chains off it, and none of it depends on
trusting where you downloaded from.

---

## The short way

```sh
curl -fsSL https://updates.seglamater.app/spawn/install.sh -o get-spawn.sh
bash get-spawn.sh --pubkey-sha256 ec005e3643f7baac232925a1a42ef31ac0058cb5ddc2844442e3ffc9b7f1bb93
```

Pass the fingerprint **from your email**, not the one on this page — this page
came from the same server as the download.

The script fetches the key, checks it against your fingerprint, verifies the
release manifest's cosign signature under that key, reads the artifact hash out
of the *signed* manifest, downloads the tarball, hashes it, and refuses on any
mismatch. Then it runs the placement script that shipped inside the tarball.

Add `--verify-only` to run the whole chain and stop before anything is placed.

**Requires:** `curl`, `sha256sum`, `python3`, `tar`, `zstd`, and
[`cosign`](https://docs.sigstore.dev/cosign/system_config/installation/).
cosign is required and there is no flag to skip it.

---

## The long way — six commands, nothing hidden

Do this if you are onboarding a regulated environment, if you are mirroring our
releases, or if you would simply rather not run a script you have not read.

**1. Get the key and prove it is the right key.**

```sh
curl -fsSL https://updates.seglamater.app/.well-known/keys/spawn.pub -o spawn.pub
sha256sum spawn.pub
```

Compare that output, character by character, with the fingerprint in your
onboarding email. **This is the only step that cannot be automated away**, and
it is the one that makes the other five mean anything.

**2. Ask the channel what the current release is.**

```sh
curl -fsSL https://updates.seglamater.app/spawn/channels/stable/latest.json
```

You get a small pointer:

```json
{
  "product": "spawn",
  "channel": "stable",
  "version": "0.0.0",
  "manifest_url": "https://updates.seglamater.app/spawn/releases/0.0.0/manifest.json",
  "updated_at": "..."
}
```

`version: "0.0.0"` means **no release has been published to that channel yet**.
It is not an error, and a client should read it as "nothing to do".

As of 2026-09-10 `stable` serves **0.1.3**, the first real Spawn release. `beta`
and `canary` are still at the `0.0.0` placeholder. This paragraph previously said
0.0.0 was "the current state of every Spawn channel", which stopped being true
the moment a release landed.

**3. Fetch the release manifest and its detached signature.**

```sh
curl -fsSL https://updates.seglamater.app/spawn/releases/<version>/manifest.json     -o manifest.json
curl -fsSL https://updates.seglamater.app/spawn/releases/<version>/manifest.json.sig -o manifest.json.sig
```

**4. Verify the signature — before you read anything in the file.**

```sh
cosign verify-blob --key spawn.pub --bundle manifest.json.sig \
    --insecure-ignore-tlog=true manifest.json
```

`--bundle`, not `--signature`. The `.sig` file is a **sigstore bundle** (JSON,
`application/vnd.dev.sigstore.bundle.v0.3+json`) — the cosign v3 default format —
rather than a bare base64 signature, regardless of its `.sig` extension.
`--signature` expects the bare form and fails on a bundle with
`ecdsa: Invalid IEEE_P1363 encoded bytes`, which does not hint at the cause.

> This document said `--signature` until 2026-09-10, so the command published
> here failed for **every** reader who followed it, not merely in some
> configurations. Corrected after running it against the published 0.1.3
> artifact and getting that error, then getting `Verified OK` from the
> `--bundle` form.

`--insecure-ignore-tlog` is correct here: Spawn manifests are signed without a
transparency-log entry, so the trust root is the key you pinned in step 1,
not the log. If this command does not print `Verified OK`, stop.

**5. Read the artifact hash out of the manifest you just verified.**

```sh
python3 -c 'import json;a=json.load(open("manifest.json"))["artifact"];print(a["sha256"],a["name"])'
```

**6. Download the tarball and compare.**

```sh
curl -fsSL https://updates.seglamater.app/spawn/releases/<version>/<name> -o <name>
sha256sum <name>
```

The two hashes must match. If they do, these bytes are the bytes we signed, and
you have proved it without trusting `updates.seglamater.app` for anything except
delivery.

---

## Mirroring, air-gaps, and USB sticks

The chain above has **no dependency on where the files came from**. Copy
`spawn.pub`, the manifest, the `.sig` and the tarball onto a USB stick, carry
them into an air-gapped network, and steps 4-6 give the same verdict.

The bootstrap supports this directly:

```sh
bash get-spawn.sh --base-url https://your-mirror.example --pubkey-file ./spawn.pub
```

With `--pubkey-file` nothing is fetched for the trust root at all. It also
resolves the tarball as *the file named in the signed manifest, sitting beside
that manifest* — never from an absolute URL inside the file — so a mirror needs
no rewriting to work.

---

## Installing it

Once verification passes, the tarball contains its own `install.sh` plus
`docs/INSTALL.md`, and those describe the procedure for the exact bytes you
have. That is on purpose: an installation guide kept anywhere else is a claim
about a tarball rather than part of one.

In outline, it places three binaries — `spawn` (from `spawn-cli`), `spawn-mcp`
and `spawn-remote` — puts them on your `PATH`, and verifies each one runs. It is
**first-install only**; it refuses if Spawn is already present, because
replacing the binaries of a running Spawn is a different and harder problem.

One step is yours rather than the script's, and skipping it leaves you with a
working Spawn that cannot dispatch anything:

```sh
spawn agents --init
```

`docs/INSTALL.md` walks through it.

---

## Which Hivemind does this Spawn work with?

Every real Spawn release manifest carries a machine-readable `compatibility`
block:

```json
"compatibility": {
  "schema": "seglamater-compat/v1",
  "requires": {
    "hivemind": { "min": "0.1.48", "max_tested": "0.1.80", "interface": "..." }
  }
}
```

- `min` — the oldest Hivemind that can use this Spawn.
- `max_tested` — the newest Hivemind it was actually exercised against. A newer
  server is supported, not proven.

Check it against your own server before you take an update:

```sh
bash get-spawn.sh --verify-only --hivemind-version 0.1.80
```

That refuses outright if the release requires a newer Hivemind than you run, and
warns if your server is newer than anything the release was tested with.

The block lives in the release manifest and nowhere else. It is inside the bytes
cosign signs, so it cannot be edited in transit, and there is no second copy to
drift out of agreement with it.

---

## Reporting a problem

`support@seglamater.com`. If the problem is a verification failure — a
fingerprint mismatch, a signature that will not verify — say so explicitly and
do not proceed; that is the case this whole document exists for.
