Files
resolutionflow/docs/handoff/2026-04-22-flowpilot-migration.md
Michael Chihlas d386d11af2
All checks were successful
Mirror to GitHub / mirror (push) Successful in 4s
docs(pilot): correct Phase 9 migration description
Handoff + migration spec incorrectly claimed Phase 9 added a new
parent_pilot_session_id FK. The implementation reuses the existing
ai_session_id column; the migration only adds the origin discriminator
+ partial unique index. Also: ScriptBuilderTab wraps ScriptBuilderChat
and ScriptBodyEditor (Monaco), not "ScriptBuilderChat in ephemeral
mode" — there is no ephemeral mode on the presentational component.

Applies applied_at call-site specifics: handleScriptDecision stamps
on one_off/draft_template, TemplateMatchPanel stamps on onMarkRun,
Script Builder tab Submit does not stamp.

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

11 KiB

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

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 + new ScriptBuilderTab controller wrapping the existing ScriptBuilderChat + Monaco editor (ScriptBodyEditor); InlineNoTemplateDialog relocates the existing NoTemplateDialog from the narrow task-lane bottomSlot to a chat-region placement wrapper; EscalateInterceptDialog gains a fourth "partial" choice; PATCH /api/v1/ai-sessions/{sid}/suggested-fixes/{fid}/script endpoint for engineer-drafted scripts (does not stamp applied_at); Alembic migration adds origin VARCHAR(20) to script_builder_sessions (reuses existing ai_session_id FK) + partial unique index on (user_id, ai_session_id) WHERE origin='pilot_inline' for idempotent get-or-create; applied_at semantics corrected to stamp only on run-declaring actions (handleScriptDecision for one_off/draft_template; new onMarkRun on TemplateMatchPanel) — 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 and docs/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 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 a new ScriptBuilderTab controller that wraps the existing (untouched) ScriptBuilderChat for AI mode and ScriptBodyEditor (Monaco) for a "Write it myself" editor mode. display: none toggling preserves chat scroll position, draft message, and editor buffer across tab switches.

The PATCH /api/v1/ai-sessions/{sid}/suggested-fixes/{fid}/script endpoint writes ai_drafted_script + ai_drafted_parameters back to the fix record without stamping applied_at — a draft is not an application. Bumps state_version so cached Resolve/Escalate previews regenerate.

The migration added origin VARCHAR(20) NOT NULL DEFAULT 'standalone' (with CHECK constraint on the two valid values + invariant that origin='pilot_inline' requires ai_session_id IS NOT NULL) to script_builder_sessions. It reuses the pre-existing ai_session_id FK rather than adding a new parent column. A partial unique index on (user_id, ai_session_id) WHERE origin='pilot_inline' backs get-or-create idempotency from the inline tab.

See docs/FlowAssist_Migration/phase-9-implementation-plan.md and docs/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 (AI + editor modes), 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 or losing editor buffer; Script Builder tab Submit persists script via PATCH without stamping applied_at; one_off/draft_template decisions DO stamp; build_template does NOT stamp; TemplateMatchPanel "I ran this" stamps via onMarkRun; 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 onlytsc -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