diff --git a/web/src/tabs/HistoryTab.tsx b/web/src/tabs/HistoryTab.tsx
index a6c976d..a65426a 100644
--- a/web/src/tabs/HistoryTab.tsx
+++ b/web/src/tabs/HistoryTab.tsx
@@ -7,7 +7,7 @@ import {
import { useCanonicalLifecycle } from '../hooks/useCanonicalLifecycle';
import { fetchTradeHistory } from '../lib/tradeHistoryApi';
import { fetchPositionsBootstrap } from '../lib/positionsApi';
-import { Badge, Button, Input, Select } from '../components/ui/Primitives';
+import { AlertBanner, Badge, Button, Input, Select } from '../components/ui/Primitives';
interface TradeRecord {
@@ -438,15 +438,15 @@ export const HistoryTab = ({ botState }: HistoryTabProps) => {
{!hasCanonicalLifecycle && (
-
- Canonical lifecycle is unavailable{canonicalLoading ? ' (loading)' : ''}. History is using fallback ledger sources.
+
+ History is using fallback ledger sources{canonicalLoading ? ' while loading' : ''}.
{canonicalError ? ` ${canonicalError}` : ''}
-
+
)}
{canonicalSnapshot?.diagnostics?.truncated && (
-
- Canonical lifecycle snapshot is truncated ({canonicalSnapshot.diagnostics.orderRows} rows). Review a narrower scope for exact audit totals.
-
+
+ {canonicalSnapshot.diagnostics.orderRows} rows were returned. Review a narrower scope for exact audit totals.
+
)}
{/* Performance Metrics Bar */}
diff --git a/web/src/tabs/PositionsTab.tsx b/web/src/tabs/PositionsTab.tsx
index 4d6e7c1..fe36cbf 100644
--- a/web/src/tabs/PositionsTab.tsx
+++ b/web/src/tabs/PositionsTab.tsx
@@ -8,7 +8,7 @@ import { createRequestId } from '../../../shared/request-id.js';
import { Layers, ListFilter, Link2, GitBranch, AlertTriangle, Lock, RefreshCw, CheckCircle, XCircle } from 'lucide-react';
import { useCanonicalLifecycle } from '../hooks/useCanonicalLifecycle';
import { fetchPositionsBootstrap } from '../lib/positionsApi';
-import { Badge, Button, Input, Select } from '../components/ui/Primitives';
+import { AlertBanner, Badge, Button, Input, Select } from '../components/ui/Primitives';
interface PositionsTabProps {
botState: BotState;
@@ -1343,66 +1343,45 @@ export const PositionsTab = ({ botState, onManageHolding }: PositionsTabProps) =
{!hasCanonicalLifecycle && (
-
- Canonical lifecycle is unavailable{canonicalLoading ? ' (loading)' : ''}. Truth labels are in fallback mode (DB/runtime-derived).
+
+ Truth labels are in fallback mode (DB/runtime-derived){canonicalLoading ? ' while loading' : ''}.
{canonicalError ? ` ${canonicalError}` : ''}
-
+
)}
{canonicalSnapshot?.diagnostics?.truncated && (
-
- Canonical lifecycle snapshot is truncated ({canonicalSnapshot.diagnostics.orderRows} rows). Narrow profile scope before operational decisions.
-
+
+ {canonicalSnapshot.diagnostics.orderRows} rows were returned. Narrow profile scope before operational decisions.
+
)}
{/* Stale Orders Warning Banner */}
{staleWarningOrders.length > 0 && (
-
-
⚠️
-
-
- {staleWarningOrders.length} Stale Order{staleWarningOrders.length > 1 ? 's' : ''} Detected
-
-
- Some orders have remained in pending_new for more than 5 minutes
- without stronger fill or position evidence. The background sync service is re-checking their exchange status.
-
-
-
+ 1 ? 's' : ''} Detected`}>
+ Some orders have remained in pending_new for more than 5 minutes
+ without stronger fill or position evidence. The background sync service is re-checking their exchange status.
+
+ )}
+
+ {positionMismatches.length > 0 && (
+
+
+ One or more open positions do not have a clean entry-order lineage by profile and trade ID.
+
+
+ {positionMismatches.map((issue) => (
+
+
+ {issue.severity}
+
+ {issue.profileName}
+ {issue.symbol}
+ {issue.tradeId}
+ {issue.reason}
+
+ ))}
+
+
)}
-
- {positionMismatches.length > 0 && (
-
-
-
-
-
-
- Lifecycle Mismatch Diagnostics ({positionMismatches.length})
-
-
- One or more open positions do not have a clean entry-order lineage by profile and trade ID.
-
-
-
- {positionMismatches.map((issue) => (
-
-
- {issue.severity}
-
- {issue.profileName}
- {issue.symbol}
- {issue.tradeId}
- {issue.reason}
-
- ))}
-
-
-
-
- )}