feat(governance): surface adr100 slo states
All checks were successful
Code Review / ai-code-review (push) Successful in 11s
CD Pipeline / tests (push) Successful in 1m0s
CD Pipeline / build-and-deploy (push) Successful in 4m0s
CD Pipeline / post-deploy-checks (push) Successful in 1m55s

This commit is contained in:
Your Name
2026-05-14 19:57:32 +08:00
parent 6c16a7b162
commit 809bc9670b
7 changed files with 559 additions and 40 deletions

View File

@@ -24,12 +24,24 @@ import { useTranslations } from 'next-intl'
// =============================================================================
export interface SloMetric {
name: 'decision_accuracy' | 'km_growth_rate' | 'mcp_call_diversity'
name:
| 'autonomy_rate'
| 'decision_accuracy'
| 'confidence_calibration'
| 'km_growth_rate'
| 'mcp_call_diversity'
| 'auto_execute_success_rate'
| 'human_override_rate'
| 'verifier_false_neg_rate'
current: number | null
target: number
status: 'healthy' | 'warning' | 'critical'
unit?: string
status: 'healthy' | 'warning' | 'critical' | 'idle' | 'syncing'
state?: 'ok' | 'warning' | 'violated' | 'skipped_low_volume' | 'no_data' | 'error' | 'partial'
unit?: '%' | 'count'
sparkline?: number[] // 7 points, most recent last
sampleCount?: number | null
window?: string
reason?: string | null
}
interface SloKpiCardProps {
@@ -45,6 +57,22 @@ const statusColor: Record<SloMetric['status'], string> = {
healthy: '#22C55E',
warning: '#F59E0B',
critical: '#FF3300',
idle: '#87867f',
syncing: '#3B82F6',
}
function formatCompactNumber(value: number): string {
if (value >= 100) return value.toFixed(0)
if (value >= 10) return value.toFixed(1)
return value.toFixed(2)
}
function reasonKey(reason?: string | null): string {
if (!reason) return 'none'
if (reason === 'denominator_below_minimum_events') return 'denominator_below_minimum_events'
if (reason === 'prometheus_nan_or_inf') return 'prometheus_nan_or_inf'
if (reason === 'prometheus_empty_result_metric_not_emitted') return 'prometheus_empty_result_metric_not_emitted'
return 'unknown'
}
// =============================================================================
@@ -73,21 +101,24 @@ export function SloKpiCard({ metric, loading = false }: SloKpiCardProps) {
if (loading) return <KpiSkeleton />
const color = statusColor[metric.status]
const orbStatus: StatusType = metric.status === 'healthy' ? 'healthy'
: metric.status === 'warning' ? 'warning'
: 'critical'
const orbStatus: StatusType = metric.status
const formattedValue = metric.current == null
? '--'
: metric.unit === '%'
? `${(metric.current * 100).toFixed(1)}%`
: metric.current.toFixed(2)
: metric.current.toFixed(0)
const formattedTarget = metric.unit === '%'
? `${(metric.target * 100).toFixed(0)}%`
: metric.target.toFixed(2)
: metric.target.toFixed(0)
const sparkData = (metric.sparkline ?? Array(7).fill(0)).map((v, i) => ({ i, v }))
const stateLabel = metric.state ? t(`state.${metric.state}`) : ''
const reasonLabel = metric.reason ? t(`reason.${reasonKey(metric.reason)}`) : null
const sampleLabel = metric.sampleCount == null
? null
: t('sampleCount', { count: formatCompactNumber(metric.sampleCount) })
return (
<GlassCard variant="elevated" padding="md" className="min-w-0 flex-1">
@@ -114,35 +145,46 @@ export function SloKpiCard({ metric, loading = false }: SloKpiCardProps) {
color,
lineHeight: 1,
marginBottom: 4,
letterSpacing: '-0.5px',
letterSpacing: 0,
}}>
{formattedValue}
</div>
{/* Target + sparkline row */}
<div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between' }}>
<span style={{
fontFamily: "'DM Mono', monospace",
fontSize: 10,
color: '#87867f',
}}>
{t('target')} {formattedTarget}
</span>
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
{/* Target + sparkline row */}
<div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 8 }}>
<span style={{
fontFamily: "'DM Mono', monospace",
fontSize: 10,
color: '#87867f',
}}>
{t('target')} {formattedTarget}
</span>
{/* Sparkline 80×24px */}
<div style={{ width: 80, height: 24 }} aria-label={t('sparkline')}>
<ResponsiveContainer width="100%" height="100%">
<LineChart data={sparkData} margin={{ top: 2, right: 0, bottom: 2, left: 0 }}>
<Line
type="monotone"
dataKey="v"
stroke={color}
strokeWidth={1.5}
dot={false}
isAnimationActive={false}
/>
</LineChart>
</ResponsiveContainer>
{/* Sparkline 80×24px */}
<div style={{ width: 80, height: 24, flexShrink: 0 }} aria-label={t('sparkline')}>
<ResponsiveContainer width="100%" height="100%">
<LineChart data={sparkData} margin={{ top: 2, right: 0, bottom: 2, left: 0 }}>
<Line
type="monotone"
dataKey="v"
stroke={color}
strokeWidth={1.5}
dot={false}
isAnimationActive={false}
/>
</LineChart>
</ResponsiveContainer>
</div>
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: 3, minHeight: 28 }}>
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color }}>
{stateLabel}
</span>
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 9, color: '#87867f', lineHeight: 1.35 }}>
{reasonLabel ?? sampleLabel ?? (metric.window ? t('window', { window: metric.window }) : '')}
</span>
</div>
</div>
</GlassCard>