Skip to content

Data & ingest

How telemetry gets into VELA, how it becomes an anomaly, and how the knowledge graph is built. The canonical shapes live in design — data spec; this page is the pipeline and the adapters.

The TelemetrySource seam

Everything the pipeline needs for one investigation is a TelemetryBundle (samples, command history, per-channel limits, the time window, and any annotation/onboard events). A TelemetrySource yields it; the composition root selects one from config via build_telemetry_source.

telemetry_source Adapter Network? Notes
replay ReplayTelemetrySource no Seeded reference scenarios — the offline default
file SampleFileTelemetrySource no A CSV dump (long or wide / OpenC3 Data Extractor)
ccsds CcsdsTelemetrySource no A raw CCSDS Space Packet dump + a packet dictionary
esa_adb EsaAdbTelemetrySource no The public ESA-ADB benchmark dataset
yamcs YamcsTelemetrySource yes Read-only Yamcs Parameter Archive
openc3 / openc3_stream OpenC3TelemetrySource yes Read-only COSMOS CmdTlmApi / streaming
mqtt MqttTelemetrySource yes Subscribe-only broker ingest
kafka KafkaTelemetrySource yes Subscribe-only Kafka / event-bus ingest
aws_gs_stream AwsGsStreamTelemetrySource yes Native AWS-GS: bounded read off a Kinesis stream
aws_gs AwsGroundStationTelemetrySource yes Read-only Ground Station contact export

Air-gap safety is structural

Reading a local file is not network egress, so replay, file, ccsds, and esa_adb are selectable in airgap. The live sources (yamcs, openc3*, mqtt, kafka, aws_gs, aws_gs_stream) hard-fail in airgap before their adapter is imported. Every source is read-only — none defines a command surface (guardrail #1).

Detection — three trigger paths

All reach an AnomalyEvent:

  • annotation — scenario labels (the default).
  • ecod — per-channel unsupervised outlier detection.
  • graph — per-channel shift scores aggregated through the KG, catching distributed subsystem faults ECOD misses (the training-free stand-in for the learned GAT seam).
  • onboard — forms events from OnboardAIRecords the source carried down (“edge detects, ground explains”).

Every path then runs apply_command_response_filter, which suppresses deviations that follow a related telecommand within command_response_window_minutes — because most “anomalies” are expected responses to a command. (Reading command history is a core feature; issuing commands is forbidden.)

CCSDS Space Packet ingest

The CCSDS Space Packet (CCSDS 133.0-B) is the universal telemetry framing beneath every vendor API. VELA decodes it — never encodes it.

Raw Space Packet dumpPacket-layout dictionaryJSON / YAMLdecode_streamTelemetrySample time seriesPUS Service 5 anomaly reportsOnboardAIRecordsTelemetryBundle
  • vela/adapters/ccsds/packet.py — a pure primary-header decoder (decode_primary_header, iter_space_packets) with wrap-aware dropped-packet inference. Stops cleanly at a truncated tail; never fabricates a packet.
  • vela/adapters/ccsds/summary.py — a dictionary-free per-APID rollup (telemetry vs telecommand, counts, bytes, gaps), surfaced by the POST /ccsds/preview endpoint and vela ingest-ccsds.
  • vela/adapters/ccsds/pus.py — decodes the PUS (ECSS-E-ST-70-41C) TM secondary header to classify packets by service and flag Service 5 (event reporting) anomaly reports — an onboard-FDIR signal read straight off the wire.
  • vela/adapters/ccsds/dictionary.py + decode.py + source.py — a mission packet-layout dictionary (per-APID offset/type/scale/bias/limits + an optional CUC time field) drives decode_stream into TelemetrySamples and lifts PUS Service 5 reports into OnboardAIRecords. CcsdsTelemetrySource is the air-gap-safe telemetry_source="ccsds".

Decode-only, by construction

A telecommand packet is counted as read-only context, never decoded as telemetry and never PUS-decoded. There is no encode/build/issue verb anywhere in the module — a test asserts the public surface exposes none.

XTCE dictionary ingest

vela/kg/xtce.py reads the telemetry half of an XTCE dictionary (TelemetryMetaData) and maps each numeric parameter to a VELA channel, emitting the channels.csv shape the onboarding importer consumes. It reports every parameter it could not map rather than dropping it. Reachable via vela ingest-xtce and the POST /xtce/preview endpoint (and the console Ingest page). It also derives a CCSDS packet-layout dictionary from an XTCE SequenceContainer (vela derive-ccsds-dictionary) so a real XTCE database decodes a downlink with no hand-written offset map.

Knowledge-graph build

The reference graph (vela/kg/reference/reference_graph.py) defines VELA-REF-1: satellite → subsystems → components → telemetry channels, failure modes, procedures, and document sections, with the edges that let a channel resolve to its failure modes and cited manual sections. A customer KG is built the same way from an FMECA CSV + an XTCE dictionary through vela/kg/onboarding.py.

Gaps are first-class

Telemetry is irregular and gappy. A blank value is a gap — skipped, never interpolated across. This is a domain rule the adapters honor everywhere.