Files
resolutionflow/docs/handoff/2026-04-22-flowpilot-migration.md
Michael Chihlas 65a831bf9a docs(pilot): Phase 9 handoff + migration spec update
Marks open items #1 (NoTemplateDialog narrow-lane) and #3 (Tabbed
Script Builder) as resolved. Records the applied_at semantics
correction as shipped. Final Phase 9 row added to the 'What shipped'
table.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 06:14:41 -04:00

89 lines
10 KiB
Markdown

---
date: 2026-04-22
branch: feat/flowpilot-migration
remote: ssh://gitea.resolutionflow.com/chihlasm/resolutionflow.git
last_commit: faf1d8d fix(pilot): applied_at stamps on run-declaring actions, not Apply click
status: Sprint 9/9 phases complete and pushed; PR not yet opened. Open items #1 and #3 resolved by Phase 9.
---
# FlowPilot Migration — Session Handoff
## Where the work lives
- Branch: `feat/flowpilot-migration` (pushed to Gitea, mirrors to GitHub)
- Spec: [docs/FlowAssist_Migration/FLOWPILOT-MIGRATION.md](../FlowAssist_Migration/FLOWPILOT-MIGRATION.md)
- Mockups: [docs/FlowAssist_Migration/mockups/](../FlowAssist_Migration/mockups/) (PNG + HTML reference)
## What shipped
All nine migration phases are merged onto the branch and verified against the live dev stack (`resolutionflow_frontend` / `resolutionflow_backend` / `resolutionflow_postgres` containers).
| Phase | Commit | What landed |
|---|---|---|
| 0 — baseline telemetry | (pre-branch) | analytics events for funnel deltas |
| 1 — `/assistant``/pilot` rename | early commits | route redirects, sidebar updates |
| 2 — What we know (facts) | (mid) | `session_facts` table, `[PROMOTE]` marker, fact CRUD endpoints, `WhatWeKnow` section |
| 3 — Suggested fix + Resolve preview | `7ccf4c6` and prior | `session_suggested_fixes`, `[SUGGEST_FIX]` marker, `ResolutionNotePreview` popover |
| 4 — Escalate + PSA writeback | `8fd2c1b` | `psa_writeback_service` with status verification, kind-parameterized preview |
| 5 — inline Script Generator | `fa61376` | `TemplateMatchPanel`, `NoTemplateDialog` three-option dialog |
| 6 — post-resolve templatize | `4aaf57a` | `draft_templates` table, accept/reject endpoints, `TemplatizePrompt` modal, account preferences |
| 7 — polish | `8a242f5` | loading/empty states, keyboard shortcuts (`⌘↵`, `⌘G`, `?` overlay), responsive bottom-drawer <1200px |
| 8 — Fix Outcome Banner | `cdd8bb0`..`a47ce07` | Six outcome columns on `session_suggested_fixes` (`status`, `applied_at`, `verified_at`, `partial_notes`, `failure_reason`, `ai_outcome_proposal`) + `PATCH /api/v1/ai-sessions/{sid}/suggested-fixes/{fid}/outcome` endpoint + `[FIX_OUTCOME]` marker; replaces task-lane `SuggestedFix` card with a chat-composer-anchored `ProposalBanner` (5 states: proposed/verifying/partial/ai_confirming/nudge + collapsed); `EscalateInterceptDialog` captures outcome before handoff; Resolve-while-verifying auto-marks success; 17 new tests (8 endpoint + 7 marker + 2 anti-parrot) |
| 9 — Tabbed Script Builder | `5bcb7aa`..`faf1d8d` | Chat-region tab strip (`[Chat] [Script Builder ●]`) with `ChatTabStrip` + `ScriptBuilderTab` (inline `ScriptBuilderChat` in ephemeral mode); `InlineNoTemplateDialog` relocated from task-lane `bottomSlot` to a chat-region placement wrapper; `EscalateInterceptDialog` gains a fourth "partial attempt" choice; `PATCH /api/v1/ai-sessions/{id}/suggested-fixes/{fid}/script` endpoint for writing back AI-drafted script; Alembic migration adds `origin` column + `parent_pilot_session_id` FK to `script_builder_sessions` with partial unique index; `applied_at` semantics corrected to stamp only on run-declaring actions (not the Apply click) |
Plus the structural fixes that came up along the way:
- `50215b9` + `d0ebdef` — full sweep removing literal payloads from AI system prompts; new `tests/test_prompt_anti_parrot.py` guardrail
- `ce7c8ac` + `ddae171` — task-lane state-leak across chats (centralized `resetSessionDerivedState()` helper)
- `8879f96` — dropped `sticky top-0` from all four lane section headers (they were orphaning over unrelated content on scroll)
## How to resume
1. `git checkout feat/flowpilot-migration`
2. `docker compose -f docker-compose.dev.yml up -d` (if the stack isn't running)
3. Verify: `docker exec resolutionflow_frontend sh -c "cd /app && npx tsc -b"` should be clean
4. Live URL: <http://localhost:5173/pilot> (or `<host-ip>:5173/pilot`)
5. Test users (password `TestPass123!`): `engineer@resolutionflow.example.com`
## Open work — pick one
Items #1 and #3 were discovered during Phase 6/7 verification. Item #2 was resolved by Phase 8. Items #1 and #3 are **resolved by Phase 9** (see below).
### 1. NoTemplateDialog narrow-lane bug
**Status: RESOLVED by Phase 9.**
Phase 9 relocated `InlineNoTemplateDialog` from the task-lane `bottomSlot` into a dedicated chat-region placement wrapper (`InlineNoTemplateDialog.tsx`). The dialog no longer renders inside the narrow 380px task lane, eliminating the `sm:grid-cols-3` viewport-breakpoint collision. The disabled-cards bug (when no `ai_drafted_script` is present) is also resolved: when no draft exists, the engineer is routed into the new `ScriptBuilderTab` inline chat instead of reaching the three-option dialog with disabled cards.
See [docs/FlowAssist_Migration/phase-9-implementation-plan.md](../FlowAssist_Migration/phase-9-implementation-plan.md) and [docs/FlowAssist_Migration/phase-9-script-builder-tab.md](../FlowAssist_Migration/phase-9-script-builder-tab.md) for full implementation details.
### 2. Task lane crowding / Suggested Fix discoverability
**Status: RESOLVED by Phase 8.** The `SuggestedFix` card no longer lives inside the scrollable task lane. Phase 8 replaced it with a chat-composer-anchored slide-up banner (`ProposalBanner`) that is always visible at the bottom of the conversation column regardless of how far the task lane has scrolled. The banner is the primary entry point for fix application; the task lane retains a compact read-only summary of the active fix for reference.
See [docs/FlowAssist_Migration/phase-8-fix-outcome-banner.md](../FlowAssist_Migration/phase-8-fix-outcome-banner.md) for the implementation plan and design rationale. Because the banner is now the primary entry point, the NoTemplateDialog narrow-lane bug (open item #1) is considerably less visible — the three-option dialog is only reached after the engineer opts in via the banner, at which point they have already acknowledged the fix.
### 3. Tabbed Script Builder inside the chat (Option A from the modal-vs-tab discussion)
**Status: RESOLVED by Phase 9.**
Phase 9 shipped the complete tabbed Script Builder integration. The chat region now has a `[Chat] [Script Builder ●]` tab strip (`ChatTabStrip`) powered by `ScriptBuilderTab`, which embeds `ScriptBuilderChat` in ephemeral mode (returns script to caller, no standalone `script_templates` row). `display: none` toggling preserves chat scroll position, draft message, and history across tab switches.
The `PATCH /api/v1/ai-sessions/{id}/suggested-fixes/{fid}/script` endpoint writes `ai_drafted_script` + `ai_drafted_parameters` back to the fix record so the three-option dialog unlocks normally after script generation.
The migration added `origin VARCHAR(20) DEFAULT 'standalone'` and `parent_pilot_session_id UUID NULL REFERENCES ai_sessions(id)` to `script_builder_sessions`, with a partial unique index ensuring only one active inline session per pilot session.
See [docs/FlowAssist_Migration/phase-9-implementation-plan.md](../FlowAssist_Migration/phase-9-implementation-plan.md) and [docs/FlowAssist_Migration/phase-9-script-builder-tab.md](../FlowAssist_Migration/phase-9-script-builder-tab.md) for full implementation details.
## Loose ends / things to verify on resume
- **PR not opened.** Branch is pushed but no Gitea PR yet. When ready: `gh pr create` works against the GitHub mirror, but the actual review happens in Gitea.
- **`/ultrareview` not run** on the final state of the branch (including Phase 9). Worth doing before PR creation.
- **Phase 9 browser QA not done.** The new tab strip, `ScriptBuilderTab`, `InlineNoTemplateDialog` chat-region placement, and `EscalateInterceptDialog` fourth-choice flow have not been exercised in a headless-browser session. Key states to cover: tab strip renders and toggles without unmounting chat; ephemeral Script Builder returns a script and unlocks the three-option dialog; partial-attempt choice in `EscalateInterceptDialog` is recorded correctly.
- **Phase 8 browser QA not done.** The `ProposalBanner` and `EscalateInterceptDialog` (three-choice variant) have not been exercised in a headless-browser session. Key states: banner appears on `[FIX_OUTCOME]` marker; banner dismisses correctly; escalate mid-fix triggers dialog; banner auto-collapses after session resolved. Use `/qa` or `/design-review` against `mockups/06-slide-up-banner.html` and `mockups/07-verify-states.html`.
- **Phase 7 visual verification was structural only** — `tsc -b` and `npm run build` both clean, HMR applied each change without error, but no headless-browser screenshot comparison against the mockup PNGs. If you want pixel-level verification, `/qa` or `/design-review` would catch deltas.
- **Anti-parrot test runs as part of `pytest`** but is not enforced in any specific CI step yet — verify `tests/test_prompt_anti_parrot.py` is discovered by the existing pytest run, and consider failing CI explicitly on regression.
## Files most likely to need attention next
- [frontend/src/pages/AssistantChatPage.tsx](../../frontend/src/pages/AssistantChatPage.tsx) — 1500+ lines, the central pilot orchestrator. Most state-leak and rendering bugs surface here first. Search for `resetSessionDerivedState` to see the chat-switch reset pattern.
- [frontend/src/components/assistant/TaskLane.tsx](../../frontend/src/components/assistant/TaskLane.tsx) — accepts `whatWeKnowSlot` / `bottomSlot` from the parent, plus a `variant: 'side' | 'drawer'` for responsive. `bottomSlot` remains active (carries `TemplateMatchPanel` + resolve/escalate preview buttons in both side and drawer variants).
- [backend/app/services/unified_chat_service.py](../../backend/app/services/unified_chat_service.py) — owns marker parsing for `[PROMOTE]`, `[SUGGEST_FIX]`, `[QUESTIONS]`, `[ACTIONS]`, `[FORK]`, `[TREE_UPDATE]`. If markers stop firing in chat, this is the first place to check.
- [backend/app/services/assistant_chat_service.py](../../backend/app/services/assistant_chat_service.py) — `ASSISTANT_SYSTEM_PROMPT` constant. Anti-parrot test enforces no literal payloads here; use `<placeholder>` syntax only.