Treeship
Concepts

Room Sessions

Shared multi-agent sessions with separate identities, one report, and Merkle-sealed evidence.

Room Sessions

Room Sessions are the proposed model for a shared multi-agent workspace:

One room, many agents, one Merkle-sealed report.

A room session lets several agents and humans collaborate in the same logical room while Treeship keeps identities, handoffs, approvals, events, artifacts, and final reporting verifiable. Each participant keeps a separate actor identity. The room produces one shared report.

Design goals

  • Preserve separate identities for each agent, human, host, and room provider.
  • Produce one shared report for the whole room, not disconnected per-agent fragments.
  • Make Merkle integrity the default: events and artifacts should be independently recomputable.
  • Stay local-first: a room can be captured, closed, packaged, and verified without Hub.
  • Support cascading proof from room-level checkpoints down to individual actions.
  • Default to privacy-preserving capture, with explicit redaction and missing-evidence rows.
  • Fit agent-native UX: Slack rooms, MCP rooms, A2A handoffs, terminal sessions, and custom providers should map into the same receipt shape.

Trust layers

Room Sessions use four layers of trust:

LayerWhat it provesExample
SemanticWhat happened in the roomagent joined, human approved, file changed
ArtifactWhich signed Treeship artifacts back the claimaction, approval, handoff, receipt
MerkleThat the room report includes the exact event or artifactevent and artifact inclusion proofs
AnchorThat a checkpoint existed at or before an external timeBitcoin or transparency-log anchor

The verifier should be able to start from an external anchor, verify the room checkpoint, verify inclusion proofs, verify signed artifacts, and finally interpret the actor, approval, handoff, or event semantics.

Identity model

Actors are identified with stable URIs:

ActorURI shape
Humanhuman://<provider>/<stable_subject>
Agentagent://<provider>/<agent_name>
Agent instanceagent-instance://<session_id>/<instance_id>
Hosthost://<host_id>
Roomroom://<provider>/<room_id>

An agent instance is session-scoped. The same underlying agent can appear in many rooms, but each room session records a fresh instance ID so events remain attributable within the session.

Room metadata should include:

  • room_id
  • room_provider
  • room_uri
  • host_id
  • started_at
  • closed_at
  • participants
  • privacy_mode
  • capture_policy

Event model

Room providers normalize their native activity into room events. The v1 target providers are:

  • Slack channels and threads
  • MCP-hosted room contexts
  • A2A collaboration rooms
  • Terminal multiplexers
  • Custom room providers

The event vocabulary that ships today

SessionEventType in packages/core/src/session/event.rs is the real, serialized vocabulary. These are the values you will see in a receipt's timeline:

EventPurpose
session.started / session.closedSession lifecycle
agent.started / agent.completed / agent.failed / agent.returnedAgent lifecycle
agent.spawned / agent.collaborated / agent.handoffMulti-agent structure
agent.called_toolA tool invocation
agent.read_file / agent.wrote_fileFile access
agent.started_process / agent.completed_processSubprocess execution
agent.connected_network / agent.opened_portNetwork access
agent.decisionA recorded decision point

Proposed room event families

The events below are design, not implemented. They are the room-specific vocabulary this model would add — room and actor lifecycle, message capture, approval linkage, and explicit evidence-absence markers. None of them serialize today; evidence.missing and handoff.requested in particular appear nowhere in the codebase. Do not match on them.

Proposed eventPurpose
room.openedStarts a room session
room.closedSeals the room session
actor.joinedAdds a human, agent, or host
actor.leftRecords departure
message.sentCaptures a chat message or normalized message summary
network.requestedCaptures network access
process.startedCaptures subprocess execution
approval.requestedLinks an action to a required human approval
approval.grantedLinks approval artifact and approving actor
approval.deniedRecords denial
handoff.requestedTransfers responsibility from one actor to another
handoff.acceptedRecords acceptance
evidence.missingStates that expected evidence is absent
evidence.redactedStates that evidence exists but was intentionally withheld

approval.denied is the one name here that also exists in the shipped CLI, but as an action label minted by treeship deny — not as a session event type. The overlap is a naming collision, not a partial implementation.

Events should carry enough fields for deterministic ordering and attribution:

  • event_id
  • sequence
  • timestamp
  • room_id
  • actor_uri
  • agent_instance_id
  • host_id
  • event_type
  • summary
  • artifact_ids
  • evidence_refs
  • privacy

Handoffs

A handoff is a semantic transfer of responsibility inside the room. It should link:

  • the source actor
  • the target actor
  • the reason
  • the task or scope
  • the prior artifact chain
  • the acceptance event
  • the handoff artifact

The report should render handoffs as edges in the agent graph and as timeline events. Verification should confirm that every accepted handoff has the expected signed handoff artifact, or else surface a missing-evidence row.

Human approvals

Approvals remain nonce-bound Treeship approval artifacts. Room Sessions add room context around them:

  • who requested the approval
  • who granted or denied it
  • which room event required it
  • which action artifact was approved
  • whether the approval was reused, expired, missing, or out of scope

The report should make approval gaps obvious. A room can still close with missing approvals, but the final trust verdict must degrade honestly.

Report shape

A closed room session produces one report with:

  • Overview
  • Participants
  • Agent graph
  • Timeline
  • Handoffs
  • Approvals
  • Side effects
  • Artifacts and proofs
  • Integrity rows
  • Missing evidence
  • Redactions

Integrity rows should say exactly what was verified:

  • receipt parses
  • canonical bytes match
  • event Merkle root matches
  • artifact Merkle root matches
  • inclusion proofs verify
  • signed artifacts verify
  • approval nonce bindings verify
  • handoff links verify
  • external anchor verifies or is absent

Missing evidence is part of the report, not a hidden failure mode. If a provider could not supply message content, file contents, a tool input, an approval artifact, or an external timestamp, the report records that absence explicitly.

Merkle and anchoring strategy

Room Sessions use checkpoint-first anchoring.

  1. Events and artifacts are captured locally.
  2. Closing the room builds event and artifact Merkle trees.
  3. The room report stores roots, leaf counts, and inclusion proofs.
  4. A room checkpoint is signed.
  5. Hub or a local worker can anchor the checkpoint to OpenTimestamps, Bitcoin, or a transparency log.

High-value evidence can also be anchored directly. Direct anchoring should be reserved for evidence that needs its own timestamp independent of the room checkpoint.

OpenTimestamps lifecycle states:

StateMeaning
absentNo timestamp was requested
pendingTimestamp was submitted but not completed
completeTimestamp verifies
failedTimestamp was attempted and failed

Timestamp semantics are intentionally limited: they prove data existed no later than the timestamp. They do not prove who created it, whether the data is true, or whether the capture was complete.

CLI

What ships today

treeship room exists in the CLI as of v0.24 with three subcommands:

treeship room create        # sugar over `session start` that also populates SessionManifest.room
treeship room status        # the active room's status (session status plus room fields)
treeship room participants  # finalized (two-signature) participants, in join order

room create is sugar over session start, so the rest of the room lifecycle runs through the session commands you already know: treeship session invite / join / countersign for participants, treeship session close to finalize, treeship session report to publish.

Proposed surface

Everything below is design, not implemented. These commands do not exist in any released CLI and will fail with unrecognized subcommand. They are recorded here so the eventual shape is reviewable — do not copy them into scripts.

# NOT IMPLEMENTED — design sketch only
treeship room start [--provider slack|mcp|a2a|terminal|custom] [--room <uri>]
treeship room event <room_id> --type <event_type> --json <event.json>
treeship room handoff <room_id> --to <actor_uri> --scope <scope>
treeship room approve <room_id> <artifact_id>
treeship room close [room_id]
treeship room report [room_id] [--format text|json|html]
treeship room verify <room-report-or-package>
treeship room anchor <room_id>

MCP propagation

Room-aware MCP tools should propagate room context through environment variables:

TREESHIP_ROOM_ID=room_...
TREESHIP_ROOM_URI=room://mcp/...
TREESHIP_ROOM_PROVIDER=mcp
TREESHIP_SESSION_ID=ssn_...
TREESHIP_ACTOR_URI=agent://...
TREESHIP_AGENT_INSTANCE_ID=agi_...
TREESHIP_HOST_ID=host_...

Tools should treat these values as context, not trust roots. Signed artifacts and verifier checks remain authoritative.

Hub API sketch

POST /v1/rooms
GET /v1/rooms/{room_id}
POST /v1/rooms/{room_id}/events
POST /v1/rooms/{room_id}/close
GET /v1/rooms/{room_id}/report
GET /v1/rooms/{room_id}/proofs/{leaf_id}
POST /v1/rooms/{room_id}/anchor

Hub is an index and distribution layer. It should not become the trust root.

Local storage

~/.treeship/rooms/
  room_<id>/
    room.json
    events.jsonl
    artifacts/
    checkpoints/
    report.json
    report.html
    proofs/
    anchors/

The portable package should include the report, proofs, artifacts, render hints, and verification metadata required to verify offline.

Privacy modes

ModeBehavior
fullCapture message and evidence content where available
metadataCapture event metadata, actor attribution, hashes, and summaries
redactedCapture only explicitly allowed fields and redaction markers
offDo not capture room events

Privacy mode belongs in the signed report. A verifier should distinguish "not captured by policy" from "expected evidence is missing."

Rendering requirements

The HTML report should:

  • show the room verdict before the narrative
  • keep participant identities visible on every event
  • distinguish live, closed, anchored, missing, and redacted states
  • render handoffs as graph edges and timeline rows
  • make approval failures visually prominent
  • support offline viewing from the package
  • avoid requiring Hub or account state

Implementation phases

  1. Define the room report schema and local storage layout.
  2. Add room event ingestion for local custom providers.
  3. Add room close/report/verify commands.
  4. Add MCP room context propagation.
  5. Add Slack and A2A adapters.
  6. Add Hub room APIs and public report rendering.
  7. Add checkpoint anchoring and OTS lifecycle display.

Open questions

  • Should room events be signed individually, or is signing the room checkpoint enough for v1?
  • Should message bodies be included by default, hashed by default, or provider-specific?
  • How should cross-host clock drift be represented in timeline verification?
  • Which providers can supply stable actor identifiers without leaking private account data?
  • What is the minimum room package needed for offline verification?
  • Capture metadata by default.
  • Sign artifacts and the final room checkpoint.
  • Build separate event and artifact Merkle roots.
  • Treat Hub as an index only.
  • Allow room close with missing evidence, but surface a degraded verdict.
  • Prefer checkpoint anchoring over direct artifact anchoring.
  • Render one shared report with separate actor attribution.