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 + +![Primary session view](mockups/01-session-primary.png) + +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 + +![Template match flow](mockups/02-script-template-match.png) + +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) + +![No template match](mockups/03-script-three-options.png) + +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 + +![Templatize prompt](mockups/04-script-templatize-prompt.png) + +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 @@ + + + + +FlowPilot — unified session + + + + +
+ + + + + + + + +
+
+ + +
+
+
+ CW #48291 + Acme Corp + · + jsmith@acme.com + · + P2 · Service board +
+
Outlook not syncing after password reset
+
+ +
+ + + + +
+
+ + +
+ +
+
MD
+
+
You
+
+ 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.
+
+ +
+
+ +
+ + diff --git a/docs/FlowAssist_Migration/mockups/01-session-primary.png b/docs/FlowAssist_Migration/mockups/01-session-primary.png new file mode 100644 index 00000000..d21d7546 Binary files /dev/null and b/docs/FlowAssist_Migration/mockups/01-session-primary.png differ diff --git a/docs/FlowAssist_Migration/mockups/02-04-script-integration.html b/docs/FlowAssist_Migration/mockups/02-04-script-integration.html new file mode 100644 index 00000000..a0adbc09 --- /dev/null +++ b/docs/FlowAssist_Migration/mockups/02-04-script-integration.html @@ -0,0 +1,1516 @@ + + + + +FlowPilot — Script Generator integration + + + + + +
+
Script Generator · session integration
+
+ 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. +
+ +
+ + + +
+
+ + +
+
+
+
+ + Script Generator +
+
Clear cached credentials + rebuild profile
+
+ +
+ +
+
+ +
+
+ Verified template · v3 · ActiveDirectory module · runs as admin +
+
+ +
+
+ +
+ 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. +
+ +
+
+ drafted script · PowerShell · 32 lines +
+
+
+ proposed parameters +
+
+
+# Query & clear duplicate GP sessions — jsmith @ Duncan +$fw = 'fw01.duncan.law' +$key = 'LUFRPT1...ZG9u' +$user = 'dfield' + +$xml = Invoke-RestMethod -Uri "https://$fw/api/?type=op&cmd=..." +$sessions = $xml.response.result.entry | Where-Object { $_.username -eq $user } +... (show full script) +
+ +
+ +
+
+ +
+
Run as one-off
+
Generate the script for this ticket only. Captured in session documentation. Discarded after.
+
+
+ + Fastest — no follow-up +
+
+ + Team won't benefit next time +
+
+ +
+ + + + + +
+
+ +
+
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. +
+
+
+ +
+
+
Proposed template · parameters highlighted
+
+# Query & clear duplicate GP sessions +# Auto-generated from CW #48307 · D. Field · Duncan + +$fw = {{ gateway_host }} +$key = {{ api_key }} +$user = {{ sam_account_name }} + +$xml = Invoke-RestMethod -Uri "https://$fw/api/?type=op&cmd=<show>..." +$sessions = $xml.response.result.entry | + Where-Object { $_.username -eq $user } + +foreach ($s in $sessions) { + Invoke-RestMethod -Uri "https://$fw/api/?type=op&cmd=<clear>..." + Write-Host "Cleared session $($s.session-id)" +} +
+
+ +
+
+
+ Extracted parameters + 3 proposed +
+ +
+ gateway_host + Firewall hostname + text + +
+ +
+ api_key + PAN API key + password + +
+ +
+ sam_account_name + Target username + text + +
+ + +
+ +
+ +
+ 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