mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-24 12:42:49 +00:00
533027ee06
`usePatrolIntelligenceState()` returned 18 members that no file outside the hook reads. A TypeScript checker scan of src and tests found no readers and no spread, computed or `Object.*` escapes of the state object. Several were also dead inside the hook. ## Change - **Return object.** Drops activePatrolFindings, activityRefreshTrigger, acceptedManualRunId, assistantHandoffFindingId, circuitBreakerStatus, fullModeUnlocked, initialSurfaceReady, isRefreshing, loadAllData, openAssistantOperationsLoopForFinding, the four decision/outcome counts, both work-evidence counts, recordPatrolWorkflowStarterActivity and setFullModeUnlocked, plus handleAssistantFindingHandoff (see below). - **Dead locals.** Removes the write-only signals (initialSurfaceReady, isRefreshing, fullModeUnlocked, assistantHandoffFindingId), the 15 s background refresh timeout that only reset isRefreshing, the unread memos, and the never-called `openAssistantOperationsLoopForFinding`. That last one was a second copy of the handoff `FindingsPanel` already performs. Locals still used inside the hook (activePatrolFindings, loadAllData, activityRefreshTrigger, acceptedManualRunId) stay. - **Test-only exports.** `openPatrolAssistantWorkflowHandoff` and `recordPatrolWorkflowStarterActivity` were used only by that dead path and by their own tests, so they go. - **Workspace.** `handleAssistantFindingHandoff` only wrote the unread handoff signal, so `PatrolIntelligenceWorkspace` no longer passes `FindingsPanel` an `onAssistantHandoff` callback. The prop is optional. - **Tests.** Raw-source pins on removed code are dropped. The manual-sync timeout test now pins the Retry path's own generation guard; a mutation of its timeout fails it. The non-blocking starter test now exercises `recordPatrolControlStarterActivity`. - **Contracts.** - patrol-intelligence said a finding-to-Assistant handoff *must* record a `pulse_patrol` workflow starter. Only the dead path did that; the live `FindingsPanel` handoff never has, so `pulse_patrol` has no browser producer. The clause now says that and keeps the content-free rules as a condition. - The "local Patrol state must expose work evidence" sentence no longer requires counts nothing reads. - Three refresh clauses that described a header refresh action now name the stale-data Retry, the only operator refresh left. - api-contracts and frontend-primitives record that `FindingsPanel` owns the handoff. ## Not in this PR The store still fetches `GET /api/ai/circuit/status` for nothing. That removal is a follow-up after #2677, because it edits the same lines. ## Evidence - Production builds before and after compared with chunk hashes, SRI strings and short identifiers normalised. Only the removed hook code differs, the unused `pulse_patrol` constant drops out of `aiChat.js`, and `index.js` reorders the same preload list. `check-bundle-size.mjs` passes. - Private demo-mode stacks for both builds, driven by the same Playwright script at 1440x900 and 390x844: Patrol load, Activity > Finding options and history, Open in Assistant (drawer opens with the finding), tab hide/show, and the forced stale-data banner plus Retry. Each phase hit the same `/api` endpoints on both builds, and neither build had console errors. - `tsc --noEmit`, eslint, and vitest for `src/features/patrol`, `AIIntelligence.test.tsx`, `frontendResourceTypeBoundaries.test.ts` and `FindingsPanel.test.ts` pass, as does the full pre-commit battery. Stacked on #2687 (which carries #2682 and #2686). Until those merge, this PR shows their commits too. `git merge-tree` is clean against main, #2690, #2677 and #2691.