"""Versioned deterministic five-dimension scoring for one cloud subscription.""" from __future__ import annotations from dataclasses import dataclass from decimal import ROUND_HALF_UP, Decimal from typing import Any from app.intelligence.scoring import ( METRIC_RULE_LABELS, MetricInput, MetricKind, health_grade, score_metric, validate_metric_key_shape_is_uniform, validate_metric_weight_totals, ) CLOUD_SCOPE_SCORE_VERSION = "cloud-scope-health-v1" CLOUD_SCOPE_DIMENSION_WEIGHTS: dict[str, Decimal] = { "cost_budget": Decimal("0.25"), "resource_utilization": Decimal("0.25"), "access_governance": Decimal("0.20"), "owner_lifecycle": Decimal("0.15"), "data_sync": Decimal("0.15"), } @dataclass(frozen=True) class CloudMetricDefinition: key: str dimension: str kind: MetricKind weight: Decimal label_zh: str = "" label_en: str = "" label_ja: str = "" def _definition( key: str, dimension: str, kind: MetricKind, weight: str, label_zh: str = "", label_en: str = "", label_ja: str = "", ) -> CloudMetricDefinition: return CloudMetricDefinition( key, dimension, kind, Decimal(weight), label_zh, label_en, label_ja ) CLOUD_SCOPE_METRICS: dict[str, CloudMetricDefinition] = { row.key: row for row in ( _definition( "cloud.cost.budget_coverage", "cost_budget", MetricKind.COVERAGE, ".25", "预算已配置覆盖率", "Budget configuration coverage", "予算設定カバレッジ", ), _definition( "cloud.cost.budget_overrun_rate", "cost_budget", MetricKind.FAILURE_RATE, ".30", "预算超支率", "Budget overrun rate", "予算超過率", ), _definition( "cloud.cost.anomaly_rate", "cost_budget", MetricKind.FAILURE_RATE, ".20", "成本异常率", "Cost anomaly rate", "コスト異常率", ), _definition( "cloud.cost.data_coverage", "cost_budget", MetricKind.COVERAGE, ".25", "成本账单数据覆盖率", "Cost billing data coverage", "コスト請求データカバレッジ", ), _definition( "cloud.resource.classified_coverage", "resource_utilization", MetricKind.COVERAGE, ".30", "资源效率已分类覆盖率", "Resource efficiency classification coverage", "リソース効率分類カバレッジ", ), _definition( "cloud.resource.actionable_rate", "resource_utilization", MetricKind.FAILURE_RATE, ".30", "可处理资源浪费率", "Actionable resource waste rate", "対処可能なリソース浪費率", ), _definition( "cloud.resource.owner_coverage", "resource_utilization", MetricKind.COVERAGE, ".20", "资源 Owner 覆盖率", "Resource owner coverage", "リソース所有者カバレッジ", ), _definition( "cloud.resource.monitoring_coverage", "resource_utilization", MetricKind.COVERAGE, ".20", "资源监控覆盖率", "Resource monitoring coverage", "リソース監視カバレッジ", ), _definition( "cloud.access.governed_coverage", "access_governance", MetricKind.COVERAGE, ".30", "已治理访问覆盖率", "Governed access coverage", "統制済みアクセスカバレッジ", ), _definition( "cloud.access.permanent_rate", "access_governance", MetricKind.FAILURE_RATE, ".20", "永久授权占比", "Permanent access rate", "恒久アクセス率", ), _definition( "cloud.access.privileged_review_coverage", "access_governance", MetricKind.COVERAGE, ".25", "特权访问复核覆盖率", "Privileged access review coverage", "特権アクセスレビューカバレッジ", ), _definition( "cloud.access.identity_gap_rate", "access_governance", MetricKind.FAILURE_RATE, ".25", "身份映射缺口率", "Identity mapping gap rate", "ID マッピング欠損率", ), _definition( "cloud.owner.active_coverage", "owner_lifecycle", MetricKind.COVERAGE, ".40", "有效 Owner 覆盖率", "Active owner coverage", "有効な所有者カバレッジ", ), _definition( "cloud.owner.confirmation_freshness", "owner_lifecycle", MetricKind.FRESHNESS, ".30", "Owner 确认新鲜度", "Owner confirmation freshness", "所有者確認の鮮度", ), _definition( "cloud.lifecycle.state_score", "owner_lifecycle", MetricKind.DIRECT, ".30", "订阅生命周期状态", "Subscription lifecycle state", "サブスクリプションのライフサイクル状態", ), _definition( "cloud.sync.scope_freshness", "data_sync", MetricKind.FRESHNESS, ".40", "订阅同步新鲜度", "Subscription sync freshness", "サブスクリプション同期の鮮度", ), _definition( "cloud.sync.cost_freshness", "data_sync", MetricKind.FRESHNESS, ".35", "成本同步新鲜度", "Cost sync freshness", "コスト同期の鮮度", ), _definition( "cloud.sync.efficiency_freshness", "data_sync", MetricKind.FRESHNESS, ".25", "效率数据新鲜度", "Efficiency data freshness", "効率データの鮮度", ), ) } def _validate_catalog() -> None: validate_metric_weight_totals( ((row.dimension, row.weight) for row in CLOUD_SCOPE_METRICS.values()), CLOUD_SCOPE_DIMENSION_WEIGHTS, ) # Uniformly ``cloud..``, i.e. the shape that does NOT # repeat the dimension — legal, and the reason this subject never hit # the 2026-09-01 citation failure. Guarded so a metric added in the # repeating shape cannot quietly create the mixture here. validate_metric_key_shape_is_uniform( ((row.key, row.dimension) for row in CLOUD_SCOPE_METRICS.values()), ) _validate_catalog() def public_cloud_scope_metric_catalog() -> list[dict[str, object]]: """Expose the immutable scoring contract without exposing subscription data.""" return [ { "key": row.key, "dimension": row.dimension, "kind": row.kind.value, "weight": str(row.weight), "labels": {"zh-CN": row.label_zh, "en-US": row.label_en, "ja-JP": row.label_ja}, "rule": { "score_version": CLOUD_SCOPE_SCORE_VERSION, "labels": METRIC_RULE_LABELS[row.kind], }, } for row in CLOUD_SCOPE_METRICS.values() ] def score_cloud_scope(metrics: list[MetricInput]) -> dict[str, Any]: """Score a complete or degraded subscription fact set. Missing catalog metrics remain explicitly unavailable and reduce confidence; they never become fabricated zero health. Unknown/duplicate keys fail closed. """ supplied: dict[str, MetricInput] = {} for input_metric in metrics: if input_metric.key not in CLOUD_SCOPE_METRICS: raise ValueError(f"Unknown cloud scope metric: {input_metric.key}") if input_metric.key in supplied: raise ValueError(f"Duplicate cloud scope metric: {input_metric.key}") supplied[input_metric.key] = input_metric dimension_rows: list[dict[str, Any]] = [] overall_sum = Decimal("0") scored_dimension_weight = Decimal("0") confidence_sum = Decimal("0") quant = Decimal("0.01") for dimension, dimension_weight in CLOUD_SCOPE_DIMENSION_WEIGHTS.items(): metric_rows: list[dict[str, Any]] = [] score_sum = Decimal("0") scored_weight = Decimal("0") dimension_confidence = Decimal("0") for definition in ( row for row in CLOUD_SCOPE_METRICS.values() if row.dimension == dimension ): metric = supplied.get(definition.key) confidence = max( Decimal("0"), min(Decimal("100"), Decimal(str(metric.confidence if metric else 0))), ) score = None if metric is not None and confidence > 0: score = score_metric( MetricInput( key=metric.key, kind=definition.kind, value=metric.value, ) ) score_sum += score * definition.weight scored_weight += definition.weight dimension_confidence += confidence * definition.weight metric_rows.append( { "key": definition.key, "kind": definition.kind.value, "value": metric.value if metric is not None else None, "weight": definition.weight, "score": score, "confidence": confidence, "evidence_refs": list(metric.evidence_refs) if metric else [], "data_as_of": metric.data_as_of if metric else None, } ) dimension_score = ( (score_sum / scored_weight).quantize(quant, rounding=ROUND_HALF_UP) if scored_weight else None ) confidence = dimension_confidence.quantize(quant, rounding=ROUND_HALF_UP) dimension_rows.append( { "key": dimension, "score": dimension_score, "confidence": confidence, "weight": dimension_weight, "metrics": metric_rows, } ) if dimension_score is not None: overall_sum += dimension_score * dimension_weight scored_dimension_weight += dimension_weight confidence_sum += confidence * dimension_weight overall = ( (overall_sum / scored_dimension_weight).quantize(quant, rounding=ROUND_HALF_UP) if scored_dimension_weight else None ) confidence = confidence_sum.quantize(quant, rounding=ROUND_HALF_UP) return { "score_version": CLOUD_SCOPE_SCORE_VERSION, "overall_score": overall, "confidence_score": confidence, "insufficient_data": confidence < 70, "grade": health_grade(overall) if overall is not None else None, "dimensions": dimension_rows, }