# Runtime Facts (Signals/Zastava) v0.1 ## Payload shapes - **Structured** (`POST /signals/runtime-facts`): - `subject` (imageDigest | scanId | component+version) - `callgraphId` (required) - `events[]`: `{ symbolId, codeId?, purl?, buildId?, loaderBase?, processId?, processName?, socketAddress?, containerId?, evidenceUri?, hitCount, observedAt?, metadata{} }` - **Streaming NDJSON** (`POST /signals/runtime-facts/ndjson`): one JSON object per line with the same fields; supports `Content-Encoding: gzip`; callgraphId provided via query/header metadata. ## Provenance/metadata - Signals stamps: - `provenance.source` (defaults to `runtime` unless provided in metadata) - `provenance.ingestedAt` (ISO-8601 UTC) - `provenance.callgraphId` - Runtime hits are aggregated per `symbolId` (summing hitCount) before persisting and feeding scoring. ## Validation - `symbolId` required; events list must not be empty. - `callgraphId` required and must resolve to a stored callgraph/union bundle. - Subject must yield a non-empty `subjectKey`. - Empty runtime stream is rejected. ## Storage and cache - Stored alongside reachability facts in Mongo collection `reachability_facts`. - Runtime hits cached in Redis via `reachability_cache:*` entries; invalidated on ingest. ## Interaction with scoring - Ingest triggers recompute: runtime hits added to prior facts’ hits, targets set to symbols observed, entryPoints taken from callgraph. - Reachability states include runtime evidence on the path; bucket/weight may be `runtime` when hits are present. - Unknowns registry stays separate; unknowns count still factors into fact score via pressure penalty. ## Replay alignment - Runtime traces packaged under CAS namespace `runtime_traces`; referenced in replay manifest with `namespace` and `analysisId` to link to static graphs. ## Determinism rules - Keep NDJSON ordering stable when generating bundles. - Use UTC timestamps; avoid environment-dependent metadata values. - No external network lookups during ingest.