---
name: wolfpack-pi-task-delegation
description: Use when opening, selecting, delegating to, checking, or cleaning up a Wolfpack Pi subagent through the endpoint-owned agent task tools.
---

# wolfpack pi task delegation

use `wolfpack-tailnet-control` for session control. this skill covers endpoint-owned v2 task lifecycle, structured handoffs, and parent verification. The cutover package default uses the epoch-bound `volatile-v1` transport with the unchanged `pi-tasks/v2` task protocol. It requires a coordinated compatible Wolfpack server; an old server is refused, never silently adopted.

## choose one assignment mode

choose exactly one mode for the initial assignment:

- **full-startup mode:** spawn with the complete `--plan`, `--prompt-file`, or concise `--prompt`. do not call `agent_task_send` for that same work.
- **endpoint mode:** spawn without a startup plan or prompt, obtain the structured `taskEndpoint`, then put the complete assignment in one `agent_task_send.task`.

never combine a plan-driven spawn with a narrower endpoint task. prefer one cohesive implementation handoff per approved PR or phase; split only at a real approval, design, isolation, or blocker boundary—not per issue, commit, finding, or verification checkpoint. the remaining v2 workflow below describes endpoint mode.

## role model selection

Pi role models are explicit and configurable at spawn time:

```bash
IMPLEMENTER_MODEL="${WOLFPACK_IMPLEMENTER_MODEL:-openai-codex/gpt-5.6-terra}"
REVIEWER_MODEL="${WOLFPACK_REVIEWER_MODEL:-openai-codex/gpt-5.6-sol}"
```

Pass `--model "$IMPLEMENTER_MODEL"` when spawning the editing implementer and `--model "$REVIEWER_MODEL"` when spawning the read-only reviewer. an explicit user or project model choice overrides the environment/default. never infer role or model from the session name, and never omit the resolved model because the current parent default may differ.

## v2 requirements and addressing

- load this package's default extension in every participating Pi process and set `WOLFPACK_SESSION_NAME`. Set `WOLFPACK_PORT` only when the local Wolfpack control port differs from `18790`.
- address `agent_task_send` targets only as `to: { relay, id }`. For the default Wolfpack adapter, the relay is `wolfpack-pi-tasks-v2` and the ID is opaque.
- create an endpoint worker with opt-in readiness and no initial assignment prompt: `wolfpack agent spawn --project-dir /absolute/worktree --name <task-role> --model "$IMPLEMENTER_MODEL" --task-worker --readiness-timeout-ms 30000 --json` (or `"$REVIEWER_MODEL"` for review). Use the actual explicit project root. This Pi-only mode rejects prompts/plans and `--notify-parent`; do not start a blocking “wait for assignments” prompt. Put the complete instructions in `agent_task_send.task`.
- read the returned `taskEndpoint` after exact live session/root and relay registration readiness succeeds. For a selected existing session, inspect structured status by its stable ID. Do not derive endpoint IDs from session names, broker IDs, terminal labels, output, or prose. Registration proves neither provider/model readiness nor task execution.
- inspect typed creation errors before retrying: `TASK_WORKER_PREFLIGHT_FAILED` precedes creation; `TASK_WORKER_NOT_READY` retains `createdSession` and `cleanup`. An `unconfirmed` cleanup requires exact-ID inspection, not an assumption that the session is gone. Do not silently fall back to ordinary spawn if the installed Wolfpack lacks readiness support; report the capability gap.
- pass the returned endpoint without translation:

```json
{
  "to": { "relay": "wolfpack-pi-tasks-v2", "id": "target-opaque-endpoint-id" },
  "task": "implement the approved phase and run focused tests",
  "timeoutMs": 3600000
}
```

The default `agent_task_send` schema is exactly `to`, `task`, and optional `timeoutMs`. Unsupported fields are rejected rather than translated. use at least `3600000` milliseconds for coding assignments; timeout is a failure deadline, not a progress-poll interval.

## phase roles and handoffs

For a multi-step project phase, retain one persistent implementer and one persistent read-only reviewer. Give the implementer the whole approved phase, including required commit ordering and focused verification, rather than opening one task per issue or checkpoint. Reuse a healthy role session for corrections and follow-up review; a completed task finishes one assignment, not the underlying session. Do not rotate a healthy role session for routine corrections. Rotate only for phase completion, material context degradation, harness failure, or required specialist independence. Keep at most one active assignment per role unless the user explicitly approves parallel work.

A coordinator-capable agent may delegate further when the quality or throughput gain justifies it. For an endpoint assignment, the spawning coordinator owns task lifecycle: record the stable session ID, acknowledge its terminal task once, then deliberately retain the child or close it with `wolfpack kill <stable-session-id> --json` and verify that exact ID is absent from `wolfpack list --json`. Full-startup children have no endpoint task ID; use their explicit completion/block notification plus parent verification before the same retain-or-exact-ID-kill decision.

`PI_TASK_WORKER=1` sessions are leaf roles. Workers cannot call `agent_task_send`; workers cannot call `agent_task_cancel`; workers cannot call `agent_task_ack`. These coordinator-tool attempts are blocked with the stable reason `PI_TASK_WORKER_COORDINATION_FORBIDDEN`, not the pre-assignment reason. They may use `agent_task_message` only for the eligible incorporated assignment named by its input `taskId`. Generic role-orchestration guidance applies only to non-worker coordinators. Task workers must not create, rotate, or close Wolfpack sessions through shell or session-control tools.

After every verified and acknowledged terminal task, explicitly retain a parent-spawned session only when concrete follow-up is likely; otherwise close it through canonical Wolfpack session control. Workers never close their own sessions. terminal `send` is only for explicit human steering; it is not task state, completion evidence, or a substitute for `agent_task_message`.

## delegation lifecycle

| event | owner | command | session outcome |
| --- | --- | --- | --- |
| assignment completion | worker | `agent_task_done` | unchanged |
| task acknowledgment | parent | `agent_task_ack` | unchanged |
| role session retention | parent | `none` | retained for reuse |
| role session teardown | spawning coordinator | `wolfpack kill <stable-session-id> --json` | exact stable session id terminated |
| teardown verification | spawning coordinator | `wolfpack list --json` | exact stable session id absent |
| Pi exit | none | `/exit` or `/quit` | not Wolfpack teardown |

Assignment completion ends the assigned task, not the reusable role session. When no further reuse is likely, the coordinator that spawned the role—not the worker itself—must pass the exact stable session ID to `wolfpack kill <stable-session-id> --json`, then inspect `wolfpack list --json` and verify that ID is absent. Never use `wolfpack session send`, `/exit`, or `/quit` for cleanup: they are terminal interaction, not Wolfpack teardown. Do not guess lifecycle commands. Workers never close themselves.

## v2 workflow

1. create a role session through the readiness path above, or select an existing role by stable ID and verify its structured liveness, canonical project, Pi harness, and registered `taskEndpoint`. Never use terminal output as readiness evidence.
2. call `agent_task_send` with the opaque endpoint and concise instructions in `task`. The tool returns after relay acceptance only, not Pi insertion or model execution. If submission reports a retryable delivery error after local persistence, use the structured task ID from the error and inspect it rather than creating an unrelated replacement.
3. after `agent_task_send`, continue useful independent coordinator work. When none remains, yield the current turn and let structured task follow-up wake the parent; do not poll `agent_task_status` or `agent_task_inbox` merely to wait. Reserve those tools for concrete progress evidence or recovery, and call `agent_task_wait` only when the user explicitly asks to block.
4. while continuing work or asking for input, use `agent_task_message` for intermediate `question`, `answer`, or `information` flow within the active endpoint lifetime. Do not use rendered text, terminal output, or logs as lifecycle evidence.
5. assignees call exactly one final `agent_task_done` with the assigned task ID, terminal status, and concise completion or blocker summary, plus optional structured result, error, and artifact declarations. Intermediate messages remain allowed; do not send a separate terminal information message before `agent_task_done`. Report source modifications in `result.changedFiles`; artifacts are receiver-project-relative regular files for a parent to inspect, not changed-file lists: `{ "result": { "changedFiles": ["src/extension.ts"] }, "artifacts": [{ "path": "verification/task-2.md" }] }`. No prose completion afterward.
6. the parent independently verifies files, diff, tests, and artifacts. Then call `agent_task_ack({ taskId })` for that one terminal task and explicitly retain or close the spawned role session.

## v2 delivery and recovery

Wolfpack is a memory-only, content-blind relay; each Pi endpoint keeps active task state, event order, retries and receipts in RAM. There is no SQLite task database. Relay acceptance is not execution; receiver receipt is not durable persistence. Model-visible `pi-tasks-event` entries include the complete structured event in session history; task wakes use Pi's safe `deliverAs: "followUp"` queue. Non-waking receipts, parent ACKs and late-terminal facts are archived as `pi-tasks-event-record` custom entries, not replayed. History is for inspection, never reconstruction/replay or worker authorization after restart. A relay restart can lose even accepted mail; a Pi restart loses its active task state and starts a fresh endpoint.

The default extension automatically replaces its endpoint lifetime only after structured `RELAY_RESET` or `RELAY_REBIND_REQUIRED` evidence. It fences and discards old RAM state, records every active old-lifetime task in Pi session history as locally failed with `RELAY_STATE_LOST` and an explicitly unknown remote outcome, then binds a fresh empty endpoint. This local loss record is not a canonical remote terminal event and does not wake the model by itself. Historical tasks are never adopted or silently reassigned. Transient availability, authentication, capacity, abort, profile and malformed-response failures do not rotate the lifetime. Old database files are not read, migrated or deleted; no backward-compatible durable mode is supported.

Receiver terminal submission has one task-wide logical identity. Same-status retries reuse it; a conflicting terminal status fails closed. Canonical status remains origin-owned, while `terminalDelivery` separately exposes `not_submitted`, `pending`, `accepted`, or `delivery_blocked`. Parent acknowledgment is terminal-only and retries reuse one logical event and stable envelope identities.

Set `PI_TASK_WORKER=1` only for task-only workers. Before a valid structured assignment matches a locally owned active task, the worker gate allows only inbox/status/wait inspection and blocks other model tools with `PI_TASK_WORKER_ASSIGNMENT_REQUIRED`.

## do not

- do not use terminal output, rendered prompts, logs, or error prose as task state.
- do not ask workers to complete in prose or close their own sessions.
- do not steer or interrupt an active Pi turn with task context; use the adapter's follow-up queue.
- Do not copy plans, source contents, or transcripts into task context.
- do not derive or transform opaque endpoint IDs.
- do not promise JWT federation, artifact byte transfer, exactly-once model execution, or migration of historical tasks to successor endpoints.
