TenantAtlas/specs/204-platform-core-vocabulary-hardening/data-model.md
2026-04-14 08:07:40 +02:00

247 lines
12 KiB
Markdown

# Data Model: Platform Core Vocabulary Hardening
## Overview
This feature introduces no new top-level persisted entity and no new mandatory database table. It formalizes a small set of internal platform contracts that clarify ownership, canonical naming, alias handling, and platform-facing subject descriptors across the existing governance, operation, and reason-translation seams.
## Existing Persisted Truth Reused Without Change
### Operation truth
- `operation_runs.type`
- `operation_runs.context`
- current run summary, monitoring, notification, and audit projections
These remain the persisted record of what ran. Spec 204 changes how platform code resolves and presents operation meaning, not the existence of those records.
### Governance and baseline truth
- `baseline_profiles.scope_jsonb`
- `baseline_snapshots`
- `baseline_snapshot_items`
- current findings and evidence payloads
- canonical Baseline Scope V2 from Spec 202
These remain the reference truth for platform-near compare and snapshot surfaces.
### Domain-owned provider and policy truth
- Intune policy records and policy versions
- backup and inventory items with Intune-native metadata
- Graph-facing provider payloads and config-backed Intune policy-type catalogs
These remain intentionally domain-owned and may continue to use Intune-native terminology such as `policy_type` where that ownership is explicit.
## New Internal Contracts
### VocabularyBoundaryClassification
**Type**: internal enum
**Purpose**: give contributors one explicit three-way classification for touched concepts
| Value | Meaning |
|------|---------|
| `platform_core` | Core product vocabulary owned by the platform itself |
| `cross_domain_governance` | Governance vocabulary shared across domains and workflows |
| `intune_specific` | Vocabulary that remains intentionally specific to the Intune domain |
### PlatformVocabularyTerm
**Type**: internal governance record
**Purpose**: define one canonical platform noun or phrase and its ownership boundary
| Field | Type | Notes |
|------|------|-------|
| `term_key` | string | Stable internal identifier for the term |
| `canonical_label` | string | Preferred operator-safe platform label |
| `canonical_description` | string | Maintained description of what the term means in platform context |
| `boundary_classification` | string | `platform_core`, `cross_domain_governance`, or `intune_specific` |
| `owner_layer` | string | `platform_core`, `domain_owned`, `provider_owned`, or `compatibility_alias` |
| `allowed_contexts` | array<string> | Surfaces or layers where the term is valid |
| `legacy_aliases` | array<string> | Historical names still recognized for compatibility |
| `alias_retirement_path` | string or `null` | Documented path for retiring any legacy alias once rollout stabilizes |
| `forbidden_platform_aliases` | array<string> | Names that must not be used as universal platform vocabulary |
### RegistryOwnershipDescriptor
**Type**: internal governance record
**Purpose**: describe whether a registry or catalog is canonical platform vocabulary, domain-owned vocabulary, or compatibility-only
| Field | Type | Notes |
|------|------|-------|
| `registry_key` | string | Stable internal identifier |
| `boundary_classification` | string | `platform_core`, `cross_domain_governance`, or `intune_specific` |
| `owner_layer` | string | `platform_core`, `domain_owned`, `provider_owned`, or `compatibility_only` |
| `source_class_or_file` | string | Class or config path that owns the registry |
| `canonical_nouns` | array<string> | Terms this registry defines authoritatively |
| `allowed_consumers` | array<string> | Surfaces allowed to consume the registry as-is |
| `compatibility_notes` | string or `null` | Transitional notes where legacy or domain-specific terms remain exposed |
### CanonicalOperationType
**Type**: internal operation catalog record
**Purpose**: describe one canonical platform operation code
| Field | Type | Notes |
|------|------|-------|
| `canonical_code` | string | Preferred platform operation code |
| `domain_key` | string or `null` | Optional domain grouping when the operation belongs to a specific subject family |
| `artifact_family` | string | Existing operation artifact grouping |
| `display_label` | string | Preferred operator-facing label |
| `supports_operator_explanation` | boolean | Mirrors existing catalog behavior |
| `expected_duration_seconds` | integer or `null` | Existing duration hint |
### OperationTypeAlias
**Type**: internal compatibility record
**Purpose**: map one stored or historical operation type value onto one canonical operation type
| Field | Type | Notes |
|------|------|-------|
| `raw_value` | string | Stored or historical operation type value |
| `canonical_code` | string | Target canonical operation code |
| `alias_status` | string | `canonical`, `legacy_alias`, or `deprecated_alias` |
| `write_allowed` | boolean | Whether new writes may still emit this raw value |
| `deprecation_note` | string or `null` | Optional explanation for reviewers or maintainers |
| `retirement_path` | string or `null` | Required rollout note describing how and when the alias stops being writable or supported |
### OperationTypeResolution
**Type**: internal derived value object
**Purpose**: represent resolved operation meaning for monitoring, filters, notifications, audit prose, and run detail surfaces
| Field | Type | Notes |
|------|------|-------|
| `raw_value` | string | Original stored value |
| `canonical` | `CanonicalOperationType` | Resolved canonical operation record |
| `aliases_considered` | array<`OperationTypeAlias`> | Alias records considered during normalization |
| `alias_status` | string | Current alias state |
| `was_legacy_alias` | boolean | Convenience flag for diagnostics and test assertions |
### PlatformReasonFamily
**Type**: internal enum
**Purpose**: classify translated reasons into one platform-owned family without changing domain-owned reason codes
| Value | Meaning |
|------|---------|
| `authorization` | Access or RBAC boundary prevented the action or view |
| `prerequisite` | Required tenant, workspace, or configuration precondition is missing |
| `compatibility` | The requested workflow or subject family is not supported together |
| `coverage` | Evidence or scope coverage is insufficient to make a trustworthy claim |
| `availability` | The referenced object, source, or provider data is absent or unavailable |
| `execution` | Runtime execution failed or degraded |
### ReasonOwnershipDescriptor
**Type**: internal derived record
**Purpose**: identify which layer owns the underlying reason code
| Field | Type | Notes |
|------|------|-------|
| `owner_layer` | string | `platform_core`, `domain_owned`, or `provider_owned` |
| `owner_namespace` | string | Stable namespace such as `provider.intune`, `governance.baseline_compare`, `access.rbac`, or `execution.runtime` |
| `reason_code` | string | Original reason code value |
| `platform_reason_family` | string | `PlatformReasonFamily` value |
### TranslatedReasonEnvelopeV2
**Type**: internal extension of the existing `ReasonResolutionEnvelope`
**Purpose**: provide one operator-safe explanation object with explicit ownership and family metadata
| Field | Type | Notes |
|------|------|-------|
| `reason_owner` | `ReasonOwnershipDescriptor` | New ownership metadata |
| `operator_label` | string | Existing translated label |
| `explanation` | string | Existing translated explanation |
| `actionability` | string | Existing actionability field |
| `next_steps` | array<string> | Existing or derived remediation hints |
| `diagnostic_label` | string or `null` | Existing technical summary |
| `trust_impact` | string or `null` | Existing trust impact summary |
| `absence_pattern` | string or `null` | Existing absence classification where relevant |
### PlatformSubjectDescriptor
**Type**: internal derived value object
**Purpose**: normalize platform-near subject meaning without assuming universal Intune policy nouns
| Field | Type | Notes |
|------|------|-------|
| `domain_key` | string | Canonical governance domain |
| `subject_class` | string | Canonical subject class |
| `subject_type_key` | string | Domain-owned subject family key |
| `subject_type_label` | string | Operator-facing subject family label |
| `platform_noun` | string | Preferred platform noun for the object |
| `display_label` | string | Subject label used on touched UI surfaces |
| `legacy_policy_type` | string or `null` | Optional legacy Intune discriminator retained only for compatibility or diagnostics |
| `owner_layer` | string | Usually `platform_core` for the descriptor itself even when the underlying subject is Intune-owned |
### SubjectDescriptorNormalizationResult
**Type**: internal derived record
**Purpose**: report how a platform-near raw payload was normalized into a `PlatformSubjectDescriptor`
| Field | Type | Notes |
|------|------|-------|
| `descriptor` | `PlatformSubjectDescriptor` | Required normalized descriptor |
| `source_surface` | string | Run detail, snapshot rendering, compare summary, evidence rendering, or similar |
| `used_legacy_alias` | boolean | Whether normalization had to fall back to `policy_type` or another legacy discriminator |
| `warnings` | array<string> | Non-fatal compatibility warnings for diagnostics |
## Relationships
- One `PlatformVocabularyTerm` may describe many `RegistryOwnershipDescriptor` or `PlatformSubjectDescriptor` contracts.
- One `CanonicalOperationType` may have many `OperationTypeAlias` records.
- One `OperationTypeResolution` is produced from exactly one raw operation type value and one resolved `CanonicalOperationType`.
- One `ReasonOwnershipDescriptor` classifies one underlying reason code and feeds one `TranslatedReasonEnvelopeV2`.
- One `SubjectDescriptorNormalizationResult` produces exactly one `PlatformSubjectDescriptor` for one touched platform-near payload.
- One registry or catalog should have exactly one `RegistryOwnershipDescriptor` to keep ownership explicit.
## Validation Rules
### Platform glossary and registry ownership
1. Every canonical platform term must have exactly one `owner_layer`.
2. Every canonical platform term must have exactly one explicit `boundary_classification`.
3. A term marked `compatibility_alias` cannot be the primary label on new platform surfaces.
4. A registry marked `domain_owned` or `provider_owned` cannot be treated as a universal platform glossary without an explicit wrapper or translation step.
5. Any term with one or more `legacy_aliases` must also define an `alias_retirement_path`.
### Operation vocabulary
1. Every stored operation type value consumed by touched platform surfaces must resolve to exactly one canonical operation code.
2. New writes on touched flows must not introduce a raw value marked `deprecated_alias`.
3. Monitoring, filters, notifications, and audit prose must render canonical labels through `OperationTypeResolution` rather than raw strings.
### Reason ownership
1. Every translated operator reason must carry explicit `reason_owner` metadata.
2. A `platform_reason_family` must be derived without renaming the original domain-owned code.
3. Platform surfaces may summarize by family, but diagnostics must preserve the original owner namespace and code.
### Platform subject descriptors
1. Every touched platform-near compare, snapshot, or review payload must provide a `PlatformSubjectDescriptor` or enough source data to derive one.
2. `legacy_policy_type` may be carried only as secondary compatibility data.
3. New or updated platform-facing summary labels must prefer `platform_noun`, `subject_type_label`, or `display_label` over raw `policy_type`.
## Transition Rules
### Operation type transition
1. Existing stored raw values remain readable.
2. Canonical resolution happens at read and presentation time for touched surfaces.
3. New or updated platform flows touched by this spec must emit canonical operation codes on new writes.
4. Legacy aliases remain documented and test-covered as read-only compatibility paths for historical data and untouched flows until intentionally retired.
### Reason translation transition
1. Existing domain reason codes remain unchanged.
2. Ownership and family metadata are added at translation time.
3. Existing operator-safe explanation fields remain the primary rendering contract.
### Platform-near subject transition
1. Existing persisted baseline and evidence truths remain intact.
2. Wrapper or presenter normalization adds `PlatformSubjectDescriptor` semantics first.
3. Legacy `policy_type` remains available only for compatibility, diagnostics, or Intune-owned surfaces.