TenantAtlas/specs/162-baseline-gap-details/data-model.md
ahmido 7d4d607475 feat: add baseline gap details surfaces (#192)
## Summary
- add baseline compare evidence gap detail modeling and a dedicated Livewire table surface
- extend baseline compare landing and operation run detail surfaces to expose evidence gap details and stats
- add spec artifacts for feature 162 and expand feature coverage with focused Filament and baseline tests

## Notes
- branch: `162-baseline-gap-details`
- commit: `a92dd812`
- working tree was clean after push

## Validation
- tests were not run in this step

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #192
2026-03-24 19:05:23 +00:00

5.0 KiB

Data Model: Enterprise Evidence Gap Details for Baseline Compare

Overview

This feature does not introduce new database tables. It extends the tenant-owned OperationRun JSONB context for baseline_compare runs and defines a derived operator-facing row model for evidence-gap detail rendering.

Entity: OperationRun

  • Ownership: Tenant-owned operational artifact with workspace_id and tenant_id
  • Storage: Existing operation_runs table
  • Relevant relationships:
    • Belongs to Tenant
    • Belongs to Workspace
    • Belongs to initiating User
  • Relevant invariant:
    • status and outcome remain service-owned through OperationRunService
    • context may be enriched by the compare job without changing lifecycle semantics

Subdocument: baseline_compare

Stored under OperationRun.context['baseline_compare'].

Fields

Field Type Required Description
inventory_sync_run_id integer no Source inventory sync run used for coverage and freshness context
subjects_total integer no Total compare subjects considered for the run
evidence_capture object no Capture stats such as requested, succeeded, skipped, failed, throttled
coverage object no Coverage proof and covered/uncovered policy types
fidelity string no Compare fidelity, typically meta or content
reason_code string no Top-level compare reason code used by the explanation layer
resume_token string or null no Resume state for incomplete content capture
evidence_gaps object no Aggregate and subject-level evidence-gap contract

Subdocument: baseline_compare.evidence_gaps

Fields

Field Type Required Description
count integer no Total evidence-gap count across all reasons
by_reason object<string,int> no Aggregate counts keyed by evidence-gap reason code
subjects object<string,list> no Bounded reason-grouped list of concrete subject keys

Validation Rules

  • count must be a non-negative integer.
  • Each by_reason value must be a non-negative integer.
  • Each subjects key must be a non-empty reason code string.
  • Each subjects[reason] list item must be a non-empty string in policy_type|subject_key format.
  • Subject lists are deduplicated per reason.
  • Subject lists are capped at the compare job limit, currently 50 items per reason.

Derived Entity: EvidenceGapDetailRow

This is not stored separately. It is derived from baseline_compare.evidence_gaps.subjects for rendering and filtering.

Fields

Field Type Source Description
reason_code string map key Stable reason identifier such as ambiguous_match or policy_not_found
reason_label string derived Operator-facing label from reason_code
policy_type string parsed from subject string Policy family segment before the first pipe
subject_key string parsed from subject string Subject identity segment after the first pipe
search_text string derived Lowercased concatenation of reason, policy type, and subject key for local filtering

Validation Rules

  • policy_type must be non-empty.
  • subject_key may be human-readable text, GUID-like values, or workspace-safe identifiers, but must be non-empty once persisted.
  • search_text must be deterministic and derived only from persisted row values.

Derived Entity: EvidenceGapReasonBucket

Groups detail rows for rendering.

Fields

Field Type Description
reason_code string Stable bucket key
reason_label string Operator-facing label
count integer Number of visible persisted subjects in the bucket
rows list Rows shown for the reason

State Model

Run detail evidence-gap states

  1. NoGaps

    • evidence_gaps.count is absent or 0
    • No evidence-gap detail section is required
  2. GapsWithRecordedSubjects

    • evidence_gaps.count > 0
    • evidence_gaps.subjects exists with at least one non-empty reason bucket
    • Render searchable grouped rows
  3. GapsWithoutRecordedSubjects

    • evidence_gaps.count > 0
    • evidence_gaps.subjects is absent or empty
    • Render explicit fallback copy indicating detail was not recorded for that run

Example Payload

{
  "baseline_compare": {
    "subjects_total": 50,
    "fidelity": "meta",
    "reason_code": "evidence_capture_incomplete",
    "evidence_capture": {
      "requested": 50,
      "succeeded": 47,
      "skipped": 0,
      "failed": 3,
      "throttled": 0
    },
    "evidence_gaps": {
      "count": 5,
      "by_reason": {
        "ambiguous_match": 3,
        "policy_not_found": 2
      },
      "subjects": {
        "ambiguous_match": [
          "deviceConfiguration|WiFi-Corp-Profile",
          "deviceConfiguration|VPN-Always-On"
        ],
        "policy_not_found": [
          "deviceConfiguration|Deleted-Policy-ABC"
        ]
      }
    }
  }
}