Policy Normalized Field Removal Design

Document ID: DESIGN-POLICY-NORMALIZED-FIELD-REMOVAL-001 Version: 1.0 Status: Draft Last Updated: 2025-12-06

Overview

This document defines the migration plan for removing deprecated and legacy normalized fields from Policy Engine models. These fields were introduced for backwards compatibility but are now superseded by deterministic, canonical alternatives.

Background

The Policy Engine currently includes several “normalized” fields that were designed for cross-source comparison but have been deprecated in favor of deterministic scoring:

  1. normalized_score- Originally used for cross-vendor score comparison, now superseded by canonical severity scoring
  2. source_rank- Used for source prioritization, now handled by trust weighting service
  3. Duplicated severity fields - Multiple representations of the same severity data

Fields Analysis

Candidates for Removal

FieldLocationStatusMigration Path
normalized_scoreRiskScoringResultDEPRECATEDUse severity with canonical mapping
source_rank in scoringPolicyDecisionSourceRankDEPRECATEDUse trust weighting service
Legacy severity_countsMultiple modelsKEEPStill used for aggregation

Fields to Retain

FieldLocationReason
severityAll scoring modelsCanonical severity (critical/high/medium/low/info)
profile_hashRiskScoringResultDeterministic policy identification
trust_weightDecision modelsActive trust weighting system
raw_scoreScoring resultsNeeded for audit/debugging

Migration Plan

Phase 1: Deprecation (Current State)

Fields marked with [Obsolete] attribute to warn consumers:

[Obsolete("Use severity with canonical mapping. Scheduled for removal in v2.0")]
[JsonPropertyName("normalized_score")]
public double NormalizedScore { get; init; }

Phase 2: Soft Removal (v1.5)

Phase 3: Hard Removal (v2.0)

API Impact

Before (Current)

{
  "finding_id": "CVE-2024-1234",
  "raw_score": 7.5,
  "normalized_score": 0.75,
  "severity": "high",
  "source_ranks": [
    {"source": "nvd", "rank": 1},
    {"source": "vendor", "rank": 2}
  ]
}

After (Target)

{
  "finding_id": "CVE-2024-1234",
  "raw_score": 7.5,
  "severity": "high",
  "trust_weights": {
    "nvd": 1.0,
    "vendor": 0.8
  }
}

Implementation Steps

Step 1: Add Deprecation Markers

Add [Obsolete] to target fields with clear migration guidance.

Step 2: Create Compatibility Layer

Add opt-in flag for legacy serialization:

public class PolicyScoringOptions
{
    /// <summary>
    /// Include deprecated normalized_score field for backwards compatibility.
    /// </summary>
    public bool IncludeLegacyNormalizedScore { get; set; } = false;
}

Step 3: Update Serialization

Use conditional serialization based on options:

[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public double? NormalizedScore =>
    _options.IncludeLegacyNormalizedScore ? _normalizedScore : null;

Step 4: Update Documentation

Fixtures

Sample payloads are available in:

Rollback Strategy

If issues arise during migration:

  1. Re-enable legacy fields via configuration
  2. No data loss - fields are computed, not stored

Acceptance Criteria

  1. Deprecated fields marked with [Obsolete]
  2. Configuration option for backwards compatibility
  3. API documentation updated
  4. Migration guide published
  5. Fixtures validate before/after behavior