Treeship
CLI reference

session

Manage attestation sessions. Start, close, report, and share Session Receipts.

A session groups related work into a single unit. When you close a session, Treeship composes a Session Receipt v1 and writes a portable .treeship package that can be inspected and verified offline, or uploaded to a hub for sharing at a permanent public URL.

See the Session Receipts concept page for the full format and determinism rules.

treeship session start

Start a new session.

treeship session start
treeship session start --name "fix auth bug"
treeship session start --actor agent://coder
treeship session start --allow-dangerous-root

Options

OptionDescription
--name <text>Human-readable session name
--actor <uri>Default actor URI for attestations in this session
--allow-dangerous-rootPermit a session whose git root is your home directory

Starting a session writes .treeship/session.json, initializes an append-only event log at .treeship/sessions/<session_id>/events.jsonl, and emits a session.started event. All subsequent attestations and wrap calls are linked to the session.

Treeship refuses to start a session when the git toplevel is your home directory. Start from a project checkout instead. Use --allow-dangerous-root only when you intentionally want a home-scoped session.

treeship session status

Show the current session state.

treeship session status

Outputs session id, name, actor, started-at timestamp, artifact count verified against the chain, and the number of events in the session's event log.

If no session is active, exits cleanly with a hint to run session start.

treeship session invite

Mint a single-use, expiring invitation that lets a second agent join an existing session. This is the host side of the multi-agent session lifecycle.

treeship session invite ssn_abc --invitee-cert "ed25519:ISSUER:org-x" --expires 1h
treeship session invite ssn_abc --invitee-pubkey deadbeefdeadbeef --capabilities tool.call
treeship session invite ssn_abc --open --expires 30m

Arguments

ArgumentDescription
[session_id]Session to mint the invitation for. Defaults to the active session.

Options

OptionDescription
--invitee-cert <issuer:subjects>Cert-restricted invitation. Format is <issuer_pubkey>:<subject1,subject2,...>.
--invitee-pubkey <fp-or-pubkey>Pubkey-restricted invitation. A 16-hex fingerprint or a full canonical pubkey.
--openOpen invitation that anyone holding the blob can redeem. Opt-in only.
--capabilities <types>Comma-separated action types to grant. Defaults to tool.call.
--expires <duration>Lifetime such as 30s, 5m, 1h, 7d. Defaults to 1 hour. The protocol max is 7 days.
--format <text|json>Output format. JSON returns { invitation_id, bootstrap_blob, session_ref, expires_at }.
--no-armorEmit raw JSON instead of the armored blob.

Exactly one of --invitee-cert, --invitee-pubkey, or --open is required. The command signs the invitation with the keystore's default key (the session host), persists it under the artifact store, and prints an armored -----BEGIN TREESHIP INVITATION----- bootstrap blob on stdout.

A joining agent only honors the invitation if the host's issuer key is pinned locally as a session_host trust root. Pin it with treeship trust add <key_id> ed25519:<pubkey> --kind session_host --yes. See Multi-Agent Sessions.

treeship session join

Redeem an invitation and emit a pending participant event. This is the joiner side of the lifecycle.

treeship session join --invite-file ./invite.blob --actor agent://researcher
cat ./invite.blob | treeship session join --invite - --actor agent://qa

Options

OptionDescription
--invite <blob>Paste the bootstrap blob inline. Use - to read from stdin.
--invite-file <path>Read the bootstrap blob from a file.
--actor <uri>Joining agent's actor URI, such as agent://researcher (required).
--format <text|json>Output format.

The command pins the issuer against the local SessionHost trust roots, verifies the invitation signature, checks expiry and restriction, records the nonce in the Approval Use Journal with max_uses=1, and emits a single-signature participant envelope that is pending the host countersign. It prints the participant artifact id to pass to session countersign. A second join against the same invitation fails through the journal's single-use path.

treeship session countersign

Host countersigns a pending participant event. After this runs, the participant envelope carries two signatures (joining agent plus host) and verifies as a finalized join.

treeship session countersign art_part_abc123

Arguments

ArgumentDescription
participant_idParticipant artifact id produced by session join.

The command confirms the running default key matches the invitation's issuer, attaches the host countersign over the same canonical bytes, self-verifies, and overwrites the storage record with the finalized two-signature envelope. A participant envelope is invalid until both signatures are present.

treeship session close

Close the active session, compose the Session Receipt, and write a .treeship package.

treeship session close
treeship session close --summary "fixed JWT expiry bug"

Options

OptionDescription
--summary <text>Plain-text summary of what the session accomplished

On close, Treeship:

  1. Appends a session.closed event to the event log.
  2. Walks the artifact chain from .last back to the session's root artifact.
  3. Composes a canonical Session Receipt v1 from the events, the artifact chain, and the agent graph.
  4. Builds a .treeship package under .treeship/sessions/<session_id>.treeship/ with receipt.json, merkle.json, render.json, per-artifact inclusion proofs, and a static preview.html.
  5. Signs a session.close chain artifact as before.
  6. Prints the package path, the canonical receipt digest, and the Merkle root.

Close is guarded by a lock so only one close or abandon operation can mutate session state at a time. Git reconciliation is also bounded: if the untracked-file scan exceeds the cap, Treeship skips per-file untracked events, records the truncation in the receipt proofs section, and treeship package verify reports a reconcile_completeness warning.

Example output:

✓ session receipt composed
  package:   .treeship/sessions/ssn_42e740bd9eb238f6.treeship
  digest:    sha256:942e6b2bfcbe860223fbae57ee7d9b73400a278ccfb0f1d5ca865aec9ce9aba6
  merkle:    mroot_effc020c67548f53
  files:     8

✓ session closed
  id:       ssn_42e740bd9eb238f6
  duration: 6m
  receipts: 2
  events:   2

After close, run treeship package verify against the package path to confirm the receipt is locally verifiable.

treeship session abandon

Quarantine a wedged active or closing session without deleting evidence.

treeship session abandon

The command moves .treeship/session.json or .treeship/session.closing plus the session event directory into .treeship/quarantine-*. Use it when a close was interrupted or a session is poisoned and you need the next session start to begin cleanly. The quarantined files remain available for debugging.

treeship session report

Upload a closed session's receipt to the configured hub and print the permanent public URL.

treeship session report
treeship session report ssn_42e740bd9eb238f6

Options

ArgumentDescription
[session_id]Session ID to upload. Defaults to the most recently closed session's package under .treeship/sessions/.

The command:

  1. Locates the .treeship package for the requested session (or the most recently modified one).
  2. Reads receipt.json verbatim so the digest signed by session close is preserved bit-for-bit.
  3. DPoP-signs a PUT {hub_endpoint}/v1/receipt/{session_id} request using the active hub connection's private key.
  4. Prints the permanent receipt URL.

If a package directory exists but receipt.json was never written, session report reports the package as incomplete instead of treating it as a missing closed session.

Example output:

✓ session receipt uploaded
  hub:      local
  session:  ssn_42e740bd9eb238f6
  agents:   1
  events:   2

  receipt:  https://treeship.dev/receipt/ssn_42e740bd9eb238f6

  → share this URL freely -- it never expires and needs no auth

The receipt URL is permanent and public. No token, no expiry, no auth required to fetch it. A2A clients, dashboards, and offline verifiers can all curl it programmatically. See GET /v1/receipt/{session_id} for the API reference.

What gets sealed in a receipt

A Session Receipt v1 includes:

  • Session metadata: id, name, mode, started-at, ended-at, duration, status
  • Participants summary: total agents, spawned sub-agents, handoffs, max delegation depth, hosts, tool runtimes
  • Agent graph: every agent instance with its role, host, depth, and edges (parent-child spawn, handoff, collaboration, return)
  • Timeline: all events in deterministic order (timestamp, sequence_no, event_id)
  • Side effects: files read, files written, ports opened, network connections, processes, tool invocations
  • Artifacts: chain entries with content-addressed ids
  • Merkle root + inclusion proofs over the artifact ids
  • Render hints for Explorer and the preview HTML

Events the session can capture include tool calls, file reads (via the daemon's sensitive-file watcher), file writes, network connections, process execution, agent spawning, handoffs, collaborations, and returns.

A session is auto-sealed: the chain of signed artifacts inside the session is what the receipt commits to via the Merkle root. The receipt itself is a human-readable summary on top of that cryptographic backbone.