TenantAtlas/specs/177-inventory-coverage-truth/data-model.md
ahmido f52d52540c feat: implement inventory coverage truth (#208)
## Summary
- implement Spec 177 inventory coverage truth across resolver, badges, KPIs, coverage page, and operation run detail surfaces
- add repo-native spec artifacts for the feature under `specs/177-inventory-coverage-truth`
- add unit, feature, and browser coverage for truth derivation, continuity, and inventory item filter/pagination smoke paths

## Testing
- `vendor/bin/sail bin pint --dirty --format agent`
- focused Spec 177 browser smoke file passed with 2 tests / 57 assertions
- extended inventory-focused test pack passed with 52 tests / 434 assertions

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #208
2026-04-05 12:35:20 +00:00

5.6 KiB

Phase 1 Data Model: Inventory Coverage Truth (177)

Existing Persisted Truth

OperationRun as coverage basis

Represents the canonical execution record for inventory syncs and remains the source of per-type sync truth.

Relevant existing fields

  • workspace_id
  • tenant_id
  • type
  • status
  • outcome
  • summary_counts
  • failure_summary
  • context
  • started_at
  • completed_at

Relevant existing inventory context shape

  • context.inventory.coverage.policy_types
  • context.inventory.coverage.foundation_types
  • each entry stores at minimum status
  • optional fields already supported by InventoryCoverage normalization:
    • item_count
    • error_code

Existing invariant

  • InventoryCoverage::fromContext() is the canonical parser for run coverage payload.

InventoryItem

Represents last observed tenant inventory rows and remains the source of current observed-item counts.

Relevant existing fields

  • workspace_id
  • tenant_id
  • policy_type
  • external_id
  • display_name
  • category
  • platform
  • meta_jsonb
  • last_seen_at
  • last_seen_operation_run_id

Existing invariant

  • Observed rows prove last observation only. They do not by themselves prove current tenant coverage completeness.

InventoryPolicyTypeMeta + capability metadata

Represents product support and capability reference for supported and foundation types.

Relevant existing fields and derived attributes

  • type
  • label
  • category
  • platform
  • restore
  • risk
  • foundation flag
  • dependency support from CoverageCapabilitiesResolver

Existing invariant

  • Capability metadata is product support truth, not tenant coverage truth.

New Derived Runtime Contract

TenantCoverageTruth

Derived runtime contract that answers the operator question: which supported types are currently covered for this tenant, which types need follow-up, and which run establishes that statement.

Proposed fields

  • tenant_id
  • basis_run_id nullable
  • basis_run_outcome nullable
  • basis_completed_at nullable
  • has_current_coverage_result boolean
  • supported_type_count
  • succeeded_type_count
  • failed_type_count
  • skipped_type_count
  • unknown_type_count
  • follow_up_type_count
  • observed_item_total
  • rows list of TenantCoverageTypeTruth

Derived invariants

  • Exactly one row exists for each supported policy type and foundation type currently in the product support catalog.
  • follow_up_type_count = failed + skipped + unknown.
  • has_current_coverage_result is true only when a completed inventory-sync basis run with parseable payload exists.
  • The basis run is chosen independently from current item counts.

TenantCoverageTypeTruth

Derived row contract for one supported type.

Proposed fields

  • type
  • segment (policy or foundation)
  • label
  • category
  • platform nullable
  • coverage_state (succeeded, failed, skipped, unknown)
  • follow_up_required boolean
  • observed_item_count
  • basis_error_code nullable
  • restore_mode nullable
  • risk_level nullable
  • supports_dependencies boolean

Derived invariants

  • follow_up_required is true for failed, skipped, and unknown; false only for succeeded.
  • observed_item_count > 0 does not change coverage_state.
  • coverage_state = unknown when the type is supported but absent from the basis run payload.
  • basis_error_code is allowed only for non-succeeded payload-backed states.

Derived State Family

Coverage state family

This feature introduces one derived state family for tenant coverage rows:

  • Succeeded
    • the basis run reported the type as successfully processed
  • Failed
    • the basis run reported the type as attempted and failed
  • Skipped
    • the basis run reported the type as intentionally skipped or not processed during that run
  • Unknown
    • no current coverage result exists for the supported type in the basis run

Behavioral consequence

  • Failed, Skipped, and Unknown all suppress calm claims and increment follow-up counts.
  • Unknown is derived, not persisted.

Relationships

  • One TenantCoverageTruth resolves for one tenant at a time.
  • One TenantCoverageTruth may reference zero or one basis OperationRun.
  • One TenantCoverageTruth contains one row per supported product type from InventoryPolicyTypeMeta::supported() and InventoryPolicyTypeMeta::foundations().
  • Each TenantCoverageTypeTruth joins one supported type to zero or one payload-backed status from the basis run and zero or more InventoryItem rows from the current tenant observation set.

Selection Rules

Basis run selection

  • candidate runs are OperationRun rows where:
    • tenant_id matches the selected tenant
    • type = inventory_sync
    • status = completed
  • candidates are ordered by:
    • completed_at DESC
    • id DESC
  • the selected basis run is the first candidate whose context.inventory.coverage payload can be parsed by InventoryCoverage::fromContext()
  • if no candidate qualifies, the tenant has no current coverage basis run

Unknown derivation

  • if a supported type is absent from both policy_types and foundation_types in the selected basis payload, the type is Unknown
  • absence from the basis payload is not converted into Skipped
  • item presence from older runs does not upgrade Unknown

Validation Rules

  • No schema migration is required.
  • No new persisted state is introduced.
  • Coverage rows must remain tenant-scoped.
  • Capability metadata must not alter the derived coverage state.
  • Surfaces may cite the basis run only when they can do so without violating authorization.