Skip to the content.

ADR-0038 — Data Lineage Tracking

Date: 2026-04-08
Status: Accepted
Deciders: GNAT Platform Team


Context

GNAT’s existing EnrichmentLogModel records enrichment operations but does not cover ingestion, export, reporting, or inter-object linking. Enterprise operators need a cross-cutting audit trail that answers:

Without cross-cutting lineage, GNAT cannot answer these questions from a single source of truth.


Decision

Add an append-only lineage event log as a thin cross-cutting concern:

LineageEventType

Seven event types covering the full object lifecycle:

Type Trigger
INGESTED Object first arrives from a connector
ENRICHED Enrichment dispatcher processes the object
NORMALIZED Mapper normalises raw data to STIX
LINKED Object linked to an investigation
EXPORTED Object exported (STIX bundle, PDF, etc.)
REPORTED Object included in a published report
DELETED Object soft-deleted

LineageEvent (dataclass)

Immutable record: id (UUID4), event_type, object_id (STIX ID), object_type, actor, source, timestamp (UTC), metadata (dict).

LineageStore (SQLAlchemy)

LineageTracker

Convenience wrapper with one record_* method per event type. Accepts store=None for a no-op mode (safe in tests and optional deployments). Exceptions during persistence are caught and logged — lineage failure never propagates to callers.

Integration points


Consequences

Positive

Negative / Trade-offs

Deferred