Skip to main content

Overview

The process manager surface centers on the handoff lifecycle. Use it to spawn a worker thread, run work synchronously or asynchronously, and manage progress/results.

Tool Name

Functions

  1. handoff - Start a visible or hidden spawned thread, optionally targeting another bot.
  2. handoff_status - Check current status for a handoff.
  3. handoff_send - Send follow-up guidance into an existing handoff thread.
  4. handoff_results - Retrieve final or intermediate results.
  5. handoff_cancel - Cancel in-progress handoff execution.
  6. handoff_list - List delegations that are still open.
  7. get_handoff_inputs - Pull parent-thread inputs in chained workflows.
  8. store_blueprint_outputs - Store outputs for downstream handoff consumers.
  9. mailbox_action - Send a message to another thread’s mailbox.

handoff

Use handoff(...) to create the worker thread. These are the customer-controlled parameters used to decide where the work runs, how visible it is, and how Genesis reports the spawned thread back to the caller. Successful calls return handoff_id, thread_id, status, and thread_link. Genesis creates and persists the spawned thread before returning thread_link, so the link is immediately durable and clickable in chat, tool activity, and the Artifacts drawer. When a watched handoff returns a child response, its result contains the child’s response text without runtime tool-announcement narration. Genesis uses that same text in the saved result and parent notification; a watch_expired response’s partial_result is filtered the same way. Example:

Typical Workflow

  1. Start work with handoff(...).
  2. If async, poll handoff_status(...).
  3. Send clarifications with handoff_send(...) when needed.
  4. Read outputs with handoff_results(...).
  5. Cancel with handoff_cancel(...) when the plan changes.

mailbox_action

Use mailbox_action(...) to send one message to another agent’s thread. A plain child created with handoff(..., on_completion="notify") uses this tool to report its final result, including when the work is blocked or failed. That report is the completion signal for the handoff; Genesis records the handoff as complete when the message is sent to the source thread. Messages are delivered automatically into the recipient’s conversation. When a report closes a delegation whose recipient is still mid-turn, a short notice is queued on that thread’s next tool result. The report itself remains in the recipient’s mailbox, so the recipient can call mailbox_action(action="READ_MAIL") immediately without ending the turn. The successful result’s note says whether this notice was queued or the message will wait for normal delivery. If the recipient is idle, or the queued wake cannot be accepted because the thread has reached its undelivered-wake limit, the report waits for the normal delivery path instead. The background delivery sweep is enabled by default, runs every 30 seconds, and only wakes threads when agent-slot capacity is available. A newly queued message brings the sweep forward for an eligible idle recipient instead of waiting for the next 30-second tick. A turn started by this wake-up acts as the thread’s recorded owner for downstream permission checks, including the owner’s email when it is recorded. If no owner is recorded, or the owner is the system default while authentication is enabled, the turn carries no user identity and permission checks can refuse the operation. Example:
The tool returns success, message_id, and to_thread_id. A successful message is queued for delivery; do not resend it just because the recipient has not replied yet. A sender-recipient pair is limited to 12 messages in a rolling 300-second window, and a single body is limited to 16,000 characters.

handoff_status

Check progress for a previously started handoff. For non-terminal records, Genesis recomputes live state from the child thread (active completion, blueprint_completed, and last-activity recency) instead of trusting a stale stored status. A plain delegation has no inferred completion from its message transcript: it remains live until the child sends its result to the source thread with mailbox_action. Blueprint handoffs complete when the blueprint sets blueprint_completed; their reconcile path can resume after a server restart. A stored watch_expired or legacy timeout therefore does not mean the child failed while it is still running. If a follow-up turn arrives before finalization, the handoff remains live until that turn is also answered. If a child thread no longer exists, the live state is child_missing and the handoff is retired with terminal status abandoned. A child that remains idle without reporting is reminded after 30 minutes of quiet, at most once per hour and three times total. A quiet handoff is abandoned after seven days when its quiet duration can be established; active work is not retired based on the handoff’s age alone. For status="stalled", inspect last_tool_call and tool_call_count before starting the work again. A stalled child may have completed useful work before it became idle; retrieve it with handoff_results(...) rather than assuming it failed.

handoff_list

List open delegations, oldest first. Use this to see what work is still outstanding, identify a stalled or missing child, or check whether a job is already in flight before dispatching more work. An empty list means no non-terminal handoffs remain. Each returned record includes handoff_id, stored status, recomputed live_state, age_days, child_thread_id, child_bot_id, parent_thread_id, blueprint_name, and nudges_sent. For one known handoff, use handoff_status(...); use handoff_results(...) to inspect its output and handoff_cancel(...) to stop tracking it. The call reads all retained handoff records, including closed records, before selecting the oldest open records; it then performs live-state checks only for the records returned. Ask once rather than polling it.

handoff_results

Retrieve whatever a handoff has produced, whether or not it is complete. A terminal handoff returns its stored result. Any other status returns partial=true plus the child’s latest response, stored blueprint outputs, cancellation or error details, and progress fields when available. This makes work recoverable after cancellation, a stalled child, or an expired watch window. Use handoff_status(...) for authoritative live state; do not re-dispatch based on status alone. The child’s latest response contains its answer text, not the runtime’s display announcements such as 🧰 Using tool: .... If the child produced only those announcements, the latest response is null rather than a successful-looking answer.

handoff_send

Queue follow-up guidance in an existing handoff thread. Queueing does not wait for or acknowledge child consumption. A successful response includes status="queued" and queued_to_live_child: true means the child was observed processing at submission time, while false means the message was queued to an idle child and may not be read. The response also includes child_state and, for an idle child, the progress fields from handoff_status. If the handoff is cancelled, error, or materialize_failed, the message is not submitted and the tool returns success=false, status="refused", and queued_to_live_child=false. Check handoff_status(...) and handoff_results(...) before re-dispatching because cancellation does not signal a child that was already running.

handoff_cancel

Stop tracking an in-progress handoff. This records the handoff as cancelled so it is no longer watched, reported, or reconciled; it does not send a cancellation signal to the child. A child already mid-task can continue and its side effects can still land. handoff_results(...) remains available for partial output, so inspect it before repeating the work.

get_handoff_inputs

Call from a child thread that was spawned by a blueprint handoff. Retrieves structured inputs the parent thread stored (for example migration_repo_id, source_connections, target_connection) so the child blueprint can start with the correct values. Returns inputs (keyed values), from_parent_thread, missing_inputs, and a hint for next steps. When the call runs with agent context (bot_id present), Genesis also persists retrieved values on the child thread as durable blueprint_inputs. When there is no agent context, inputs are still returned and held in the thread outputs cache for the current call, but the durable blueprint_inputs write is skipped.

store_blueprint_outputs

Call when completing a blueprint (typically before the final phase exit through @END) to store named output values (for example migration_repo_id) so get_handoff_inputs or BLUEPRINT_HANDOFF auto-extraction can supply them to a downstream blueprint. Returns success, stored_outputs, blueprint_name, message, and a contextual hint. The hint depends on how this thread was spawned:
  • When handoff_completion_mode is notify (the parent used on_completion="notify") or handoff_is_remediation is true (handoff context included remediation_repo_id), Genesis instructs the agent not to chain another blueprint from this thread. Stored outputs are delivered to the waiting parent automatically when this blueprint exits through @END.
  • Otherwise, the hint suggests calling handoff() to chain to the next blueprint with auto-extracted inputs.

Blueprint chain handoffs

When handoff(...) or BLUEPRINT_HANDOFF launches another blueprint, Genesis sets handoff_reason to blueprint_chain on the child thread, inherits blueprint_journey_context from the parent when present, and can create a dedicated child Mission project for the handoff thread. Mission Center uses this metadata to render the blueprint chain strip and to mark journey stages as spawned, expected, or skipped. When the parent or child thread stores a presenter-safe coding_agent blueprint input (ginie, cocoa, or claude_code), the chain API and Mission Center strip expose it as a compact coding-agent badge. When handoff(...) sets blueprint_name, Genesis seeds blueprint kickoff context on the spawned thread after materialization. Genesis activates project_manager_tools on that thread so the delegated agent can call _blueprint_tool during the blueprint. When the target agent uses allowlist tool policy and its tool_access_list omits project_manager_tools, Genesis elevates the agent’s durable tool_access_list to include that group so the kickoff tools survive the effective-state filter. When a blueprint-chain child produces its first stable response during a synchronous watch (async_mode=false or a bounded timeout_seconds), Genesis stamps the handoff record first_response — not completed — so handoff_status can keep live-recomputing while the mission runs. Parent on_completion="notify" and the [HANDOFF COMPLETE] message fire when the child blueprint reaches @END, not at first response.

Notes

  • Warnings for undeliverable handoff notifications repeat at most once per hour for the same reason, bot, and thread. A different failure condition is logged immediately; the mailbox sweep continues to log each failed delivery pass at INFO.
  • Use show_in_thread_list=false for internal sub-threads and background work that should stay out of the default sidebar list. When omitted, Genesis defaults it to true for visibility="visible" and false for visibility="hidden".
  • Use visibility="hidden" when the spawned thread should be hidden from normal UI surfaces, not only omitted from the default sidebar list.
  • For blueprint-backed spawned threads, continuous mode can be paused without losing the current phase. If an operator cancels continuous execution, or Genesis pauses the thread after detecting suspected replay growth, Genesis keeps the active phase on the child thread and switches it back to manual mode for human review.
  • handoff(...) refuses deactivated target agents (resolved by bot_id or display name). It returns success=false and an error such as Agent 'Adam' is deactivated and cannot receive handoffs. Reactivate it or choose an active agent. When materialization is blocked by lifecycle, status is materialize_failed.
  • If Genesis cannot create the child thread during the initial handoff, handoff(...) returns success=false, status="materialize_failed", and an error instead of a thread_link.
  • Use constrained allowed_tools for risky operations. The server refuses out-of-list calls, but the scope cannot grant tools the target does not already have and falls back to the target’s own tool set if the child’s thread state is unreadable.
  • Keep timeout_seconds explicit for synchronous waits; long blueprints often exceed the default 300 s watch window — that stamps watch_expired, not failure. Poll handoff_status (or rely on on_completion="notify") for the real outcome.
  • Blueprint-chain parents that delegate with on_completion="notify" resume automatically when the child mission completes — no manual poll required unless you need the stored result payload.