From 8b18ec2efbc7bef4c8ebc9de4333b92d02e74ab1 Mon Sep 17 00:00:00 2001 From: rcourtman <8825017+rcourtman@users.noreply.github.com> Date: Wed, 7 Oct 2026 17:50:51 +0100 Subject: [PATCH] Stop Patrol fetching the circuit-breaker status nobody reads The Patrol page fetched GET /api/ai/circuit/status on every load, every 60 s poll, every return to the tab, and again in the background after Retry. Its only reader was the circuitBreakerStatus memo in usePatrolIntelligenceState, which nothing read and which the previous commit removed. Nothing else renders breaker state: an open breaker already reaches the page through /api/ai/patrol/status as the circuit_open blocked cause, and the paused banner shows its reason. Remove the store's breaker signal, getter, signal export, loader, org-switch reset and dashboard-bundle entry, the hook's background read, and AIAPI.getCircuitBreakerStatus with its CircuitBreakerStatus type. The client's unit tests, the store and page test mocks, and seven E2E route stubs go with them. The store bundle test still pins the exact AIAPI read set. The backend route stays for API users and diagnostics. Production builds before and after differ only in the removed code (check-bundle-size passes). A Playwright pass on private demo stacks at 1440 and 390 px shows the breaker read going from 1-2 requests per phase to none across Patrol load, tab hide/show and stale-data Retry, with every other endpoint and the Assistant handoff unchanged. A forced circuit_open Patrol status still shows "Patrol paused / circuit breaker is open" on both builds. --- .../v6/internal/subsystems/ai-runtime.md | 5 ++ .../v6/internal/subsystems/api-contracts.md | 6 ++ .../subsystems/frontend-primitives.md | 3 +- .../subsystems/patrol-intelligence.md | 11 ++-- .../d5b7642323c07d2a.json | 43 ++++++++++++++ .../api/__tests__/ai.branchcov0718.test.ts | 56 +------------------ frontend-modern/src/api/ai.ts | 13 ----- .../patrol/usePatrolIntelligenceState.ts | 1 - .../pages/__tests__/AIIntelligence.test.tsx | 7 --- .../stores/__tests__/aiIntelligence.test.ts | 7 +-- frontend-modern/src/stores/aiIntelligence.ts | 27 --------- .../tests/18-patrol-runtime-state.spec.ts | 28 ---------- .../tests/51-quickstart-cross-surface.spec.ts | 14 ----- ...patrol-assistant-operator-briefing.spec.ts | 14 ----- .../78-monitor-first-patrol-workbench.spec.ts | 14 ----- ...rational-trust-attention-workbench.spec.ts | 13 ----- ...erational-trust-availability-facet.spec.ts | 9 --- 17 files changed, 66 insertions(+), 205 deletions(-) create mode 100644 frontend-modern/browser-verification/d5b7642323c07d2a.json diff --git a/docs/release-control/v6/internal/subsystems/ai-runtime.md b/docs/release-control/v6/internal/subsystems/ai-runtime.md index 9ab54a9d35..52922d3d38 100644 --- a/docs/release-control/v6/internal/subsystems/ai-runtime.md +++ b/docs/release-control/v6/internal/subsystems/ai-runtime.md @@ -6728,6 +6728,11 @@ The browser does not read the global learned-correlation list: `/api/ai/intelligence/correlations`, and neither the shared AI intelligence store nor the Patrol page loads it, because no page renders it. The resource drawer reads per-resource correlations from the resource-intelligence payload. +The browser does not read `GET /api/ai/circuit/status` either: +`frontend-modern/src/api/ai.ts` carries no client for it and the shared AI +intelligence store holds no breaker state, because an open breaker already +reaches Patrol as the `circuit_open` runtime block cause. The route stays a +backend API surface. AI-facing policy metadata must also be cloned through the shared unified- resource policy helper so chat and tools consumers do not maintain their own policy copy logic. Chat mention prefetch now calls that shared helper directly diff --git a/docs/release-control/v6/internal/subsystems/api-contracts.md b/docs/release-control/v6/internal/subsystems/api-contracts.md index 32dd950388..4c1f9b6ad9 100644 --- a/docs/release-control/v6/internal/subsystems/api-contracts.md +++ b/docs/release-control/v6/internal/subsystems/api-contracts.md @@ -7305,6 +7305,12 @@ no client for it, and neither the dashboard load bundle in fetches it. The resource drawer's correlation evidence comes from the resource-intelligence payload above. The route stays an API surface behind the `ai:execute` scope. +The frontend does not load `GET /api/ai/circuit/status` either. No surface +renders provider breaker state, so `frontend-modern/src/api/ai.ts` carries no +client or `CircuitBreakerStatus` type for it, and neither that dashboard bundle +nor the Patrol refresh path fetches it. An open breaker reaches the Patrol page +through `/api/ai/patrol/status` as the `circuit_open` blocked cause. The route +stays a backend API surface. That correlations route now reads through the canonical AI intelligence facade first, so the handler and its payload keep the detector behind one shared access layer instead of routing directly to Patrol-local correlation diff --git a/docs/release-control/v6/internal/subsystems/frontend-primitives.md b/docs/release-control/v6/internal/subsystems/frontend-primitives.md index a74aa51a76..2e9921113f 100644 --- a/docs/release-control/v6/internal/subsystems/frontend-primitives.md +++ b/docs/release-control/v6/internal/subsystems/frontend-primitives.md @@ -6822,7 +6822,8 @@ Patrol stale-data Retry action spin indefinitely or stay disabled while Patrol findings and status remain visible. Neither the Patrol load and poll path (the store's `loadDashboardData` bundle) nor the Retry path's background supporting reads fetch the global -learned-correlation list, which no Patrol surface shows. +learned-correlation list or the provider circuit-breaker status, neither of +which any Patrol surface shows. That same Patrol shell should make scoped trigger policy legible without another navigation step. `frontend-modern/src/features/patrol/PatrolIntelligenceHeader.tsx` should keep actionable scoped-trigger state legible without promoting diff --git a/docs/release-control/v6/internal/subsystems/patrol-intelligence.md b/docs/release-control/v6/internal/subsystems/patrol-intelligence.md index f69c33fd67..8770c7c757 100644 --- a/docs/release-control/v6/internal/subsystems/patrol-intelligence.md +++ b/docs/release-control/v6/internal/subsystems/patrol-intelligence.md @@ -2181,10 +2181,13 @@ requester identity as safe metadata, without copying the approval command payload into Assistant. That same store now owns the Patrol dashboard load bundle as well, so the page refresh path stays aligned on a single orchestrated AI bundle instead of -repeating the individual summary, findings, circuit-breaker, and approval -fetches inline. Neither that bundle nor the Patrol refresh path fetches the -global learned-correlation list: the Patrol page renders no correlations, so -the store holds no copy of that list. +repeating the individual summary, findings, and approval fetches inline. +Neither that bundle nor the Patrol refresh path fetches the global +learned-correlation list: the Patrol page renders no correlations, so +the store holds no copy of that list. Nor do they fetch the provider +circuit-breaker status: an open breaker already reaches the page as the +`circuit_open` Patrol runtime block on `/api/ai/patrol/status`, so the store +holds no separate breaker state. The shared `frontend-modern/src/components/Infrastructure/ResourceChangeSummary.tsx` and `frontend-modern/src/components/Infrastructure/ResourceCorrelationSummary.tsx` diff --git a/frontend-modern/browser-verification/d5b7642323c07d2a.json b/frontend-modern/browser-verification/d5b7642323c07d2a.json new file mode 100644 index 0000000000..8777779821 --- /dev/null +++ b/frontend-modern/browser-verification/d5b7642323c07d2a.json @@ -0,0 +1,43 @@ +{ + "version": 1, + "base_sha": "3e6e9c3ffb8762b032efab544fda2f339cdb3d96", + "verified_at": "2026-10-07T16:28:00Z", + "result": "passed", + "changed_paths": [ + "frontend-modern/src/api/ai.ts", + "frontend-modern/src/features/patrol/usePatrolIntelligenceState.ts", + "frontend-modern/src/stores/aiIntelligence.ts" + ], + "content_sha256": { + "frontend-modern/src/api/ai.ts": "8ab01c7c5daac6c2088985423d3bb4584561b67ec306331ff92bf32cb9551738", + "frontend-modern/src/features/patrol/usePatrolIntelligenceState.ts": "dba595d1677002a9c55a31b45b4a4b5c600df7b4866afa8eb6bbe6dafbb75503", + "frontend-modern/src/stores/aiIntelligence.ts": "d10124d374625cb4a6b2e5b17a357211f73b724473bba9b7a4d0d0d15ccaf6b8" + }, + "routes": [ + "/patrol", + "/patrol (Activity > Finding options and history)", + "/patrol (Pulse Assistant drawer)" + ], + "viewports": [ + { + "width": 1440, + "height": 900 + }, + { + "width": 390, + "height": 844 + } + ], + "states": [ + "Embedded production builds (vite build into internal/api/frontend-modern/dist, go build) of the parent tree (3e6e9c3ffb, the merge of #2677 into #2695) and this tree, each on a private DEMO_MODE mock stack with a fresh data dir and its own port; the same Playwright script ran against both at both widths.", + "Patrol load, tab hide/show, forced stale-data banner and Retry: GET /api/ai/circuit/status goes from 1-2 requests per phase on the parent build to 0 on this build; every other /api endpoint per phase is identical, and neither build logs a console error.", + "Served active finding, Activity > Finding options and history, Resolve or dismiss > Open in Assistant: the Pulse Assistant drawer opens with the finding attached on both builds, with identical requests.", + "Patrol status forced to runtime_state blocked with blocked_cause circuit_open (page.route): both builds show 'Patrol paused' with 'circuit breaker is open', so breaker state still reaches the page through Patrol status alone.", + "Dist proof: 187 files each side; after normalising chunk hashes, SRI strings and short identifiers, only the removed store loader, signal, getter and API client differ in index.js and the removed supporting read in AIIntelligence.js; check-bundle-size.mjs passes." + ], + "interactions": [ + "Demo auto sign-in; on /patrol open the Activity tab and 'Finding options and history', expand the served finding, open 'Resolve or dismiss', click 'Open in Assistant', close the drawer.", + "Dispatch visibilitychange hidden then visible; reload with GET /api/settings/ai failing, then click Retry with the route restored; reload /patrol with a circuit_open Patrol status.", + "Desktop 1440x900 and phone 390x844 contexts; screenshots of the Patrol page, Assistant drawer, stale-data banner and paused banner inspected." + ] +} diff --git a/frontend-modern/src/api/__tests__/ai.branchcov0718.test.ts b/frontend-modern/src/api/__tests__/ai.branchcov0718.test.ts index bf338db2a1..753efb6e99 100644 --- a/frontend-modern/src/api/__tests__/ai.branchcov0718.test.ts +++ b/frontend-modern/src/api/__tests__/ai.branchcov0718.test.ts @@ -21,7 +21,7 @@ import { apiFetch, apiFetchJSON } from '@/utils/apiClient'; // response-handling of the currently-uncovered AIAPI request functions: // testConnection, resetCostHistory, exportCostHistory, getAnomalies, // getLearningStatus, analyzeKubernetesCluster, approveRemediationPlan, -// executeRemediationPlan, rollbackRemediationPlan, getCircuitBreakerStatus. +// executeRemediationPlan, rollbackRemediationPlan. // Each test asserts the concrete request (final path + query string + method + // body) and the concrete parsed result for happy paths and each optional / // default-parameter branch arm. @@ -421,58 +421,4 @@ describe('AIAPI branch coverage (request shaping + response handling)', () => { expect(result).toStrictEqual({ success: false }); }); }); - - // -------------------------------------------- - // getCircuitBreakerStatus - // -------------------------------------------- - describe('getCircuitBreakerStatus', () => { - it('GETs /api/ai/circuit/status and returns a closed-breaker payload verbatim', async () => { - const payload = { - state: 'closed' as const, - can_patrol: true, - consecutive_failures: 0, - total_successes: 128, - total_failures: 1, - }; - apiFetchJSONMock.mockResolvedValueOnce(payload as any); - - const result = await AIAPI.getCircuitBreakerStatus(); - - expect(apiFetchJSONMock).toHaveBeenCalledWith('/api/ai/circuit/status'); - expect(result).toStrictEqual(payload); - }); - - it('round-trips an open-breaker payload that blocks patrol', async () => { - const payload = { - state: 'open' as const, - can_patrol: false, - consecutive_failures: 5, - total_successes: 100, - total_failures: 10, - }; - apiFetchJSONMock.mockResolvedValueOnce(payload as any); - - const result = await AIAPI.getCircuitBreakerStatus(); - - expect(apiFetchJSONMock).toHaveBeenCalledWith('/api/ai/circuit/status'); - expect(result).toStrictEqual(payload); - expect(result.can_patrol).toBe(false); - }); - - it('round-trips a half-open breaker probe state', async () => { - const payload = { - state: 'half-open' as const, - can_patrol: true, - consecutive_failures: 0, - total_successes: 100, - total_failures: 5, - }; - apiFetchJSONMock.mockResolvedValueOnce(payload as any); - - const result = await AIAPI.getCircuitBreakerStatus(); - - expect(apiFetchJSONMock).toHaveBeenCalledWith('/api/ai/circuit/status'); - expect(result.state).toBe('half-open'); - }); - }); }); diff --git a/frontend-modern/src/api/ai.ts b/frontend-modern/src/api/ai.ts index b78e0b1d31..6f8bc1c96b 100644 --- a/frontend-modern/src/api/ai.ts +++ b/frontend-modern/src/api/ai.ts @@ -276,11 +276,6 @@ export class AIAPI { }) as Promise<{ success: boolean }>; } - // Circuit breaker status - static async getCircuitBreakerStatus(): Promise { - return apiFetchJSON(`${this.baseUrl}/ai/circuit/status`) as Promise; - } - // ============================================ // Investigation Fix Approvals // ============================================ @@ -567,14 +562,6 @@ export interface RemediationExecutionResult { completed_at?: string; } -export interface CircuitBreakerStatus { - state: 'closed' | 'open' | 'half-open'; - can_patrol: boolean; - consecutive_failures: number; - total_successes: number; - total_failures: number; -} - // ============================================ // Investigation Fix Approval Types // ============================================ diff --git a/frontend-modern/src/features/patrol/usePatrolIntelligenceState.ts b/frontend-modern/src/features/patrol/usePatrolIntelligenceState.ts index 80a6ee305d..1ccd4907f6 100644 --- a/frontend-modern/src/features/patrol/usePatrolIntelligenceState.ts +++ b/frontend-modern/src/features/patrol/usePatrolIntelligenceState.ts @@ -646,7 +646,6 @@ export function usePatrolIntelligenceState() { void Promise.allSettled([ aiIntelligenceStore.loadIntelligenceSummary(), aiIntelligenceStore.loadFindings(), - aiIntelligenceStore.loadCircuitBreakerStatus(), ]); } diff --git a/frontend-modern/src/pages/__tests__/AIIntelligence.test.tsx b/frontend-modern/src/pages/__tests__/AIIntelligence.test.tsx index f945d40037..35ed214a00 100644 --- a/frontend-modern/src/pages/__tests__/AIIntelligence.test.tsx +++ b/frontend-modern/src/pages/__tests__/AIIntelligence.test.tsx @@ -41,7 +41,6 @@ const { findingsPanelState, runHistoryState, intelligenceState } = vi.hoisted(() }, intelligenceState: { findings: [] as Array>, - circuitBreakerStatus: null as { state: string; consecutive_failures: number } | null, summary: null as { timestamp: string; overall_health: { @@ -254,13 +253,11 @@ vi.mock('@/stores/aiIntelligence', () => { loadFindings: vi.fn().mockResolvedValue(undefined), loadPatrolFindings: vi.fn().mockResolvedValue(undefined), loadIntelligenceSummary: vi.fn().mockResolvedValue(undefined), - loadCircuitBreakerStatus: vi.fn().mockResolvedValue(undefined), loadPendingApprovals: vi.fn().mockResolvedValue(undefined), loadDashboardData: vi.fn().mockImplementation(async () => { await Promise.all([ store.loadFindings(), store.loadIntelligenceSummary(), - store.loadCircuitBreakerStatus(), store.loadPendingApprovals(), ]); }), @@ -273,9 +270,6 @@ vi.mock('@/stores/aiIntelligence', () => { get intelligenceSummary() { return intelligenceState.summary; }, - get circuitBreakerStatus() { - return intelligenceState.circuitBreakerStatus; - }, get patrolPendingApprovals() { return []; }, @@ -631,7 +625,6 @@ describe('AIIntelligence entitlement gating', () => { findingsPanelState.latestProps = null; runHistoryState.selection = null; intelligenceState.findings = []; - intelligenceState.circuitBreakerStatus = null; intelligenceState.summary = null; getPatrolStatusMock.mockResolvedValue(defaultPatrolStatus()); diff --git a/frontend-modern/src/stores/__tests__/aiIntelligence.test.ts b/frontend-modern/src/stores/__tests__/aiIntelligence.test.ts index 1d22c8781f..d9f2282882 100644 --- a/frontend-modern/src/stores/__tests__/aiIntelligence.test.ts +++ b/frontend-modern/src/stores/__tests__/aiIntelligence.test.ts @@ -6,7 +6,6 @@ vi.mock('@/api/ai', () => ({ getRemediationPlans: vi.fn(), getPendingApprovals: vi.fn(), getIntelligenceSummary: vi.fn(), - getCircuitBreakerStatus: vi.fn(), }, })); @@ -622,8 +621,6 @@ describe('aiIntelligenceStore', () => { incidents_tracked: 0, }, }); - vi.mocked(AIAPI.getCircuitBreakerStatus).mockResolvedValueOnce(null as never); - await aiIntelligenceStore.loadDashboardData(); expect(AIAPI.getIntelligenceSummary).toHaveBeenCalledTimes(1); @@ -631,13 +628,13 @@ describe('aiIntelligenceStore', () => { // These are every AIAPI read the bundle makes (Patrol findings come from // the Patrol API module). It does not load the global learned-correlation // list: no page renders it, and the resource drawer reads per-resource - // correlations from resource intelligence instead. + // correlations from resource intelligence instead. Nor does it load the + // provider circuit-breaker status, which no surface renders. const aiReads = Object.entries(AIAPI) .filter(([, read]) => vi.isMockFunction(read) && read.mock.calls.length > 0) .map(([name]) => name) .sort(); expect(aiReads).toEqual([ - 'getCircuitBreakerStatus', 'getIntelligenceSummary', 'getPendingApprovals', 'getUnifiedFindings', diff --git a/frontend-modern/src/stores/aiIntelligence.ts b/frontend-modern/src/stores/aiIntelligence.ts index ee56b0cfe2..7435e3b285 100644 --- a/frontend-modern/src/stores/aiIntelligence.ts +++ b/frontend-modern/src/stores/aiIntelligence.ts @@ -5,7 +5,6 @@ * - Unified findings (alerts + AI findings) * - Canonical intelligence summary * - Remediation plans - * - Circuit breaker status */ import { createSignal } from 'solid-js'; @@ -25,7 +24,6 @@ import { import type { ResourceCriticality } from '@/api/resourceOperatorState'; import type { RemediationPlan, - CircuitBreakerStatus, UnifiedFindingRecord, InvestigationRecord, ApprovalRequest, @@ -449,14 +447,6 @@ function getPatrolOpenWorkCount(): number { return activeFindingIds.size; } -// ============================================ -// Circuit Breaker -// ============================================ - -const [circuitBreakerStatus, setCircuitBreakerStatus] = createSignal( - null, -); - // ============================================ // Canonical Intelligence Summary // ============================================ @@ -482,7 +472,6 @@ eventBus.on('org_switched', () => { setPlansError(null); setPendingApprovalsWithExpiryTracking([]); setApprovalsError(null); - setCircuitBreakerStatus(null); setIntelligenceSummary(null); }); @@ -796,12 +785,6 @@ export const aiIntelligenceStore = { } }, - // Circuit Breaker - get circuitBreakerStatus() { - return circuitBreakerStatus(); - }, - circuitBreakerStatusSignal: circuitBreakerStatus, - // Canonical Intelligence Summary get intelligenceSummary() { return intelligenceSummary(); @@ -813,7 +796,6 @@ export const aiIntelligenceStore = { this.loadIntelligenceSummary(), this.loadFindings(), this.loadPatrolFindings(), - this.loadCircuitBreakerStatus(), this.loadPendingApprovals(), ]); }, @@ -830,15 +812,6 @@ export const aiIntelligenceStore = { } }, - async loadCircuitBreakerStatus() { - try { - const status = await AIAPI.getCircuitBreakerStatus(); - setCircuitBreakerStatus(status); - } catch (e) { - logger.error('Failed to load circuit breaker status:', e); - } - }, - // Initialize - load all data async initialize() { await Promise.all([this.loadDashboardData(), this.loadRemediationPlans()]); diff --git a/tests/integration/tests/18-patrol-runtime-state.spec.ts b/tests/integration/tests/18-patrol-runtime-state.spec.ts index da3a1deccb..6a1b5a31ec 100644 --- a/tests/integration/tests/18-patrol-runtime-state.spec.ts +++ b/tests/integration/tests/18-patrol-runtime-state.spec.ts @@ -349,20 +349,6 @@ async function mockBlockedPatrolRuntimeState( }); }); - await page.route("**/api/ai/circuit/status", async (route) => { - await route.fulfill({ - status: 200, - contentType: "application/json", - body: JSON.stringify({ - state: "closed", - can_patrol: true, - consecutive_failures: 0, - total_successes: 42, - total_failures: 0, - }), - }); - }); - await page.route("**/api/ai/approvals", async (route) => { await route.fulfill({ status: 200, @@ -523,20 +509,6 @@ async function mockScopedTriggerPatrolRuntimeState( }); }); - await page.route("**/api/ai/circuit/status", async (route) => { - await route.fulfill({ - status: 200, - contentType: "application/json", - body: JSON.stringify({ - state: "closed", - can_patrol: true, - consecutive_failures: 0, - total_successes: 42, - total_failures: 0, - }), - }); - }); - await page.route("**/api/ai/approvals", async (route) => { await route.fulfill({ status: 200, diff --git a/tests/integration/tests/51-quickstart-cross-surface.spec.ts b/tests/integration/tests/51-quickstart-cross-surface.spec.ts index 3efb255114..69b6b2e960 100644 --- a/tests/integration/tests/51-quickstart-cross-surface.spec.ts +++ b/tests/integration/tests/51-quickstart-cross-surface.spec.ts @@ -285,20 +285,6 @@ async function mockRetiredQuickstartSurface( }); }); - await page.route("**/api/ai/circuit/status", async (route) => { - await route.fulfill({ - status: 200, - contentType: "application/json", - body: JSON.stringify({ - state: "closed", - can_patrol: false, - consecutive_failures: 0, - total_successes: 0, - total_failures: 0, - }), - }); - }); - await page.route("**/api/ai/approvals", async (route) => { await route.fulfill({ status: 200, diff --git a/tests/integration/tests/73-patrol-assistant-operator-briefing.spec.ts b/tests/integration/tests/73-patrol-assistant-operator-briefing.spec.ts index e122ddf30e..9d5f76a8cd 100644 --- a/tests/integration/tests/73-patrol-assistant-operator-briefing.spec.ts +++ b/tests/integration/tests/73-patrol-assistant-operator-briefing.spec.ts @@ -541,20 +541,6 @@ test.describe("Patrol Assistant operator briefing", () => { }); }); - await page.route("**/api/ai/circuit/status", async (route) => { - await route.fulfill({ - status: 200, - contentType: "application/json", - body: JSON.stringify({ - state: "closed", - can_patrol: true, - consecutive_failures: 0, - total_successes: 42, - total_failures: 0, - }), - }); - }); - await page.route("**/api/ai/approvals", async (route) => { await route.fulfill({ status: 200, diff --git a/tests/integration/tests/78-monitor-first-patrol-workbench.spec.ts b/tests/integration/tests/78-monitor-first-patrol-workbench.spec.ts index 976cdc1cf2..ebc74eb263 100644 --- a/tests/integration/tests/78-monitor-first-patrol-workbench.spec.ts +++ b/tests/integration/tests/78-monitor-first-patrol-workbench.spec.ts @@ -476,20 +476,6 @@ async function mockMonitorFirstPatrolWorkbench( }); }); - await page.route("**/api/ai/circuit/status", async (route) => { - await route.fulfill({ - status: 200, - contentType: "application/json", - body: JSON.stringify({ - state: "closed", - can_patrol: true, - consecutive_failures: 0, - total_successes: 4, - total_failures: 0, - }), - }); - }); - await page.route("**/api/ai/approvals", async (route) => { const approvals = resolved.pendingApprovalCount > 0 diff --git a/tests/integration/tests/91-operational-trust-attention-workbench.spec.ts b/tests/integration/tests/91-operational-trust-attention-workbench.spec.ts index 94d85f0e78..dd374fec6f 100644 --- a/tests/integration/tests/91-operational-trust-attention-workbench.spec.ts +++ b/tests/integration/tests/91-operational-trust-attention-workbench.spec.ts @@ -493,19 +493,6 @@ async function mockAttention( }), }); }); - await page.route("**/api/ai/circuit/status", async (route) => { - await route.fulfill({ - status: 200, - contentType: "application/json", - body: JSON.stringify({ - state: "closed", - can_patrol: true, - consecutive_failures: 0, - total_successes: 1, - total_failures: 0, - }), - }); - }); await page.route("**/api/ai/approvals", async (route) => { await route.fulfill({ status: 200, diff --git a/tests/integration/tests/92-operational-trust-availability-facet.spec.ts b/tests/integration/tests/92-operational-trust-availability-facet.spec.ts index b5d96d83ed..238badf3dc 100644 --- a/tests/integration/tests/92-operational-trust-availability-facet.spec.ts +++ b/tests/integration/tests/92-operational-trust-availability-facet.spec.ts @@ -730,15 +730,6 @@ async function routePatrolSupport( }, }); }); - await page.route("**/api/ai/circuit/status", async (route) => { - await fulfillJSON(route, { - state: "closed", - can_patrol: true, - consecutive_failures: 0, - total_successes: 1, - total_failures: 0, - }); - }); await page.route("**/api/ai/approvals", async (route) => { await fulfillJSON(route, { approvals: [] }); });