TenantAtlas/specs/158-artifact-truth-semantics/data-model.md
ahmido e7c9b4b853 feat: implement governance artifact truth semantics (#188)
## Summary
- add shared governance artifact truth presentation and badge taxonomy
- integrate artifact-truth messaging across baseline, evidence, tenant review, review pack, and operation run surfaces
- add focused regression coverage and spec artifacts for artifact truth semantics

## Testing
- not run in this step

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #188
2026-03-23 00:13:57 +00:00

8.1 KiB

Data Model: Governance Artifact Truthful Outcomes & Fidelity Semantics

Overview

This feature introduces a shared read-model for operator-facing artifact truth across existing governance artifacts. The first slice does not require a new primary table. Instead, it standardizes how existing persisted artifact records are projected into one truth envelope.

Entities

ArtifactTruthEnvelope

Operator-facing read model derived from one governance artifact or artifact-targeted run.

Fields:

  • artifactFamily (enum): baseline_snapshot, evidence_snapshot, tenant_review, review_pack, artifact_run
  • artifactKey (string): stable identifier in the form {family}:{id}
  • workspaceId (int)
  • tenantId (int|null): null for workspace-owned baseline snapshots and workspace-level runs
  • executionOutcome (enum|null): pending, succeeded, partially_succeeded, blocked, failed
  • artifactExistence (enum): not_created, historical_only, created, created_but_not_usable
  • contentState (enum): trusted, partial, missing_input, metadata_only, reference_only, empty, unsupported
  • freshnessState (enum): current, stale, unknown
  • publicationReadiness (enum|null): not_applicable, internal_only, publishable, blocked
  • supportState (enum): normal, limited_support
  • actionability (enum): none, optional, required
  • primaryReasonCode (string|null)
  • primaryLabel (string): top-level operator-facing state summary
  • primaryExplanation (string|null): concise explanation of the main degraded dimension
  • diagnosticLabel (string|null): renderer or implementation-oriented label shown only secondarily
  • nextActionLabel (string|null)
  • nextActionUrl (string|null)
  • relatedRunId (int|null)
  • relatedArtifactUrl (string|null)

Validation rules:

  • artifactExistence = not_created MUST NOT coexist with contentState = trusted.
  • publicationReadiness MAY be non-null only for review and review-pack families.
  • supportState = limited_support MUST NOT be used as the primary failure dimension if another truth dimension explains operator impact.
  • actionability = required MUST include either nextActionLabel or a stable reason explanation.

ArtifactTruthDimension

Normalized dimension entry for badges, helper text, summaries, and canonical filter values.

Fields:

  • axis (enum): execution_outcome, artifact_existence, content_fidelity, data_freshness, publication_readiness, support_maturity, operator_actionability
  • state (string)
  • label (string)
  • classification (enum): primary, secondary, diagnostic
  • badgeDomain (string|null)
  • badgeState (string|null)

Validation rules:

  • At most one primary dimension may drive the top-level alert state at a time.
  • Diagnostic dimensions MUST still be preserved for detail pages even when not rendered on list pages.

ArtifactTruthCause

Stable explanation payload for degraded states.

Fields:

  • reasonCode (string|null)
  • translationArtifact (string|null): provider_reason_codes, execution_denial_reason_code, tenant_operability_reason_code, rbac_reason, or a bounded baseline/review artifact
  • operatorLabel (string|null)
  • shortExplanation (string|null)
  • diagnosticCode (string|null)
  • nextSteps (list)

Validation rules:

  • If reasonCode is translated, operatorLabel SHOULD come from the centralized translator.
  • Unknown codes MAY fall back to persisted message text, but raw codes remain diagnostics-only.

Source Projections

BaselineSnapshotProjection

Existing workspace-owned source record: BaselineSnapshot.

Source fields used:

  • id, workspace_id, captured_at
  • summary_jsonb.fidelity_counts
  • summary_jsonb.gaps
  • derived fidelity from FidelityState::fromSummary(...)

Derived truth rules:

  • Full artifact trust requires usable captured content and no misleading gap interpretation.
  • unsupported fidelity remains diagnostic-only unless it also implies that no trustworthy comparison artifact exists.
  • Zero-subject or unusable-upstream cases should be explained from related run context where available.

EvidenceSnapshotProjection

Existing tenant-owned source record: EvidenceSnapshot.

Source fields used:

  • id, workspace_id, tenant_id, status, completeness_state, generated_at, expires_at
  • summary.missing_dimensions, summary.stale_dimensions
  • child items.state, items.source_kind, items.freshness_at
  • operation_run_id

Derived truth rules:

  • status models lifecycle; completeness_state models coverage/freshness and must not be collapsed into lifecycle.
  • missing_dimensions > 0 indicates incomplete coverage, not run failure.
  • stale_dimensions > 0 indicates freshness follow-up, not absence.

TenantReviewProjection

Existing tenant-owned source record: TenantReview.

Source fields used:

  • id, workspace_id, tenant_id, status, completeness_state, generated_at, published_at, archived_at
  • summary.publish_blockers
  • summary.section_state_counts
  • evidence_snapshot_id, current_export_review_pack_id, operation_run_id
  • child sections.completeness_state, sections.measured_at

Derived truth rules:

  • status answers lifecycle (draft, ready, published, etc.), not evidence completeness by itself.
  • Publish blockers control publicationReadiness = blocked even when the review artifact exists.
  • A review may be internally useful while still not publishable.

ReviewPackProjection

Existing tenant-owned source record: ReviewPack.

Source fields used:

  • id, workspace_id, tenant_id, status, generated_at, expires_at, file_size
  • summary.review_status
  • summary.evidence_resolution.*
  • tenant_review_id, evidence_snapshot_id, operation_run_id

Derived truth rules:

  • status = ready means a file exists, not necessarily that the source review is still publishable.
  • Provenance must consider linked review state and evidence completeness at generation time.
  • expired is historical-only rather than a runtime failure.

ArtifactRunProjection

Existing source record: OperationRun limited to artifact-targeted families.

Source fields used:

  • id, workspace_id, tenant_id, type, status, outcome, summary_counts, failure_summary, context
  • translated reason via ReasonPresenter
  • related links via OperationRunLinks

Derived truth rules:

  • Run lifecycle and run outcome remain distinct from whether an artifact was actually produced.
  • Artifact-targeted families in this slice: baseline_capture, tenant.evidence.snapshot.generate, tenant.review.compose, tenant.review_pack.generate
  • The run truth section may reuse persisted context or summary enrichment to state whether the intended artifact exists and is usable.

State Transitions

Truth-envelope transitions

These are read-model transitions, not persistence transitions:

  1. not_createdcreated
    • Trigger: artifact record becomes available and usable.
  2. createdcreated_but_not_usable
    • Trigger: artifact exists but content, freshness, or readiness makes it unsafe for the primary operator task.
  3. created or created_but_not_usablehistorical_only
    • Trigger: artifact remains intelligible for history, but is expired, superseded, or no longer current for primary use.
  4. publicationReadiness = blockedpublishable
    • Trigger: review blockers clear or a derived pack is generated from a publishable review.

Existing persisted lifecycle references

  • EvidenceSnapshot.status: queuedgeneratingactivesuperseded|expired|failed
  • TenantReview.status: draftreadypublished|archived|superseded|failed
  • ReviewPack.status: queuedgeneratingready|failed|expired
  • OperationRun.status/outcome: service-owned lifecycle that remains unchanged by this feature

No New Primary Persistence in First Slice

  • No new top-level table is required.
  • Backward-compatible enrichment of existing JSON payloads is allowed if a family cannot otherwise satisfy truthful artifact provenance.
  • Any enrichment must remain optional for historical records and degrade gracefully when absent.