# Pi Goal Mode Design

## 1. Design Goals

This project primarily references `references/narumitw-pi-goal/`. It extends that project's session-scoped state, agent loop, pause/resume, and continuation mechanisms with Goal refinement and an independent verifier. `references/misunders2d-pi-goal/` is used only to understand requirement alignment and independent acceptance; it is not a source for the code architecture or implementation.

The core flow is:

```text
User states the main goal
    ↓
Main agent discusses it with the user and refines it into verifiable subtasks
    ↓
User approves the Goal
    ↓
Main agent keeps working in the original session
    ↓
Main agent submits the final result through `goal_submit({ result })`
    ↓
The same result is shown to the user and independently evaluated by a fresh verifier
    ├─ Pass → complete
    └─ Fail → return the result to the main agent and continue the execution loop
```

Design priorities:

- The user and agent jointly determine the Goal before execution.
- Only the user can initiate Goal changes.
- The verifier and main agent use separate contexts.
- The verifier observes the workspace with tools and judges the current state against the approved Goal.
- The verifier receives exactly the same worker result shown to the user, without relying on worker-selected evidence or the rest of the conversation.
- The verifier reports success or failure through a result tool.
- Each session branch maintains one current Goal, with no Goal list, queue, or parallel scheduling.
- State transitions produced during a run are committed serially at settled boundaries. User actions take priority over agent intents and the next continuation.

## 2. Key Terms

### 2.1 Goal

A Goal is a user-approved specification that remains stable during execution:

```ts
interface GoalSpec {
  mainGoal: string;
  subtasks: string[];
  details: string[];
  suggestions: string[];
}
```

- `mainGoal`: the overall required outcome.
- `subtasks`: required outcomes that make up the main goal and can be verified independently.
- `details`: additional acceptance information needed to interpret and judge the Goal without repeating `mainGoal` or `subtasks`.
- `suggestions`: optional worker guidance that does not affect pass or fail.

The prompt requires every subtask to be specific, outcome-oriented, and verifiable, avoiding vague implementation steps. For example:

```text
Weaker: Implement a configuration parser
Better: The CLI reads the JSON file specified by --config and applies its configuration to the runtime result
```

The main agent uses the complete GoalSpec. The verifier receives only an acceptance projection containing `mainGoal`, `subtasks`, and `details`; it must not receive `suggestions`. The prompt defines each field's semantics and distinguishes acceptance information from worker guidance according to whether suggestions affect pass or fail.

### 2.2 Execution Plan

The main agent creates and adjusts its execution plan while working. The plan is not part of the Goal and is not provided to the verifier.

The Goal describes the state that must be achieved. The execution plan describes how the main agent intends to achieve it. This separation lets the user modify the target specification while the agent freely adjusts its implementation path.

### 2.3 Acceptance Judgment

The verifier does not redefine the acceptance criteria and does not need to generate, submit, or persist a verification plan. It receives the approved `mainGoal`, `subtasks`, and Goal details, then uses the available tools as instructed by the prompt to inspect the workspace and decide whether the current state meets those criteria.

During reasoning, the verifier naturally chooses the required reads, tests, or runtime operations. This is internal agent work and does not enter the Goal data model or extension protocol. The extension cares only about the success/failure verdict and conclusion details that the verifier ultimately submits through the result tool.

## 3. Goal Lifecycle

### 3.1 State Machine

```text
empty
  └─ user /goal <main goal> → refining

refining
  ├─ agent submits or updates a Goal draft → refining
  ├─ user selects Start → active
  ├─ user requests further changes → refining
  └─ user cancels → cancelled

active
  ├─ main agent calls goal_submit(result) → verifying
  ├─ user pauses → paused
  ├─ main agent calls goal_pause(reason) → paused
  ├─ Pi pauses automatically (reason) → paused
  ├─ user initiates an edit → refining
  └─ user cancels → cancelled

paused
  ├─ user resumes → active
  ├─ agent calls goal_resume() → active
  ├─ user initiates an edit → refining
  └─ user cancels → cancelled

verifying
  ├─ verifier passes → complete
  ├─ verifier fails → active
  ├─ verifier/Pi runtime failure (reason) → paused
  ├─ user pauses → paused
  ├─ user initiates an edit → refining
  └─ user cancels → cancelled
```

`complete` and `cancelled` are terminal states. `paused` preserves the Goal and existing progress. The user can restore it with `/goal resume`, or the agent can restore it by calling `goal_resume()` in a later turn.

The diagram shows the final outcomes of transitions. While the main agent or verifier is running, user commands and agent tools only record transition intents; they do not immediately change state. When the current run reaches a settled boundary, the controller processes user intents first, agent/verifier intents second, and only then permits the next continuation. A settled boundary means that the current agent run has reached the `agent_settled` dispatch or that the fresh verifier session is fully settled. It does not mean that the entire automatic Goal loop has ended. If that dispatch starts a fresh verifier, the extension handler continues waiting until the verifier fully settles, so the main session does not publish the successful run's final `agent_settled` event during acceptance.

### 3.2 State Semantics

- `refining`: the user and agent are discussing a Goal draft or waiting for user approval.
- `active`: the main agent is running the automatic loop.
- `paused`: the user, agent, or Pi has stopped automatic execution; agent- and Pi-triggered pauses must record and display a reason.
- `verifying`: the main agent has submitted the user-visible final result, the main loop is stopped, and a fresh verifier is evaluating it. This evaluation remains part of the current Goal run's execution phase.
- `complete`: the verifier has confirmed that the main goal and every subtask are complete.

## 4. Creating a Goal

### 4.1 User States the Main Goal

The user enters:

```text
/goal <main goal>
```

This text is the initial request awaiting refinement. After escaping XML text characters, the extension wraps it in `<initial_request>...</initial_request>`, sends it to the main agent, and describes it as the refinement starting input. The state enters `refining`; long-running execution does not begin immediately.

The user can also enter `/goal propose <main goal>`. This form skips agent refinement and Control Panel confirmation. It sets the input text as the main goal, leaves `subtasks`, `details`, and `suggestions` empty, persists the Goal directly as `active`, and immediately sends the execution kickoff. Creation is still rejected when a non-terminal Goal already exists.

### 4.2 Agent and User Refine Together

In the current conversation, the main agent performs refinement driven by material uncertainty and proportional to Goal risk:

1. Align with the user's actual needs and treat requirements already stated by the user as known information.
2. Independently investigate the workspace, applicable skills, documentation, `AGENTS.md`, and shared context discoverable through tools.
3. Ask only about material requirements that the user has not specified and shared context cannot answer. A requirement is material when different answers would substantially change the deliverable, scope, behavior, or completion judgment.
4. Organize questions into one concise numbered round. Ask another round only when earlier answers reveal new material uncertainty.
5. Do not silently choose an interpretation that would create a material difference. Low-risk matters that are clear from context may be inferred.
6. Produce a complete GoalSpec that remains understandable outside the conversation and does not refer to historical concepts such as “above” or “the option we discussed.” The GoalSpec may rely on durable shared context such as applicable skills, workspace documentation, and `AGENTS.md`.
7. Submit the complete Goal draft when the remaining uncertainty can no longer materially change execution or acceptance.

The prompt requires each subtask to support an independent completion judgment. The agent may use workspace tools to understand the project. The extension does not create a setup-stage tool permission system. Before Goal approval, the agent focuses on investigation and discussion and does not implement the task early.

### 4.3 Confirmation in the Control Panel

After the agent calls `goal_propose`, the tool handler only records the complete draft. Once the current refinement run settles, the controller writes the draft to `draft`. When a new draft is first created or updated, Pi automatically opens the Goal Control Panel once at an idle boundary with no pending message.

`goal_propose` uses custom tool rendering. The collapsed view highlights only the proposed main goal; the expanded view shows the main goal, all subtasks, details, and worker-only suggestions. The fixed “recorded; review after settlement” message is only dim helper text at the end and does not replace the Goal content.

The panel shows:

```text
Main goal
Subtasks
Details
```

The user then selects:

- `Start`: fix the Goal and transition from `refining` to `active`.
- `Edit`: open the GoalSpec JSON directly in Pi's configured external editor; save it and return to the updated review popup when the editor exits successfully with valid JSON.
- `Refine with agent`: remain in `refining`, close the panel, and return to the current conversation for further discussion.

Draft review has no Cancel control or separate Close control. Pressing `Esc` performs exactly the same action as `Refine with agent`: preserve the draft and `refining` state, exit the panel, and return focus to the main agent chat. The entire Goal can be cancelled only by explicitly running `/goal cancel`.

TUI refinement does not provide an inline JSON editor. `Edit` pauses the TUI and starts an external editor according to this priority: `externalEditor`, `$VISUAL`, `$EDITOR`, then Pi's platform default. The command must identify a program executable by the current Pi process. After a successful editor exit, the extension reads and validates the JSON. Valid content updates the draft and returns to the Control Panel. Invalid content displays an error and reopens the external editor with the current content. A launch failure or nonzero exit preserves the original draft, reports the failure, and returns to the Control Panel. Non-TUI interfaces continue using Pi's extension editor dialog as a compatibility path.

Draft creation and waiting for the user to select Start both belong to `refining`; no separate state is added. The agent can propose a draft, while the user retains the final decision. An unapproved draft cannot drive automatic execution. After returning to chat, the user can reconstruct and re-enter the panel with bare `/goal`. The same draft submission is not automatically reopened merely because a later `agent_settled` event occurs.

### 4.4 Unified Goal Control Panel

Bare `/goal` is the fixed entry point to the Control Panel. Depending on current state, the panel displays:

- lifecycle status, including a discussing or draft-ready description in `refining`;
- the current draft or approved Goal's main goal, subtasks, details, and worker-only suggestions;
- agent running/idle state, settled execution rounds, and automatic-turn information;
- a pending user action and its waiting state;
- pause source/reason, the current submitted result, verification attempts, and latest verifier details;
- state-appropriate Start, Edit, Refine, Pause, and Resume controls.

The Control Panel never provides a Cancel control. The entire Goal can be cancelled only with `/goal cancel`. During `refining` draft review, `Esc` is equivalent to Refine and returns to the main-agent conversation. In other states, `Esc` only closes the read-only or management panel and does not change Goal state.

There is no authoritative per-subtask progress during execution. The panel therefore shows only subtask text and does not infer completion marks from the main agent's narrative. All criteria can be shown as passed only after a verifier pass.

In `active` and `verifying`, the GoalSpec in the panel is read-only and no Edit control is available. The user can request changes only through explicit `/goal edit`. In `refining`, the draft can be edited directly. In `paused`, no owner is running, so the panel may also enter the edit/refine flow. State controls such as Pause must enter the same serialized transition dispatcher as the equivalent command even when triggered from the panel; UI callbacks must not rewrite state directly.

The Control Panel uses a centered `ctx.ui.custom(..., { overlay: true })` popup. Its content area has a fixed viewport, supports `↑`/`↓` line scrolling and `PageUp`/`PageDown` paging, and places Start, Edit, Refine, Pause, and Resume shortcuts in a fixed footer to avoid conflicts with scrolling keys.

Exiting the panel does not change Goal data. The extension keeps no Goal widget above the input box and uses only a short status line: `Goal <status>`. Once at least one worker execution round has settled, it appends `#N`. The status line does not show pending actions or other details.

## 5. Pausing and Resuming a Goal

Every case that stops automatic execution while preserving the Goal enters `paused`. The pause source is recorded as `user`, `agent`, or `pi`. On every transition to `paused`, the extension appends a prominent warning to the transcript: agent and Pi pauses show `Goal paused — <reason>`, while user pauses show `Goal paused by user.`. This message supplements the status line and makes the paused state and reason immediately visible after run errors such as exhausted network retries.

### 5.1 User Pause

The user requests a pause with `/goal pause`. If no goal-owned run is active, the controller enters `paused` immediately. If the main agent or verifier is running:

1. Persist `pendingUserAction: pause`.
2. Keep the current state and allow the run to reach its settled boundary.
3. Prevent a new continuation or verifier from starting at that boundary.
4. Preserve the Goal and existing workspace progress, then enter `paused`.

A user-initiated pause does not require a reason. The Control Panel's Pause control reuses the same flow. To stop a long-running turn early, the user can use Pi's interrupt; the state transition is still committed at the next settled boundary.

### 5.2 Agent Pause

The main agent can call `goal_pause({ reason })`. The `reason` must specifically explain why work cannot continue and is shown to the user. Appropriate cases include:

- user credentials or a decision are required;
- a required external service is unavailable;
- external action is still required after multiple attempts;
- Goal requirements conflict and the user must edit the Goal.

The tool handler only records the pause intent and ends the current tool batch. After the current agent run settles, the controller enters `paused` and stops the automatic loop unless a higher-priority user action exists. The agent should continue working through ordinary difficulty, a single command failure, or whenever another viable path remains.

### 5.3 Automatic Pi Pause

Pi pauses the Goal for hard runtime problems or safety boundaries, including:

- exhausted provider/network retries;
- provider quota or authentication problems;
- unrecoverable compaction/retry failures;
- required tool failures;
- automatic-turn or no-progress safety limits.

Retryable errors first use Pi's existing retry mechanism. Once recovery is impossible, Pi enters `paused` after the relevant run settles and records and displays the reason.

### 5.4 Resume

When the user runs `/goal resume`, the Goal has no active owner and can resume immediately. When an agent can continue any `paused` Goal, it should call `goal_resume()` regardless of whether the pause came from the user, agent, or Pi. The tool records a transient resume intent and resumes after the calling agent turn reaches its settled boundary. A pending user action still takes priority.

Both resume entry points perform the same transition:

- preserve the original Goal and workspace progress;
- clear the pause reason;
- reset automatic-execution safety counters for this run;
- restore `active` and the normal agent loop.

`goal_resume()` does not wake an agent in the paused state. It can only be called from a later agent turn that has already started; automatic continuation restarts after the call is committed.

## 6. Editing a Goal

### 6.1 Only the User Can Initiate Edits

The main agent cannot independently change:

- `mainGoal`;
- subtasks;
- details;
- suggestions.

If the agent finds the Goal unreasonable, contradictory, or impossible, it can explain the problem, suggest an edit, and pause with a reason while waiting for the user. It cannot lower the criteria to make the task easier to pass.

### 6.2 Edit Flow

In `active` and `verifying`, only `/goal edit` can initiate an edit; the Control Panel provides no direct edit entry point. If the current run has not settled:

1. Persist `pendingUserAction: edit` without changing GoalSpec or status yet.
2. Let the current worker or verifier continue to the settled boundary.
3. At that boundary, discard any uncommitted continuation, submission, or verification intent.
4. Enter `refining`.
5. Copy the currently approved Goal into a new draft.
6. Open the Control Panel edit flow or return to the conversation to discuss changes with the agent.
7. Have the agent submit a complete new Goal draft.
8. Enter `active` after the user selects Start again.

If no owner is running when `/goal edit` is called, this transition can occur immediately. `paused` and `refining` have no automatic-execution owner, so users can also enter the same edit/refine flow from the Control Panel.

GoalState does not maintain a revision number. Historical GoalSpecs remain available in the branch's ordered session custom entries; execution and acceptance use only the currently approved GoalSpec.

Ordinary user guidance does not silently modify the Goal. Changes to acceptance content require the explicit edit/refine flow.

## 7. Goal Completion and Independent Acceptance

### 7.1 Main Agent Declares Completion

The main agent decides when to call:

```ts
goal_submit({ result: string })
```

The call means:

> This is the complete final result for the current Goal. Show it to the user unchanged and begin independent acceptance.

`result` is the only parameter and must contain the worker's complete user-facing deliverable. The tool result content preserves the string unchanged. Its renderer supports collapsed and expanded views: the collapsed view wraps at the current width, shows up to four lines, and adds an ellipsis to the final line when truncated; the expanded view shows the complete result. This display-only truncation does not modify the string persisted by the runtime or sent to the verifier. Separate “user” and “verifier” versions are forbidden. This gives the verifier an acceptance object even for tasks whose deliverable is an answer, analysis, report, or other content supplied directly in the conversation.

The call does not immediately change Goal status. The tool handler accepts it only from the current `active` goal-owned run, records a submission intent, and ends the current tool batch. When the main agent reaches settled dispatch, the controller processes pending user actions first. It transitions from `active` to `verifying` and starts the verifier only if there is no user edit, pause, or cancel request. The dispatch waits for the verifier to settle fully. A pass then ends the successful run; a failure first returns the acceptance details to the main agent and resumes execution.

### 7.2 Fresh Verifier Independence

Every acceptance attempt creates a new in-memory verifier session that:

- does not inherit the main-agent conversation;
- does not inherit the main agent's execution plan;
- receives exactly the same `goal_submit.result` shown to the user;
- does not receive worker-selected evidence;
- does not receive the main agent's self-assessment of subtasks;
- does not inherit the previous verifier's context or conclusion.

The verifier's initial context contains only:

1. verifier role and behavior instructions;
2. the approved Goal's acceptance projection, including the main goal, subtasks, and Goal details while explicitly excluding suggestions;
3. the unchanged, persisted, user-visible submitted result;
4. objective runtime information such as the workspace location.

The submitted result is deliverable data to evaluate, not verifier instructions, and it does not automatically prove its claims. The verifier should determine whether the result itself satisfies the Goal and independently confirm objective claims with workspace tools.

The verifier can independently read project documentation, code, tests, Git state, and other workspace facts.

### 7.3 Verifier Tools

Following Pi's minimal-tool philosophy, the fresh verifier enables only the built-in `read` and `bash` tools plus the verifier-specific `goal_verification_result`. `read` provides direct file access. `bash` already covers command execution, search, directory traversal, tests, builds, services, temporary probes, and browser, network, or project-specific CLIs available in the workspace. Separate `edit`, `write`, `grep`, `find`, or `ls` wrappers are therefore unnecessary. The MVP does not load other extension-owned tools because loading their factories would also inherit lifecycle hooks and break the isolation boundary that prevents the verifier from inheriting the main extension context.

This allowlist simplifies the product surface and context; it is not a security sandbox because `bash` can modify files. The verifier prompt continues to require investigation and acceptance only, with no implementation, repair, or target-state changes.

Restricting built-in tools does not create a reliable write boundary because `bash` can create, modify, and delete files. The project therefore uses prompt-level behavioral constraints:

- investigate and verify only;
- do not implement missing functionality;
- do not repair discovered problems;
- do not change product code, tests, or external target state to obtain a pass;
- tests, builds, service runs, and temporary probes are allowed;
- unavoidable caches, build artifacts, or temporary files from testing are allowed;
- when verification requires a destructive action or external write, do not perform it and explain the unconfirmed portion in failure details.

This is a behavioral constraint, not a security sandbox. It prevents the verifier from also acting as implementer, but cannot stop a malicious model from deliberately modifying the workspace through `bash`.

Goal lifecycle tools are not operational capabilities. The verifier returns its conclusion through a dedicated terminal result tool and does not participate in controlling the main Goal's pause, edit, or completion state.

### 7.4 Verifier Requirements

The verifier prompt specifies only responsibilities and the termination protocol:

1. Judge whether the submitted result and related workspace state satisfy the main goal and every verifiable subtask in the complete Goal.
2. Use any available tools as needed to gather sufficient facts.
3. Investigate and evaluate only; do not modify or repair the task result.
4. If completion cannot be confirmed, fail and explain why in `details`.
5. Always call the result tool at the end. Ordinary assistant text, natural language containing `complete`, or the session's final reply cannot change Goal state.

The extension does not require the verifier to output a verification plan first and defines no verification-plan, per-item evidence, or observation protocol.

### 7.5 Result Tool

The verifier ends acceptance through a dedicated tool:

```ts
goal_verification_result({
  result: "pass" | "fail",
  details: string,
})
```

- `result` is the sole success/failure signal.
- `details` explains the verifier's conclusion; on failure it must explain what failed or could not be confirmed.
- The tool handler captures structured arguments as a verifier result intent and terminates the verifier run.
- The runtime does not parse assistant prose or check whether returned text contains `complete`.
- The tool handler must reject empty `details`, duplicate calls, and calls from outside the current verifier run.
- After the verifier session settles, the controller processes pending user actions before deciding whether to commit the result intent.

The runtime handles only protocol correctness and serialized state transitions. The independent verifier judges Goal compliance from the prompt, Goal, and tool observations.

### 7.6 Acceptance UI

When the controller starts a fresh verifier, it appends a TUI-only `goal-verification-ui-v1` custom entry to the main session transcript as a stable display anchor. The entry uses a custom renderer similar to a tool result:

- The card uses built-in tool-call title and outcome background styles. While acceptance is running, a bracketed ASCII spinner (`[-]`, `[\]`, `[|]`, `[/]`) appears as a dim, non-bold suffix to the bold `Verifying` title over `toolPendingBg`. The spinner stops when acceptance settles or the session shuts down.
- While acceptance is running, the collapsed view directly displays the latest trace in a scrolling viewport of up to four lines.
- While acceptance is running, the expanded view displays the complete bounded verifier trace, including the request, finalized thinking/assistant content, tool calls, and tool results. All trace labels and body text use the ordinary `toolOutput` body style; labels such as `bash` and `read` are neither blue nor bold.
- After the verifier settles, the same anchor rerenders with the title `Verification pass`, `Verification fail`, or `Verification error`. A pass uses `toolSuccessBg`; failure/error uses the same red `toolErrorBg` as a failed tool call.
- The collapsed settled view shows a `details` summary wrapped to the current width and limited to three lines, with excess text truncated by an ellipsis. The expanded view shows the complete `details` or runtime error reason. Neither view shows verifier traces after completion.

Pi session entries are append-only. The UI uses the first start entry as a dynamic renderer anchor. Finalized interactions during the run update an in-memory projection and refresh the anchor through a status-line render request without appending duplicate transcript lines. On settlement, an invisible final snapshot stores the bounded transcript and details. Session restoration reconstructs the anchor projection from the current branch's start/final entries. At most 80 interactions are retained, with at most 8,000 characters per text item, to prevent unbounded verification output.

Each verifier display operation uses an internal `operationId` in its observational entry. This prevents a historical card and current card from incorrectly sharing a projection when different Goals both begin at verification attempt #1. It is not a Goal/run identity and does not enter GoalState, prompts, tool parameters, the status line, or the Control Panel.

These entries exist only for user observation and display restoration. They do not enter LLM context, do not belong to GoalState, and do not affect settled ordering for pass/fail. The main controller still accepts only `goal_verification_result` as an acceptance conclusion.

### 7.7 Acceptance Passes

After the verifier session settles, if a valid pass intent exists and no user action is pending:

- state enters `complete`;
- all Goal continuations stop;
- a concise acceptance report is persisted;
- the verifier's `details` are shown to the user;
- the Goal lifecycle ends.

### 7.8 Acceptance Fails

After the verifier session settles, if a valid fail intent exists and no user action is pending:

1. Persist the acceptance report.
2. Return state from `verifying` to `active`.
3. Send the verifier's failure result to the main agent as a follow-up.
4. Let the main agent continue repairs through the same agent loop used during normal execution.
5. When the main agent again considers the Goal complete, call `goal_submit({ result })` again.
6. Create another fresh verifier that begins independently from the Goal and current workspace.

If the user requests edit, pause, or cancel while the verifier is running, that user action takes priority after the verifier settles and the current result intent does not drive a state transition.

A new verifier does not read the previous acceptance report. The prior report guides the main agent and explains the outcome to the user; it does not anchor the next verifier.

If acceptance failure exposes a problem in the Goal itself, the main agent cannot edit the Goal. It should pause through `goal_pause({ reason })` and wait for the user to initiate an edit.

### 7.9 Verifier Runtime Failure

A model, network, tool, or verifier-session failure is not a Goal acceptance failure. After the verifier session settles, if no user action is pending:

- no pass/fail is produced;
- the Goal and work state are preserved;
- Pi sets state to `paused` and displays the reason;
- after the environment recovers, the user runs `/goal resume` to start a fresh verifier again or return to active and resubmit.

## 8. Main Agent Loop and Serialized Transitions

After the Goal enters `active`, the main agent keeps working in the original Pi session:

1. Each `before_agent_start` injects the currently approved Goal and continuous-execution rules.
2. The agent implements the task using its own plan.
3. `goal_submit` and `goal_pause` only record terminal intents, while `goal_resume` only records a resume intent; tool handlers do not transition state directly.
4. `/goal edit`, `/goal pause`, and `/goal cancel` received during a run only record pending user actions.
5. `agent_end` records a continuation intent without sending it immediately.
6. `agent_settled` is the only main-run transition commit boundary.
7. The controller processes pending user actions first, then agent proposal, pause, resume, submission, or Pi-pause intents, and considers continuation last.
8. It sends one continuation only while the Goal remains `active`, Pi is idle, and no message is pending.

User actions always take priority. Once Cancel, Edit, or Pause is recorded, settlement of the current round starts no verifier and sends no next continuation. Tool results, UI callbacks, and asynchronous message-delivery callbacks cannot bypass the controller to write Goal status directly.

If a command arrives with no running owner, the controller may treat the current idle state as a settled boundary and commit immediately. Fresh verifiers follow the same serialization rule: the result tool records only a verdict, pass/fail is committed only after the verifier session settles, and user actions recorded in the meantime take priority.

The design adopts `narumitw-pi-goal`'s intent → settled-dispatch pattern to prevent transitions and continuations from interleaving with retries, compaction, steering, or follow-ups. After an acceptance failure returns to `active`, the same loop continues; no separate recovery state machine is created.

## 9. One Current Goal and Persistence

Each Pi session branch maintains at most one current non-terminal Goal. The MVP provides no Goal list, queue, parallel active Goals, or command to select a Goal by identifier. When a current Goal exists, a new `/goal <main goal>` should tell the user to edit or first cancel the current Goal. Related work should be expressed as subtasks; unrelated parallel work should use separate Pi sessions.

Goal state is stored only in Pi session custom entries. Restoration reads the final canonical state on the current branch. After `/tree` navigation, the controller cleans up transient owners from the old branch and reconstructs canonical state and verifier display from the new branch. `refining` is restored unchanged. `active` waits for the user's next message and resumes automatic continuation only after that round settles. `verifying` is persisted as Pi `paused`, and any leftover verifier card is marked interrupted. A branch from before Goal creation clears the status line. Tree restoration neither writes old-branch in-memory state to the new leaf nor automatically starts a worker or verifier.

```ts
interface GoalState {
  version: 1;
  status: GoalStatus;
  draft?: GoalSpec;
  approved?: GoalSpec;
  pause?:
    | { source: "user" }
    | { source: "agent" | "pi"; reason: string };
  pendingUserAction?: {
    kind: "edit" | "pause" | "cancel";
    requestedAt: number;
  };
  iteration: number;
  automaticTurns: number;
  noProgressTurns: number;
  lastAutomaticOutputFingerprint?: string;
  verificationAttempts: number;
  submissionResult?: string;
  lastVerification?: {
    result: "pass" | "fail";
    details: string;
  };
  createdAt: number;
  updatedAt: number;
}
```

GoalState has no revision. `iteration` counts settled worker execution rounds; the status line shows it as `#N` only when greater than zero. `submissionResult` preserves the exact result shown to the user and given to the current verifier, allowing `verifying` to restore the same content after reload. Every `verifying` state must contain `submissionResult`; loading rejects entries that violate this invariant. `lastAutomaticOutputFingerprint` stores only a SHA-256 hash of normalized assistant-visible text to continue no-progress detection across reloads; it is not a Goal or run identity. Once a user command is acknowledged, `pendingUserAction` is persisted. On session restoration, the controller must commit that action before deciding whether to restore the worker or verifier.

Agent and verifier intents belong to the current run that produced them and are consumed only by its corresponding settled callback. Session shutdown, replacement, or extension reload stops unfinished callbacks through `AbortSignal`, controller disposal, and object ownership. These are general asynchronous resource-management mechanisms and do not enter Goal state, prompts, tool parameters, or the Control Panel.

In addition to canonical `goal-state-v1` entries, the extension stores observational `goal-verification-ui-v1` entries to reconstruct user-visible verifier cards. They do not participate in Goal-state restoration or LLM context. The MVP creates no disk mirror, evidence database, general event journal, Goal queue, phase DAG, or authority state.

## 10. User Commands and Agent Tools

### 10.1 User Commands

```text
/goal <main goal>          # Create a Goal and enter discussion/refinement
/goal                      # Open the unified Goal Control Panel
/goal propose <main goal>  # Skip refinement and confirmation; approve and execute directly
/goal status               # Print a non-interactive status summary
/goal pause
/goal resume
/goal edit
/goal cancel
```

While the main agent or verifier is running, `pause`, `edit`, and `cancel` only record a pending user action and commit it at the corresponding settled boundary. `/goal edit` is the only way to modify GoalSpec in `active` and `verifying`. Bare `/goal` can inspect these states but cannot edit them directly in the panel. `/goal cancel` is the only user entry point for cancelling the entire Goal; the Control Panel has no equivalent button.

### 10.2 Main-Agent Tools

```text
goal_propose
  - Available only in refining
  - Arguments contain mainGoal, subtasks, details, and suggestions
  - Records a complete Goal draft, committed after the refinement run settles

goal_submit
  - Available only in an active goal-owned run
  - Its only argument, `result`, is the complete final result shown to the user and given to the verifier
  - Records a submission intent without changing status directly

goal_pause
  - Available only in an active goal-owned run
  - Requires reason and records a pause intent

goal_resume
  - Available only while paused, regardless of pause source
  - Takes no arguments and records a resume intent when the Goal can continue
  - Restores active and automatic continuation after the current agent turn settles; does not wake the agent directly
```

These tools accept no Goal identity or run-generation parameters. The runtime records intents in the corresponding state and commits them at settled boundaries. Proposal, submission, and pause still must match the current serialized Goal run. The agent has no tool for editing an approved Goal; only a user command can open editing.

### 10.3 Verifier Result Tool

```text
goal_verification_result
  - Available only to the current fresh verifier session
  - Arguments are result: "pass" | "fail" and details: string
  - Records a result intent; details preserves and carries the acceptance conclusion
  - Terminates the verifier session after the call; state transitions after the verifier settles
```

## 11. Implementation Foundation and Reference Boundaries

### 11.1 Extend `narumitw-pi-goal`

The implementation uses the code and lifecycle of `references/narumitw-pi-goal/` as its baseline, retaining the problems it already solves:

- session-scoped state;
- active/pause/resume;
- run ownership and interruption cleanup;
- compaction/reload restoration;
- settled-boundary continuation;
- provider-error and safety-limit handling;
- simple terminal tools.

The project adds:

1. a discussion and refinement phase after `/goal` starts;
2. user confirmation of the main goal and verifiable subtasks;
3. a unified Goal Control Panel;
4. user-only Goal editing and renewed refinement;
5. a serialized settled-boundary transition dispatcher;
6. `goal_submit({ result })` recording a user-visible submission intent;
7. a fresh verifier with `read`, `bash`, and a dedicated result tool;
8. the verifier result tool recording a pass/fail intent;
9. return to the existing agent loop after failure and transition to `complete` after success.

Narumitw's terminal-tool protocol, which requires the model to return a random identifier, does not enter this project's product protocol. The implementation should reuse its lifecycle, runtime, and continuation boundaries while reshaping state commits into a serialized dispatcher for one current Goal. General session/run cleanup remains internal to the runtime.

Implementation should prioritize reusing or adapting Narumitw's runtime, persistence, lifecycle, command, and safety structures before designing another large state machine.

### 11.2 `misunders2d-pi-goal` Is a Product Reference Only

`references/misunders2d-pi-goal/` helps confirm only two product requirements: clarification is needed before a Goal starts, and final completion needs acceptance in an independent context. Its source structure, states, tools, and audit protocol are not design templates for this project.

Goal refinement and the independent verifier are reimplemented directly against Narumitw's existing interfaces. The implementation is based on the behavior defined in this document, Narumitw's lifecycle/runtime boundaries, and the Pi SDK. It does not copy Misunders2d and then remove parts. Architecture decisions should preserve consistency with the Narumitw model.

## 12. Suggested Module Structure

```text
src/
├── index.ts           # Extension composition
├── state.ts           # GoalState, pure transitions, session persistence
├── prompts.ts         # Refinement, execution, continuation, and verifier prompts
├── commands.ts        # /goal routing, Control Panel, pending user actions
├── tools.ts           # Propose, submit, pause, and resume intents
├── lifecycle.ts       # Session, compaction, settled transition dispatcher, error handling
├── continuation.ts    # Intent/delivery single-flight
├── verifier.ts        # Fresh session, tool access, interaction observation, result intent
├── verification-ui.ts # Verifier transcript projection, append-only UI entries, collapsed/expanded renderer
└── safety.ts          # Turn limit, no-progress, provider-error classification
```

Key boundaries:

- `state.ts` does not depend on UI or models.
- Every Goal status write is committed by the main/verifier settled dispatcher.
- The Control Panel cannot directly modify GoalSpec in `active` or `verifying`.
- The Control Panel has no Cancel control; `Esc` and Refine use the same action during `refining` review.
- `verifier.ts` can return only a result intent; the main controller owns state transitions.
- Prompt builders are pure functions.
- A verifier failure returns directly to the normal agent loop without an additional evaluator layer.

## 13. Implementation Order

1. One current GoalState, pending user actions, and session persistence.
2. `/goal` creation, discussion, draft, Control Panel, confirmation, Esc/Refine behavior, and slash-only cancellation.
3. Active agent loop, settled transition dispatcher, and continuation.
4. Unified user/agent pause/resume and Pi-error transitions.
5. User-only edit/refine/reapprove flow and read-only active/verifying UI constraints.
6. `goal_submit({ result })` intent → settled → `verifying`.
7. Full-built-in-tool fresh verifier, result intent, and verifier-settled commit.
8. Fail → active loop; pass → complete.
9. Tests for compaction, reload, pending-action precedence, late-callback cleanup, and safety limits.

## 14. Conclusion

The final design has three fixed boundaries:

1. **Goal boundary**: Before execution starts, the user and main agent jointly form a main goal and verifiable subtasks. Only the user can initiate changes.
2. **Transition boundary**: Each session branch has one current Goal. User actions, agent lifecycle intents, and verifier results produced during a run are committed serially at the corresponding settled boundary.
3. **Acceptance boundary**: Through `goal_submit`, the main agent gives the same final result to both the user and a fresh verifier. The verifier uses its own context, tools, and observations to confirm whether that result and the related workspace state truly satisfy the Goal.

The Control Panel displays GoalSpec read-only in `active` and `verifying`. The user queues an edit after the current run through `/goal edit`. User actions take priority over submission, verification, and continuation, preventing old and new Goal content from concurrently driving state transitions.

The verifier does not redefine the Goal and does not rely on the main agent's plan or evidence. It receives the approved Goal's acceptance projection (`mainGoal`, `subtasks`, and `details`) without `suggestions`, the same submitted result shown to the user, and workspace tools. It reports through `goal_verification_result({ result, details })`. Only a `pass` committed after the verifier settles can move the Goal to `complete`; a `fail` and its details return to the main agent, continuing the existing Narumitw-style execution loop.
