# AWP I2 Vision Recovery Plan — Real Planning / Goal Management

**Date:** 2026-08-24
**Status:** COMPLETE — provider/model-catalog/reasoning-effort correction live-proved on dogfood
**Reason:** Slice 2 was prematurely declared complete after the implementation substituted deterministic forms/state transitions for the specified model-backed Planner-led conversation.

## Authority

This recovery plan does not redefine the product. It restores the already-approved authority in:

- `docs/VISION.md`;
- `docs/specs/domains/planning.md`;
- `docs/specs/workflows/interactive-planning.md`;
- `docs/specs/ui/planning.md`;
- `docs/plans/AWP-PLANNER-LEADERSHIP-UX.md`;
- `docs/plans/AWP-INCREMENTAL-DELIVERY-PLAN.md`.

When this file conflicts with the earlier I2 completion record, this corrective plan wins until the recovery contract is fully closed.

## Owner-authorized sequencing amendment

On 2026-08-24 the owner explicitly directed AWP to reopen Slice 2, correct its plan/spec drift, and continue toward the original Real Planning vision until completion. This is the explicit governance amendment that authorizes I2 vision-recovery work even though the earlier I1-only sequencing guard has not yet marked GOLIVE acceptance complete.

This exception is narrow: it activates only the I2 Real Planning recovery contract. It does not waive, weaken, fabricate, or pre-accept any I1 GOLIVE criterion, and it does not authorize I3-I9 expansion. Slice 1 execution/auth/durability/publication safety invariants remain binding regression requirements.

### Owner sequencing amendment — 2026-08-24

The owner has explicitly directed: review/fix the plan and specs and continue working toward the original Slice 2 vision until completion. This instruction reopens I2 implementation now, even though the independent I1 GOLIVE owner-proof lane has not yet reached 30/30. The exception is narrow: only the corrected I2 recovery described here is authorized. It does not validate the quarantined form-only implementation, does not mark I1 proof complete, and does not authorize unrelated I3–I9 expansion.

## Drift diagnosis

The prior I2 implementation correctly created useful structured substrate: `PlanningSession`, PlanningProfile, Simple/Expert participation, Plan Index, structured decisions/recommendations, deferrals, readiness, Goal management, connection return, and Start/Schedule/Park.

It did **not** implement the defining interaction loop:

```text
owner message
 -> real Planner Agent model invocation
 -> planner reply/recommendation/question
 -> typed interpretation of the turn
 -> durable Planning state mutation
 -> next agenda selection
 -> repeat
```

The earlier completion checklist failed to include a model invocation/provenance/conversation acceptance gate, so tests could pass while the vision-defining behavior was absent. The earlier P1–P10 high-fi requirement was also treated as a renderer-state map instead of a real pre-implementation design/usability gate.

## Corrected I2 architecture

### Planner is a distinct agent role

The I2 Planner Agent forms/revises a Plan through Planning authority. It is not an Advisor Agent, Execution Agent, or Resolver Agent. It uses the existing Account/Model/Provider and Model Gateway seams; it never reads provider secrets or creates a second token authority.

### Planner model selection

Effective Planner routing is resolved in this order:

```text
PlanningSession explicit override, when present
 -> Project Planning interviewer default
 -> System Planning interviewer default
 -> not configured (visible blocker; never silently borrow execution model)
```

The configuration surface exposes at least:

```text
planning.interviewerAccountId
planning.interviewerModel
```

Changing Project/System defaults affects subsequent Planner turns that do not have a session override. A session override is explicit and visible. Execution/Factory model selection remains a separate configuration/launch concern.

### Turn provenance

Every model-produced Planner turn durably records enough provenance to explain:

```text
PlanningSession / sequence / timestamp
provider/account/model
model invocation identifier when available
input PlanningSession revision
output disposition / affected planning item
status/failure category when the model call fails
```

Conversation text is interaction evidence, not canonical Plan truth. Accepted decisions, findings, risks, deferrals, artifacts, readiness and PlanRevision remain structured authority.

### Planner turn contract

For each user message the Planner must:

1. respond to the current input;
2. interpret whether the current Planning item is resolved, still under discussion, or safely deferred;
3. update structured Planning state only through validated application commands;
4. surface material uncertainty instead of inventing certainty;
5. select the highest-value unresolved next item;
6. lead into that item with a recommendation/brief or one consequential question.

A model may propose a mutation; application validation remains authoritative. A model response cannot bypass OwnerRequired/PolicyRequired authority, readiness rules, launch confirmation, connection policy, or revision checks.

## Recovery completion contract

Slice 2 is **not complete** until all items below are true on canonical `main` and dogfood:

- [x] Binding I2 specs explicitly require the Planner model-backed turn loop, model-routing hierarchy, failure semantics, and turn provenance.
- [x] Project Settings exposes Planner interviewer routing separately from Factory execution configuration.
- [x] System, Project, and Plan/session Planner controls expose provider, account, catalog-backed model, and model-supported reasoning-effort selectors; no free-text-only model configuration remains when a live catalog is available.
- [x] Global System Settings exposes Planner routing defaults as authoritative values inherited by Projects, with Project override/reset provenance.
- [x] Planning workspace exposes the effective Planner routing and an explicit per-session override/reset path.
- [x] Starting Planning can produce the first real Planner response from the configured model without a synthetic hard-coded interview question.
- [x] Subsequent user messages invoke the real configured Planner model and return visible conversational responses.
- [x] Planner responses can resolve/continue/defer the current item through typed, validated state transitions and then advance the structured agenda.
- [x] Simple mode remains low-interruption full planning; Expert mode makes DelegableExpert recommendations normal conversational interview items.
- [x] Planner conversation and structured state survive refresh/restart; accepted Plan truth does not depend on transcript reconstruction.
- [x] Every Planner model turn records provider/account/model/reasoning-effort provenance and input revision; provider-observed reasoning effort is retained when reported, and failures are visible/retryable without losing state.
- [x] Provider/account/model/effort changes do not rewrite historical turn attribution.
- [x] Connection/auth interruption returns to the exact Planning item and conversation state.
- [x] The P1–P10 visual set is re-ratified against the actual conversation-first Planner experience, including real conversation/composer states rather than form-only substitutes.
- [x] Automated tests prove model invocation, routing/config inheritance, stale revision rejection, malformed model output handling, provider failure recovery, persistence/restart, UI conversation, and existing I2 structured invariants.
- [x] A real dogfood Planner turn is executed through the deployed Model Gateway/Subrouter using a catalog-selected provider/account/model/reasoning effort and the response confirms the requested effort.
- [x] Full repository gate passes on debian1/2/3, exact candidate is deployed, and owner-facing Tailscale UI is usable.
- [x] No Slice 1 execution/review/merge invariants regress.

## Post-completion correction — global configuration surface

The owner identified a remaining I2 implementation drift after the initial recovery closure: the typed configuration authority already supported `system -> project -> session`, and the Settings spec explicitly required System and Project scopes, but the live web UI exposed only Project Settings. This made the global Planner default effectively API-only and violated the product rule that configurable defaults must be inspectable/editable at their normal scope.

The corrective acceptance is explicit: `/settings` must provide System-level Planner account/model controls; Project Settings must visibly inherit those values until overridden; Project reset must return to System; the shared mutation client must correctly save both `<input>` and `<select>` controls; and the live dogfood UI must prove the inheritance path.

## Post-completion correction — provider/model/effort selection

Owner review identified a second concrete I2 completion drift. The broader Accounts/Models/Providers domain already required independent Provider/Account/Model primitives and model capability metadata including effort modes, but the narrow I2 Planning acceptance text named only account/model configuration. The implementation followed that minimum too literally: provider was implicit in the account, model was a free-text input, live model catalog metadata was discarded, and reasoning effort was not configurable or persisted.

Corrective acceptance is explicit: obtain selectable models and supported effort modes from the selected account/provider catalog; expose provider -> account -> model -> effort controls at System, Project, and PlanningSession scope; pass the selected effort to the provider request; persist provider/account/model/effort on Planner turns; reject provider/account and model/effort mismatches at the explicit Plan override boundary; and live-prove a non-default effort through dogfood.

## Provider/model/effort correction closure — 2026-08-24

The owner-reported routing/settings drift is closed on dogfood.

- System Settings (`/settings`), Project Settings (`/projects/<projectId>?tab=settings#planning-interviewer`), and the PlanningSession header (`/planning/<sessionId>`) now expose the same dependent `Provider -> Account -> Model -> Reasoning effort` selection model. Provider/account choices come from canonical account inventory; model names, labels, context metadata, defaults, and effort choices come from the selected account's live model catalog. Hidden/non-API catalog entries are not offered as normal choices.
- The active Planner gateway explicitly declares supported providers. The current Codex-compatible gateway accepts `codex` and rejects unsupported provider selections before model invocation, so Provider is enforced routing semantics rather than decorative provenance.
- Existing built-in configuration definitions now have versioned forward replacement semantics. The changed `planning.interviewerModel` definition advanced from schema v1 to v2; startup validates all existing override values before replacement, preserves valid overrides, rejects newer-runtime definitions, and still fails closed on same-version metadata drift. This repaired the first dogfood deploy failure without deleting configuration.
- Exact source gate on the final functional candidate `764afee76c430ce582cb713cc45902d38255e3eb` passed on debian2: 77 test files passed, 5 skipped; 330 tests passed, 9 skipped; typecheck/lint/build/format clean; architecture 6/6; dependency-cruiser reported zero violations across 136 modules / 268 dependencies.
- Dogfood deployed that exact source as tree `d5e7c223a19f79788b47cdb52a1d8be322d11e6b`; `/health` reported PostgreSQL migrations 23/23, zero pending, zero drift, and all three user services active.
- The live Project `2cf632f2-d1f0-46bc-a885-d9fc086d018f` now resolves `codex / chatgpt@alex.org.il / gpt-5.6-luna / high` from Project scope. The live catalog reported GPT-5.6-Luna default effort `medium` with supported efforts `low`, `medium`, `high`, `xhigh`, and `max`, proving `high` was an explicit non-default selection.
- PlanningSession `600b182a-475e-4584-b9a3-298e69b2cfca` executed through the deployed Model Gateway -> Subrouter path. Two malformed-output attempts were retained as retryable failed turns without changing authoritative Planning truth; the third real model turn completed with response `resp_07408f24335e78b1016a8ca4a01fc087d2aa23be3ab8ee9d20`, resolved `intent`, and advanced to `vision-alignment`.
- The completed Planner turn durably records `providerId=codex`, `accountId=chatgpt@alex.org.il`, `model=gpt-5.6-luna`, requested `reasoningEffort=high`, provider-observed `observedReasoningEffort=high`, the real response ID, input revision, item, and disposition. The adapter fails closed if a provider reports a different effort from the requested value.
- After an explicit control-plane restart, the same PlanningSession returned at revision 4 with the same completed turn/provenance and active item `vision-alignment`. FactoryRun, AgentRun, and ChangeSet counts remained `0 / 0 / 0`; Planning did not exercise execution/publication authority.
- Owner-facing Tailscale routing remains `https://debian3.taild2daa0.ts.net/` -> `http://127.0.0.1:4173`.

## Live recovery evidence

### Global Settings correction evidence

The post-completion Settings gap is closed:

- `/settings` is now the canonical System Settings surface and renders every typed System-scope configuration definition from PostgreSQL, including `planning.interviewerAccountId` and `planning.interviewerModel`;
- Project navigation exposes both `System Settings` and `Project Settings`; Project Settings shows inherited provenance and `Reset to inherited`, while System values can be cleared explicitly at the root scope;
- the browser mutation path is shared by System and Project controls and now correctly reads `<select>` as well as `<input>` values, fixing the previously broken Planner-account Project save path;
- API regression proves `System default -> Project inherits -> Project override -> Project reset -> System default` for the Planner model;
- exact repository gate after implementation passed on debian2 with 296 tests before the explicit precedence regression was added; the final closure gate is recorded in the durable progress file;
- dogfood `main@801a4e616d15a9d3400578077f730b02486c15e4` rendered the System Settings surface directly against the live registry: both Planner definitions advertise `allowedScopes: [system, project]`, both global controls are present, and the existing proof Project continues to resolve its explicit Project account/model override;
- live System Planner defaults were intentionally left unset rather than silently changing global behavior. The owner can now configure them from `/settings`; Projects without overrides inherit them automatically.


The completion contract was closed on 2026-08-24 against the debian3 dogfood deployment using the owner-authorized Codex OAuth account `chatgpt@alex.org.il` and Planner model `gpt-5.6-luna`.

- The first live attempt exposed and preserved two real failure modes rather than hiding them: host-to-K3s Model Gateway DNS was unreachable, then the generic non-streaming Responses request shape was rejected by Codex. These produced durable retryable/provider failure turns without mutating structured Planning truth.
- Dogfood routing was repaired to use the Model Gateway ClusterIP from the host control plane, consistent with Subrouter/Fabro host-to-K3s routing.
- `ModelGatewayPlanningProvider` was repaired to use the Codex-compatible streaming Responses contract: list-form `input`, `stream: true`, SSE output reconstruction and real response-ID provenance.
- A real live Planner turn completed in PlanningSession `4341b402-c139-4599-9bd1-10632da1e86e`, model response `resp_05cbd5dd5f90339b016a8c7af47be887d2ae2228afb532285f`, resolving `intent` and advancing to `vision-alignment`.
- The control plane was restarted. The exact session, account/model/provider/input-revision provenance and response ID survived restart with no FactoryRun, AgentRun or ChangeSet created.
- A subsequent post-restart live conversation recovered from one deliberately preserved malformed-output failure and then completed successfully with response `resp_0d60fb3985bb9172016a8c7b5df36c87d2b4def8b1bf57c323`, resolving `vision-alignment` and advancing to `scope`.
- Project-scoped Planner defaults were then set on the dedicated proof Project. A newly started PlanningSession `d250ad47-8350-4861-9c2f-92a8f2b9a6d0` resolved effective routing from `source: project` and produced its first real Planner response `resp_05fe2d6168ad4b1c016a8c7befe7fc87d2845cafc621b6033b` using `chatgpt@alex.org.il / gpt-5.6-luna`.
- The production start and follow-up HTTP routes are covered by `tests/application/planning-api.test.ts`, proving that starting Planning immediately invokes the Planner Agent and `/turns` invokes it again.
- No execution/publication authority was exercised by the I2 live proof.

## Implementation sequence

1. Correct specs/plan/progress authority and add regression tests that fail on the missing Planner loop.
2. Extend typed configuration for Planner account/model defaults.
3. Extend Model Gateway capability semantics for Planning-purpose model calls without weakening Attempt isolation.
4. Add Planner model provider port/client and typed Planner output contract.
5. Add durable conversation/provenance to Planning state and revision-safe Planner application command.
6. Add HTTP endpoints for Planner turns and session routing override.
7. Replace the form-only center with conversation-first interaction while preserving structured decision shortcuts and Plan Index/context rails.
8. Re-ratify P1–P10 visual acceptance and responsive states.
9. Run focused and full gates on allowed build hosts.
10. Rebase onto latest `origin/main`, deploy exact candidate to debian3, configure a dogfood Planner model/account, execute a real turn, verify restart/resume, then land only when every recovery criterion is closed.
