Skip to content
VerifAIer
Home / Docs / Engineering / Signal lifecycle
Engineering · Lifecycles

Signal lifecycle

Signals are the export boundary, a deterministic, self-contained snapshot of one operation's trust posture, ready to leave the system through a connector.

Signal lifecycle

SignalEngine.generate(...) projects any combination of existing runtime outputs into deterministic SignalEvents wrapped in a SignalExport. It is strictly a generation layer: no networking, no HTTP, no queues, no telemetry, and no communication with WIW. It reads only already-safe serialized fields and duplicates no upstream logic.

src/vailidator/signals/engine.py · models.py
flowchart TD
  IN["Any of: evidence · trust · identity
trust_profile · passport · reputation"] --> G["SignalEngine.generate(...)"] G --> H{"any usable data?"} H -->|no| E0["SignalExport (signal_count 0, signals empty)"] H -->|yes| PJ["project fields with precedence
trust > identity > profile > passport"] PJ --> SID["signal_id = 'sig_' + sha256(type|agent|evidence|receipt|prov|passport|reputation)[:16]"] SID --> EVT["one consolidated SignalEvent"] EVT --> XID["export_id = 'sigx_' + sha256(signal_ids)[:16]"] XID --> EX["SignalExport (signal_count 1)"]
Signal lifecycle, deterministic projection into a portable signal. Source: signals/engine.py.

When any input carries data, the engine emits a single consolidated SignalEvent that flattens the operation's ids and posture (trust/reputation scores, compliance status, risk/quality levels, provider/runtime/platform). Field selection uses a fixed precedence, for scores and levels, trust > identity > profile > passport. When no input has data, the export is empty (signal_count 0) rather than an error.

Content-addressed determinism

  • signal_id = sig_ + SHA-256 over signal_type | agent_id | evidence_id | receipt_id | provenance_id | passport_id | reputation_id (first 16 hex). No timestamp is in the hash, so the same operation always yields the same signal id.
  • export_id = sigx_ + SHA-256 over the contained signal ids.
  • created_at is injectable via clock: the only non-deterministic field, and it is outside the id hash by design.

Endpoint & composition

POST /api/v1/signals/export is a thin transport. If evidence is supplied (and truthy, an empty {} is treated as absent), it composes the chain Evidence → Trust → Identity → Trust Profile → Passport → Reputation → SignalExport, but any explicitly supplied layer takes precedence and is never recomputed. The response is the full SignalExport dict.

Where signals go. Delivery is a separate concern. The connector layer (connectors/) wraps a SignalExport into a ConnectorPayload addressed to a target (WIW, SIEM, data lake, OEM/white-label, analytics, archive), but it too is generation-only: no networking, no queues. The signal lifecycle ends at a portable, deterministic artifact.