# Testing

The project uses short feedback loops. Run the closest test after each module change, then run the complete check before moving to another lifecycle area.

## Automated checks

```bash
npm run typecheck
npm test
npm run check
```

The Node test runner executes TypeScript through `tsx`.

Current coverage includes:

- GoalSpec validation and approval, including legacy restoration with empty suggestions;
- pending user-action settlement;
- user and agent pause/resume safety reset, agent resume from every pause source, settled user-action precedence, and transcript warnings that expose network-failure pause reasons;
- pass/fail verification transitions and verifier-held lifecycle dispatch until settlement;
- branch-aware canonical state restore on startup and `/tree`, including empty status clearing, idle active restoration, unchanged refinement, and verification interruption pauses;
- XML-delimited, escaped initial-request kickoff wording and requirement-aligned refinement prompt boundaries, stated-requirement reuse, shared-context investigation, proportional questioning, conversation-independent GoalSpecs, and dependency-aware rounds;
- no-progress fingerprints;
- continuation single-flight, pending-message gating, and cancelled delivery interception;
- user edit precedence over worker submission;
- verifier user-action precedence;
- `/goal` parsing and completion, including direct `propose` activation;
- direct external Goal editor launching, invalid-JSON relaunch, compact/expanded `goal_propose` rendering, user-visible `goal_pause` reasons, `goal_resume` execution guidance, and four-line collapsed versus complete expanded `goal_submit` rendering;
- verifier-message projection that excludes worker-only Goal suggestions, state-dependent verification titles, tool-outcome backgrounds, rolling collapsed traces, complete expanded traces, settled details-only rendering, width-aware detail summaries, same-card completion rerendering, and display restoration;
- the verifier's exact `read`, `bash`, and `goal_verification_result` tool allowlist;
- real Pi resource-loader smoke loading of `src/index.ts`, `/goal`, all four tools, and the verifier entry renderer.

## Isolated Pi launch

Use Pi's explicit extension flag while disabling discovered extensions:

```bash
pi -ne -e ./src/index.ts --no-session
```

The useful manual sequence is:

1. Run `/goal status` and confirm the extension reports an empty Goal.
2. Run `/goal <small test goal>` and confirm the main agent refines without implementing: it treats requirements already stated as known, investigates durable shared context itself, and asks concise numbered questions only about material unspecified requirements.
3. Let the agent call `goal_propose` and confirm the panel opens only after settlement.
4. Press `Esc`; confirm the panel returns to chat and preserves the draft.
5. Reopen bare `/goal`; confirm there is no Cancel button.
6. Press `E`; confirm the configured external editor opens directly with the draft JSON and no inline JSON editor appears. Save valid JSON and exit; confirm the updated Control Panel returns. Repeat with invalid JSON and confirm an error appears before the external editor reopens with the edited content. Start and confirm active execution begins.
7. During execution run `/goal edit`; confirm the panel does not mutate until the agent settles.
8. Resume execution and let the worker call `goal_submit({ result })`; for a long result, confirm collapsed output is limited to four wrapped lines with an ellipsis and expansion shows the complete exact result. Confirm the verification card title cycles through the bracketed ASCII `[-]`, `[\]`, `[|]`, `[/]` spinner in subdued, non-bold text after bold **Verifying** over the pending-tool background while it runs, then stops animating at settlement. Collapsed output must directly tail the latest body-styled trace item; expanded output must show the complete bounded body-styled trace.
9. Confirm the same card title becomes **Verification pass**, **Verification fail**, or **Verification error** when the verifier settles. Pass must use the successful-tool background; fail/error must use the red failed-tool-call background. Collapsed output must show a width-aware, three-line `details` summary; expanded output must show complete `details`; neither settled view may retain the verifier trace.
10. Run `/goal cancel`; confirm cancellation works without any panel action.

A named tmux session is convenient for repeatable TUI inspection:

```bash
tmux new-session -s pi-goal-test 'cd /path/to/pi-goal && pi -ne -e ./src/index.ts --no-session'
tmux capture-pane -pt pi-goal-test
```

Stop the test session when finished:

```bash
tmux kill-session -t pi-goal-test
```

## Verifier testing

A full verifier test calls the configured model and can consume provider quota. Keep automated tests deterministic by testing runtime settlement with synthetic verifier outcomes. Use a small real workspace Goal for final integration testing.

A real verifier pass should show all of these properties:

- a fresh context with no worker transcript;
- the approved GoalSpec acceptance projection (`mainGoal`, `subtasks`, and `details`) and workspace path, with `suggestions` absent;
- exactly `read`, `bash`, and `goal_verification_result`;
- no `edit`, `write`, `grep`, `find`, `ls`, or Goal lifecycle tools;
- pass/fail applied only after the fresh session settles.

## Recorded live smoke

The initial implementation was exercised with Pi 0.84.1 using:

```bash
PI_OFFLINE=1 pi -ne -e ./src/index.ts --no-session
```

The initial implementation run covered an empty status, agent-assisted refinement, a structured `goal_propose`, automatic Control Panel opening after settlement, refining `Esc` returning to chat, panel reopening, Start, workspace edits and `npm run check`, a worker submission, a fresh independent verifier, a structured verifier pass, and final `complete` status.

After the submission/UI redesign, a second live run used a conversation-only two-sentence deliverable. It confirmed the centered overlay at normal terminal size, a bounded viewport and `1-14/22` → `9-22/22` PageDown movement after resizing to 100×20, keyboard Start, no above-editor widget, `Goal refining` → `Goal verifying #1` → `Goal complete #1`, exact `goal_submit.result` rendering in the main conversation, and a fresh verifier pass whose details explicitly assessed that same 33-word result.

A third live TUI run verified the proposal-display fixes and the former two-step popup editor flow. Collapsed `goal_propose` output showed only the proposed main goal plus a dim status note, and `Ctrl+O` expanded the same row to all subtasks and details. Current automated coverage additionally checks expanded worker-only suggestions and their exclusion from verifier input. The current implementation supersedes that popup flow: `E` launches the external editor directly, as covered by the automated UI contract tests and the manual sequence above.

A fourth live run verified the initial observable verifier card with a conversation-only deliverable. A fifth live run verified the refined card in a 100×28 terminal: the former fixed **Verifier** title and rolling latest-trace viewport appeared while collapsed and running; `Ctrl+O` exposed the complete request, thinking, tool call, and tool result trace; settlement rerendered the same card as **PASS** with a details summary; expanding it showed complete details and no trace. A sixth live run verified the former style: ANSI capture showed the title using the same white tool-title color as built-in calls and **PASS** using yellow emphasis; the running collapsed card rendered its latest trace as ordinary body text. The current animated, subdued, non-bold bracketed ASCII spinner after **Verifying**, the state-dependent **Verification pass/fail/error** titles, and pending/success/error tool-call backgrounds are covered by renderer tests. A seventh live run submitted a six-line checklist in a 90×26 terminal: collapsed `goal_submit` output showed four lines ending in `Test…`, and `Ctrl+O` restored all six lines through `Release` without changing verifier input. An eighth live run exercised the refinement prompt with `/goal Add a way to export Goal status`: the agent first inspected existing status commands, UI, state, and docs, then presented four numbered material unspecified requirements covering destination, format/content, intended use, and export-only versus import scope. It did not implement, repeat questions already answered by the request, or ask the user for discoverable repository facts. In-memory progress updates and the invisible final snapshot produced no duplicate status cards.

A ninth live tmux run exercised `/goal propose Reply with the exact text LIVE_PROPOSE_OK, then submit that exact text as the Goal result.` in an empty isolated workspace. The first agent-visible message was the execution kickoff; no refinement question or Control Panel appeared. The statusline advanced through `Goal verifying #1` to `Goal complete #1`, and the independent verifier passed the exact `LIVE_PROPOSE_OK` submission. Subsequent direct-activation coverage asserts the finalized contract that `subtasks`, `details`, and `suggestions` remain empty.

A later user-session investigation of the former popup flow found that the affected Pi process had resolved `$EDITOR` to `vim`, while `vim` was absent from its `PATH`; spawning the editor therefore failed immediately. A comparison process inherited `EDITOR=nvim` and launched it correctly. The direct editor flow retains the same configuration requirement and now reports launch or unsuccessful-exit failures before returning to the unchanged Control Panel.
