Handoffs
A handoff is a signed transfer of work between actors or across Treeships.
A handoff records the chain of custody when work moves between agents, between humans and agents, or between organizations.
Handoff scenarios
Agent to Agent
One agent hands off research results to another agent for execution, with a signed transfer record.
Agent to Human
An agent produces output that a human needs to review. The handoff proves what was delivered and when.
Cross-Treeship
Work moves between organizations. Each side has its own keys. The handoff bridges trust domains.
Same-Treeship handoff
treeship attest handoff \
--from agent://researcher \
--to agent://executor \
--artifacts art_research_001,art_validate_002✓ handoff attested
id: art_handoff_xyz
from: agent://researcher
to: agent://executor
artifacts: art_research_001, art_validate_002The receiver can verify the handoff before acting:
treeship verify art_handoff_xyz✓ verified
target: art_handoff_xyz
actor: agent://researcher -> agent://executor
actor proof: asserted (ship key)
artifacts: 2 named, all present in this storeverify checks the handoff envelope, then reports whether the artifacts it names are in this store. The handoff verifies on its own: a receiver holding only the handoff sees the envelope pass and the named work reported as absent, with a warning that nothing above vouches for the work itself.
Cross-Treeship handoff (cross-org)
When work moves between organizations, each side has its own Treeship and keys.
# Company A -- attest a handoff
treeship attest handoff \
--from agent://company-a/researcher \
--to agent://company-b/legal-review \
--artifacts art_output_123
treeship hub push art_handoff_xyz
# -> https://treeship.dev/verify/art_handoff_xyz
# Share this URL with Company B# Company B -- verify before acting
treeship hub pull art_handoff_xyz
# Pin Company A's key once, then verify against your own trust store.
# There is no --trusted-key flag: trust roots are pinned, not passed per call.
# The first argument is the KEY ID Company A's `treeship keys export` printed
# (key_<16 hex>), not a label: pins are matched against the signature's key id.
treeship trust add key_<company-a key id> ed25519:<company-a-pubkey> --kind cert_issuer --label company-a --yes
treeship verify art_handoff_xyz✓ verified
target: art_handoff_xyz
actor: agent://company-a/researcher -> agent://company-b/legal-review
actor proof: asserted (ship key)
artifacts: 1 named, 1 NOT in this store: art_output_123
⚠ the handoff names work this store does not holdThe handoff verifies; the work it names is not here. hub pull the named artifacts too, or ask Company A for a bundle that includes them (treeship bundle export), then import it and verify again.
No shared infrastructure required. The signature is the trust. Company B does not need to trust the Hub or any third party -- only the public key of Company A.
The key-id matching above is specific to this actor-proof flow (treeship verify <artifact-id>, which walks a signed agent_cert.v1 against cert_issuer pins by key id). treeship package verify -- the check a .treeship package runs on its own signers, including receipt_binding -- matches every pin (cert_issuer, agent_cert, session_host alike) by the key's own bytes instead, never by id. Two different checks, two different matching rules; neither is a stand-in for the other.
Handoff flags
| Flag | Required | Description |
|---|---|---|
--from <uri> | Yes | Actor URI of the sender |
--to <uri> | Yes | Actor URI of the receiver |
--artifacts <ids> | Yes | Comma-separated artifact IDs being transferred |
--approvals <ids> | No | Approval IDs the receiver inherits |
--obligations <text> | No | Obligations the receiver must satisfy |