Features / Team Handoff

Hand off a session,
not a Slack message

Full conversation context, workspace state, ticket + persona provenance, and curated attachments transfer between teammates — with revoke, decline, comment threads, and an audit trail.

Developer A
$ sfs handoff ses_abc \
--to sarah@company.com \
--ticket tkt_8f3a --persona atlas \
--attach kb_entry:412 --attach wiki_page:auth \
--message "JWT middleware is the problem"
Handoff hnd_x7k9 created.
Session pushed. Sarah notified.
Developer B (Sarah)
$ sfs pull-handoff hnd_x7k9
Workspace resolved via git remote.
Active ticket tkt_8f3a written to ~/.sessionfs/active_ticket.json.
Next captured session inherits persona = atlas.
$ sfs resume ses_abc --in codex
Session resumed. 47 messages loaded.

Paths auto-resolve by git remote URL. No manual configuration.

How handoff works

Provenance carry-through

Attach --ticket and --persona at create time. On claim, the recipient's CLI writes the active-ticket payload to ~/.sessionfs/active_ticket.json so the next captured session is automatically tagged with that context.

Team handoffs (Team+)

Hand off to a team with --to-team-id; any team member can claim with atomic race protection. UPDATE WHERE status='pending' runs first — race losers never write blobs.

Curated attachments

Attach KB entries, wiki pages, or ticket refs with --attach kind:ref_id. Validated against the sender's project at create time and re-validated against the recipient's accessible projects on claim; inaccessible refs are silently dropped with structured reasons.

Revoke / decline / comment

Sender can revoke with a required reason; recipient can decline. Both parties can post comments; every state change emits an audit event. Email notifications fire for claim, revoke, decline, and comment (all html.escape()'d).

404-not-403 existence hiding

Non-parties get 404 (not 403) on all handoff routes — recipients can't distinguish pending vs claimed vs revoked via response codes. Eligibility is checked before any lazy-expire write or status-specific response.

Email notifications

Recipients get an email with session details and the pull command. Lifecycle events (claim, revoke, decline, comment) fire to the other party. Supports Resend, SMTP, or no email for air-gapped enterprise deployments.

What transfers in a handoff

Everything the recipient needs to continue exactly where you left off — not just the messages, but the full context.

Read the handoff docs
Full conversation history
Every message, tool call, and response from the original session.
Git workspace snapshot
Branch, commit SHA, remote URL, and dirty file list at handoff time.
Tool configuration
Which tool was used (Claude Code, Codex, Gemini, etc.) and resume target.
Sender's message
The optional note you add at handoff time to orient the recipient.