Skip to content

Record Trust Cues

DASH-DATA-005 — record-level confidence and freshness vocabulary, policies, precedence, and rollout semantics.

Record-level confidence and freshness cues for publications (DASH-DATA-005). They let workspace members distinguish fresh, trusted, stale, conflicting, partial, and unknown evidence at the point of decision, without an opaque quality score. Field-level trust remains the field provenance inspector; this page covers the record-level layer on top of it.

Two independent axes, documented in @platform/schemas (TrustFreshnessStateSchema, TrustConfidenceStateSchema) and derived by @platform/utils (trust-cues):

AxisStatesDecided by
Freshnessfresh, aging, stale, unknownFetch timestamp vs. freshness policy
Confidencetrusted, edited, partial, conflicting, unknownProvenance field states

Confidence precedence when several signals apply: conflicting > unknown > partial > edited > trusted. A record with one conflicting field is conflicting even if everything else is fine; a record with no attributable evidence at all is unknown; missing evidence alongside attributable fields is partial; deliberate edits alone are edited, not a trust failure.

Freshness policy (publication enrichment v1)

Section titled “Freshness policy (publication enrichment v1)”
StateAge of last_fetched_at
fresh≤ 90 days
aging> 90 and ≤ 180 days
stale> 180 days
unknowntimestamp missing or invalid — never rendered as healthy

The policy lives in PUBLICATION_FRESHNESS_POLICY (@platform/utils); changing the numbers changes the dashboard badges and the server-side filter together. It aligns with manual/periodic enrichment cadence; per-source budgets are a later expansion behind the same schema.

  • Publications list: per-row freshness badge (desktop column + mobile card), freshness filter (all / fresh / aging / stale), served by the publication-query worker as bounded last_fetched_at comparisons against the same policy boundaries. The freshness header is not sortable: ingestion-date sorting was deliberately removed from this surface.
  • Provenance inspector: record trust summary with freshness + confidence badges and plain-language reasons (which fields conflict, which are missing, which were edited, fetch age).
  • Cues are derived on read from existing authorized contracts — the provenance response (record.last_fetched_at, per-field states) and list rows (last_fetched_at). No persistence, no new route, no worker change for the badge layer (ADR-0020).
  • Derivation is pure and bounded: O(supported fields) per record; perf tests pin list-scale and record-scale batches.
  • Degraded input degrades explicitly: malformed field lists or missing timestamps produce unknown cues, never a thrown error or a healthy default.
  • Filter usage is reported in listPublications route metrics (freshness attribute); filter queries flow through the worker’s traced DB queries (db.logic: publication-list-*).
  • Rollout: enable the filter/badges on the publications list first; extend to further surfaces only after interpretation is validated. Worker filter changes follow the standard production deploy + route verification for workers/*.
  • Rollback: remove the cue layer from affected routes (badges/summary are presentational; the filter param is optional and rejected-safe). No schema or data rollback exists because nothing new is persisted.
  • Publications only; person records and works keep their existing surfaces for now.
  • The list-level freshness badge uses fetch timestamps only — record confidence needs the provenance inspector (per-record evidence is not loaded on lists by design).
  • unknown freshness cannot be filtered server-side (a missing timestamp cannot be queried); it is always visible as a badge instead.