diff --git a/docs/FLOWPILOT-AND-RESOLUTIONASSIST.md b/docs/FLOWPILOT-AND-RESOLUTIONASSIST.md
new file mode 100644
index 00000000..cefbb7d9
--- /dev/null
+++ b/docs/FLOWPILOT-AND-RESOLUTIONASSIST.md
@@ -0,0 +1,163 @@
+# FlowPilot & ResolutionAssist
+
+> ResolutionFlow offers two AI-driven troubleshooting modes that share the same session backend but present very different interaction styles. Both work standalone and become richer when paired with a PSA connection.
+
+---
+
+## At a glance
+
+| | **FlowPilot** | **ResolutionAssist** |
+|---|---|---|
+| **Style** | Guided, structured | Conversational, freeform |
+| **Entry** | `/pilot` | `/assistant` |
+| **Interaction** | Questions → Actions → Resolution, one step at a time | Natural chat with inline questions/actions |
+| **Best for** | Reproducible workflows, low-context engineers, handoffs | Exploratory problems, quick lookups, rubber-ducking |
+| **Lifecycle** | Active → Paused → Resolved / Escalated / Abandoned | Active → Resolved / Abandoned (lightweight) |
+| **Confidence tracking** | Yes — drives tier transitions | No — always responsive to user direction |
+| **Navigation guard** | Yes — prevents accidental loss | No — free to leave and return |
+
+Both modes share the `ai_sessions` table (discriminated by `session_type`), the same multimodal AI backend (image uploads, markdown, cached prompts), and the same `[QUESTIONS]` / `[ACTIONS]` / `[FORK]` marker vocabulary that renders inline TaskLane elements.
+
+---
+
+## FlowPilot — guided troubleshooting
+
+FlowPilot is a wizard-style AI engineer that walks you through a problem one diagnostic step at a time. It runs on confidence tiers:
+
+- **Discovery** (confidence < 0.4) — asking broad, open-ended questions to characterize the problem
+- **Exploring** (0.4–0.8) — proposing targeted actions and narrowing hypotheses
+- **Guided** (≥ 0.8) — recommending a specific fix with steps to verify
+
+### The FlowPilot session flow
+
+1. **Intake.** You start from `/pilot` or from the dashboard "New Session" button. The intake screen accepts free-text description, PSA ticket context, screenshots, or log pastes.
+2. **Preference check.** Before suggesting any fix, the AI asks whether you want a **GUI** or **script** approach. This is enforced in the system prompt so you never get steps you can't execute.
+3. **Step-by-step progression.** Each AI response is either a question (with clickable options), an action (with "Done" / "Didn't work" buttons), a `[FORK]` (two distinct paths to try), or a final resolution suggestion. You respond, the AI updates its confidence, and the next step is generated.
+4. **Action bar.** The session header always shows **Pause & Leave**, **Resolve**, **Escalate**, **Share Update**, and **Close**. Pausing freezes the session; resuming restores the full context.
+5. **Resolve / Escalate.** *Resolve* marks the ticket fixed and generates a clean summary of what worked. *Escalate* packages the problem summary and steps tried into an **escalation package** that the next engineer (or the PSA ticket) inherits.
+
+### Why FlowPilot exists
+
+- **New engineers** get senior-engineer-level diagnostic rigor without needing the experience to know what to ask next.
+- **Documented resolutions** — every step is captured, so the generated note on the ticket is substantive (not just "fixed it").
+- **Handoff-friendly** — escalation packages mean the next person doesn't start from zero.
+
+---
+
+## ResolutionAssist — conversational AI
+
+ResolutionAssist is a chat with an expert IT systems engineer. It's less structured than FlowPilot but still surfaces interactive elements when the AI wants structured input.
+
+### The ResolutionAssist flow
+
+1. **Open a chat.** From `/assistant` or the dashboard. Sessions show up in the left sidebar just like any messaging app.
+2. **Send a message.** Freeform prose. Attach up to 3 images per message (screenshots, error dialogs, network diagrams). Paste logs, code, or PowerShell output.
+3. **AI responds.** The response is prose, but any `[QUESTIONS]` or `[ACTIONS]` blocks render as a **TaskLane** — a side panel with clickable options and action buttons. You can answer via chat or click the TaskLane elements.
+4. **Branching (`[FORK]`).** If the AI proposes two paths ("check cable or restart switch?"), the fork renders as a choice. Picking one continues the conversation down that path.
+5. **Resume later.** Unlike FlowPilot, there's no navigation guard. Leave mid-conversation; every message is stored.
+
+### Why ResolutionAssist exists
+
+- **Unstructured problems** — "I have no idea where to start, here's a screenshot" works great.
+- **Reference lookups** — "what's the right PowerShell command to check Exchange health" is faster in chat than through an intake form.
+- **Senior engineers** — when you already know what you're doing and just want a second opinion or a syntax check.
+
+---
+
+## Without a PSA connection
+
+Both modes work standalone. Without ConnectWise connected:
+
+- Sessions live entirely in ResolutionFlow. They're listed in your session history, searchable, and shareable via public share links (`/shared/sessions/:token`).
+- Summaries generated on Resolve are saved to the session record but **not** written anywhere else. You can copy/paste into whatever ticketing or documentation system you use.
+- Escalating a FlowPilot session routes the escalation package to another ResolutionFlow engineer on your team — not to an external PSA ticket.
+- No ticket context is injected into the AI prompt, so the AI starts cold with only what you provide in the intake or first message.
+
+**Standalone use cases:**
+- Evaluating ResolutionFlow before committing to a PSA integration
+- Troubleshooting internal IT issues that aren't client-facing
+- Teams using a PSA ResolutionFlow doesn't integrate with yet
+- Knowledge-base research ("what are my options for X") that don't map to a ticket
+
+---
+
+## With a PSA connection (ConnectWise)
+
+When ConnectWise is connected, both modes become ticket-aware and write back to the PSA as a first-class client.
+
+### FlowPilot + PSA
+
+**Starting from a ticket:**
+- Click a ticket row (from `/tickets` or the dashboard queue) and pick "Start FlowPilot." The ticket's problem description, recent notes, configurations, company details, and related tickets are auto-injected into the AI's context. No manual retyping.
+- The session shows the linked ticket badge in the header.
+
+**During the session:**
+- **Share Update** — posts an interim note to the CW ticket with the current AI summary, so stakeholders can see progress without interrupting you.
+- **Status changes** — the detail panel and session header let you move the ticket through statuses (New → In Progress → Waiting on Customer → Resolved) directly from ResolutionFlow. Status writes are verified against CW so you're never told "success" when CW silently rejected the change.
+- **Resource assignment** — add yourself or a teammate as a co-assignee without touching the owner. If the ticket has no owner yet, assigning sets owner; if there's already an owner, you're added as an additional resource via a CW schedule entry.
+
+**On Resolve:**
+- Final summary is posted as a ticket note.
+- Ticket status can auto-update to Resolved (per your team's settings).
+
+**On Escalate:**
+- The escalation package (problem summary + steps tried) is posted as a note.
+- The ticket can be routed via CW's normal escalation rules.
+- The next engineer picking up the ticket can auto-start a new session with the full escalation context pre-filled.
+
+**Spin-off tickets (new):**
+- During any session, if you discover a separate issue, the AI can propose `create_spin_off_ticket`. Accepting opens the New Ticket modal pre-filled with the current ticket's company and board, so a second ticket is one click away without leaving your session.
+
+### ResolutionAssist + PSA
+
+**Starting from a ticket:**
+- Same ticket-context injection as FlowPilot. When opened with a linked ticket, the AI sees company, configs, notes, and related tickets.
+- A "New Ticket" button appears in the header — lets you spawn a separate ticket mid-conversation (same flow as FlowPilot's spin-off).
+
+**During the chat:**
+- Ask the AI about the ticket directly: *"Summarize what's been tried," "What configs does this company have?"* — the AI already has that context loaded.
+- `[ACTIONS]` can include `create_spin_off_ticket` when the AI detects a separate issue surfaced in the conversation.
+
+**Writing back:**
+- ResolutionAssist is a lighter-weight mode, so it doesn't auto-post on resolve. You can manually copy the conversation summary to a ticket note if useful.
+- Status updates and resource assignment are done via the `/tickets` page rather than the chat UI.
+
+---
+
+## Choosing between them
+
+| I want to… | Use |
+|---|---|
+| Walk through a known issue type with step-by-step rigor | **FlowPilot** |
+| Document every action taken for audit or handoff | **FlowPilot** |
+| Escalate with a full context package | **FlowPilot** |
+| Ask a question, get an answer, move on | **ResolutionAssist** |
+| Paste a screenshot and say "what's wrong here?" | **ResolutionAssist** |
+| Stay on the ticket for 2 minutes, not 20 | **ResolutionAssist** |
+| Troubleshoot without breaking flow to switch pages | Either, with the linked ticket panel open alongside |
+
+The two modes aren't competitive. A common workflow is to start in ResolutionAssist to scope the problem, then kick off a FlowPilot session when you realize the issue is going to take real diagnosis. Both show up in the unified session history.
+
+---
+
+## Tickets page — the PSA hub
+
+`/tickets` is the CW ticket manager built into ResolutionFlow. With a PSA connection:
+
+- Search and filter tickets by assignment (me / unassigned / specific member via searchable picker), board, status, priority, company, open/closed.
+- Slide-out detail panel shows notes, configurations, related tickets, and assignees — all fetched in parallel for fast hydration.
+- From the detail panel: change status, add/remove assignees, post notes, or "Start FlowPilot" / "Open in ResolutionAssist" with full context.
+- New Ticket modal offers both AI-parse ("Create a high-priority ticket for Acme — Outlook not syncing for jsmith") and a traditional form.
+
+Without a PSA connection, `/tickets` is hidden from the sidebar entirely — there's nothing to show.
+
+---
+
+## Summary
+
+- **FlowPilot** = guided, structured, lifecycle-heavy, ideal for resolvable issues and handoffs.
+- **ResolutionAssist** = freeform chat, ideal for scoping and quick answers.
+- **Without PSA** = both work, sessions live in ResolutionFlow, summaries are yours to export.
+- **With PSA** = both become ticket-aware, write back to CW (notes, status, resources), and can spawn spin-off tickets mid-session.
+
+The AI is the same under the hood. The difference is how much structure you want around the conversation — and how deeply the result needs to integrate with your ticketing system.
diff --git a/docs/FlowAssist_Migration/FLOWPILOT-MIGRATION.md b/docs/FlowAssist_Migration/FLOWPILOT-MIGRATION.md
new file mode 100644
index 00000000..6009b7cb
--- /dev/null
+++ b/docs/FlowAssist_Migration/FLOWPILOT-MIGRATION.md
@@ -0,0 +1,794 @@
+# FlowPilot Migration — Design & Implementation Doc
+
+> **Target:** Transform `/assistant` (ResolutionAssist) into the new unified `/pilot` (FlowPilot) surface.
+> **Audience:** Claude Code (implementation) reviewed by Michael (owner).
+> **Status:** Design locked. Ready for phased implementation.
+> **Last updated:** April 17, 2026
+
+---
+
+## 0. Prerequisite reading for Claude Code
+
+Before writing any code, read these in order:
+
+1. This document end-to-end.
+2. `mockups/01-session-primary.png` — the target state for the main session UI.
+3. `mockups/02-script-template-match.png`, `03-script-three-options.png`, `04-script-templatize-prompt.png` — Script Generator integration states.
+4. The source HTML files `mockups/01-session-primary.html` and `mockups/02-04-script-integration.html` — authoritative for spacing, colors, and component structure. When CSS or layout questions arise during implementation, these files are the tiebreaker.
+
+Do not proceed to implementation until you have confirmed you understand the following three architectural claims. If any of them are unclear, stop and ask.
+
+1. **There is one AI troubleshooting surface, not two.** The existing split between FlowPilot (guided) and ResolutionAssist (chat) is collapsed into a single chat-primary product called FlowPilot at `/pilot`. The `ai_sessions.session_type` discriminator column is retained for data, but the product shows one unified UI.
+2. **The task lane is the load-bearing structural feature.** It is not a sidebar of metadata. It actively tracks diagnostic state: *What we know*, *Questions*, *Diagnostic checks*, *Suggested fix*. Engineers interact with it; facts flow between sections.
+3. **Resolve and Escalate are deterministic artifact generators, not free-text prompts.** When an engineer clicks Resolve, a structured summary is generated from task lane state (not from the chat transcript alone) and posted to CW. The summary structure is fixed: *Problem / What we confirmed / Root cause / Resolution*.
+
+---
+
+## 1. Why this change
+
+### The current state
+
+- `/assistant` is a chat-primary AI session with a `[QUESTIONS]` and `[DIAGNOSTIC_CHECKS]` task lane.
+- `/pilot` was specced as a separate guided, confidence-tiered wizard with a different UI and lifecycle.
+- The `FLOWPILOT-AND-RESOLUTIONASSIST.md` design document treated them as two products sharing a backend.
+
+### The problems with the current state
+
+- Two sidebar entries, two session histories, two mental models for engineers to learn.
+- The PSA integration scope doubles (writebacks for lifecycle events must be built twice, or built for Pilot and bolted onto Assist).
+- The Team Wiki moat depends on structured session artifacts with explicit resolutions — a chat-only mode produces weaker artifacts.
+- The cockpit positioning (the core ResolutionFlow brand promise) does not map to a blank chat window.
+- Branching into two modes forces a decision onto the engineer ("which mode for this ticket?") that has no right answer.
+
+### The resolution
+
+The existing `/assistant` UI already does most of what `/pilot` was supposed to do — structured questions, diagnostic checks, lifecycle actions in the header. It is closer to the right product than the doc anticipated. Rather than building Pilot as a second surface, we extend Assist with the missing structural features (*What we know*, auto-generated summaries, escalation packages) and rename it FlowPilot.
+
+### The strategic move
+
+FlowPilot becomes the single canonical troubleshooting surface. Every PSA writeback, every Wiki compilation path, every Script Generator invocation points here. One session shape, one lifecycle, one integration surface.
+
+---
+
+## 2. Terminology used in this document
+
+| Term | Meaning |
+|---|---|
+| **Session** | A single `ai_sessions` row representing one troubleshooting conversation. |
+| **Task lane** | The right-side panel containing What we know, Questions, Diagnostic checks, Suggested fix. |
+| **Fact** | An item in the What we know section. Has `text`, `source_type` (`question` / `diagnostic_check` / `user_note`), and `source_ref` (FK to the originating question/check, or null for user notes). |
+| **Suggested fix** | The AI's current best-guess resolution path. Has a confidence score and, optionally, a reference to a Script Library template. |
+| **Promotion** | The act of a question answer or diagnostic check result being converted into a fact in What we know. Triggered by AI, confirmed/editable by engineer. |
+| **Resolution note** | The structured document generated when the engineer clicks Resolve. Posted to CW as a ticket note. |
+| **Escalation package** | The structured handoff document generated when the engineer clicks Escalate. Posted to CW and attached to the session for the next engineer. |
+
+---
+
+## 3. Target UI — annotated
+
+### 3.1 Primary session view
+
+
+
+The session UI is a four-column layout:
+
+1. **Icon rail** (64px wide) — primary app navigation. FlowPilot / Tickets / Trees / Scripts / Wiki. Avatar at bottom.
+2. **Session list** (260px wide) — all sessions grouped by state (Active / Recent). Each row shows title, state dot, PSA ticket number, and client name.
+3. **Conversation column** (fluid) — the chat thread, composer, and incident header.
+4. **Task lane** (380px wide) — *What we know*, *Questions*, *Diagnostic checks*, *Suggested fix*, and the Resolve action at the bottom.
+
+Key visual and behavioral elements numbered against the mockup:
+
+**Incident header (top of conversation column)**
+- PSA chip showing `CW #48291` in cyan, monospaced
+- Client / contact / priority meta line
+- Incident title in Bricolage Grotesque 19px
+- Four lifecycle buttons right-aligned: **Pause** (ghost), **Share update** (neutral), **Escalate** (amber), **Resolve** (green)
+
+**Conversation column**
+- Standard chat thread with pilot and user avatars
+- Pilot uses cyan gradient avatar; user uses purple gradient
+- AI messages in `bg-2` bubbles with subtle border; user messages in cyan-tinted bubbles
+- Composer at bottom with inline action chips (Attach / Paste logs / Ticket context) and a send button
+
+**Task lane sections, in order:**
+
+1. **What we know** (NEW)
+ - Header: `WHAT WE KNOW · 4` (section title + count)
+ - Each fact is a card: `bg-2` background, dashed circular green check, fact text, and a provenance line (`from question · rules out tenant/license`)
+ - "+ Add a note" button at the bottom for manual facts from the engineer
+ - Background has a subtle green-to-transparent gradient to visually distinguish from the rest of the lane
+
+2. **Questions**
+ - Header: `QUESTIONS · 2 unanswered`
+ - Each unanswered question: title, AI hint text, Answer / Skip buttons
+ - Answered questions dim to 55% opacity with a dashed border and show the resolution inline (`Answered · isolated to jsmith (promoted to What we know)`)
+
+3. **Diagnostic checks**
+ - Header: `DIAGNOSTIC CHECKS · 1 / 3 run`
+ - "Run remaining 2 checks" button at top when applicable
+ - Each check: icon + command name (monospaced), description
+ - Completed checks dim and show "Complete · findings promoted to What we know" in green
+
+4. **Suggested fix**
+ - Header: `SUGGESTED FIX · 94% confidence`
+ - Amber-accented card with fix title and description
+ - Clicking opens the Script Generator flow (Section 5)
+
+**Resolve action bar (bottom of task lane)**
+- Small hint text ("Summary preview is open →")
+- Full-width "Resolve & post to CW" button in green
+
+**Resolution note preview (floating, anchored to Resolve button)**
+- A persistent popover, NOT a modal
+- Shows the draft resolution note with Problem / What we confirmed / Root cause / Resolution sections
+- Displays the target ticket (`CW #48291`) and status change (`Resolved`)
+- Edit button opens an inline editor; Confirm & post fires the PSA writeback
+
+### 3.2 Script Generator integration — template match
+
+
+
+When the suggested fix references an existing Script Library template, clicking the fix opens the Script Generator panel in place of (or sliding over) the task lane. Key behavior:
+
+- A **Verified template** badge appears above the parameter form
+- Parameters pre-filled from session context get a cyan `from session` tag and a cyan-tinted input background
+- Each pre-filled parameter has a hint line explaining the source: *"Pulled from CW company config for Acme Corp"*
+- The engineer can adjust any pre-filled value before generating
+- `⌘K` → "script" invokes the generator mid-conversation from anywhere in the session
+
+### 3.3 Script Generator integration — no template match (three-option dialog)
+
+
+
+When no template matches the suggested fix, FlowPilot drafts a session-specific script and presents three paths:
+
+1. **Run as one-off** (neutral outline CTA)
+ - Script generated and captured in session documentation, discarded after
+ - Tradeoffs: fastest, but team won't benefit next time
+
+2. **Run now, templatize after resolve** (RECOMMENDED, cyan primary CTA)
+ - Script generated for this ticket; draft template queued
+ - Post-resolve prompt offers to templatize (Section 5.3)
+ - Tradeoffs: zero cognitive overhead now, only templatize what works, ~30s review later
+
+3. **Build as template now** (purple outline CTA)
+ - Full parameterization upfront
+ - Tradeoffs: immediate team benefit, but adds time mid-ticket
+
+The drafted script renders as a code preview above the option cards with the AI's proposed parameters highlighted in amber.
+
+### 3.4 Script Generator integration — post-resolve templatization prompt
+
+
+
+If the engineer picked Option 2 in the three-option dialog and Resolve succeeds, this prompt appears after the resolution note is posted to CW:
+
+- Success banner confirms the resolution posted
+- Templatize card shows the script with AI-proposed parameters substituted in as `{{ gateway_host }}`, etc.
+- Right pane lists extracted parameters with remove buttons (engineer can adjust)
+- Provenance note: *"generated from CW #48307 · resolved by M. Davis"*
+- Three actions: Skip / Edit parameters / Save as team template
+- "Don't ask me again for this team" opt-out in footer
+
+---
+
+## 4. Data model changes
+
+### 4.1 New columns on `ai_sessions`
+
+```sql
+ALTER TABLE ai_sessions
+ ADD COLUMN resolution_note_markdown TEXT NULL,
+ ADD COLUMN resolution_note_posted_at TIMESTAMPTZ NULL,
+ ADD COLUMN resolution_note_external_id VARCHAR(128) NULL, -- CW note ID after posting
+ ADD COLUMN escalation_package_markdown TEXT NULL,
+ ADD COLUMN escalation_package_posted_at TIMESTAMPTZ NULL;
+```
+
+No migration of `session_type` — the column stays. New sessions all default to the unified FlowPilot type.
+
+### 4.2 New `session_facts` table (the What we know backing store)
+
+```sql
+CREATE TABLE session_facts (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ session_id UUID NOT NULL REFERENCES ai_sessions(id) ON DELETE CASCADE,
+ account_id UUID NOT NULL REFERENCES accounts(id), -- for RLS, per multi-tenant architecture
+ text TEXT NOT NULL,
+ source_type VARCHAR(32) NOT NULL CHECK (source_type IN ('question', 'diagnostic_check', 'user_note', 'ai_synthesis')),
+ source_ref UUID NULL, -- FK to session_questions.id or session_diagnostic_checks.id, null for user_note
+ source_summary TEXT NULL, -- free-text provenance label, e.g. "rules out tenant/license"
+ created_by UUID NOT NULL REFERENCES users(id),
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
+ deleted_at TIMESTAMPTZ NULL
+);
+CREATE INDEX idx_session_facts_session ON session_facts(session_id) WHERE deleted_at IS NULL;
+CREATE INDEX idx_session_facts_account ON session_facts(account_id);
+```
+
+**Important:** `source_ref` is a polymorphic FK and should NOT have a database-level FK constraint. Enforce integrity at the service layer.
+
+### 4.3 New `session_suggested_fixes` table
+
+```sql
+CREATE TABLE session_suggested_fixes (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ session_id UUID NOT NULL REFERENCES ai_sessions(id) ON DELETE CASCADE,
+ account_id UUID NOT NULL REFERENCES accounts(id),
+ title VARCHAR(200) NOT NULL,
+ description TEXT NOT NULL,
+ confidence_pct INTEGER NOT NULL CHECK (confidence_pct BETWEEN 0 AND 100),
+ script_template_id UUID NULL REFERENCES script_templates(id), -- null if no template match
+ ai_drafted_script TEXT NULL, -- populated if no template match
+ ai_drafted_parameters JSONB NULL, -- AI's proposed parameterization
+ user_decision VARCHAR(32) NULL CHECK (user_decision IN ('one_off', 'draft_template', 'build_template', 'dismissed')),
+ superseded_at TIMESTAMPTZ NULL, -- set when a new suggestion replaces this one
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now()
+);
+CREATE INDEX idx_session_suggested_fixes_session ON session_suggested_fixes(session_id) WHERE superseded_at IS NULL;
+```
+
+A session can have multiple suggested fixes over time as the AI's understanding evolves. Only one is active (superseded_at IS NULL) at a time.
+
+### 4.4 New `draft_templates` table
+
+Backing store for Option 2 in the three-option dialog — scripts generated during sessions that are pending templatization.
+
+```sql
+CREATE TABLE draft_templates (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ account_id UUID NOT NULL REFERENCES accounts(id),
+ source_session_id UUID NOT NULL REFERENCES ai_sessions(id),
+ source_user_id UUID NOT NULL REFERENCES users(id),
+ script_body TEXT NOT NULL,
+ proposed_parameters JSONB NOT NULL, -- {"parameters": [{"key": "...", "label": "...", "type": "..."}]}
+ proposed_name VARCHAR(200) NULL,
+ proposed_category_id UUID NULL REFERENCES script_categories(id),
+ status VARCHAR(32) NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'accepted', 'rejected')),
+ resolved_at TIMESTAMPTZ NULL, -- when the user acted on the draft
+ promoted_template_id UUID NULL REFERENCES script_templates(id), -- if accepted, the created template
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now()
+);
+```
+
+Accepted draft templates produce a new `script_templates` row and record the source session for provenance display.
+
+### 4.5 Extension to `script_templates`
+
+```sql
+ALTER TABLE script_templates
+ ADD COLUMN source_session_id UUID NULL REFERENCES ai_sessions(id),
+ ADD COLUMN source_user_id UUID NULL REFERENCES users(id),
+ ADD COLUMN source_ticket_ref VARCHAR(64) NULL; -- e.g. "CW #48307" for display
+```
+
+These fields power the provenance chip in the Script Library: *"generated from CW #48307 · resolved by M. Davis · used 7 times"*.
+
+### 4.6 Per-account settings
+
+```sql
+ALTER TABLE account_settings
+ ADD COLUMN templatize_prompt_enabled BOOLEAN NOT NULL DEFAULT true;
+```
+
+Controls whether the post-resolve templatize prompt appears. Toggleable from the prompt's footer ("Don't ask me again for this team") and from admin settings.
+
+---
+
+## 5. API endpoints
+
+All endpoints follow ResolutionFlow conventions: `/api/v1/` prefix, JWT auth, tenant-scoped via RLS.
+
+### 5.1 Session facts
+
+```
+GET /api/v1/sessions/{id}/facts List facts for a session (ordered by created_at ASC)
+POST /api/v1/sessions/{id}/facts Create a manual fact (user_note source_type)
+PATCH /api/v1/sessions/{id}/facts/{fact_id} Edit fact text or summary (only for user_note or AI-synthesized facts)
+DELETE /api/v1/sessions/{id}/facts/{fact_id} Soft-delete
+POST /api/v1/sessions/{id}/facts/promote Promote a question answer or check result to a fact
+ Body: { source_type, source_ref, proposed_text, proposed_summary }
+ Returns the created fact. Used by the AI synthesis flow and
+ by the engineer's explicit "promote to What we know" action.
+```
+
+### 5.2 Suggested fixes
+
+```
+GET /api/v1/sessions/{id}/suggested-fixes/active Returns the current active fix (superseded_at IS NULL) or 404
+POST /api/v1/sessions/{id}/suggested-fixes/{fix_id}/decision
+ Body: { decision: "one_off" | "draft_template" | "build_template" | "dismissed" }
+ Records the user's path choice. Server-side side effects:
+ - one_off: generates script via ScriptTemplateEngine, returns rendered script
+ - draft_template: same as one_off, plus creates draft_templates row
+ - build_template: redirects to full template creation flow
+ - dismissed: marks fix as superseded
+```
+
+### 5.3 Draft templates (post-resolve flow)
+
+```
+GET /api/v1/draft-templates List pending drafts for the current user's account
+ (used by the Script Library "X scripts ready to review" notification)
+GET /api/v1/draft-templates/{id} Get a single draft including its proposed parameterization
+POST /api/v1/draft-templates/{id}/accept Body: { name, category_id, parameters_schema, edits }
+ Creates a new script_templates row with source_session_id set,
+ sets draft status to 'accepted', returns the new template
+POST /api/v1/draft-templates/{id}/reject Sets status to 'rejected'
+```
+
+### 5.4 Resolution notes and escalation packages
+
+```
+POST /api/v1/sessions/{id}/resolution-note/preview Generates the draft resolution note from current session state
+ WITHOUT posting. Returns { markdown, target_ticket_ref }.
+ Called when the task lane renders and refreshed whenever
+ facts/suggested fix change.
+POST /api/v1/sessions/{id}/resolution-note/post Body: { markdown } (engineer-edited version)
+ Posts to the linked PSA ticket, updates ticket status if configured,
+ marks session resolved.
+POST /api/v1/sessions/{id}/escalation-package/preview Same pattern for escalation
+POST /api/v1/sessions/{id}/escalation-package/post Posts and transitions session to escalated state
+```
+
+---
+
+## 6. Services to implement
+
+### 6.1 `FactSynthesisService` (new)
+
+**Location:** `services/fact_synthesis_service.py`
+
+**Purpose:** Converts question answers and diagnostic check results into candidate facts. Called by the AI pipeline when the LLM emits a `[PROMOTE]` marker, and by explicit engineer action.
+
+**Key methods:**
+- `synthesize_from_question(question_id: UUID, raw_answer: str) -> dict` — returns `{proposed_text, proposed_summary}` via LLM call. The summary is the short provenance label ("rules out tenant/license").
+- `synthesize_from_check(check_id: UUID, check_output: str) -> dict` — same pattern for diagnostic check output.
+- `create_fact(session_id, source_type, source_ref, text, summary, user_id) -> SessionFact` — persists the fact.
+
+**Prompt engineering note:** The synthesis prompt should be conservative — short, factual statements. Hallucinated specifics are a trust-killer. The prompt must explicitly instruct: *"Use only information present in the answer/output. If the answer does not contain a substantive fact, return null."*
+
+### 6.2 `ResolutionNoteGeneratorService` (new)
+
+**Location:** `services/resolution_note_generator.py`
+
+**Purpose:** Produces the structured resolution note markdown from session state.
+
+**Input:** session_id
+**Output:** `{markdown: str, target_ticket_ref: str | None}`
+
+**Template structure:**
+```markdown
+## Problem
+{ai-synthesized one-paragraph problem statement, pulling from session description + incident header}
+
+## What we confirmed
+{bulleted list of session_facts, grouped by source_type}
+
+## Root cause
+{ai-synthesized from the active suggested fix + facts}
+
+## Resolution
+{description of the fix applied, parameters used if a script ran, outcome}
+```
+
+The service pulls from four data sources: `ai_sessions`, `session_facts`, `session_suggested_fixes` (active), and `script_generations` (if scripts ran during the session). Passwords in script_generations.parameters_used must be redacted (already a Script Generator pattern per the existing plan).
+
+**Critical:** This service is called on every fact/suggestion change to keep the preview live. Cache aggressively — LLM calls for every keystroke will blow the budget. Invalidate the cache on any write to session_facts or session_suggested_fixes.
+
+### 6.3 `EscalationPackageGeneratorService` (new)
+
+**Location:** `services/escalation_package_generator.py`
+
+Same structure as ResolutionNoteGenerator but with a handoff-oriented template:
+
+```markdown
+## Problem
+...
+
+## What we've confirmed
+...
+
+## What we've tried
+{list of diagnostic_checks run with their outcomes, scripts generated}
+
+## Current hypothesis
+{active suggested fix description}
+
+## Suggested next steps
+{ai-synthesized from the gap between facts and a complete resolution}
+```
+
+### 6.4 `TemplateExtractionService` (new)
+
+**Location:** `services/template_extraction_service.py`
+
+**Purpose:** Given a concrete rendered script and session context, propose a parameterization.
+
+**Input:** `{script_body: str, session_context: dict, ticket_context: dict}`
+**Output:** `{parameters: [{key, label, type, inferred_from}], templated_body: str}`
+
+**Implementation approach:**
+- LLM call with a structured prompt: "Given this script that resolved a ticket, identify values that would change for a different invocation. Propose a parameter schema following the Script Generator conventions (text / password / select / boolean / multi_text / number / textarea)."
+- Post-process to ensure the proposed template renders back to the original script when given the extracted parameter values.
+- Conservative default: prefer fewer parameters. If a value looks environment-agnostic (e.g. a command name), don't parameterize it.
+
+This service is the engine behind Option 2 and Option 3 of the three-option dialog, and behind the post-resolve templatize prompt.
+
+### 6.5 Extend `PSAWritebackService` (existing)
+
+Add methods:
+- `post_resolution_note(session_id, markdown) -> {external_id, posted_at}`
+- `post_escalation_package(session_id, markdown) -> {external_id, posted_at}`
+- `transition_ticket_status(ticket_ref, new_status) -> {success, verified_status}`
+
+The `transition_ticket_status` method must verify the status change took effect (per the existing ConnectWise integration principle: "never told 'success' when CW silently rejected the change").
+
+### 6.6 Model selection per service
+
+Each AI-calling service must use a configurable model string from application settings, not a hardcoded model. Use these defaults:
+
+```python
+FACT_SYNTHESIS_MODEL = "claude-haiku-4-5-20251001" # short transformation, latency-sensitive
+RESOLUTION_NOTE_MODEL = "claude-sonnet-4-6" # customer-facing artifact, quality matters
+ESCALATION_PACKAGE_MODEL = "claude-sonnet-4-6" # same
+TEMPLATE_EXTRACTION_MODEL = "claude-sonnet-4-6" # creates persistent library artifact
+MAIN_CONVERSATION_MODEL = "claude-sonnet-4-6" # primary FlowPilot chat
+```
+
+Do not hardcode model strings at call sites. Every new service must read from settings with a service-specific key.
+
+**Instrumentation requirement:** log a `disputed_fact_rate` metric for fact synthesis — the percentage of AI-synthesized facts that engineers subsequently edit or delete. If this exceeds 10% over a 500-session window, escalate `FACT_SYNTHESIS_MODEL` to `claude-sonnet-4-6`. If under 5%, Haiku is performing correctly.
+
+Do not use Opus 4.7 for any of these services at current scale.
+
+---
+
+## 7. Frontend components
+
+### 7.1 Routes to change
+
+| Current route | New route | Action |
+|---|---|---|
+| `/assistant` | `/pilot` | **Rename** the route. The existing page moves. `/assistant` permanently redirects to `/pilot` with no sunset date. |
+| `/pilot` (if it exists as a separate guided flow) | REMOVED | Collapse into the unified surface. |
+| `/pilot/session/:id` | `/pilot/session/:id` | No change (this is where the unified session UI lives) |
+
+Sidebar nav entry renames from "ResolutionAssist" to "FlowPilot" with the cockpit icon.
+
+### 7.2 New React components
+
+Under `src/components/pilot/`:
+
+```
+TaskLane.tsx -- The right-side panel, owns all four sections
+ sections/
+ WhatWeKnow.tsx -- New component for the facts list
+ WhatWeKnowItem.tsx -- Single fact card with provenance line
+ AddNoteButton.tsx -- "+ Add a note" inline composer
+ Questions.tsx -- Existing questions rendering (moved if already present)
+ DiagnosticChecks.tsx -- Existing checks rendering (moved if already present)
+ SuggestedFix.tsx -- New or refactored component for the suggested fix card
+ResolveButton.tsx -- The Resolve CTA at the bottom of the task lane
+ResolutionNotePreview.tsx -- Floating popover anchored to Resolve button
+EscalatePackagePreview.tsx -- Same pattern for Escalate
+
+ScriptGenInline/ -- Script Generator embedded in session context
+ TemplateMatchPanel.tsx -- Scene 1 mockup: template pre-filled
+ NoTemplateDialog.tsx -- Scene 2 mockup: three-option dialog
+ TemplatizePrompt.tsx -- Scene 3 mockup: post-resolve prompt
+ ParameterizationPreview.tsx -- Shared component: script with highlighted params
+```
+
+### 7.3 Component behavior contracts
+
+**`WhatWeKnowItem`**
+- Props: `{fact: SessionFact, onEdit, onDelete}`
+- Renders the fact text, a green checkmark, and the provenance line with source-type color coding
+- Clicking the fact text opens inline edit (only for `user_note` and `ai_synthesis` sources — question/check facts are read-only, edit the source instead)
+
+**`TaskLane`**
+- Subscribes to a session state hook that polls for fact / question / check / suggested-fix updates
+- On any state change, calls `POST /api/v1/sessions/{id}/resolution-note/preview` to refresh the ResolutionNotePreview
+- Debounce preview refresh to 500ms to avoid LLM spam
+
+**`NoTemplateDialog`** (three-option dialog)
+- Props: `{suggestedFix, onDecision}`
+- Renders the three cards with the middle (draft_template) marked as recommended
+- `onDecision` posts to `/api/v1/sessions/{id}/suggested-fixes/{fix_id}/decision` and either opens the Script Generator (one_off / draft_template) or navigates to full template creation (build_template)
+
+**`TemplatizePrompt`**
+- Rendered after successful Resolve when a draft template exists for the session
+- Fetches proposed parameters from the draft template record
+- Save button posts to `/api/v1/draft-templates/{id}/accept`
+
+---
+
+## 8. AI prompt changes
+
+The existing FlowPilot / ResolutionAssist system prompt needs updates to emit the new markers.
+
+### 8.1 New marker: `[PROMOTE]`
+
+Used to surface facts to What we know. Syntax:
+
+```
+[PROMOTE]
+source_type: question
+source_ref: {question_id}
+text: OWA login and send/receive confirmed working for jsmith
+summary: rules out tenant/license
+[/PROMOTE]
+```
+
+The AI should emit `[PROMOTE]` blocks in the same message that answers or processes a question/check, so the fact appears in What we know simultaneously with the chat acknowledgment.
+
+### 8.2 New marker: `[SUGGEST_FIX]`
+
+```
+[SUGGEST_FIX]
+title: Clear cached credentials + rebuild Outlook profile
+description: Stale cached credential in Credential Manager is holding the pre-reset token...
+confidence: 94
+script_template_slug: clear-outlook-credentials # or omitted if no template match
+ai_drafted_script: | # only if no template match
+ # Generated by FlowPilot...
+ ...
+[/SUGGEST_FIX]
+```
+
+### 8.3 Removed markers
+
+The old `[FORK]` marker from the ResolutionAssist prompt is removed. Forks were a Guided-mode concept; in the unified model, they're replaced by Questions with mutually exclusive answer options.
+
+---
+
+## 9. Implementation phases
+
+Each phase ends with a git commit and verification step. Do not advance to the next phase until verification passes.
+
+### Phase 0 — Prompt caching infrastructure (prerequisite)
+
+A codebase audit revealed that prompt caching is only implemented in `assistant_chat_service.py` (the file being deprecated). Every other Anthropic API call site — including all of FlowPilot's 7 call sites through `AnthropicProvider` — is uncached. Phase 0 must land before Phase 2 starts because new services built in Phase 2 will inherit caching from `AnthropicProvider` automatically once it's fixed.
+
+**Deliverables:**
+
+- **0.1** Promote `AnthropicProvider.generate_json()` and `generate_text_stream()` in `ai_provider.py` to the cached pattern currently implemented in `assistant_chat_service.py:_call_anthropic_cached()`. Convert the `system` string parameter to a structured system block list with `cache_control: {"type": "ephemeral"}` on the static portion. Add a second breakpoint on the last history message. For the streaming variant, capture the final usage object via `get_final_message()`. Log `cache_read_input_tokens` and `cache_creation_input_tokens` on every response.
+- **0.2** Update `integrations.py:557` (`/tickets/ai-parse`) to move the members list and team-stable boards data into a cached system block.
+- **0.3** Add `cache_control` to one-shot generators: `ai_tree_generator`, `kb_conversion`, `ai_fix`, `script_builder`. Same pattern as 0.1.
+- **0.4** Extract the caching logic from `assistant_chat_service.py:_call_anthropic_cached()` into `AnthropicProvider` and delete `_call_anthropic_cached`. `assistant_chat_service` should call the provider like every other service. This prevents two canonical implementations of the same pattern.
+
+**Verification:**
+
+- Hit any FlowPilot endpoint twice within 5 minutes. First call shows `cache_creation_input_tokens > 0`, second call shows `cache_read_input_tokens > 0`.
+- If the second call returns zero cache reads, inspect the prefix for silent invalidators (timestamps, unsorted JSON keys, varying tool list ordering). Fix before proceeding.
+
+```
+git commit -m "feat(ai): promote AnthropicProvider to cached pattern, consolidate caching implementation"
+```
+
+**Dependencies:**
+
+- Phase 1 (route rename and schema) can run in parallel with Phase 0.
+- Phase 2 (What we know) must not start until Phase 0 is complete and verified.
+
+### Phase 1 — Data model and route rename (backend + routing only)
+
+**Deliverables:**
+- Alembic migration creating `session_facts`, `session_suggested_fixes`, `draft_templates` tables and the column additions to `ai_sessions`, `script_templates`, `account_settings`
+- All tables include `account_id` and have RLS policies following the multi-tenant architecture (per existing project standard)
+- `/assistant` → `/pilot` route rename with permanent redirect (stays in place indefinitely; no sunset date)
+- Sidebar nav entry rename
+- No UI changes yet beyond the nav label
+
+**Verification:**
+- Run migration on a fresh dev database
+- Confirm RLS policies active via the existing CI grep check for `tenant_filter()`
+- Navigate to `/assistant` — should 301 to `/pilot`
+- Navigate to `/pilot` — should render the existing ResolutionAssist UI with the sidebar entry now reading "FlowPilot"
+
+```
+git commit -m "feat(pilot): rename /assistant to /pilot, add session_facts + suggested_fixes + draft_templates schema"
+```
+
+### Phase 2 — What we know (task lane + service + API)
+
+**Deliverables:**
+- `FactSynthesisService` and its LLM prompt
+- Fact CRUD API endpoints
+- `WhatWeKnow`, `WhatWeKnowItem`, `AddNoteButton` components
+- Task lane layout adjustment: What we know section renders above Questions
+- Counter in task lane header updates to `X / Y answered` format
+- AI prompt updated to emit `[PROMOTE]` markers; backend parses them and creates facts
+
+**Verification:**
+- Open a session, answer a question; within 2 seconds a fact should appear in What we know with correct provenance
+- Click "+ Add a note", type a manual fact, confirm it appears with `source_type: user_note`
+- Run a diagnostic check, confirm the check result promotes to a fact
+- Facts persist across page reloads
+- RLS: a user from a different account cannot read or write facts for this session
+
+```
+git commit -m "feat(pilot): add What we know section with fact synthesis"
+```
+
+### Phase 3 — Suggested fix + resolution note preview
+
+**Deliverables:**
+- `session_suggested_fixes` API endpoints and data flow
+- `SuggestedFix` component in the task lane
+- AI prompt updated to emit `[SUGGEST_FIX]` markers
+- `ResolutionNoteGeneratorService` and preview endpoint
+- `ResolutionNotePreview` floating popover anchored to Resolve button
+- Preview refreshes on fact / suggested-fix changes (debounced)
+
+**Verification:**
+- Session with ≥3 facts and an active suggested fix shows a populated Resolve preview
+- Editing a fact updates the preview within 1 second
+- Preview markdown renders correctly with all four sections (Problem / What we confirmed / Root cause / Resolution)
+- Preview contains no hallucinated information not present in session state (human review of 5 real-ish sessions)
+
+```
+git commit -m "feat(pilot): add suggested fix tracking and Resolve note preview"
+```
+
+### Phase 4 — Resolve and Escalate PSA writebacks
+
+**Deliverables:**
+- `transition_ticket_status` method with CW verification
+- `post_resolution_note` endpoint and CW integration
+- Resolve button fires: post note → transition status → mark session resolved → show templatize prompt (if applicable)
+- `EscalationPackageGeneratorService` and parallel flow for Escalate
+- Escalate button fires: post package → transition status → mark session escalated → route via CW rules
+
+**Verification:**
+- Complete a session end-to-end with a ConnectWise test instance
+- Click Resolve, edit the preview, confirm post — verify the note appears in CW and status changes to Resolved
+- Click Escalate on a different session — verify the package is posted and the ticket routes correctly
+- Attempt to Resolve without a linked PSA ticket — should mark the session resolved without erroring, note stored in `resolution_note_markdown` only
+
+```
+git commit -m "feat(pilot): wire Resolve and Escalate to ConnectWise writeback"
+```
+
+### Phase 5 — Script Generator inline integration
+
+**Deliverables:**
+- `ScriptGenInline/TemplateMatchPanel` — when suggested fix has `script_template_id`, clicking the fix opens this panel with pre-filled parameters from session context
+- Parameter pre-fill logic: pulls from session facts, ticket context (company configs), and AI-suggested values in the `[SUGGEST_FIX]` marker
+- `ScriptGenInline/NoTemplateDialog` — three-option dialog when no template match
+- User decision persisted on `session_suggested_fixes.user_decision`
+- `TemplateExtractionService` for generating parameterization proposals
+- Script generation flow produces a `script_generations` record linked to the session (existing Script Generator behavior)
+
+**Verification:**
+- Session with a template-matched suggested fix: clicking opens generator with ≥2 pre-filled parameters
+- Session with a custom script suggested fix: dialog appears with three options, script preview shows parameters highlighted
+- All three paths end correctly: one-off generates and closes, draft creates `draft_templates` row and generates, build_template opens full template creation
+- `⌘K` → "script" anywhere in a session opens the generator directly
+
+```
+git commit -m "feat(pilot): integrate Script Generator inline with suggested fixes"
+```
+
+### Phase 6 — Post-resolve templatize prompt
+
+**Deliverables:**
+- `TemplatizePrompt` component
+- Logic: after Resolve success, check for pending `draft_templates` rows for this session; if any, show the prompt
+- Accept flow creates a new `script_templates` row with `source_session_id`, `source_user_id`, `source_ticket_ref` set
+- "Don't ask me again" writes to `account_settings.templatize_prompt_enabled`
+- Script Library sidebar shows a small badge when `draft_templates` with `status='pending'` exist for the current user
+
+**Verification:**
+- Resolve a session where the engineer picked Option 2 — templatize prompt appears with AI-proposed parameters
+- Accept the prompt — new template appears in the Script Library with the provenance chip ("generated from CW #...")
+- Skip the prompt — draft marked rejected, Script Library shows no new template
+- Toggle "don't ask me again" — next session Resolve skips the prompt even with a pending draft
+
+```
+git commit -m "feat(pilot): add post-resolve templatize prompt for draft templates"
+```
+
+### Phase 7 — Polish
+
+**Deliverables:**
+- Visual polish against the mockup files (spacing, colors, animations)
+- Loading states for LLM calls (fact synthesis, preview generation, template extraction)
+- Empty states (new session with no facts yet, no active suggested fix, no draft templates pending)
+- Keyboard shortcuts: `⌘K` (command menu), `⌘↵` (send composer), `⌘G` (generator), `⌘R` (resolve with confirm)
+- Responsive behavior: task lane collapses on <1200px viewports into a bottom drawer
+
+**Verification:**
+- Compare each major screen side-by-side with the mockup PNG files — colors, spacing, typography within 5px / exact color match
+- All flows work on a 1280px viewport without horizontal scroll
+- Keyboard shortcuts documented in-app via `?` overlay
+
+```
+git commit -m "feat(pilot): visual polish and keyboard shortcuts"
+```
+
+---
+
+## 10. Design system reference
+
+All components must use the existing ResolutionFlow design system. Pulling the key tokens from the mockup CSS for quick reference — these should already exist in your tokens file; if they don't, add them:
+
+```css
+/* Backgrounds */
+--bg-0: #070b12; /* page background */
+--bg-1: #0d131c; /* sidebar / chrome */
+--bg-2: #121a25; /* card / bubble background */
+--bg-3: #1a2332; /* raised element */
+
+/* Borders */
+--border: rgba(148, 163, 184, 0.12);
+--border-strong: rgba(148, 163, 184, 0.22);
+
+/* Text */
+--text-primary: #e2e8f0;
+--text-secondary: #94a3b8;
+--text-tertiary: #64748b;
+
+/* Brand cyan (FlowPilot accent) */
+--cyan-400: #22d3ee;
+--cyan-500: #06b6d4;
+--cyan-600: #0891b2;
+--cyan-bg: rgba(34, 211, 238, 0.10);
+--cyan-border: rgba(34, 211, 238, 0.30);
+
+/* Semantic */
+--success: #34d399; /* Resolve, facts */
+--warning: #fbbf24; /* Escalate, proposed parameters */
+--danger: #f87171;
+--purple: #a78bfa; /* Script Generator / templates */
+```
+
+**Typography:**
+- Body: IBM Plex Sans, 14px/1.5
+- Headings: Bricolage Grotesque, 500 weight, -0.01em letter-spacing
+- Code: JetBrains Mono
+
+**Icons:** Phosphor Icons (Duotone) per the memory-recorded design decision to migrate off Lucide.
+
+---
+
+## 11. Non-goals for this migration
+
+Do not build these as part of this work. They belong to later phases of the roadmap.
+
+- **Confidence tiers (Discovery / Exploring / Guided).** We explicitly removed these. The task lane itself is the progress signal.
+- **Mode toggle between Guided and Quick ask.** There is one mode.
+- **"Convert to guided" promotion flow.** No longer applicable.
+- **Team Wiki compilation from resolved sessions.** Tracked separately; depends on this migration but is not part of it.
+- **SharePoint integration.** Sequenced after ConnectWise per roadmap.
+- **Template marketplace / sharing across accounts.** Tracked under Client Context System roadmap item.
+
+---
+
+## 12. Risks and mitigations
+
+| Risk | Mitigation |
+|---|---|
+| LLM fact synthesis hallucinates specifics not in the answer | Conservative prompt; engineer can edit/delete any AI-synthesized fact; provenance line shows the source so the engineer can verify |
+| Resolution note preview LLM cost at scale | Cache aggressively, invalidate only on session state write; debounce UI updates to 500ms; consider lower-tier model for preview generation (final post-to-CW version can use the better model) |
+| ConnectWise silently rejects status change | `transition_ticket_status` must re-fetch and verify; fail loudly if the change didn't stick |
+| Template extraction proposes bad parameterization | Engineer reviews before saving; draft templates never silently become real templates; provenance chip lets team admins audit |
+| Users lose muscle memory from `/assistant` → `/pilot` rename | Permanent redirect (no sunset date); inline toast on first `/pilot` visit explaining the rename |
+| Existing sessions have no `session_facts` entries, so What we know is empty | Acceptable — Phase 2 deliberately does not backfill; facts only accumulate for new or ongoing sessions after deploy. Document in release notes. |
+
+---
+
+## 13. Questions for Michael before implementation starts
+
+These are the decisions Claude Code cannot make unilaterally. Answer these inline in the doc or in chat before kicking off Phase 1.
+
+1. **Keyboard shortcut for Resolve** — I've proposed `⌘R` (with a confirm). Browsers intercept `⌘R` for page reload. Alternative: `⌘⇧R` or no shortcut. Preference?
+2. **Default `templatize_prompt_enabled` value** — I defaulted to `true`. If your beta testers find it annoying we'll learn fast, but it's a tradeoff between "every engineer sees the prompt" and "feature gets discovered only by those who know about it".
+3. **Resolution note posts immediately, or stage for review?** — Current design: engineer edits preview inline, clicks Confirm & post. Alternative: stage in CW as draft note for a supervisor to approve before posting. Affects MSPs with strict compliance.
+
+---
+
+## End of document
diff --git a/docs/FlowAssist_Migration/mockups/01-session-primary.html b/docs/FlowAssist_Migration/mockups/01-session-primary.html
new file mode 100644
index 00000000..a07c66e4
--- /dev/null
+++ b/docs/FlowAssist_Migration/mockups/01-session-primary.html
@@ -0,0 +1,1320 @@
+
+
+
+ User jsmith can't sync Outlook after the password reset at 14:02. AD shows unlocked, license is active. Works on OWA fine.
+
+
+
+
+
+
FP
+
+
FlowPilot
+
+ Classic pattern after a password reset when OWA works but Outlook doesn't — the stale auth token on the client hasn't been invalidated, or the Autodiscover cache is pointing at the old credential state. I've pushed a few questions and diagnostic checks to the task lane to narrow it.
+
+ Answer what you already know and I'll run the rest as we go.
+
+
+
+
+
+
MD
+
+
You
+
+ OWA confirmed working, password was reset via AD not SSPR, and it's only this user — others on the same tenant are fine.
+
+
+
+
+
+
FP
+
+
FlowPilot
+
+ Got it — I've promoted those three facts into What we know. That narrows it to a client-side token/cache issue, not tenant or license.
+
+ The Autodiscover check is the fastest way to confirm. Run Test-OutlookConnectivity -Identity jsmith from the DC, or click the check in the task lane.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Resolution note preview
+
+
Generated from What we know + resolution action
+
+ Will post to CW #48291 · status will change to Resolved
+
+
+
+
Problem
+
User jsmith@acme.com unable to sync Outlook desktop following AD password reset at 14:02. OWA functioning normally.
+
+
What we confirmed
+
+
OWA login and mail flow working for affected user
+
Password reset performed via AD (not SSPR)
+
Issue isolated to single user — tenant-wide sync healthy
+
AD unlocked, Exchange Online license active
+
+
+
Root cause
+
Stale cached credential in Windows Credential Manager holding the pre-reset authentication token, preventing Outlook from completing the new auth handshake.
+
+
Resolution
+
Cleared cached credentials via rundll32.exe keymgr.dll, removed the Autodiscover cache entry, and rebuilt the Outlook profile. Sync resumed within 30 seconds of profile reload.
+ Three states showing how script creation flows from a FlowPilot session — matched template, custom script with three-option dialog, and the post-resolve templatization prompt.
+
+
+
+
+
+
+
+
+
+
1
+ Template match
+
+
Suggested fix has a matching template
+
+ When FlowPilot's suggested fix maps to a template in the Script Library, clicking opens the generator with parameters pre-filled from What we know. The engineer confirms, generates, done.
+
+
+
+
+
+
+
+
+
resolutionflow.com/pilot/session/48291
+
+
+
+
+
+
+ CW #48291
+
Outlook not syncing after password reset
+
Acme Corp · jsmith@acme.com · P2 · Service board
+
+
+
+
+
+ What we know · 4 facts
+
+
+
✓OWA working — rules out tenant/license
+
✓Password reset via AD at 14:02
+
✓Isolated to jsmith — not tenant-wide
+
✓AD unlocked, EXO license active
+
+
+
+
+
+
+ Suggested fix · template found94% match
+
+
Clear cached credentials + rebuild Outlook profile
+
+ From your team library · resolved 7 similar sessions · last used 3 days ago
+
+
+
+
+
+ You can also invoke the script generator anytime with ⌘K → "script" or from the composer toolbar.
+
+ 3 of 5 parameters pre-filled from session context. Review and adjust the highlighted fields, then generate.
+
+
+
+
Target user
+
+
+
+ SAM account name*
+ from session
+
+
+
Pulled from ticket subject + What we know.
+
+
+
+
+ Domain*
+ from Acme config
+
+
+
Pulled from CW company config for Acme Corp.
+
+
+
Cache targets
+
+
+
+ Clear Windows Credential Manager entries*
+
+
+
Wildcard patterns. Default covers Outlook + ADAL cached tokens.
+
+
+
+
+ Clear Autodiscover cache
+
+
+
+
+
Profile rebuild
+
+
+
+ Rebuild strategy
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
2
+ No template match
+
+
AI generates a custom script — three paths
+
+ When no existing template matches, FlowPilot drafts a session-specific script and offers three paths. The middle option (one-off now, template later) is the default because it captures institutional knowledge without blocking the engineer mid-crisis.
+
+
+
+
+
+
+
+
+
resolutionflow.com/pilot/session/48307
+
+
+
+
+
+
+ CW #48307
+
VPN session torn down every 3–5 minutes
+
Duncan & Partners · GlobalProtect · P3
+
+
+
+
+
+ What we know · 3 facts
+
+
+
✓Gateway logs show GPTunnel: session timeout every 3–5min
+
✓Happens on both wifi and LAN — not network-path
+
✓Gateway-side teardown confirmed via PAN XML API
+
+
+
+
+
+
+ Suggested fix · custom script
+
+
Query & clear duplicate sessions from GP gateway
+
+ No template match in your library · AI drafted this from session context.
+
+
+
+
+
+
+
+
+ No template match — how would you like to proceed?
+
+
+ FlowPilot has drafted a PowerShell script for this ticket
+
+
+ The script queries the GP gateway's active session table via the PAN XML API and clears duplicates. Pick how this gets saved — the choice affects whether your team benefits from it later.
+
Generate the script for this ticket only. Captured in session documentation. Discarded after.
+
+
+
+ Fastest — no follow-up
+
+
+
+ Team won't benefit next time
+
+
+
+
+
+
+
+
Recommended
+
+
+
+
Run now, templatize after resolve
+
Generate for this ticket. If it works, FlowPilot offers to turn it into a team template when you click Resolve.
+
+
+
+ Zero cognitive overhead now
+
+
+
+ Only templatize what actually works
+
+
+
+ ~30 sec review after resolve
+
+
+
+
+
+
+
+
+
+
+
Build as template now
+
Full parameterization up front. Takes 2–3 min but becomes a first-class team template immediately.
+
+
+
+ Immediate team benefit
+
+
+
+ Adds time mid-ticket
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
3
+ Post-resolve prompt
+
+
Turn what just worked into a reusable template
+
+ After Resolve posts the summary to CW, FlowPilot surfaces the templatization prompt for any custom script that ran successfully. The engineer reviews AI-proposed parameters, adjusts if needed, and ships — or skips.
+
+
+
+
+
+
+
+
+
resolutionflow.com/pilot/session/48307 · resolved
+
+
+
+
+
+
+
+
+
+
+
Session resolved — summary posted to CW #48307
+
+ Status set to Resolved
+ ·
+ 7 minutes total session time
+ ·
+ Custom script ran successfully
+
+
+
+
+
+
+
+
+
+
+
+
One more thing
+
Turn this into a team template?
+
+ The script you just ran resolved the VPN session teardown for D. Field at Duncan & Partners. If a similar ticket comes in next week, your team can skip the analysis and run this in 10 seconds.
+
+ Provenance tracked · this template will show "generated from CW #48307 · resolved by M. Davis" in the library. Visible to your team only until promoted to Verified by an admin.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/FlowAssist_Migration/mockups/02-script-template-match.png b/docs/FlowAssist_Migration/mockups/02-script-template-match.png
new file mode 100644
index 00000000..0361416e
Binary files /dev/null and b/docs/FlowAssist_Migration/mockups/02-script-template-match.png differ
diff --git a/docs/FlowAssist_Migration/mockups/03-script-three-options.png b/docs/FlowAssist_Migration/mockups/03-script-three-options.png
new file mode 100644
index 00000000..c3f7d1a5
Binary files /dev/null and b/docs/FlowAssist_Migration/mockups/03-script-three-options.png differ
diff --git a/docs/FlowAssist_Migration/mockups/04-script-templatize-prompt.png b/docs/FlowAssist_Migration/mockups/04-script-templatize-prompt.png
new file mode 100644
index 00000000..117be997
Binary files /dev/null and b/docs/FlowAssist_Migration/mockups/04-script-templatize-prompt.png differ