# Architecture

`@minhduydev/pi-subagents` is a runtime-only fork of `pi-task`. The package entrypoint (`src/task-runtime.ts`) wraps the in-repo task extension with a durable orchestration kernel; it does not bundle agent profiles.

## Layers

```text
Product surface
  task · task_control · slash commands · widget · skill · lifecycle/RPC

Durable task kernel
  runs · claims/heartbeats · contexts · evidence · review · schedules · journal

Runtime adapters
  Herdr agent backend · tmux backend · Pi SDK backend · Git worktree
```

## Sources of truth

1. Child Pi session JSONL: final assistant text and stop reason.
2. `runs.json`: current execution/verification/review state.
3. `events.jsonl`: append-only correctness/audit journal.
4. backend handle: current observable process/resource identity.

Herdr status and terminal snapshots are signals, never final-result authority.

## Completion ordering

```text
child settled
  → persist execution outcome
  → resolve canonical session
  → collect/normalize evidence
  → verify
  → compute review state
  → release lease
  → persist final run state
  → emit lifecycle event
  → send one individual or grouped parent notification
  → close only the owned backend resource
```

Background `task-complete` messages are intercepted before delivery, not audited after success has already reached the parent. Correctness events use durable idempotency keys, and terminal execution phases cannot be resurrected or rewritten.

Gate-authoritative evidence is runtime-bound: either the canonical Pi session or a typed artifact receipt containing runtime observation time, producer identity, claim binding, and SHA-256. Handoff/self-report evidence remains useful context but cannot satisfy a proof gate.

## Identity

- `invocationId`: generated by runtime; authority and ownership identity.
- `taskId`: canonical identity generated by task runtime after launch.
- `orchestration.id`: caller correlation label only.
- RPC `handle`: opaque recursive invocation ownership scope.
- Herdr identity: socket + parent pane + pane ID + terminal ID + agent/workspace/tab.

## Child mode

CLI children receive `PI_TASK_TOOL_DISABLED=1`. The wrapper calls the base extension, which exits before registration, and also skips the orchestration control plane. Child allowlists remove `task` and `task_control`. This avoids recursive managers, timers, RPC responders and self-authorized release/review operations.

## Isolation and claims

Claims serialize scheduling/merge ownership. They are not an OS sandbox. Parallel/sensitive writers use Git worktrees so changed paths can be attributed to one run. Worktree launch requires a clean source repository so uncommitted local edits cannot be silently omitted from the delegated base. Parent `edit`/`write` calls consult leases through Pi's global `tool_call` hook and reject project escapes through symlinks while leases are active. Isolated child shell policy remains the responsibility of normal Pi/tool/repository policy.

## Recovery

At `session_start`, non-terminal durable runs are reloaded into the runtime cache, schedules are reinstalled, and lease heartbeats resume. Allocating runs are conservatively rebound to a unique matching durable registry entry; terminal Pi JSONL discovered after a parent restart is reconciled before notifying the parent. The upstream task registry reconnects pane/session polling. Completion/release events use idempotency keys, and terminal run transitions are immutable.
