diff --git a/docs/release-control/v6/internal/subsystems/ai-runtime.md b/docs/release-control/v6/internal/subsystems/ai-runtime.md index 6f8f453c37..1e840c9d4e 100644 --- a/docs/release-control/v6/internal/subsystems/ai-runtime.md +++ b/docs/release-control/v6/internal/subsystems/ai-runtime.md @@ -6761,6 +6761,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 475fabad79..c044a02da4 100644 --- a/docs/release-control/v6/internal/subsystems/api-contracts.md +++ b/docs/release-control/v6/internal/subsystems/api-contracts.md @@ -7486,6 +7486,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 f726c2be1d..fc70eddf45 100644 --- a/docs/release-control/v6/internal/subsystems/frontend-primitives.md +++ b/docs/release-control/v6/internal/subsystems/frontend-primitives.md @@ -6864,7 +6864,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 4ccd8fc25c..e9f43aa1a2 100644 --- a/docs/release-control/v6/internal/subsystems/patrol-intelligence.md +++ b/docs/release-control/v6/internal/subsystems/patrol-intelligence.md @@ -2197,10 +2197,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/4e0edf7cbbe4f3d3.json b/frontend-modern/browser-verification/4e0edf7cbbe4f3d3.json new file mode 100644 index 0000000000..ae1e774f05 --- /dev/null +++ b/frontend-modern/browser-verification/4e0edf7cbbe4f3d3.json @@ -0,0 +1,41 @@ +{ + "version": 1, + "base_sha": "1b01ab6e1bbbb12996d39ea4c8b64cf379ce2e01", + "verified_at": "2026-10-07T23:54:00Z", + "result": "passed", + "changed_paths": [ + "frontend-modern/src/features/patrol/usePatrolIntelligenceState.ts" + ], + "content_sha256": { + "frontend-modern/src/features/patrol/usePatrolIntelligenceState.ts": "ef09be2978d90248ad165176d49b131939ea1231b02e4fe239bb01e9da11e4d0" + }, + "routes": [ + "/patrol", + "/patrol (Activity > Finding options and history)", + "/patrol (Pulse Assistant drawer)" + ], + "viewports": [ + { + "width": 1440, + "height": 900 + }, + { + "width": 390, + "height": 844 + } + ], + "states": [ + "Follow-up receipt for merging the repaired #2695 head (32fad38aa4, which contains current main) into this branch: the hook's final content is that head's hook minus the circuit-breaker supporting read this branch removes.", + "Embedded production builds (vite build into internal/api/frontend-modern/dist, go build) of 32fad38aa4 and of this merged tree (1b01ab6e1b), run on pulse-dev because local memory pressure refused heavy work; each on a private DEMO_MODE mock stack with a fresh data dir; the same Playwright script ran against both at both widths.", + "Patrol load, tab hide/show, stale-data banner forced by failing GET /api/settings/ai and Retry: GET /api/ai/circuit/status drops from one request per phase on the parent build to none; the banner shows and Retry clears it on both builds; no console errors on either.", + "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.", + "Patrol status forced to runtime_state blocked with blocked_cause circuit_open (page.route): both builds show 'Patrol paused' with 'circuit breaker is open'.", + "Across the run the only other endpoint difference is one GET /api/updates/plan from the update banner, which fires once the server's background update check completes and does not depend on this change.", + "Dist proof on pulse-dev: 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." + ], + "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, wait for the banner, restore the route and click Retry, wait for the banner to clear; reload /patrol with a circuit_open Patrol status.", + "Desktop 1440x900 and phone 390x844 contexts; screenshots of the Patrol page, Finding options and history, the Assistant drawer, the stale-data banner and the paused banner inspected." + ] +} 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 5c33d076a8..948aea8e66 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: [] }); });