TenantAtlas/specs/163-baseline-subject-resolution/data-model.md
ahmido c17255f854 feat: implement baseline subject resolution semantics (#193)
## Summary
- add the structured subject-resolution foundation for baseline compare and baseline capture, including capability guards, subject descriptors, resolution outcomes, and operator action categories
- persist structured evidence-gap subject records and update compare/capture surfaces, landing projections, and cleanup tooling to use the new contract
- add Spec 163 artifacts and focused Pest coverage for classification, determinism, cleanup, and DB-only rendering

## Validation
- `vendor/bin/sail bin pint --dirty --format agent`
- `vendor/bin/sail artisan test --compact tests/Unit/Support/Baselines tests/Feature/Baselines tests/Feature/Filament/OperationRunEnterpriseDetailPageTest.php`

## Notes
- verified locally that a fresh post-restart baseline compare run now writes structured `baseline_compare.evidence_gaps.subjects` records instead of the legacy broad payload shape
- excluded the separate `docs/product/spec-candidates.md` worktree change from this branch commit and PR

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #193
2026-03-25 12:40:45 +00:00

8.5 KiB

Data Model: Baseline Subject Resolution and Evidence Gap Semantics Foundation

Overview

This feature does not require a new primary database table. It introduces a richer logical model for subject classification and resolution, then persists that model inside existing compare and capture run context for new runs. Development-only run payloads using the old broad reason shape may be removed or regenerated instead of preserved through a compatibility contract.

Entity: SubjectDescriptor

Business-level descriptor for a compare or capture target before local resolution.

Fields

Field Type Required Description
policy_type string yes Canonical policy or foundation type from support metadata
subject_external_id string no Stable local or tenant-local external identifier when available
subject_key string yes Deterministic comparison key used across capture and compare
subject_class enum yes One of policy_backed, inventory_backed, foundation_backed, derived
resolution_path enum yes Intended local path, such as policy, inventory, foundation_policy, foundation_inventory, or derived
support_mode enum yes supported, limited, excluded, or invalid_support_config
source_model_expected enum no Which local model is expected to satisfy the lookup

Validation Rules

  • policy_type must exist in canonical support metadata.
  • subject_class must be one of the supported subject-class values.
  • resolution_path must be compatible with subject_class.
  • support_mode=invalid_support_config is only valid when metadata claims support but no truthful runtime path exists.

Entity: ResolutionOutcomeRecord

Deterministic result of attempting to resolve a SubjectDescriptor against tenant-local state.

Fields

Field Type Required Description
resolution_outcome enum yes Precise outcome such as resolved_policy, resolved_inventory, policy_record_missing, inventory_record_missing, foundation_inventory_only, resolution_type_mismatch, unresolvable_subject, permission_or_scope_blocked, retryable_capture_failure, capture_failed, throttled, or budget_exhausted
reason_code string yes Stable operator-facing reason family persisted with the run
operator_action_category enum yes none, retry, run_inventory_sync, run_policy_sync_or_backup, review_permissions, inspect_subject_mapping, or product_follow_up
structural boolean yes Whether the outcome is structural rather than operational or transient
retryable boolean yes Whether retry may change the outcome without prerequisite changes
source_model_found enum or null no Which local model actually satisfied the lookup when resolution succeeded

State Families

Family Outcomes
resolved resolved_policy, resolved_inventory
structural foundation_inventory_only, resolution_type_mismatch, unresolvable_subject, invalid_support_config
operational policy_record_missing, inventory_record_missing, permission_or_scope_blocked, ambiguous_match, invalid_subject, duplicate_subject
transient retryable_capture_failure, throttled, budget_exhausted, capture_failed

Validation Rules

  • resolution_outcome must map to exactly one state family.
  • structural=true is only valid for structural state-family outcomes.
  • retryable=true is only valid for transient outcomes or explicitly retryable operational outcomes.

Entity: SupportCapabilityRecord

Runtime truth contract for whether a subject type may enter baseline compare or capture.

Fields

Field Type Required Description
policy_type string yes Canonical type key
subject_class enum yes Dominant subject class for the type
compare_capability enum yes supported, limited, or unsupported
capture_capability enum yes supported, limited, or unsupported
resolution_path enum yes Truthful runtime resolution path
config_supported boolean yes Whether metadata claims support
runtime_valid boolean yes Whether the runtime can honor that support claim

Validation Rules

  • config_supported=true and runtime_valid=false must be surfaced as invalid_support_config rather than silently ignored.
  • Types with compare_capability=unsupported must not enter compare scope.
  • Types with capture_capability=unsupported must not enter capture execution.

Entity: EvidenceGapDetailRecord

Structured subject-level record persisted under compare or capture run context for new runs.

Fields

Field Type Required Description
policy_type string yes Canonical type
subject_external_id string or null no Stable identifier when available
subject_key string yes Deterministic subject identity
subject_class enum yes Classified subject class
resolution_path enum yes Path attempted or declared
resolution_outcome enum yes Deterministic resolution result
reason_code string yes Stable reason family
operator_action_category enum yes Recommended next action family
structural boolean yes Structural versus non-structural marker
retryable boolean yes Retryability marker
source_model_expected enum or null no Expected local evidence model
source_model_found enum or null no Actual local evidence model when present

Storage Locations

  • operation_runs.context.baseline_compare.evidence_gaps.subjects[]
  • operation_runs.context.baseline_capture.gaps.subjects[] or equivalent capture-context namespace

Validation Rules

  • New-run records must store structured objects, not only string subject tokens.
  • subject_key must be deterministic for identical inputs.
  • reason_code and resolution_outcome must not contradict each other.
  • Old development rows that omit the new fields are cleanup candidates and should be regenerated or deleted rather than treated as a first-class runtime shape.

Derived Entity: EvidenceGapProjection

Read-model projection used by canonical run-detail and tenant review surfaces.

Fields

Field Type Description
detail_state enum no_gaps, structured_details_recorded, details_not_recorded, legacy_broad_reason
count integer Total gap count
by_reason map<string,int> Aggregate counts by reason
recorded_subjects_total integer Number of structured subject rows available for projection
missing_detail_count integer Gap count that has no structured row attached
structural_count integer Number of recorded structural gap rows
operational_count integer Number of recorded non-structural, non-retryable rows
transient_count integer Number of recorded retryable rows
legacy_mode boolean Indicates the run still stores a broad legacy gap payload
buckets list Grouped records by reason with searchable row payload
requires_regeneration boolean Whether stale local development data should be regenerated rather than interpreted semantically

State Transitions

Resolution lifecycle for a subject

  1. described
    • SubjectDescriptor is created from scope, metadata, and capability information.
  2. validated
    • Runtime support guard confirms whether the subject may enter compare or capture.
  3. resolved
    • The system attempts the appropriate local path and emits a ResolutionOutcomeRecord.
  4. persisted
    • New runs store the structured EvidenceGapDetailRecord or resolved outcome details in OperationRun.context.
  5. projected
    • Existing operator surfaces consume the new structured projection. Stale development data is regenerated or removed instead of driving a permanent compatibility path.

Example New-Run Compare Gap Record

{
  "policy_type": "roleScopeTag",
  "subject_external_id": "42f4fcb8-5b35-44ec-9240-0a1ad7c31fb1",
  "subject_key": "rolescopetag|42f4fcb8-5b35-44ec-9240-0a1ad7c31fb1",
  "subject_class": "foundation_backed",
  "resolution_path": "foundation_inventory",
  "resolution_outcome": "foundation_inventory_only",
  "reason_code": "foundation_not_policy_backed",
  "operator_action_category": "product_follow_up",
  "structural": true,
  "retryable": false,
  "source_model_expected": "inventory_item",
  "source_model_found": "inventory_item"
}