Outcome
A parent agent can say “hand this to the Risk Agent” and Runtime does the rest: a human approves the handoff, a new session starts on the Risk Agent’s template attributed to the Risk Agent, the prompt is forwarded, the reply comes back into the parent’s run, and the dashboard shows a “Delegated work to subagent” card linking to the child session. Every hop is graded against its own agent’s rubric.How it works
There is no “delegate” primitive in Runtime. Delegation is composed from four things you already have, and that is what makes it reproducible:RUNTM_API_URL and a session-scoped RUNTM_API_KEY that mirrors the launching user’s role, so a member’s session can create sessions. The create endpoint accepts agent_id directly; runtm-api session create has no --agent-id flag yet, which is why the script uses curl for that one call and the CLI for everything else.
Before you start
- Each subagent exists as a roster agent with a Default template that carries its own skill. Build and prove every subagent alone first (see Prove it works). A subagent’s skill must say it never runs
runtm-api session create|launch|prompt. - The parent has its own template. Its skill and context describe when to delegate and what to do with the reply.
- The team ids for approvers, if you gate by team. Org admins and owners can always resolve;
--required-team <id>narrows it. - Template ids and roster agent ids for every target:
runtm-api template list,runtm-api agents list.
Do it
Write the delegate script into a skill
delegate-to-agent with one script at scripts/delegate.sh. The table at the top maps a --target name to the child’s template id, roster agent id, and the approval kind the gate will use. Everything else is generic.0 ok, 2 bad arguments, 3 the subagent never reached running, 4 the template was not applied (nothing was prompted), 5 create or prompt failed, 6 the session could not be made team-visible.Write the SKILL.md so the agent always uses the two-line form
Add the gate hook to the parent's template
PreToolUse, Type command, matcher Bash, Timeout (sec) 600 (it must outlive the approval wait). The script maps each target to an approval kind and an approver team, denies a delegation command that lacks the attribution comment, remembers an approval for 10 minutes so an infrastructure retry does not re-ask, and gates any raw runtm-api session create|launch|prompt or direct call to the sessions API as agent_handoff for admins.Tell the parent when to delegate
Rebuild the parent template, then prove one hop
What the dashboard shows
The card is drawn from the Bash command text, not from any server-side link. Its parser matchesruntm-api session create|launch|prompt or scheduled-agents run-now in the command, reads --template-id and --agent-id (or TEMPLATE_ID= and AGENT_ID= assignments), takes the last # "Label" comment on the line with the id as the name hint, and picks the child session id from a subagent session: <uuid> line in the output. That is why the attribution comment uses the CLI’s syntax even though the script uses curl: the comment is for the parser, the curl is for the API.
Verify
runtm-api session get <child_id>showstemplateset,visibility: team, and telemetry attributed to the child agent (agents scorecardlists the child with a graded run).runtm-api session approvals list <parent_id>shows one approval per gate with the kind you expect andresolved_by.- The parent’s transcript ends with the child’s reply pasted into the parent’s own output format.
- A bare
delegate.shcall (no comment line) is denied with the prepend instruction and no approval row is created.
Gotchas
- An unknown template id creates a blank session instead of failing. The script checks
templateon the created session and destroys it if empty (exit 4). Keep that check. - The hook’s timeout must exceed the approval wait.
--timeout 540inside a hook withtimeout: 600. A shorter hook timeout kills the wait and the harness treats it as a failed hook. - Allow reasons never reach the model. Anything the agent must know after an approval (the approval id, who approved) has to travel through the marker file, which is why the script reads it and echoes
approval: .... - Approvals are resolved on the Sessions board or with the CLI, not in Slack. Scope
--required-teamto a team that is actually watching, or leave the admin fallback. - Children must not delegate. Put “never run
runtm-api session create|launch|prompt” in every subagent skill, or you get recursion with no gate. - The two-line command is one Bash call. If the agent runs the comment and the script as two separate tool calls, the hook sees a bare
delegate.shand denies it. The denial text says exactly what to prepend, so one retry fixes it. - Set the Bash tool timeout. A gate can hold the call for 9 minutes and the child’s prompt streams until it finishes; the runbook tells the agent to use a 600000 ms timeout.