From 247bccded471930e8a6736eb680481501d15dbba Mon Sep 17 00:00:00 2001 From: rcourtman Date: Wed, 25 Mar 2026 18:11:16 +0000 Subject: [PATCH] Move Patrol investigation context behind findings Patrol now renders investigation context beneath the findings and history workspace, keeping the primary summary card focused on assessment and verification while preserving the same context content and toggle behavior. --- .../subsystems/patrol-intelligence.md | 4 ++ .../patrol/PatrolIntelligenceSummary.tsx | 62 ------------------- .../patrol/PatrolIntelligenceWorkspace.tsx | 56 +++++++++++++++++ .../pages/__tests__/AIIntelligence.test.tsx | 6 ++ 4 files changed, 66 insertions(+), 62 deletions(-) diff --git a/docs/release-control/v6/internal/subsystems/patrol-intelligence.md b/docs/release-control/v6/internal/subsystems/patrol-intelligence.md index f79261eaa..48d6287fd 100644 --- a/docs/release-control/v6/internal/subsystems/patrol-intelligence.md +++ b/docs/release-control/v6/internal/subsystems/patrol-intelligence.md @@ -192,6 +192,10 @@ operator whether Patrol recently completed a successful full patrol, only ran scoped alert-triggered checks, or ended its most recent full patrol with errors, so the page does not leave trust and coverage as implicit background knowledge. +The same hierarchy applies to investigation context. Correlations, recent +changes, and policy posture are secondary evidence for deeper investigation, so +the `Investigation context` section belongs beneath the primary findings/history +workspace rather than inside the assessment card itself. The Patrol status bar should stay factual and operational within that same hierarchy. `frontend-modern/src/components/patrol/PatrolStatusBar.tsx` is a recent-activity strip, not a second health verdict: when Patrol is active it diff --git a/frontend-modern/src/features/patrol/PatrolIntelligenceSummary.tsx b/frontend-modern/src/features/patrol/PatrolIntelligenceSummary.tsx index b3356c0ea..91fadaf11 100644 --- a/frontend-modern/src/features/patrol/PatrolIntelligenceSummary.tsx +++ b/frontend-modern/src/features/patrol/PatrolIntelligenceSummary.tsx @@ -13,9 +13,6 @@ import { } from '@/utils/patrolSummaryPresentation'; import { getPatrolRuntimePresentation } from '@/utils/patrolRuntimePresentation'; import { getSemanticTonePresentation } from '@/utils/semanticTonePresentation'; -import { ResourcePolicySummary } from '@/components/Infrastructure/ResourcePolicySummary'; -import { ResourceCorrelationSummary } from '@/components/Infrastructure/ResourceCorrelationSummary'; -import { ResourceChangeSummary } from '@/components/Infrastructure/ResourceChangeSummary'; import { formatRelativeTime } from '@/utils/format'; import type { PatrolIntelligenceState } from './usePatrolIntelligenceState'; @@ -190,66 +187,7 @@ export function PatrolIntelligenceSummary(props: { state: PatrolIntelligenceStat - - - -
-
-
-

- Investigation context -

-

- Secondary change and policy signals for deeper investigation. -

- -

- {state.investigationContextSummary()} -

-
-
- - -
- - -
- 0}> - - - -
- 0}> - - - - -
-
-
-
-
)} diff --git a/frontend-modern/src/features/patrol/PatrolIntelligenceWorkspace.tsx b/frontend-modern/src/features/patrol/PatrolIntelligenceWorkspace.tsx index 1a85f6199..2f2480013 100644 --- a/frontend-modern/src/features/patrol/PatrolIntelligenceWorkspace.tsx +++ b/frontend-modern/src/features/patrol/PatrolIntelligenceWorkspace.tsx @@ -4,6 +4,9 @@ import { ApprovalBanner, PatrolStatusBar, RunHistoryPanel } from '@/components/p import { getFindingSeverityToneClasses } from '@/utils/aiFindingPresentation'; import { formatRelativeTime } from '@/utils/format'; import { formatTriggerReason } from '@/utils/patrolFormat'; +import { ResourcePolicySummary } from '@/components/Infrastructure/ResourcePolicySummary'; +import { ResourceCorrelationSummary } from '@/components/Infrastructure/ResourceCorrelationSummary'; +import { ResourceChangeSummary } from '@/components/Infrastructure/ResourceChangeSummary'; import type { PatrolIntelligenceState } from './usePatrolIntelligenceState'; export function PatrolIntelligenceWorkspace(props: { state: PatrolIntelligenceState }) { @@ -120,6 +123,59 @@ export function PatrolIntelligenceWorkspace(props: { state: PatrolIntelligenceSt patrolStream={state.patrolStream} /> + + +
+
+
+

+ Investigation context +

+

+ Secondary change and policy signals for deeper investigation. +

+ +

{state.investigationContextSummary()}

+
+
+ + +
+ + +
+ 0}> + + + +
+ 0}> + + + + +
+
+
+
+
); } diff --git a/frontend-modern/src/pages/__tests__/AIIntelligence.test.tsx b/frontend-modern/src/pages/__tests__/AIIntelligence.test.tsx index c26b012c2..f4f486685 100644 --- a/frontend-modern/src/pages/__tests__/AIIntelligence.test.tsx +++ b/frontend-modern/src/pages/__tests__/AIIntelligence.test.tsx @@ -600,6 +600,12 @@ describe('AIIntelligence entitlement gating', () => { expect(screen.getByText('No active issues detected')).toBeInTheDocument(); }); + const findingsPanel = screen.getByTestId('findings-panel'); + const contextHeading = screen.getByText('Investigation context'); + expect( + Boolean(findingsPanel.compareDocumentPosition(contextHeading) & Node.DOCUMENT_POSITION_FOLLOWING), + ).toBe(true); + expect(screen.getByText(/Health A · 91\/100/)).toBeInTheDocument(); expect(screen.getByText('Investigation context')).toBeInTheDocument(); expect(screen.getByText('1 recent change · 4 governed resources')).toBeInTheDocument();