From 3ee0101c6d1833c21de723951c37f1c01b60921b Mon Sep 17 00:00:00 2001 From: Michael Chihlas Date: Thu, 23 Apr 2026 23:49:08 -0400 Subject: [PATCH] =?UTF-8?q?docs(pilot):=20Phase=209=20spec=20=E2=80=94=20o?= =?UTF-8?q?wnership=20+=20schema=20corrections?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - scriptBuilderMode ownership: pinned to ScriptBuilderTab, removed from AssistantChatPage's state list. Parent never drives the AI/editor toggle; controller owns it and resets naturally on session switch via unmount/remount. scriptBuilderHasProgress stays on the page (needed for the tab strip indicator dot) and is driven by the controller via an onProgressChange callback. - ScriptBuilderCreateRequest schema: explicitly calls for TWO new optional fields (origin + ai_session_id), not just origin. Handler enforces: when origin='pilot_inline', ai_session_id is required and must pass the current-user ownership check. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../phase-9-script-builder-tab.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/FlowAssist_Migration/phase-9-script-builder-tab.md b/docs/FlowAssist_Migration/phase-9-script-builder-tab.md index babba435..8deb441d 100644 --- a/docs/FlowAssist_Migration/phase-9-script-builder-tab.md +++ b/docs/FlowAssist_Migration/phase-9-script-builder-tab.md @@ -248,12 +248,13 @@ The 5-session cap applies only to `standalone` rows (see §Data-model filter cha ### Frontend state (AssistantChatPage) -New local state: +New local state on the page: - `chatTab: 'chat' | 'script_builder'` — which tab is visible. Defaults to `'chat'`. -- `scriptBuilderMode: 'ai' | 'editor'` — which sub-view inside the Script Builder tab. Defaults to `'ai'`. -- `scriptBuilderHasProgress: boolean` — drives the indicator dot. +- `scriptBuilderHasProgress: boolean` — drives the indicator dot. Set by `ScriptBuilderTab` via an `onProgressChange` callback. -Reset in `resetSessionDerivedState`: all three back to defaults. +Reset in `resetSessionDerivedState`: both back to defaults. + +`scriptBuilderMode` ('ai' | 'editor') lives **inside `ScriptBuilderTab`**, not on the page — the parent never needs to drive the AI/editor toggle. The controller resets it naturally via unmount/remount when the page switches sessions. Banner's Apply handler (`handleApplyFix`) updated: - If no script + no template → set `chatTab = 'script_builder'` (and show tab strip). @@ -344,7 +345,7 @@ Manual verification (no component test harness in this codebase per CLAUDE.md): **Backend — modified:** - `backend/app/models/script_builder_session.py` — add `origin` column only (`ai_session_id` already exists). - `backend/app/schemas/session_suggested_fix.py` — add `SessionSuggestedFixScriptRequest`. -- `backend/app/schemas/script_builder.py` (or equivalent) — add optional `origin` field to the `POST /script-builder/sessions` request schema; default `'standalone'`. +- `backend/app/schemas/script_builder.py` — extend `ScriptBuilderCreateRequest` with two new optional fields: `origin: Literal['standalone', 'pilot_inline'] = 'standalone'` and `ai_session_id: UUID | None = None`. Handler-side validation: when `origin='pilot_inline'`, `ai_session_id` is required (not null) AND must pass the current-user ownership check. Legacy callers pass neither and continue to create standalone sessions as before. - `backend/app/api/endpoints/session_suggested_fixes.py` — add PATCH /script endpoint. Move the existing `applied_at` stamp out of the apply path and into `handleScriptDecision('one_off' | 'draft_template')` plus `TemplateMatchPanel`'s new "I ran this" handler (server side: no change to `/apply`; callers shift instead). - `backend/app/api/endpoints/script_builder.py` — accept `origin` on session creation; enforce the `pilot_inline ⇒ ai_session_id` invariant at the handler level. - `backend/app/services/script_builder_service.py` — persist `origin`; `list_sessions` + `count_user_sessions` filter to `origin='standalone'` by default.