TenantAtlas/specs/153-evidence-domain-foundation/data-model.md
ahmido a74ab12f04 feat: implement evidence domain foundation (#183)
## Summary
- add the Evidence Snapshot domain with immutable tenant-scoped snapshots, per-dimension items, queued generation, audit actions, badge mappings, and Filament list/detail surfaces
- add the workspace evidence overview, capability and policy wiring, Livewire update-path hardening, and review-pack integration through explicit evidence snapshot resolution
- add spec 153 artifacts, migrations, factories, and focused Pest coverage for evidence, review-pack reuse, authorization, action-surface regressions, and audit behavior

## Testing
- `vendor/bin/sail artisan test --compact --stop-on-failure`
- `CI=1 vendor/bin/sail artisan test --compact`
- `vendor/bin/sail bin pint --dirty --format agent`

## Notes
- branch: `153-evidence-domain-foundation`
- commit: `b7dfa279`
- spec: `specs/153-evidence-domain-foundation/`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #183
2026-03-19 13:32:52 +00:00

3.7 KiB

Data Model: Evidence Domain Foundation

1. EvidenceSnapshot

  • Purpose: Immutable, tenant-scoped evidence package captured at a specific point in time and reused by downstream consumers.
  • Ownership: Tenant-owned (workspace_id + tenant_id NOT NULL)
  • Fields:
    • id
    • workspace_id
    • tenant_id
    • operation_run_id nullable
    • initiated_by_user_id nullable
    • fingerprint nullable, 64-char SHA-256
    • previous_fingerprint nullable
    • status enum: queued, generating, active, superseded, expired, failed
    • completeness_state enum: complete, partial, missing, stale
    • summary JSONB
    • generated_at timestampTz nullable
    • expires_at timestampTz nullable
    • created_at, updated_at
  • Relationships:
    • belongs to Workspace
    • belongs to Tenant
    • belongs to OperationRun
    • belongs to initiator User
    • has many EvidenceSnapshotItem
  • Validation / invariants:
    • workspace_id and tenant_id required on every row
    • successful snapshots are immutable in content after status becomes active
    • one active snapshot per tenant evidence scope in v1
    • identical fingerprint for the same tenant scope reuses the existing non-expired snapshot

2. EvidenceSnapshotItem

  • Purpose: One curated evidence dimension inside an evidence snapshot.
  • Ownership: Tenant-owned (workspace_id + tenant_id NOT NULL)
  • Fields:
    • id
    • evidence_snapshot_id
    • workspace_id
    • tenant_id
    • dimension_key string
    • state enum: complete, partial, missing, stale
    • required boolean
    • source_kind string
    • source_record_type nullable string
    • source_record_id nullable string
    • source_fingerprint nullable string
    • measured_at timestampTz nullable
    • freshness_at timestampTz nullable
    • summary_payload JSONB
    • sort_order integer default 0
    • created_at, updated_at
  • Relationships:
    • belongs to EvidenceSnapshot
  • Validation / invariants:
    • unique per snapshot: (evidence_snapshot_id, dimension_key)
    • workspace_id/tenant_id must match the parent snapshot
    • summary_payload stores curated summary/reference data only; no secrets, tokens, or raw Graph dumps

3. Evidence dimensions in first rollout

  • findings_summary
  • permission_posture
  • entra_admin_roles
  • baseline_drift_posture
  • operations_summary

Each dimension stores:

  • inclusion state (complete|partial|missing|stale)
  • source provenance (record type, identifier, fingerprint)
  • freshness timestamp
  • dimension-specific summary payload

4. Derived completeness rules

  • Snapshot overall completeness precedence:
    • missing if any required dimension is missing
    • stale if no required dimensions are missing and at least one required dimension is stale
    • partial if no required dimensions are missing or stale and at least one required dimension is partial
    • complete only when all required dimensions are complete

5. Lifecycle transitions

EvidenceSnapshot status

  • queued -> generating
  • generating -> active
  • generating -> failed
  • active -> superseded
  • active -> expired
  • superseded -> expired

No transition may mutate snapshot items after active is reached.

6. Downstream resolution contract

EvidenceResolutionRequest

  • Purpose: Explicit request from a downstream consumer for a tenant evidence package.
  • Fields:
    • workspace_id
    • tenant_id
    • snapshot_id nullable explicit selection
    • required_dimensions array
    • allow_stale boolean default false

EvidenceResolutionResult

  • Outcomes:
    • resolved with snapshot id and eligible dimensions
    • missing_snapshot
    • snapshot_ineligible with missing/stale dimension reasons