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-rootOptions
| Option | Description |
|---|---|
--name <text> | Human-readable session name |
--actor <uri> | Default actor URI for attestations in this session |
--allow-dangerous-root | Permit 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 statusOutputs 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 30mArguments
| Argument | Description |
|---|---|
[session_id] | Session to mint the invitation for. Defaults to the active session. |
Options
| Option | Description |
|---|---|
--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. |
--open | Open 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-armor | Emit 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://qaOptions
| Option | Description |
|---|---|
--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_abc123Arguments
| Argument | Description |
|---|---|
participant_id | Participant 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
| Option | Description |
|---|---|
--summary <text> | Plain-text summary of what the session accomplished |
On close, Treeship:
- Appends a
session.closedevent to the event log. - Walks the artifact chain from
.lastback to the session's root artifact. - Composes a canonical Session Receipt v1 from the events, the artifact chain, and the agent graph.
- Builds a
.treeshippackage under.treeship/sessions/<session_id>.treeship/withreceipt.json,merkle.json,render.json, per-artifact inclusion proofs, and a staticpreview.html. - Signs a
session.closechain artifact as before. - 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: 2After 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 abandonThe 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_42e740bd9eb238f6Options
| Argument | Description |
|---|---|
[session_id] | Session ID to upload. Defaults to the most recently closed session's package under .treeship/sessions/. |
The command:
- Locates the
.treeshippackage for the requested session (or the most recently modified one). - Reads
receipt.jsonverbatim so the digest signed bysession closeis preserved bit-for-bit. - DPoP-signs a
PUT {hub_endpoint}/v1/receipt/{session_id}request using the active hub connection's private key. - 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 authThe 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.