# Data Model: Compare Job Legacy Drift Path Cleanup

## Overview

This feature introduces no new top-level persisted entity and no new runtime or product-facing contract. It removes an obsolete implementation branch from `CompareBaselineToTenantJob` and preserves the existing persisted truths and compare contracts that already drive the live strategy-based compare flow. The OpenAPI document in `contracts/` is a planning-only logical artifact that records invariants for this cleanup; it does not define a new runtime integration surface.

## Existing Persisted Truth Reused Without Change

### Workspace-owned baseline truth

- `baseline_profiles`
- `baseline_snapshots`
- `baseline_snapshot_items`
- Canonical baseline scope payload already stored in profile and run context

These remain the baseline reference truth that compare reads.

### Tenant-owned current-state and operational truth

- `inventory_items`
- `operation_runs` for `baseline_compare`
- findings written by the baseline compare lifecycle
- existing run-context JSON such as `baseline_compare`, `findings`, and `result`

These remain the long-lived operational truths written or consumed by compare.

### Existing evidence inputs reused without change

- policy-version content evidence
- inventory meta evidence
- current-state hash resolution
- coverage and gap context already recorded in the compare run

Spec 205 changes none of these inputs; it only removes a dead alternate computation path.

## Existing Internal Contracts Preserved

### Compare orchestration path

The live orchestration path remains:

1. `CompareBaselineToTenantJob::handle()`
2. `CompareStrategyRegistry::select(...)`
3. `CompareStrategyRegistry::resolve(...)`
4. `strategy->compare(...)`
5. `normalizeStrategySubjectResults(...)`
6. finding upsert, summary aggregation, gap handling, and run completion

No new branch, fallback path, or second engine is introduced.

### CompareStrategySelection

Existing selection metadata remains unchanged and continues to be written into the compare run context.

| Field | Purpose | Change in Spec 205 |
|------|---------|--------------------|
| `selection_state` | Supported vs unsupported strategy state | unchanged |
| `strategy_key` | Active compare strategy family | unchanged |
| `diagnostics` | Secondary strategy selection detail | unchanged |

### CompareOrchestrationContext

Existing strategy input context remains unchanged.

| Field | Purpose | Change in Spec 205 |
|------|---------|--------------------|
| `workspace_id` | Workspace scope for compare run | unchanged |
| `tenant_id` | Tenant scope for compare run | unchanged |
| `baseline_profile_id` | Baseline profile reference | unchanged |
| `baseline_snapshot_id` | Snapshot reference | unchanged |
| `operation_run_id` | Run identity | unchanged |
| `normalized_scope` | Canonical scope payload | unchanged |
| `coverage_context` | Coverage and unsupported-type context | unchanged |

### CompareSubjectResult and CompareFindingCandidate

Existing per-subject compare results and finding projection contracts remain unchanged.

| Contract | Purpose | Change in Spec 205 |
|----------|---------|--------------------|
| `CompareSubjectResult` | Strategy-owned per-subject compare outcome | unchanged |
| `CompareFindingCandidate` | Strategy-neutral finding mutation payload | unchanged |

### OperationRun compare context

The compare run continues to record current strategy, evidence coverage, gap counts, fidelity, reason translation, and result summaries inside the existing context structure. Spec 205 does not add, remove, or rename run-context fields.

### Finding lifecycle output

Finding severity, change type, recurrence key, evidence fidelity, timestamps, reopen behavior, and auto-close behavior remain unchanged. Spec 205 only preserves the live path that already feeds these outputs.

## Deleted Internal Cluster

Current repository inspection confirms one dead implementation cluster anchored by `computeDrift()` inside `CompareBaselineToTenantJob`, plus exclusive helpers clustered beneath it. The current candidate delete set includes:

- `computeDrift()`
- `effectiveBaselineHash()`
- `resolveBaselinePolicyVersionId()`
- `selectSummaryKind()`
- `buildDriftEvidenceContract()`
- `buildRoleDefinitionEvidencePayload()`
- `resolveRoleDefinitionVersion()`
- `fallbackRoleDefinitionNormalized()`
- `roleDefinitionChangedKeys()`
- `roleDefinitionPermissionKeys()`
- `resolveRoleDefinitionDiff()`
- `severityForRoleDefinitionDiff()`

The final delete list is confirmed by call-graph inspection during implementation. Any method still used by the live orchestration path remains out of scope.

## Relationships

- One `baseline_compare` run selects one supported strategy.
- One selected strategy processes many compare subjects.
- One `CompareSubjectResult` may yield zero or one `CompareFindingCandidate`.
- Existing finding and summary writers consume the strategy result contracts directly.
- The legacy drift cluster is not part of any required runtime relationship after Spec 203 and is therefore removed.

## Validation Rules

1. `CompareBaselineToTenantJob::handle()` must not call `computeDrift()` or any helper used exclusively by that legacy path.
2. Compare execution must continue to run through strategy selection, strategy resolution, and `strategy->compare(...)`.
3. Existing `OperationRun` status, outcome, summary-count, and context semantics must remain unchanged.
4. Existing finding lifecycle behavior must remain driven by normalized strategy subject results.
5. No new persistence, contract, or state family may be introduced as part of the cleanup.

## State Transitions

No new state transition is introduced.

Existing compare run transitions such as queued -> running -> completed or blocked remain unchanged, and finding lifecycle transitions remain governed by the current writers and services.