signed apt repository
apt install spectroscope.
This is the signed apt repository for spectroscope, the agent orchestrator you can watch. Pin one key, add one source, and apt keeps the desktop build current the same way it keeps everything else on the machine current.
install
three lines, in this order
The first two lines are the whole client side. They pin the signing key
to its own keyring and point one source at one base URL. Nothing here
uses trusted=yes, and there is no allow-insecure switch
anywhere in this repository.
Fetch the public half of the signing key and store it as its own keyring.
curl -fsSL https://apt.spectroscope.dev/spectroscope.asc | sudo gpg --dearmor -o /usr/share/keyrings/spectroscope.gpg
Add the source, bound to that keyring by signed-by and nothing else.
echo "deb [signed-by=/usr/share/keyrings/spectroscope.gpg] https://apt.spectroscope.dev stable main" | sudo tee /etc/apt/sources.list.d/spectroscope.list
Then apt takes over.
sudo apt update
sudo apt install spectroscope
measured 2026-07-31 on debian 12 (bookworm, apt 2.6.1) and ubuntu 24.04.4 LTS,
both amd64:
apt update exits 0 with no signature warning, the package
installs, dpkg -V re-hashes every installed file without a
complaint, and apt remove puts the machine back as it was
arm64 index exists and is covered by the signature, but it is
empty, so apt on an arm64 machine will add this source without error and
then find nothing to install. On Apple silicon, take the notarized dmg or
the homebrew cask below.
the package unpacks to /opt/spectroscope and registers
/usr/bin/spectroscope through update-alternatives ·
sudo apt remove spectroscope takes both back off ·
~/.spectro holds your sessions, settings and downloaded
models, and install and remove both leave it alone
the index
what is in here right now
One package. Everything below is read out of
dists/stable/main/binary-amd64/Packages, the file apt
downloads and checks against the signature.
| package | spectroscope |
|---|---|
| version | 0.5.0 |
| architecture | amd64 |
| size | 187306672 bytes (178.63 MiB) |
| installed size | 546947 KiB (534.1 MiB on disk) |
| sha256 | 7f25fd52c5a29ab8cc6e955f5b165ce9b2fa513aa9b8e086c6a88ab8234df62f |
| filename | pool/main/s/spectroscope/spectroscope_0.5.0_amd64.deb |
| description | the agent orchestrator you can watch. The Electron desktop shell, which spawns and supervises the spectro-server JVM. |
| served from | the v0.5.0 release assets, reached by a 302 from the pool path above |
the arm64 index is present and signed and contains zero packages
(sha256 e3b0c442…, the hash of the empty file)
trust nothing, check everything
how to check this yourself
The point of a signed repository is that you never have to take our word for any of it. Here is what protects the install, and the commands that show you each part working.
the key
One ed25519 key, no expiry, no subkeys. It signs the apt indexes and nothing else. It is deliberately not the Maven signing key, so revoking one surface can never break the other.
spectroscope apt <chris@spectroscope.ai>
E603 2682 4E65 D5CB 3116 02D7 9DF6 0ECC 1605 83D8
read that fingerprint back off the key you just downloaded:
curl -fsSL https://apt.spectroscope.dev/spectroscope.asc | gpg --show-keys --with-fingerprint
what signed-by does
signed-by binds this one keyring to this one source. apt
checks the signature on InRelease against that key alone, so
a signature from any other key is refused even when it is perfectly valid
in itself. Without the flag, any key in apt's global trust store could
speak for this repository.
verify the index signature by hand, the same way the publish script does:
curl -fsSL https://apt.spectroscope.dev/spectroscope.asc | gpg --dearmor > /tmp/spectroscope.gpg
curl -fsSL https://apt.spectroscope.dev/dists/stable/InRelease > /tmp/InRelease
gpgv --keyring /tmp/spectroscope.gpg /tmp/InRelease
why the redirect is not a hole
The indexes are served from here. The packages are not: one deb is
178.63 MiB and a Cloudflare static asset may be 25 MiB, so
/pool/ answers with a 302 at the GitHub release asset that
holds the bytes. The target is looked up in
pool-map.json and never guessed, and a
filename missing from that map gets a 404 that says so.
apt does not trust a package because of where it came from.
It hashes the bytes it received against the sha256 in the index, and that
index hangs off the signature you just pinned. The download host is
untrusted by construction: it can make an install fail, never quietly
change one. A flipped byte with the length preserved is caught as a
Hash Sum mismatch, the bytes are quarantined as
.deb.FAILED, and nothing is unpacked. A wrong length is
caught earlier still.
see the redirect, then check the bytes it points at against the signed index:
curl -sI https://apt.spectroscope.dev/pool/main/s/spectroscope/spectroscope_0.5.0_amd64.deb
# 302, with the release asset in the location header
curl -fsSL https://apt.spectroscope.dev/dists/stable/main/binary-amd64/Packages | grep -E '^(Version|Size|SHA256):'
apt-get download spectroscope && sha256sum spectroscope_*.deb
# the two sha256 values are the same one
the whole pass in one container
scripts/verify-client.sh
runs the client side end to end: it serves the tree on loopback, runs the
two documented lines, installs, removes, confirms ~/.spectro
survived, and finishes with a negative control that corrupts
Packages.gz and requires apt to reject it. It exits non-zero
at the first step that misbehaves, so CLIENT OK is the only
successful ending.
git clone https://github.com/spectroscope/apt.git && cd apt
docker run --rm -v "$PWD":/srv/apt:ro debian:12 sh /srv/apt/scripts/verify-client.sh
the scripts and the worker source are kept out of the served tree
(.assetsignore), so they live in the repository, not at this
hostname
other doors
other ways to get spectroscope
apt is the Linux door. The packaged desktop builds are macOS on Apple
silicon, and they carry their own JRE and their own
llama-server, so the machine needs no Java and no Homebrew.
homebrew
One command, and brew upgrade keeps it current. The cask
installs the notarized release build.
brew install --cask spectroscope/tap/spectroscope
the cask lives at spectroscope/homebrew-tap
notarized dmg
Signed and notarized, so it opens on double-click without a warning to click through. Drag the app in and you are done.
the latest release carries the dmg, the CLI zip and the plain server jar
from source
Clone and go. The ./spectro launcher resolves a JDK 21+
for you, and the code is MIT.
git clone https://github.com/spectroscope/spectroscope.git
cd spectroscope && ./spectro web start
the release the pool points at
The deb this repository indexes is attached to release v0.5.0. Every other artifact of that cut sits next to it.
the two sites
spectroscope.ai is the product site and the home of the user guide. spectroscope.dev is the developer portal: the five-line facade, the JSONL event contract, the reference.