diff --git a/.ai/HANDOFF.md b/.ai/HANDOFF.md index 3677ad80..bfca176f 100644 --- a/.ai/HANDOFF.md +++ b/.ai/HANDOFF.md @@ -2,32 +2,24 @@ # HANDOFF.md -**Last updated:** 2026-05-01 (session 6 — PR #156 QA'd, merged, branch deleted) +**Last updated:** 2026-05-01 (session 9 — started issue cleanup plan sections 1 and 2) **Active task:** None. Pick next from `.ai/TODO.md` or roadmap. -**Just-merged:** PR #156 (suggested-fix `applied_pending` non-terminal outcome) merged into `main` as `3ba4532`. +**Just-updated:** issue cleanup plan sections 1 and 2 were started and documented. ## Where this session ended -PR #156 QA'd in the dev environment and merged. +Issue cleanup plan follow-up completed: -1. Working tree had two commits' worth of pending work: the prior session's local review fixes (5 source files + 3 `.ai/` notes describing them) and this session's docker-exec docs (`.ai/PROJECT_CONTEXT.md` + `AGENTS.md`). Committed each as a separate logical commit, attributed to the agent that authored each. -2. Browser QA via `/qa`: 5 of 7 scripted checks PASS with concrete DB-level + UI-level evidence — PendingBanner rendering, "It worked" / "Update reason" / "Dismiss" actions, page-level Resolve auto-patch, Escalate intercept with new generalized copy. 2 entry-path checks (VerifyingBanner overflow → "Waiting to verify…", nudge "Still checking") deferred because they require live AI-generated chat state. The mutating handlers behind those entry paths are verified via the tested transitions, so risk is rendering-only. -3. Pushed `feat/fix-pending-verification` to remote. Required Gitea CI checks (`CI / frontend`, `CI / backend`) plus `CI / e2e` all green at merge. Merged via Gitea API as a merge commit (`3ba4532`). -4. Local `main` fast-forwarded to remote; `feat/fix-pending-verification` deleted locally and on the remote. - -**Validation evidence:** - -- `/gstack/qa-reports/qa-report-pending-verification-2026-04-30.md` — full report with screenshots in `screenshots/`. -- Gitea PR #156 state: `closed`, `merge_commit_sha=3ba45326`, `merged_at=2026-05-01T03:42:10Z`. +- Section 1: frontend lint is clean. Stale lint disables from the warning set were removed or replaced with justified comments, hook dependency warnings were resolved, e2e selectors were added for session history and the FlowPilot command-palette entry, and `AssistantChatPage` now logs unexpected `currentChatRef` stale async discards. +- Section 2: `TaskLane` action cards now have diagnostic help affordances for common commands (connectivity, DNS, IP config, event logs, services, and generic checks). #128 was documented as "keep existing responsive side-panel/bottom-drawer behavior unless pilot feedback proves a preference is needed." +- Updated `docs/plans/2026-05-01-issue-cleanup-plan.md` with section 1/2 status and validation. +- Validation passed: `docker exec -w /app resolutionflow_frontend npm run lint`, `docker exec -w /app resolutionflow_frontend npx tsc -b`, and `docker exec -w /app resolutionflow_frontend npm run build` (existing Vite large-chunk warning only). ## Resume point — DO THIS NEXT -Pick a task from `.ai/TODO.md` or `03-DEVELOPMENT-ROADMAP.md`. Two non-blocking follow-ups for the just-shipped feature: - -- Drive checks 1 and 5 from the QA report in real pilot usage to close the entry-path UI rendering gap. -- Watch whether engineers lose track of multiple pending fixes across sessions; if so, revisit the cross-session "Follow-ups" rollup that was scoped out of PR #156. +If tracker auth is available, close #127 and close/archive stale PR #124; rewrite #66 to template packs / one-click install only. Then continue the plan at section 3: #58 structured "step is wrong" quality signals. After that, section 4 is #60 recurring issue detection and section 5 is #129 hierarchical guide navigation. ## Environment notes (carry-forward) diff --git a/.ai/SESSION_LOG.md b/.ai/SESSION_LOG.md index 5fbad84a..57a41ebd 100644 --- a/.ai/SESSION_LOG.md +++ b/.ai/SESSION_LOG.md @@ -12,6 +12,33 @@ --- +## 2026-05-01 07:20 UTC — Codex — Start issue cleanup plan sections 1 and 2 + +- Started `docs/plans/2026-05-01-issue-cleanup-plan.md` sections 1 and 2. +- Cleaned frontend lint to zero warnings by removing stale lint disables, tightening hook dependencies, and adding justified comments where effects are intentionally keyed to route or owner identity. +- Added e2e selectors for session history controls and the FlowPilot command-palette entry. +- Added `AssistantChatPage` observability for unexpected `currentChatRef` stale async discards. +- Added `TaskLane` diagnostic help affordances for common command categories and documented #128 as "keep the existing responsive side-panel/bottom-drawer behavior until pilot feedback says otherwise." +- Verified `npm run lint`, `npx tsc -b`, and `npm run build` in `resolutionflow_frontend`; build only reported the existing Vite large-chunk warning. +- Files touched: frontend lint-cleanup files, `frontend/src/components/assistant/TaskLane.tsx`, `frontend/src/pages/AssistantChatPage.tsx`, `frontend/src/pages/SessionHistoryPage.tsx`, `frontend/src/components/layout/CommandPalette.tsx`, `docs/plans/2026-05-01-issue-cleanup-plan.md`, `.ai/HANDOFF.md`, `.ai/SESSION_LOG.md`. + +## 2026-05-01 06:05 UTC — Codex — Clean stale TODOs and add issue cleanup plan + +- Removed the resolved pytest-xdist item from `.ai/TODO.md` and reset "Up next" to no selected task. +- Removed the resolved "Add role gate to handoff claim endpoint" backlog item from `.ai/TODO.md`. +- Updated the frontend lint cleanup TODO from 23 warnings to the current `npm run lint` result: 24 warnings, 0 errors. +- Tried to close Gitea #127 through the API, but this environment has no Gitea token; API returned `401 token is required`. +- Added `docs/plans/2026-05-01-issue-cleanup-plan.md` with safe tracker actions and a recommended order for clearing remaining issues. +- Files touched: `.ai/TODO.md`, `.ai/HANDOFF.md`, `.ai/SESSION_LOG.md`, `docs/plans/2026-05-01-issue-cleanup-plan.md`. + +## 2026-05-01 05:40 UTC — Codex — Audit TODO backlog and Gitea issue validity + +- Compared `.ai/TODO.md`, inline code TODOs, and open Gitea issues against current `main`. +- Verified pytest-xdist is already shipped (`backend/requirements-dev.txt`, `backend/tests/conftest.py`, `.gitea/workflows/ci.yml`) so the `.ai/TODO.md` xdist item is stale. Ran frontend lint in Docker; current state is `0 errors, 24 warnings`, so the lint cleanup item remains valid but its count is stale. +- Verified Gitea issue status: #58, #60, #128, #129, #130 remain valid; #66 is partially resolved by current `.rfflow` import/export and should be narrowed to template packs/marketplace; #127 is mostly resolved by current UI copy and prompt boundaries unless an always-visible scope badge is still wanted. Open PR #124 is stale/unmergeable against current `main`. +- Verified inline TODOs still valid: post-session contextual feedback prompt, FlowPilot analytics domain/time-entry placeholders, prompt-cache verification note unless live telemetry has confirmed it, proposal `modify` flow editor wiring, and procedural ghost-step accept/dismiss buttons. +- Files touched: `.ai/HANDOFF.md`, `.ai/SESSION_LOG.md`. + ## 2026-05-01 03:45 UTC — Claude Opus 4.7 — QA, merge, and ship PR #156 pending-verification - Committed two logical units of pending work on `feat/fix-pending-verification`: prior session's local review fixes as `5bee264` (Codex-attributed, 5 source files + 3 `.ai/` notes) and this session's docker-exec docs as `15042af` (Claude-attributed, `.ai/PROJECT_CONTEXT.md` + `AGENTS.md`). Cleaned up a 20MB `core.22120` Chromium dump left behind by an earlier sandbox crash. diff --git a/.ai/TODO.md b/.ai/TODO.md index 3f5ab56d..438c6e20 100644 --- a/.ai/TODO.md +++ b/.ai/TODO.md @@ -5,11 +5,11 @@ ## Up next -- [ ] **Parallelize backend pytest with pytest-xdist.** ✅ landing as PR #151. Verified locally: backend suite 22 min → 4m 28s with `-n auto` on the 8-core homelab runner. Per-worker DB isolation via `PYTEST_XDIST_WORKER` in conftest.py. +None selected. Pick from the backlog below or `03-DEVELOPMENT-ROADMAP.md`. ## Backlog -- [ ] **Frontend lint warnings cleanup.** 23 `react-hooks/exhaustive-deps` warnings remain after PR #149 (mostly missing-deps in useEffect). Either fix them or audit them for known-safe ones and add eslint-disable comments. Not blocking CI today. +- [ ] **Frontend lint warnings cleanup.** `npm run lint` currently reports 24 warnings (0 errors): mostly `react-hooks/exhaustive-deps` plus a few unused eslint-disable directives. Either fix them or audit known-safe ones and add/remove eslint-disable comments intentionally. Not blocking CI today. - [ ] **Audit `filterwarnings` ignores added in `wip(handoff): restore backend suite to green`.** Codex added narrow `ResourceWarning` filters for unclosed socket/transport/event-loop noise from pytest-asyncio teardown. Worth periodically reviewing whether those are still needed (e.g. when bumping pytest-asyncio) — if a real warning appears in those forms it would be silenced. - [ ] **Add `data-testid` attributes to e2e-critical interactive elements.** PR #152 fixed five Playwright tests by chasing UI-text changes (`Sessions` → `Session History`, `Account Settings` → `Account Management`, `/assistant` → `/pilot`, "Flow Sessions" tab, Resume button on session cards). Each was a one-line selector update, but every UI churn re-breaks them. Adding stable `data-testid` attributes on the targeted elements (page heading wrappers, tab nav, primary action buttons) and switching tests to `getByTestId` would make these immune to copy/route renames. Scope it small — start with `SessionHistoryPage` heading, the AI/Flow Sessions tab buttons, the per-session `Resume` button, and the command-palette FlowPilot option. - [ ] **Per-test transactional rollback in `test_db` fixture.** Bigger engineering than xdist (which we already shipped). Instead of `DROP SCHEMA public CASCADE` per test, wrap each test in a savepoint and rollback at teardown. ~30-40% additional speedup on top of xdist for test-DB-heavy tests. Real refactor; only worth it if the suite gets significantly larger or runs more frequently. @@ -20,4 +20,6 @@ - [ ] **Mobile/responsive design for EscalationQueue + handoff-context screen.** Pre-PMF wedge demo targets desktop only — MSP techs work on laptops/desktops in shop environments. Once 3+ paying customers exist and a tech requests mobile (likely on-call use case), spec the responsive behavior: stacked card layout below `sm:` breakpoint, full-bleed handoff-context overlay on mobile, swipe-to-claim gesture instead of Pick Up button. Surfaced from /plan-design-review on the Escalation-Mode wedge plan. -- [ ] **(MOVED IN-SCOPE for Escalation Mode v1, 2026-04-27)** ~~Add role gate to handoff claim endpoint.~~ Codex review correctly flagged this as wedge-relevant (the race-condition story depends on auth gating). Now part of the Escalation Mode v1 build, not a deferred TODO. +- [ ] **`bg-card-hover` Tailwind class doesn't resolve.** [`frontend/src/components/layout/CommandPalette.tsx:450-451`](../frontend/src/components/layout/CommandPalette.tsx) uses `bg-card-hover` as a Tailwind utility, but Tailwind v4 generates `bg-{token}` from `--color-{token}` — and the token in [`frontend/src/index.css:15`](../frontend/src/index.css) is `--color-bg-card-hover`, which generates `bg-bg-card-hover`, not `bg-card-hover`. So those classes silently produce nothing. Other call sites (KnowledgeBaseCards, TeamSummary, ProposalBanner) use the explicit `hover:bg-[var(--color-bg-card-hover)]` form which works. Fix: change the CommandPalette classes to the explicit-var form, OR add a `--color-card-hover` semantic mapping in index.css alongside `--color-card`. Surfaced 2026-05-01 during impeccable polish sweep. + +- [ ] **`ConcludeSessionModal` paused/escalated step forces single-artifact choice — should allow multi-select.** [`frontend/src/components/assistant/ConcludeSessionModal.tsx`](../frontend/src/components/assistant/ConcludeSessionModal.tsx) ~lines 430-474 ("Paused/Escalated: status update options"). Today the engineer clicks ONE of Ticket Notes / Client Update / Email Draft, the buttons disappear, and the result replaces them. Real MSP escalations almost always need at least two: technical notes for the next engineer's PSA AND a non-technical client update. Same for pause (client update + ticket notes for context when resuming). Recommended shape: multi-select with smart defaults — three checkboxes (`☑ Ticket Notes ☑ Client Update ☐ Email Draft`); for `escalated` pre-check Ticket Notes + Client Update; for `paused` pre-check Client Update only. One "Generate" button fires all selected in parallel via existing `aiSessionsApi.generateStatusUpdate(...)` (already supports the three `audience` values: `ticket_notes`, `client_update`, `email_draft`). Each result renders in its own card with its own Copy / Post-to-PSA / Send-Email action. Surfaced 2026-05-01. Feature work, not polish — touches streaming wiring for parallel calls. diff --git a/docs/plans/2026-05-01-issue-cleanup-plan.md b/docs/plans/2026-05-01-issue-cleanup-plan.md new file mode 100644 index 00000000..25fbf983 --- /dev/null +++ b/docs/plans/2026-05-01-issue-cleanup-plan.md @@ -0,0 +1,81 @@ +# Issue Cleanup Plan - 2026-05-01 + +## Tracker Hygiene + +These are safe tracker updates before any feature work: + +1. Close Gitea #127 (`feat: show AI content scope indicator`) unless an always-visible badge is still desired. + - Current code already has IT/MSP scope copy in the assistant empty state. + - `ASSISTANT_SYSTEM_PROMPT` also has an off-domain redirect boundary. +2. Rewrite Gitea #66 (`Tree Templates + Import/Export`) to the remaining scope only. + - `.rfflow` export/import is implemented in `tree_transfer.py` and exposed in the library UI. + - Remaining work: curated packs, authenticated one-click install from gallery, template versioning, marketplace/community path. +3. Close or archive open PR #124 (`feat/cockpit-harness`). + - It is unmergeable against current `main` and overlaps newer `/pilot` work. +4. Keep Gitea #58, #60, #128, #129, #130 open. + - They still describe real product gaps. + +## Recommended Order + +### 1. Low-Risk Maintenance + +- Status: started 2026-05-01. +- Frontend lint is clean after removing stale disable comments and tightening hook dependencies. +- Added `data-testid` selectors for e2e-critical session history and FlowPilot command-palette controls. +- Added `AssistantChatPage` observability for unexpected `currentChatRef` guard mismatches so stale async discards are visible in the console. + +Why first: these reduce future regression cost and are small, well-bounded changes. + +### 2. Pilot UX Friction + +- Status: started 2026-05-01. +- #130: Added diagnostic command help affordances in `TaskLane` action cards. Each active diagnostic card can explain what it checks, what to look for, and when to use it. +- #128: Keep the existing responsive drawer behavior for now. `TaskLane` already uses a side panel on wide screens and a bottom drawer below the desktop breakpoint; do not add a top/side preference unless pilot feedback shows the current responsive layout is blocking workflow. +- EscalationQueue mobile design stays deferred until a customer asks for it. + +Why second: this improves the current FlowPilot wedge without changing core data models. + +Validation run: + +- `docker exec -w /app resolutionflow_frontend npm run lint` +- `docker exec -w /app resolutionflow_frontend npx tsc -b` +- `docker exec -w /app resolutionflow_frontend npm run build` + +### 3. Workflow Quality Signals + +- #58: Add structured "step is wrong" flags separate from thumbs-up/down helpfulness. +- Existing `StepFeedback` is not enough; it only records helpful/unhelpful and cannot capture incorrect/outdated/unclear/missing-info reasons. + +Why third: useful, but needs schema/API/UI/admin surfaces. + +### 4. Client Intelligence + +- #60: Recurring issue detection. +- Start with a read-only banner using existing `sessions.client_name + tree_id` filters. +- Add same-resolution detection only after confirming the available session outcome/node data is reliable enough. + +Why fourth: high value, but it touches session-start and close-out flows and needs careful false-positive handling. + +### 5. Documentation Structure + +- #129: Hierarchical guide navigation. +- Current `/guides` route is a card grid plus detail pages with sections and breadcrumbs, but not a collapsible guide tree. + +Why fifth: valid UX request, but less urgent than pilot workflow gaps. + +## Gitea Actions Needed + +The current environment does not have a Gitea token configured, so API writes fail with `401 token is required`. Once authenticated: + +```bash +curl -X PATCH \ + https://gitea.resolutionflow.com/api/v1/repos/chihlasm/resolutionflow/issues/127 \ + -H "Authorization: token $GITEA_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"state":"closed"}' +``` + +For #66, prefer editing the title/body instead of closing it: + +- Title: `feat: curated template packs and one-click install` +- Body: remove completed `.rfflow` export/import acceptance criteria and keep pack/install/versioning work. diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index c3a27f1c..1487ac33 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -16,7 +16,7 @@ function App() { } else { setLoading(false) } - }, []) + }, [fetchUser, isAuthenticated, setLoading]) return } diff --git a/frontend/src/components/analytics/FlowAnalyticsPanel.tsx b/frontend/src/components/analytics/FlowAnalyticsPanel.tsx index 19923775..0c0a736c 100644 --- a/frontend/src/components/analytics/FlowAnalyticsPanel.tsx +++ b/frontend/src/components/analytics/FlowAnalyticsPanel.tsx @@ -39,7 +39,7 @@ export function FlowAnalyticsPanel({ treeId }: FlowAnalyticsPanelProps) { useEffect(() => { // eslint-disable-next-line react-hooks/set-state-in-effect setLoading(true) - // eslint-disable-next-line react-hooks/set-state-in-effect + setError(false) analyticsApi .getFlowAnalytics(treeId, period) diff --git a/frontend/src/components/assistant/ActionCardGroup.tsx b/frontend/src/components/assistant/ActionCardGroup.tsx index 3af0619c..bf8dae4d 100644 --- a/frontend/src/components/assistant/ActionCardGroup.tsx +++ b/frontend/src/components/assistant/ActionCardGroup.tsx @@ -74,7 +74,7 @@ export function ActionCardGroup({ actions, onSubmit, disabled, stale }: ActionCa onClick={() => setExpanded(true)} className="w-full rounded-lg border border-default/50 bg-elevated/20 p-2.5 flex items-center justify-between text-left hover:bg-elevated/40 transition-colors group" > -
+
{pendingCount} diagnostic check{pendingCount !== 1 ? 's' : ''} — not completed
@@ -95,7 +95,7 @@ export function ActionCardGroup({ actions, onSubmit, disabled, stale }: ActionCa
{responses.map((r, i) => ( -
+
{r.state === 'done' ? ( ) : ( @@ -118,7 +118,7 @@ export function ActionCardGroup({ actions, onSubmit, disabled, stale }: ActionCa
{/* Command with copy button */} {action.command && response.state !== 'skipped' && (
- + {action.command} @@ -282,7 +282,7 @@ export function ActionCardGroup({ actions, onSubmit, disabled, stale }: ActionCa {submitError && ( -
+
Failed to send
@@ -203,7 +203,7 @@ function ChatItem({
{confirming ? (
- Delete? + Delete?