224 lines
10 KiB
Markdown
224 lines
10 KiB
Markdown
# Data Model: Baseline Compare Engine Strategy Extraction
|
|
|
|
## Overview
|
|
|
|
This feature introduces no new top-level persisted entity. It reuses the existing baseline compare start path, compare run persistence, finding lifecycle, and evidence storage, but inserts a new internal strategy boundary between platform compare orchestration and domain-specific compare logic.
|
|
|
|
## Existing Persisted Truth Reused Without Change
|
|
|
|
### Workspace-owned baseline truth
|
|
|
|
- `baseline_profiles`
|
|
- `baseline_snapshots`
|
|
- `baseline_snapshot_items`
|
|
- Canonical Baseline Scope V2 from Spec 202
|
|
|
|
These remain the reference truth that compare reads.
|
|
|
|
### Tenant-owned operational truth
|
|
|
|
- `operation_runs` for `baseline_compare`
|
|
- existing drift findings and recurrence tracking
|
|
- existing evidence and compare diagnostics stored in current finding and run payloads
|
|
|
|
These remain the long-lived operator truth written by compare.
|
|
|
|
### Existing subject and evidence inputs
|
|
|
|
- inventory-backed current state
|
|
- policy version and baseline snapshot evidence used by the current Intune path
|
|
- compare coverage and trust context already stored in the run and summary layers
|
|
|
|
This feature changes how domain logic is organized, not where those truths live.
|
|
|
|
## New Internal Contracts
|
|
|
|
### CompareStrategyKey
|
|
|
|
**Type**: string enum or equivalent value object
|
|
**Purpose**: identify one compare strategy family
|
|
|
|
| Value | Status | Notes |
|
|
|------|--------|-------|
|
|
| `intune_policy` | active | First explicit compare strategy family |
|
|
| future values | reserved | Additional families may be added later without changing the platform orchestration shape |
|
|
|
|
### CompareStrategyCapability
|
|
|
|
**Type**: derived registry record
|
|
**Purpose**: declare which canonical scope families a strategy supports
|
|
|
|
| Field | Type | Notes |
|
|
|------|------|-------|
|
|
| `strategy_key` | string | `CompareStrategyKey` value |
|
|
| `domain_keys` | array<string> | Supported governance domains |
|
|
| `subject_classes` | array<string> | Supported canonical subject classes |
|
|
| `subject_type_keys` | array<string> or `all` | Optional narrowing to known subject families |
|
|
| `compare_supported` | boolean | Whether compare may be started for the declared family |
|
|
| `active` | boolean | Whether the strategy is currently available |
|
|
|
|
### StrategySelectionState
|
|
|
|
**Type**: internal enum
|
|
**Purpose**: capture compare preflight compatibility outcome
|
|
|
|
| Value | Meaning |
|
|
|------|---------|
|
|
| `supported` | Exactly one compatible strategy family matches the requested scope |
|
|
| `unsupported` | No compatible strategy supports the requested scope |
|
|
| `mixed` | More than one strategy family would be required by the requested scope |
|
|
|
|
This is an orchestration contract, not a new top-level persisted domain status family.
|
|
|
|
### CompareStrategySelection
|
|
|
|
**Type**: internal orchestration record
|
|
**Purpose**: represent preflight strategy resolution for a compare start
|
|
|
|
| Field | Type | Notes |
|
|
|------|------|-------|
|
|
| `selection_state` | `StrategySelectionState` | Required |
|
|
| `strategy_key` | string or `null` | Present only when `selection_state = supported` |
|
|
| `matched_scope_entries` | array<object> | Canonical scope entries accepted by the selected strategy |
|
|
| `rejected_scope_entries` | array<object> | Scope entries rejected as unsupported or mixed |
|
|
| `operator_reason` | string | Short operator-safe explanation |
|
|
| `diagnostics` | array<string, mixed> | Secondary detail for logs and run detail |
|
|
|
|
### CompareOrchestrationContext
|
|
|
|
**Type**: internal execution record
|
|
**Purpose**: represent the platform-owned inputs to one compare run
|
|
|
|
| Field | Type | Notes |
|
|
|------|------|-------|
|
|
| `workspace_id` | integer | Required |
|
|
| `tenant_id` | integer | Required for tenant-owned compare runs |
|
|
| `baseline_profile_id` | integer | Required |
|
|
| `baseline_snapshot_id` | integer | Required reference snapshot |
|
|
| `operation_run_id` | integer | Required |
|
|
| `normalized_scope` | canonical scope document | Required |
|
|
| `strategy_selection` | `CompareStrategySelection` | Required |
|
|
| `coverage_context` | array<string, mixed> | Existing compare coverage truth |
|
|
| `launch_context` | array<string, mixed> | Existing start-surface context such as tenant or matrix origin |
|
|
|
|
### CompareSubjectIdentity
|
|
|
|
**Type**: internal value object
|
|
**Purpose**: represent one subject being compared without assuming policy-only semantics
|
|
|
|
| Field | Type | Notes |
|
|
|------|------|-------|
|
|
| `domain_key` | string | Canonical governance domain |
|
|
| `subject_class` | string | Canonical subject class |
|
|
| `subject_type_key` | string | Domain-owned subject family discriminator |
|
|
| `external_subject_id` | string | Stable external identifier where available |
|
|
| `subject_key` | string | Stable compare key used for deduplication and finding identity |
|
|
|
|
### CompareSubjectProjection
|
|
|
|
**Type**: internal value object
|
|
**Purpose**: provide the platform with operator-safe subject metadata for findings and summaries
|
|
|
|
| Field | Type | Notes |
|
|
|------|------|-------|
|
|
| `platform_subject_class` | string | Canonical class for platform writers |
|
|
| `domain_key` | string | Canonical governance domain |
|
|
| `subject_type_key` | string | Strategy-owned subject family |
|
|
| `operator_label` | string | Operator-facing subject label |
|
|
| `summary_kind` | string or `null` | Optional summary discriminator |
|
|
| `additional_labels` | array<string, string> | Optional secondary labels for diagnostics or detail surfaces |
|
|
|
|
### CompareState
|
|
|
|
**Type**: internal enum
|
|
**Purpose**: represent per-subject compare outcome
|
|
|
|
| Value | Meaning |
|
|
|------|---------|
|
|
| `no_drift` | Subject compared successfully and no drift was confirmed |
|
|
| `drift` | Subject compared successfully and drift was confirmed |
|
|
| `unsupported` | Subject or family is not supported by the selected strategy |
|
|
| `incomplete` | Evidence was insufficient to classify the subject fully |
|
|
| `ambiguous` | Identity or evidence ambiguity prevented a trustworthy compare decision |
|
|
| `failed` | Processing failed for this subject |
|
|
|
|
These values map to existing compare truth and do not imply a new top-level persisted run state family.
|
|
|
|
### CompareSubjectResult
|
|
|
|
**Type**: internal orchestration contract
|
|
**Purpose**: one structured output row from a compare strategy back to platform orchestration
|
|
|
|
| Field | Type | Notes |
|
|
|------|------|-------|
|
|
| `subject_identity` | `CompareSubjectIdentity` | Required |
|
|
| `projection` | `CompareSubjectProjection` | Required |
|
|
| `baseline_availability` | string | Required; e.g. `available`, `missing`, `not_applicable` |
|
|
| `current_state_availability` | string | Required; e.g. `available`, `missing`, `unknown` |
|
|
| `compare_state` | `CompareState` | Required |
|
|
| `trust_level` | string | Required; maps to current trust semantics |
|
|
| `evidence_quality` | string | Required; maps to existing evidence completeness semantics |
|
|
| `severity_recommendation` | string or `null` | Optional |
|
|
| `finding_candidate` | `CompareFindingCandidate` or `null` | Present when a finding should be written or updated |
|
|
| `diagnostics` | array<string, mixed> | Secondary detail for run context and troubleshooting |
|
|
|
|
### CompareFindingCandidate
|
|
|
|
**Type**: internal value object
|
|
**Purpose**: provide the unified finding writer with strategy-neutral mutation input
|
|
|
|
| Field | Type | Notes |
|
|
|------|------|-------|
|
|
| `change_type` | string | Existing finding change type or equivalent classification |
|
|
| `severity` | string | Existing severity family |
|
|
| `fingerprint_basis` | array<string, mixed> | Stable values used by finding recurrence logic |
|
|
| `evidence_payload` | array<string, mixed> | Strategy-owned evidence detail |
|
|
| `auto_close_eligible` | boolean | Whether absence in the current run should close the finding |
|
|
|
|
## Relationships
|
|
|
|
- One `CompareStrategyCapability` belongs to one `CompareStrategyKey`.
|
|
- One `CompareStrategySelection` is produced for each compare start attempt.
|
|
- One `CompareOrchestrationContext` contains exactly one supported `CompareStrategySelection` when a compare run is allowed to start.
|
|
- One strategy processes many `CompareSubjectIdentity` values and emits many `CompareSubjectResult` values for one `CompareOrchestrationContext`.
|
|
- One `CompareSubjectResult` may yield zero or one `CompareFindingCandidate`.
|
|
- Existing finding and summary writers consume `CompareSubjectResult` and `CompareFindingCandidate` without needing to inspect strategy internals directly.
|
|
|
|
## Validation Rules
|
|
|
|
### Strategy selection
|
|
|
|
1. Canonical scope must already be normalized to Baseline Scope V2.
|
|
2. Exactly one active strategy family must support all included scope entries.
|
|
3. Inactive or unsupported subject types fail selection before compare is enqueued.
|
|
4. Mixed strategy families fail selection before compare is enqueued.
|
|
5. No implicit fallback to `intune_policy` is allowed.
|
|
|
|
### Compare-subject result contract
|
|
|
|
1. Every processed subject must return one `CompareSubjectResult`.
|
|
2. Every result must include identity, projection, availability, compare state, trust, evidence quality, and diagnostics.
|
|
3. `finding_candidate` may be omitted only when the compare state does not warrant finding persistence.
|
|
4. The platform must not need raw strategy-private fields to build summaries, findings, or run diagnostics.
|
|
|
|
## Transition Rules
|
|
|
|
### Compare start to strategy selection
|
|
|
|
1. Receive canonical scope from the baseline profile plus any compare narrowing already allowed by the current workflow.
|
|
2. Resolve the compatible strategy family from the registry.
|
|
3. Reject unsupported or mixed scope before creating subject work.
|
|
4. Persist the selected strategy family and compatibility diagnostics into existing compare run context only when a run is created.
|
|
|
|
### Strategy selection to subject processing
|
|
|
|
1. Build `CompareOrchestrationContext` from existing baseline, tenant, snapshot, and run truth.
|
|
2. Hand domain-specific subject discovery and classification work to the selected strategy.
|
|
3. Reuse generic current-state and hashing helpers where they remain strategy-neutral.
|
|
|
|
### Subject results to existing run and finding truth
|
|
|
|
1. Aggregate `CompareSubjectResult` values into existing compare summary counts and trust semantics.
|
|
2. Write or update findings through the existing unified finding lifecycle using `CompareFindingCandidate`.
|
|
3. Persist strategy diagnostics only as secondary run or evidence detail inside existing persistence shapes.
|
|
4. Preserve existing run outcome ownership and current operator-visible compare semantics. |