subagent-request-approval · git:20260922.794a6b2 · 2026-09-22 · sha256 6e00ec6288a33fdb
subagent-request-approval git:20260922.794a6b2A
Immutable. This exact content never changes and is served at /api/v1/blob/6e00ec6288a33fdb.
--- name: subagent-request-approval description: Use when a T3 command was blocked or a predictable ordered T3 set must be requested before execution --- # Request Approval — Producer Branch ## Plan-first set After read-only investigation, collect every predictable exact T3 command that forms one coherent bounded operation -- one command or several. Do not attempt the commands first, even a single one: request it proactively through the same verb. Run one CLI request, with one `--command` per atomic item in execution order: ``` gaia approvals request-set --command '<exact 0>' --command '<exact 1>' --rationale '<goal, risk>' --verification '<check to run after>' --rollback '<how to undo>' --agent-id <agent_id> [--session-id <session_id>] ``` A single predictable T3 command uses the identical verb with one `--command`. `--session-id` is optional, and the same rule governs `request-file-write`: pass it only when the dispatch handed you a session id; never invent one, and never guess one. Omitted, the row is born without an owner and the first host session that presents it adopts it, in the same write as the SHOWN event (`bin/cli/approvals.py::cmd_opencode_present`); from then on every other session is refused. A dispatched OpenCode agent has no way to learn its own session id -- the plugin exports nothing but `GAIA_DISPATCH_AGENT` into its shell -- so omitting the flag is the normal case there. A wrong value is worse than none: an approval owned by a session that will never present it cannot be presented by anyone, and dies pending with a single REQUESTED event. The CLI validates T3 eligibility, persists REQUESTED, and returns `status`, the canonical `approval_id`, and `command_set` with each command fingerprint. Relay those values inside `approval_request`; do not calculate an id or fingerprint. The order-sensitive `request_fingerprint` is persisted but not returned by this command; when it is needed, read the pending back with `gaia approvals list --json` and match the full canonical id. ## Blocked single command When the pre-execution policy gate returns `[T3_BLOCKED]`, stop. Copy the returned `approval_id` and sealed payload verbatim into `approval_request`. Do not retry, reword, split, wrap, or seek the same effect through another tool. ## Checkpoint and stop 1. Set `agent_state` to `APPROVAL_REQUEST`. 2. Put all exact consent data in `approval_request`, including full ordered set, risk, rollback, and verification when COMMAND_SET. 3. Add only the block/request outcome to evidence; do not duplicate payloads. 4. Set `pending_steps` to execution after consent and `next_action` to relay the request to the user. 5. Finalize the non-terminal contract and stop; the persisted row is the delivery. The producer does not present an approval as already granted and does not verify execution before it happens. `orchestrator-present-approval` selects the host modality and presents consent; `execution` owns post-grant execution. ## Grouping boundary Use a set only for exact commands already implied by the accepted plan, with one risk/rollback/verification narrative. Do not group unrelated effects, alternatives, speculative cleanup, or commands derived from earlier outputs. Consent grouping is not atomic execution. For continuation after a failed set, follow `command-execution` for the execution-time stop and `agent-protocol` for consumer reconciliation. This skill constructs the new exact request that reconciliation identifies.