Skip to Content
PlatformHow-to guidesSend a hand-off

How to send a hand-off

Use this guide when a record needs another persona’s work or decision: a closed notebook entry ready for an SOP check, a supply slip the lead must know about, a question reassigned to a scientist. You start with a record; you end with a handoff_requests row sent that appears in the addressee’s inbox and on the program board, and later accepted with a program-visible thread pinned to the record. Sending needs program.handoffs.manage, which every program persona except the viewer holds. Every surface here carries the status word designed until the R3 gates pass.

Hand-offs are the only channel between twins, and they are records. A twin may propose one (console.propose_handoff), but the row exists only after you approve it; the receiving twin may prepare only after the receiving person accepts. There is no agent-to-agent channel and no messaging tool.

Prerequisites

  • A record in Evidence, Plans, Review or Progress that you can read, and program.handoffs.manage.
  • Knowing the persona you address (to_persona_key); naming a person (to_user_id) is optional.

Choose the kind and the addressee

From the record’s actions choose Hand off (the phase-2 record action “Send to QA” is the same thing with the quality reviewer pre-selected). Kinds: review (please check this), data (please supply or link data), decision (please decide this), information (for your awareness). Address a persona; optionally a person. Write a short message; it passes redaction and never carries retrieved source text.

Send, or approve your twin’s proposal

Send calls POST /programs/{program_id}/handoffs with HandoffCreate {to_persona_key, to_user_id?, kind, linked_type, linked_id, message_md}. The API creates the row sent, writes one inbox item per current holder of the addressed persona (one item when a person is named), notifies a named addressee with handoff_received (a persona-wide hand-off goes to the digest), and audits handoff.send. When your twin proposed the hand-off (“EXP-0421 ready for SOP check”), the proposal waits in your inbox like any other write and Approve creates the same row; the record then reads “Proposed by Maya N.’s twin (agent); decided by Maya N.” (illustrative).

What the addressee sees

The item sits under Hand-offs in their inbox with your name, the kind, the linked record and “Why now”. The first holder to Accept (POST .../handoffs/{handoff_id}/accept) becomes to_user_id; the sibling items of the other holders are withdrawn in the same transaction; a program-visible thread opens (visibility = program, scope_type = handoff, pinned to the record) so people, not twins, resolve questions in the open; and the addressee’s twin, if active, runs twin_handoff to prepare (for QA: the check bound to the SOP version in force, filed as a proposal for QA to approve). Decline needs a reason. The board shows the card in the addressee persona’s column.

Complete or withdraw

The person who accepted marks it Complete when the work is in the record (handoff.complete). You can Withdraw a hand-off that is still sent (handoff.withdraw). Each route is scoped to its party: withdraw to the sender, accept and decline to the addressee or a current persona holder, complete to the acceptor.

Read what changed

The hand-off page (/p/<slug>/handoffs/[id]) shows the status chip, both parties, the linked record, the thread and the decision reason. Setup › Audit shows handoff.send, handoff.accept and handoff.complete with actor_kind = human; a twin-proposed hand-off additionally carries interrupt_id, twin_id and the two hashes on the handoff.send row.

Troubleshooting

SymptomCauseFix
409 handoff_existsa hand-off of the same kind to the same persona on the same record is already sent or acceptedopen the existing one; a different kind (for example data after review) is allowed
409 self_handoffyou would be the addresseeaddress another persona or person
Accept is missingyou are neither the named addressee nor a current holder of the addressed personaask the sender to re-address it
403 bound_user_only on the proposalyou opened a colleague’s twin proposalonly the bound person approves a twin’s proposal
No e-mail arrivedthe hand-off was addressed to a persona, not a personpersona-wide hand-offs are summarised in the daily digest

Source: PRODUCT-PLAN.md Part 7 sections 2 (hand-off duties), 4 (twin-to-twin requests are records) and 7.4; PRODUCT-CONTRACT.md sections 11.4 and 11.7; api/app/db/models/handoff.py (HANDOFF_KINDS, HANDOFF_STATUSES, HANDOFF_LIVE_INDEX); api/app/tools/catalogue.py (console.propose_handoff); api/app/services/audit_actions.py (handoff.*); api/scripts/designed-routes.json (/programs/{}/handoffs routes); web/lib/api/types.ts (HandoffCreate, HandoffDecision, HandoffOut); decisions/0023-handoffs-and-event-triggers.md

Last updated on