# pi-goal

Unattended goal orchestration for [pi](https://pi.dev). Give it a checkable
completion condition with `/goal` and walk away — it decomposes the goal into
reviewable tasks, works them in dependency-ordered waves, merges the results,
runs a cleanup sweep, and reviews the integrated whole against the original
goal until it reaches a clear terminal state: `achieved`, `unmet`, `halted`,
or `budget_limited`.

Each task is modeled as an [OpenSpec](openspec/) change, so it carries a spec
with acceptance criteria. Reviewers gate against the **real source of truth**
(running tests, reading files, checking specs) rather than judging the
transcript.

> **Status:** the orchestration engine (`src/`) is implemented and unit-tested.
> The pi extension that drives it unattended is wired up; a few command
> subcommands (`runs`, `resume`, `continue`) are still being connected.

## Install

```
pi install npm:@peeraponw/pi-goal
```

The extension loads automatically in every pi session. To try it without
installing, use a one-off run instead:

```
pi -e npm:@peeraponw/pi-goal
```

Requires [pi](https://pi.dev) (Node 22+).

## Quick start

Set a goal that carries checkable acceptance criteria:

```
/goal Add a file `hello.txt` at the repo root whose entire contents are the
single line `pong`. Acceptance: `[ -f hello.txt ] && [ "$(cat hello.txt)" = "pong" ]`
exits with status 0.
```

pi decomposes the goal, spawns worker and reviewer subagents per task in
isolated git worktrees, merges each wave, and reports the terminal verdict.
Progress is tailed under `goal-runs/<run-id>/`.

| Command | Action |
|---|---|
| `/goal <condition>` | **Set** the goal and start working. Replaces any active goal. |
| `/goal` | **Status** — condition, current wave, task progress, elapsed time, spend. |
| `/goal clear` | **Clear** the active goal (aliases: `stop`, `off`, `reset`, `none`, `cancel`). Records the run as `halted`. |
| `/goal resume` | Restart from the last persisted checkpoint. *(in progress)* |
| `/goal continue` | Resume after human intervention. *(in progress)* |
| `/goal runs` | Browse past runs and open a report. *(in progress)* |

Per-run overrides go anywhere in the invocation:

```
/goal --worker-model anthropic/claude-sonnet-4-5 --max-cost 2 \
      migrate src/api/users.ts to v2; npm test -- users exits 0
```

## How it works

The system is split into three layers that keep decisions testable and
transport-free:

- **Thin pi extension** (`.pi/extensions/goal.ts`) owns the `/goal` command,
  session-scoped state, the live status indicator, and resume. It hands each
  run to the engine.
- **Pure engine** (`src/`) makes every decision: config resolution, wave
  computation, the task state machine, budget enforcement, blast-radius
  excursion detection, merge-strategy selection, the debt ledger, and run
  reports. It has no dependency on pi and is fully unit-tested.
- **pi-subagents** performs each agent stage (planner, worker, reviewer,
  merger, goal-reviewer, refactor, arbiter).

The workflow per goal:

1. **Decompose** — one planner pass over the entire goal produces tasks (scope,
   checkable acceptance criteria, predicted blast radius, dependency edges).
   Waves are the topological levels of the dependency graph.
2. **Execute a wave** — tasks within a wave run in parallel, each in its own
   system-owned git worktree. Per task: worker → read-only reviewer → bounded
   rework, then `blocked` if still unresolved. Deferred findings accumulate in
   a run-level debt ledger.
3. **Merge the wave** — clean or disjoint blast radii fast-forward; generated
   files (lockfiles, build artifacts) are regenerated; other overlaps go to a
   merger pass, then a planner-as-arbiter, then human escalation.
4. **Refactor sweep** — one worker consumes the debt ledger (cleanup only).
5. **Goal review** — a whole-system reviewer gates the integrated result
   against the original goal. On `unmet`, recovery escalates: targeted re-plan
   → full re-plan → human.

A single task failing is isolated — it never aborts the goal; it is reported at
the end. Budget is checked at every wave, rework, and amendment boundary.

## Configuration

Sources, in ascending precedence (highest wins):

1. Global — `~/.pi/agent/goal.config.yaml`
2. Project — `.pi/goal.config.yaml`
3. CLI flags — on the `/goal` invocation

Models and scalar limits merge per-field, so a project file that sets only the
`worker` model keeps the global `planner`. See [`docs/goal.md`](docs/goal.md)
for the full schema, defaults, CLI flags, and resource-limit semantics
(per-role memory / CPU-time / task-count ceilings enforced at agent-launch
boundaries).

## Development

Prerequisites: Node.js 22+ and npm.

```bash
npm install                 # install dev dependencies
npm test                    # run the unit suite (252 tests)
npm run typecheck           # tsc --noEmit
npm run build:extension     # bundle the extension → dist/goal.extension.js
```

The unit suite is self-contained and never calls a model. The engine is pi-free,
so it is exercised with fake launchers in `src/**/*.test.ts`.

### End-to-end smoke test

`test/smoke.test.ts` spawns **real** child-pi subagents for every role against a
throwaway git repo, so it spends real model calls. It is skipped by default:

```bash
GOAL_SMOKE=1 npx vitest run test/smoke.test.ts
```

### Bundling

`build-extension.mjs` bundles `.pi/extensions/goal.ts` and the entire `src/`
engine into a single self-contained `dist/goal.extension.js` (the `yaml`
dependency is inlined; the only pi import is a type that is erased). That bundle
is what `pi install npm:@peeraponw/pi-goal` loads.

## Project layout

```
.pi/extensions/goal.ts   # thin pi extension: /goal command, state, status
src/                     # pure, pi-free orchestration engine (unit-tested)
  orchestrator.ts        #   end-to-end run: plan → waves → refactor → review
  planning/              #   planner contract, wave computation, amendments
  execution/             #   worker→reviewer loop, concurrency, debt ledger
  merge/                 #   adaptive merge, regeneration, arbiter, escalation
  refactor/              #   debt-ledger cleanup sweep
  review/                #   goal-level reviewer + recovery tiers
  config/                #   file/CLI config resolution and merging
  budget/                #   budget enforcement
  state/                 #   task state machine, checkpoints, terminal state
  trace/                 #   event stream, run report, status formatting
  runtime/               #   child-pi subagent launcher (the pi adapter)
  vcs/                   #   system-owned git worktree lifecycle
docs/goal.md             # full configuration reference and workflow detail
openspec/                # design docs, specs, and task breakdowns
test/                    # end-to-end / live integration tests (opt-in)
```

## Documentation

- [`docs/goal.md`](docs/goal.md) — full configuration reference, resource
  limits, CLI flags, and the workflow in detail.
- [`openspec/changes/`](openspec/changes/) — the design docs, specs, and
  validation findings that shaped the architecture.
- [pi documentation](https://pi.dev) — the coding agent this extends.

## License

MIT
