Skip to main content

Alpha quickstart

This is the shortest flow that works today: compile a Context Capsule from one agent's task state, put it on a relay, and fetch it back as a handoff another agent can read.

The five steps below walk through each arrow above in order. Every command was run against v0.0.0 before this page was written.

Before you start: Alpha access is invite-gated​

Ophiuchus is not publicly installable. The repository is private, there is no package on PyPI, and there is no git clone URL that works without access. That is deliberate for the Alpha — the product is gated while the docs are open (ADR-0011). There is no account system, no self-service sign-up and no password: access is a request, a manual founder decision, and — once the relay is deployed with the gate on — a shared token.

How it works, end to end:

  1. You ask. Send a short request — who you are and what you'd use it for — to [email protected].
  2. The founder approves manually. There is no queue, ticketing system or SLA. A founder reviews the request and decides, by hand, for this first cohort.
  3. You receive two things over that same private channel: repository access (so git clone and the install steps below work), and — if the deployed relay has the Alpha access gate turned on — an Alpha access token. Set it as OPHIUCHUS_ALPHA_TOKEN in your environment, or pass --alpha-token on send/receive. The loopback relay this quickstart runs never checks for this token — the gate is a property of a deployed relay, and it does nothing until its operator configures it. If you were not given one, you don't need one for anything on this page.
  4. You run the steps below. Same public quickstart everyone reads, gated or not — there is no separate "Alpha-only" documentation.
Operator reference: minting, rotating and revoking an Alpha token

This is the founder/operator side of step 2 above, for a relay deployment that has the Alpha access gate (ADR-0011) turned on. It is a separate mechanism from the per-capsule capability token every send/receive already uses — gating who can reach the relay at all is not the same question as who can read one capsule, and the two are checked independently.

Mint one token per approved tester:

uv run ophiuchus alpha-token-new
# token: <a fresh secret — deliver this to the tester privately>
# hash: <its SHA-256 digest — append this to the relay's allowlist>

Only the hash is ever configured on the relay (OPHIUCHUS_ALPHA_TOKEN_HASHES, a comma-separated list) — the raw token is never stored anywhere, mirroring exactly how a capability token is handled. Append the new hash to the existing value and redeploy the relay.

To revoke or rotate a tester's access: remove their hash from OPHIUCHUS_ALPHA_TOKEN_HASHES (and, for a rotation, add the hash of a freshly minted replacement token) and redeploy. No code change, no database migration — the allowlist is the whole mechanism.

To gate a relay that has never had the gate on: set OPHIUCHUS_ALPHA_TOKEN_HASHES to a non-empty value. An empty or unset value (the default) leaves every relay — including the loopback one this quickstart runs — ungated, exactly as before this mechanism existed.

You also need Python 3.13 or newer and uv. macOS and Linux are the platforms Ophiuchus is developed against; CI runs on Linux. Windows is untested.

1. Install​

From your checkout of the repository. Every uv run command on this page runs from here:

uv sync --locked
uv run ophiuchus --version # -> 0.0.0 (also available as `ophiuchus version`)
uv run ophiuchus status # version + the effective config, as JSON

Configuration comes from OPHIUCHUS_* environment variables and nowhere else. There is no .env file loading. status prints what is actually in effect, and prints no secrets — the capability token is never configuration.

If anything below doesn't work, run uv run ophiuchus doctor first — see Troubleshooting at the end of this page.

2. Start the relay​

The relay is the thing in the middle that holds a capsule between the two sessions. Run it on loopback in its own terminal:

uv run python -c "from ophiuchus.transport.relay import run; run()"
curl -s http://127.0.0.1:8099/health
# {"status":"ok","version":"0.0.0","dev_mode":false}

This relay is deliberately dumb. It stores bytes under a token, expires them, and hands them back. It does no summarizing, embedding, scoring or search.

There is no hosted relay yet

The loopback relay is the relay that exists. A hosted relay you could point two machines at is not available, and no URL for one is published here because none is running. To hand off between two machines today you have to operate a relay both of them can reach, with your own HTTPS in front of it. Ophiuchus does not provide that transport security; it assumes it.

3. Compile a capsule​

ophiuchus capture takes a task's structured state on stdin — from claude -p --output-format json prompted to emit these fields, or hand-filled — and writes a schema-validated capsule plus a human-readable rendering. Only goal, state and next_action are required.

Point --repo at the git repository the work belongs to, so the capsule is grounded in that repo's real branch and commit. Run it from your ophiuchus checkout like every other command here — uv run resolves the project from the current directory, so running it from the work repo instead cannot find the ophiuchus command:

echo '{
"goal": "make the token refresh survive a clock skew",
"state": "reproduced the failure; the expiry is compared in local time",
"next_action": "switch the expiry comparison to UTC and add a regression test",
"rejected": ["the network-timeout theory - the request never leaves the client"],
"evidence": ["test_refresh_after_skew fails only when TZ=America/Chicago"],
"constraints": ["cannot change the token format - other services already parse it"],
"open_questions": ["does the mobile client hit the same comparison, or a separate one?"]
}' | uv run ophiuchus capture --name handoff --out-dir .ophiuchus \
--repo /path/to/the/work/repo \
--producer-version "$(claude --version)"

# wrote .ophiuchus/handoff.capsule.json canonical, schema-validated
# wrote .ophiuchus/handoff.capsule.md human-readable

Only goal, state and next_action are required. evidence, rejected, constraints and open_questions are all optional lists — include whichever ones the task actually has; an empty list is the honest default, not an error.

  • rejected is the field that does the most work. It is the negative knowledge a normal handoff note loses, and it is what stops the recipient walking back into a dead end.
  • constraints is a boundary the successor must not cross while continuing the work — a decision already made, not a hypothesis still being tested.
  • open_questions is something the predecessor did not resolve. Naming it explicitly is different from omitting it: an omitted question looks answered, an open one is flagged as still unknown.

Your shell resolves --producer-version, not Ophiuchus. The version cannot be discovered from the model's own output without trusting the model's claim about its environment, so omitting the option records claude-code/unknown — an honest absence rather than a guessed number.

Two things will stop a capture, loudly and before anything is written:

  • The advisory secret scan. The producer refuses to emit a capsule that trips it. --allow-secrets overrides and still reports every finding, masked, on stderr. Read Safe use before you use that flag.
  • Control characters. No capsule string may contain one other than a newline or a tab, which stay legal in the text fields. In practice this means coloured tool output pasted into evidence is refused; rerun the tool without colour, or strip it. A file saved with CRLF line endings fails for the same reason — the carriage return is refused even though the newline beside it is not.

4. Send it​

uv run ophiuchus send .ophiuchus/handoff.capsule.json
# location_id: bb0f870f… 32 hex chars; a locator, share freely
# expires_at: 2026-08-18T06:15:09.080727+00:00
# token: HNwRSQs8… a secret; shown once

The location_id is a locator and can be shared freely. The token is a secret, it is shown once, and anyone holding it can fetch the capsule until it expires — deliver it over a private channel. Add --delete-after-read to make the first successful fetch consume the capsule.

Deleting a capsule before it expires

There is no ophiuchus command for this in v0.0.0 — you cannot delete a sent capsule via the CLI. The relay does implement the operation (DELETE /capsules/{location_id}, the same bearer token send printed), and it destroys the capsule immediately rather than waiting for expiry:

curl -s -X DELETE -H "Authorization: Bearer $TOKEN" \
https://your-relay-host/capsules/<location_id>
# 204 on success, 404 if it was already gone

Use this if a capsule was sent to the wrong place, or sent too broad a TTL.

Believe the earlier of the two expiry times. The relay will not keep a capsule past its own ceiling (one hour by default), but it returns the payload unchanged, so a capsule built with a longer TTL goes on advertising an expiry the relay will not honour. send warns when the two disagree, and --json reports both: expires_at is the relay's, capsule_expires_at is the payload's claim.

5. Receive it as a handoff​

On the receiving side, the token is read from $OPHIUCHUS_CAPABILITY_TOKEN or from stdin. Never from a flag, so it cannot land in shell history or a process listing.

export OPHIUCHUS_CAPABILITY_TOKEN=…the token send printed…
uv run ophiuchus receive --location-id bb0f870f… \
--name handoff --with codex

--location-id is used rather than the bare positional form because it also works for a locator beginning with -, which an argument parser would otherwise read as an option name. Locators this relay mints are hex and never do, so ophiuchus receive bb0f870f… is equally fine.

--with codex renders the Markdown as a Codex-ready handoff: it quotes every line the sender wrote as the sender's claim, tells the reader not to re-attempt the rejected hypotheses, and checks the capsule's commit against your checkout. The verbatim JSON is always written unchanged first, so a one-shot capsule survives a rendering error.

Point your Codex session at the written handoff.capsule.md. Codex is not driven for you and need not be installed.

If your checkout does not contain the capsule's commit, the output says so:

warning: STALE CONTEXT — Capsule commit `9bb80720c1f0` is not present in this
checkout — the histories appear unrelated. Treat this context as history, not
current truth.

That is the intended behaviour, not a bug. Stale context is always surfaced; Ophiuchus never presents it as fresh. A missing, expired, consumed or wrong-token fetch fails the same loud way, and the failures are deliberately indistinguishable from each other.

Troubleshooting​

Before asking for help, run:

uv run ophiuchus doctor

It checks the things that actually break a new setup — CLI/config loaded, relay URL parses, DNS resolves, the relay is reachable and reports healthy, the Alpha access gate (if the relay you're pointed at has one) accepts your token, and your local .ophiuchus/ state directory is writable — each bounded by a few seconds so it never hangs. A required failure prints what to try next; an optional one (like Codex not being installed) never blocks handoff. It never prints a capability token, an Alpha token, or any other secret. Add --json for a stable, scriptable report; the exit code is 0 when ready and 1 when a required check failed.

uv run ophiuchus doctor
# Ophiuchus Doctor
# ✓ CLI version: ophiuchus 0.0.0
# ✓ Configuration loaded: relay_url='http://127.0.0.1:8099' database_backend=sqlite
# ✓ Relay URL valid: http://127.0.0.1:8099
# ✓ DNS resolution: '127.0.0.1' is a loopback address; no DNS lookup needed
# ✓ Relay reachable: connected (HTTP 200)
# ✓ Relay healthy: status=ok version=0.0.0
# ✓ Access configuration: relay accepted the probe request (Alpha gate is off, or open for this token)
# ✓ Protocol/schema compatibility: client 0.0.0 (capsule schema v1) matches relay 0.0.0
# ✓ Local state directory writable: .ophiuchus is writable
# ✓ Codex available (optional): /usr/local/bin/codex
#
# Ready for handoff.

If a check fails, its remediation line (-> ...) names the setting or action to try — most setup problems described in this doc (a wrong OPHIUCHUS_RELAY_URL, a relay that isn't running, a missing or stale Alpha token) show up here before you ever have to send a capture/send/receive diagnosis to the founder.

What the Alpha does not do​

  • One adapter pair only: Claude Code to Codex. No Copilot, no Cursor.
  • No hosted relay, no accounts, no web application, no dashboard.
  • No durable team memory. A capsule is a directed handoff with an expiry.
  • No end-to-end encryption, and no search or retrieval over past capsules.

Whether a capsule actually beats a normal handoff is still being measured. See Privacy and safe use before you put real work into one.