Skip to main content

Adapter support matrix

Every row below is read off one adapter's metadata — the same declaration manifests/<id>.json publishes and python -m synapse_cdm.harness --list-adapters prints — so the four cannot say different things about the same adapter. The page is regenerated by the command in its header, and tests/test_cdm_support_matrix.py in the test suite fails while the page on disk and the declarations disagree (no CI step runs the generator's --check; the suite is what holds it); a sentence in it is not a claim somebody typed.

How to read the binding column. standard-encoding means the bytes this adapter reads and writes are the cited document's own encoding, checked by this repository's fixtures and tests — verified by this package's own evidence, not by an independent implementation or a normative schema (those are the external evidence categories below). provisional-internal-profile means the element names or namespace were chosen here from the standard's data model because the normative binding resource is not held, or (added 2026-10-10) that the wire form is an interface this repository defines itself, for which no external normative binding exists; reader and writer agreeing proves the profile is self-consistent and nothing more. normative-verified would mean the wire form was validated against the authorised normative schema through the adapter's local-resource hook; no shipped adapter declares it, and the manifests test holds the value to an exercise report.

The matrix​

adapterformateditionbindingdirectionreplayed formsmaturitylicence
adsbADS-B 1090ES Extended Squitter (Mode S DF17/DF18)not stated — see the limitationsstandard-encodingbidirectional (ingest, egress).adsb, .parsed.jsonL3LICENSED
airnow_hourlyEPA AirNow hourly observation files (HourlyData, HourlyAQObs)AirNow Hourly Data File fact sheet (last updated August 2025) and Hourly AQ Obs File fact sheet (updated March 2023)standard-encodingingest (ingest).dat, .parsed.jsonL3PUBLIC_GOVERNMENT
aisAIS (NMEA 0183 AIVDM/AIVDO)not stated — see the limitationsstandard-encodingbidirectional (ingest, egress).nmea, .parsed.jsonL3LICENSED
aixm511AIXM5.1.1 (XML Schema, April 2016; GML 3.2.1; AIXM Temporality Concept 1.1)standard-encodingingest (ingest).parsed.json, .xmlL3OPEN
aixm52AIXM5.2 (XML Schema release 5.2.0, 17 January 2025; GML 3.2.1; AIXM Temporality Concept 1.1)standard-encodingingest (ingest).parsed.json, .xmlL3OPEN
c2simC2SIMSISO-STD-019-2020 v1.0 (Core + SMX) with SISO-STD-020-2020 (LOX); XML schema C2SIMArtifacts v1.0.1standard-encodingbidirectional (ingest, egress).parsed.json, .xmlL4OPEN
cat021EUROCONTROL ASTERIX Category 021 — ADS-B Target ReportsEdition 2.6standard-encodingbidirectional (ingest, egress).cat021, .parsed.jsonL3PUBLIC_GOVERNMENT
cat023EUROCONTROL ASTERIX Category 023 — CNS/ATM Ground Station and Service Status ReportsEdition 1.3standard-encodingbidirectional (ingest, egress).cat023, .parsed.jsonL3PUBLIC_GOVERNMENT
cat034EUROCONTROL ASTERIX Category 034 — Monoradar Service MessagesEdition 1.29standard-encodingbidirectional (ingest, egress).cat034, .parsed.jsonL3PUBLIC_GOVERNMENT
cat048EUROCONTROL ASTERIX Category 048 — Monoradar Target ReportsEdition 1.32standard-encodingbidirectional (ingest, egress).cat048, .parsed.jsonL3PUBLIC_GOVERNMENT
cat062EUROCONTROL ASTERIX Category 062 — SDPS Track MessagesEdition 1.21standard-encodingbidirectional (ingest, egress).cat062, .parsed.jsonL3PUBLIC_GOVERNMENT
cogGeoTIFF / Cloud Optimized GeoTIFF (OGC GeoTIFF 1.1, OGC COG 1.0)OGC GeoTIFF Standard 1.1 (19-008r4) and OGC Cloud Optimized GeoTIFF Standard 1.0 (21-026), on classic TIFF Revision 6.0; GDAL VRT as GDAL's driver documentation describes itstandard-encodingingest (ingest).parsed.json, .tif, .vrtL3OPEN
coops_csvNOAA CO-OPS data API response (datagetter)api.tidesandcurrents.noaa.gov/api/prod, read 2026-10-14standard-encodingingest (ingest).csv, .json, .parsed.jsonL3PUBLIC_GOVERNMENT
dis7DIS7 / IEEE 1278.1-2012 Entity State subsetstandard-encodingbidirectional (ingest, egress).dis, .parsed.jsonL4LICENSED
geojsonGeoJSONRFC 7946 (August 2016)standard-encodingbidirectional (ingest, egress).jsonL4OPEN
geopackageGeoPackage1.4.0 (OGC 12-128r19)standard-encodingingest (ingest).gpkg, .parsed.jsonL3OPEN
gmtiSTANAG 4607 / AEDP-4607 — NATO Ground Moving Target Indicator Format (GMTIF)AEDP-4607 Edition A Version 1standard-encodingbidirectional (ingest, egress).gmti, .parsed.jsonL3PUBLIC_GOVERNMENT
grib2GRIB2 (WMO FM 92 GRIB edition 2)GRIB edition 2, read against NCEP's WMO GRIB2 Documentation version 37.0.0 (2026-06-01)standard-encodingingest (ingest).grb2, .parsed.jsonL3PUBLIC_GOVERNMENT
iem_n0qIEM NEXRAD N0Q composite PNG (W3C PNG, IEM product composite_n0q)Portable Network Graphics (PNG) Specification (Third Edition), W3C Recommendation 24 June 2025; IEM composite_n0q at 12200 x 5400 cells, the grid IEM has published since 2014-08-08standard-encodingingest (ingest).parsed.json, .pngL3OPEN
legionPicogrid Legion Platform API v3v3standard-encodingingest (ingest).jsonL3LICENSED
link16_gatewaySC Link16 Gateway1.0.0provisional-internal-profilebidirectional (ingest, egress).bin, .jsonL4OPEN
ndbc_stdmetNDBC standard meteorological data (stdmet)NDBC Web Data Guide, Version 2.0 (June 2023)standard-encodingingest (ingest).parsed.json, .stdmetL3PUBLIC_GOVERNMENT
nexrad2NEXRAD Level II (Archive II)ICD 2620010J (Archive II/User) and ICD 2620002Y (RDA/RPG), Build 23.0standard-encodingingest (ingest).ar2v, .parsed.jsonL3PUBLIC_GOVERNMENT
pntmapPNTMAP GNSS interference alertnot stated — see the limitationsstandard-encodingingest (ingest).jsonL3OPEN
readsb_tracereadsb trace JSONreadsb v3.16.17standard-encodingingest (ingest).parsed.json, .traceL3OPEN
stanag4586STANAG 4586 — Standard Interfaces of UAV Control System (UCS), DLI telemetryEdition 3standard-encodingingest (ingest).parsed.json, .s4586L3PUBLIC_GOVERNMENT
stanag4609STANAG 4609 / MISP-2019.1 — the UAS Datalink Local SetMISP-2019.1 (STANAG 4609 Edition 5 wrapper)standard-encodingbidirectional (ingest, egress).klv, .parsed.jsonL3PUBLIC_GOVERNMENT
stanag4676STANAG 4676 / AEDP-12 — NATO ISR Tracking Standard (NITS)AEDP-12 Edition B Version 2provisional-internal-profilebidirectional (ingest, egress).nits.xml, .parsed.jsonL3PUBLIC_GOVERNMENT
tacticalapiTacticalAPIrheinmetall.tactical_api.v0, commit 58661c9 (2026-09-01); no tag or release existsstandard-encodingingest (ingest).binpb, .parsed.jsonL3OPEN
takCursor-on-Target (TAK)not stated — see the limitationsstandard-encodingbidirectional (ingest, egress).parsed.json, .xmlL3PUBLIC_GOVERNMENT

direction is the declared value with the directions the capability block says are exercised in brackets; the model refuses a disagreement between the two. replayed forms are the file suffixes in the adapter's packaged fixture directory — the wire form and, for binary and XML adapters, the parsed twin beside it. maturity is the declared rung, which the conformance suite computes independently and the manifests test holds to the evidence.

Evidence scope​

The five evidence categories of evidence.EvidenceCategory, per adapter. The first two the conformance suite produces from this repository's own fixtures; the other three only an exercise report from outside it can make PRESENT, and until one exists each reads ABSENT with the reason. A rung's requirement is satisfied by PRESENT only.

adapterinternal_fixtureself_round_tripindependent_expectednormative_schemaindependent_endpoint
adsbinternal — the suite's checks A/B/C over the packaged synthetic fixturesinternal — check E, this package encoding and decoding on both legs; not independenceABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
airnow_hourlyinternal — the suite's checks A/B/C over the packaged synthetic fixturesNOT_APPLICABLE — ingest only, no egress leg to round-tripABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
aisinternal — the suite's checks A/B/C over the packaged synthetic fixturesinternal — check E, this package encoding and decoding on both legs; not independenceABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
aixm511internal — the suite's checks A/B/C over the packaged synthetic fixturesNOT_APPLICABLE — ingest only, no egress leg to round-tripABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
aixm52internal — the suite's checks A/B/C over the packaged synthetic fixturesNOT_APPLICABLE — ingest only, no egress leg to round-tripABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
c2siminternal — the suite's checks A/B/C over the packaged synthetic fixturesinternal — check E, this package encoding and decoding on both legs; not independenceABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
cat021internal — the suite's checks A/B/C over the packaged synthetic fixturesinternal — check E, this package encoding and decoding on both legs; not independenceABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
cat023internal — the suite's checks A/B/C over the packaged synthetic fixturesinternal — check E, this package encoding and decoding on both legs; not independenceABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
cat034internal — the suite's checks A/B/C over the packaged synthetic fixturesinternal — check E, this package encoding and decoding on both legs; not independenceABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
cat048internal — the suite's checks A/B/C over the packaged synthetic fixturesinternal — check E, this package encoding and decoding on both legs; not independenceABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
cat062internal — the suite's checks A/B/C over the packaged synthetic fixturesinternal — check E, this package encoding and decoding on both legs; not independenceABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
coginternal — the suite's checks A/B/C over the packaged synthetic fixturesNOT_APPLICABLE — ingest only, no egress leg to round-tripABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
coops_csvinternal — the suite's checks A/B/C over the packaged synthetic fixturesNOT_APPLICABLE — ingest only, no egress leg to round-tripABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
dis7internal — the suite's checks A/B/C over the packaged synthetic fixturesinternal — check E, this package encoding and decoding on both legs; not independenceABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
geojsoninternal — the suite's checks A/B/C over the packaged synthetic fixturesinternal — check E, this package encoding and decoding on both legs; not independenceABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
geopackageinternal — the suite's checks A/B/C over the packaged synthetic fixturesNOT_APPLICABLE — ingest only, no egress leg to round-tripABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
gmtiinternal — the suite's checks A/B/C over the packaged synthetic fixturesinternal — check E, this package encoding and decoding on both legs; not independenceABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
grib2internal — the suite's checks A/B/C over the packaged synthetic fixturesNOT_APPLICABLE — ingest only, no egress leg to round-tripABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
iem_n0qinternal — the suite's checks A/B/C over the packaged synthetic fixturesNOT_APPLICABLE — ingest only, no egress leg to round-tripABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
legioninternal — the suite's checks A/B/C over the packaged synthetic fixturesNOT_APPLICABLE — ingest only, no egress leg to round-tripABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
link16_gatewayinternal — the suite's checks A/B/C over the packaged synthetic fixturesinternal — check E, this package encoding and decoding on both legs; not independenceABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
ndbc_stdmetinternal — the suite's checks A/B/C over the packaged synthetic fixturesNOT_APPLICABLE — ingest only, no egress leg to round-tripABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
nexrad2internal — the suite's checks A/B/C over the packaged synthetic fixturesNOT_APPLICABLE — ingest only, no egress leg to round-tripABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
pntmapinternal — the suite's checks A/B/C over the packaged synthetic fixturesNOT_APPLICABLE — ingest only, no egress leg to round-tripABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
readsb_traceinternal — the suite's checks A/B/C over the packaged synthetic fixturesNOT_APPLICABLE — ingest only, no egress leg to round-tripABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
stanag4586internal — the suite's checks A/B/C over the packaged synthetic fixturesNOT_APPLICABLE — ingest only, no egress leg to round-tripABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
stanag4609internal — the suite's checks A/B/C over the packaged synthetic fixturesinternal — check E, this package encoding and decoding on both legs; not independenceABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
stanag4676internal — the suite's checks A/B/C over the packaged synthetic fixturesinternal — check E, this package encoding and decoding on both legs; not independenceABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
tacticalapiinternal — the suite's checks A/B/C over the packaged synthetic fixturesNOT_APPLICABLE — ingest only, no egress leg to round-tripABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)
takinternal — the suite's checks A/B/C over the packaged synthetic fixturesinternal — check E, this package encoding and decoding on both legs; not independenceABSENT — no expected result derived by another implementation: every golden in this repository was written by the code under testABSENT — check B validates the CDM's own published schema, which this repository wrote; no authorised normative schema of the source format is held offline (F05)ABSENT — no exchange with an independently implemented endpoint has been recorded; external_exercise is null and L6 is not awardable from this repository's own evidence (ARCHITECTURE.md §3.3)

Per adapter: message families and exclusions​

adsb — ADS-B 1090ES​

Format. ADS-B 1090ES Extended Squitter (Mode S DF17/DF18), not stated — see the limitations. Binding standard-encoding. No profile declared.

Message families implemented.

  • DF17 (ADS-B)
  • DF18 (TIS-B / non-ICAO)
  • ME type codes: identification, surface_position, airborne_position, airborne_velocity_ground, airborne_velocity_air, aircraft_status, operational_status

Exclusions and limitations, as declared.

  • the edition this adapter is written against is NOT STATED by any document in this repository — no pin record exists for RTCA DO-260x or ICAO Annex 10, both of which fixtures/adsb/spec/adsb_terms.json records as priced, so format.version is null rather than guessed
  • DF17 and DF18 only; every other downlink format is out of scope
  • a single frame carries no unambiguous position — the 17-bit CPR fields need a second frame of the opposite parity or a reference position, and no frame carries a time at all
  • leftovers are parked in Entity.attributes / Event.payload under source_extras (lossless.residual()), not in the origin-identifying container ARCHITECTURE.md §5 gives to P3 — the Part 1 stance that section rules for the adapters already shipped
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run and the release pipeline attaches it to the GitHub Release. evidence.available is true because the records for 2.1.2 are attached to the v2.1.2 Release and retrievable by a third party, and it says nothing about what the wheel contains
  • of §3.5's five resource limits this adapter enforces ONE — max_input_bytes, declared in capabilities.limits with its basis beside it and refused before decode by the base class (round P5). The other four are still absent, each with its own reason in capabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today

airnow_hourly — EPA AirNow hourly observation file (HourlyData, HourlyAQObs) translator​

Format. EPA AirNow hourly observation files (HourlyData, HourlyAQObs), AirNow Hourly Data File fact sheet (last updated August 2025) and Hourly AQ Obs File fact sheet (updated March 2023). Binding standard-encoding. No profile declared.

Message families implemented.

  • EPA AirNow HourlyData_yyyymmddhh.dat (header-less, |-delimited) or HourlyAQObs_yyyymmddhh.dat (quoted CSV), one file per call, as its octets or its parsed twin; one ENVIRONMENTAL_OBSERVATION Event per line carrying point-observation/1, and one Entity per site

Exclusions and limitations, as declared.

  • HourlyData and HourlyAQObs files are read; the forecast file (reportingarea.dat), the site file (monitoring_site_locations.dat), the API's responses and EPA AQS records are not, and nothing is joined from another file
  • a HourlyData line states no position: it comes only from a caller's site table (a StationTable keyed by AQSID), else the site Entity's position is null; a HourlyAQObs line's Latitude and Longitude are its stated position, and its Elevation, whose datum the fact sheet does not state, stays in the residual
  • a stamp is the GMT start of a one-hour period: validity.effective is [start, start + 1 h] and observed_at its end; the GMT offset (to local standard time) is never applied
  • a HourlyAQObs AQI field is carried with the unit AQI under the fact sheet's definition, an index with no other unit; a concentration's unit is its own *_Unit field, verbatim
  • a HourlyAQObs line stating neither an AQI nor a concentration is refused no-reading, and a HourlyData line with a blank value or unit is refused blank-value: the fact sheets say only valid data are reported, and the design record holds no such line
  • AirNow's hourly files carry no per-value quality flag, so every contract states quality_flags_basis; the data are preliminary, and the AirNow Data Exchange Guidelines' terms bind the consumer, not this package
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run, and the release pipeline generates the records for every shipped adapter and attaches them to the GitHub Release of the version it publishes. evidence.available is true because every published distribution that carries this adapter has that Release, so its records are retrievable by a third party; it says nothing about what the wheel contains

ais — AIS​

Format. AIS (NMEA 0183 AIVDM/AIVDO), not stated — see the limitations. Binding standard-encoding. No profile declared.

Message families implemented.

  • AIVDM/AIVDO message types 1, 2, 3, 4, 5, 18, 19, 21

Exclusions and limitations, as declared.

  • the edition this adapter is written against is NOT STATED by any document in this repository — the format has two publishers, ITU-R (M.1371) and NMEA (0183), and fixtures/ais/spec/ais_terms.json records both without naming the edition this implementation targets, so format.version is null rather than guessed
  • message types 1, 2, 3, 4, 5, 18, 19 and 21 are in scope; every other type is named in FORMAT_COVERAGE.md with the reason it is out
  • type 24 static data is out of scope, so a vessel's name and call sign arrive in no message this adapter reads
  • leftovers are parked in Entity.attributes / Event.payload under source_extras (lossless.residual()), not in the origin-identifying container ARCHITECTURE.md §5 gives to P3 — the Part 1 stance that section rules for the adapters already shipped
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run and the release pipeline attaches it to the GitHub Release. evidence.available is true because the records for 2.1.2 are attached to the v2.1.2 Release and retrievable by a third party, and it says nothing about what the wheel contains
  • of §3.5's five resource limits this adapter enforces ONE — max_input_bytes, declared in capabilities.limits with its basis beside it and refused before decode by the base class (round P5). The other four are still absent, each with its own reason in capabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today

aixm511 — AIXM 5.1.1​

Format. AIXM, 5.1.1 (XML Schema, April 2016; GML 3.2.1; AIXM Temporality Concept 1.1). Binding standard-encoding. Profiles Digital NOTAM Specification 2.0 scenario RWY.CLS version 2.0 (DRAFT guidance, page 220791360 v30, 2025-12-09; rules RWY.CLS.01–RWY.CLS.06) on AIXM 5.1.1 Event Schema 2.0.m, Digital NOTAM Specification 2.0 scenario ATSA.ACT version 2.0 (DRAFT guidance, page 220791511 v35, 2025-09-25; rules ER-01–ER-06) on AIXM 5.1.1 Event Schema 2.0.m, Digital NOTAM Specification 2.0 scenario SAA.ACT version 2.0 (DRAFT guidance, page 220791162 v57, 2023-09-19; rules ER-01–ER-09) on AIXM 5.1.1 Event Schema 2.0.m, Digital NOTAM Specification 2.0 scenario NAV.UNS version 2.0 (DRAFT guidance, page 220791463 v35, 2026-03-20; rules NAV.UNS.01–NAV.UNS.11) on AIXM 5.1.1 Event Schema 2.0.m.

Message families implemented.

  • AIXMBasicMessage / Airspace time slices — type, designator, name, geometry components (AirspaceVolume limits with references, horizontalProjection in the pinned Surface forms, contributor airspace), activation with schedules; one Entity per slice and a CONTROL_MEASURE PlanObject with an Area when the slice states a projectable BASE geometry; ingest
  • AIXMBasicMessage / AirportHeliport time slices — designators, ICAO/IATA codes, type, field elevation, ARP ElevatedPoint, availability (operationalStatus, warning, schedules); one FACILITY Entity per slice; ingest
  • AIXMBasicMessage / Runway and RunwayDirection time slices — designators, type, dimensions, bearings, TDZ elevation, the airport / runway / starting element references, ManoeuvringAreaAvailability (closures) with schedules; one FACILITY Entity per slice; ingest
  • AIXMBasicMessage / Navaid time slices — type, designator, name, location ElevatedPoint, NavaidOperationalStatus with schedules, component equipment, served airport and runway direction references; one FACILITY Entity per slice; ingest
  • AIXMBasicMessage / VerticalStructure time slices — name, type, lighting and marking flags, dimensions, every part with its verticalExtent and its point, linear or surface horizontal projection; one FACILITY Entity per slice; ingest
  • AIXMBasicMessage / event:Event time slices (Digital NOTAM Event Schema 2.0.m on AIXM 5.1.1) — name, designator, scenario, version, estimatedValidity, activity, concernedAirspace / concernedAirportHeliport / parentEvent / causeEvent / provider references, every NOTAM notification typed beside its source, the pinned scenario profile (RWY.CLS, ATSA.ACT, SAA.ACT, NAV.UNS at 2.0) and the slice's source assertion (initial, correction, cancellation, termination, replacement) with its temporal basis; one UNKNOWN Entity per slice with attributes.dnotam (aixm-dnotam/1); and, on any feature slice whose aixm:extension carries event:theEvent, the binding, the Event's scenario and the scenario rule layer's findings; ingest

Exclusions and limitations, as declared.

  • the five families are Airspace, AirportHeliport, Runway, RunwayDirection, Navaid and VerticalStructure, plus the Digital NOTAM event:Event (its own reading, limitation digital-notam-profiles); a feature of any other class (Unit, OrganisationAuthority, Route, Procedure …) becomes an Entity of type UNKNOWN carrying the GENERIC reading only — identity, interpretation, sequence and correction numbers, validTime, featureLifetime, the pinned simple properties the slice happens to state, and the ledger-bound complex elements (CARRIED_ELEMENTS: location, ARP, a repeated availability — or a single one on the eleven NavaidEquipment classes NAV.UNS binds, whose time-slice types list it — activation, part, navaidEquipment, geometryComponent) carried source-verbatim at their block field — with every other property in the residual and no position or status, and validate_source names it; a member that is not a feature at all (no aixm:timeSlice) is carried whole in the residual. Within a family only the pinned properties are typed (the implementation record lists them); the rest is residual
  • Digital NOTAM is read on the AIXM 5.1.1 + Event Schema 2.0.m combination only (Event 2.0.k and 2.0.l accept the same documents; 1.0 / 2.0.f / 2.0.j do not; no Event schema targets AIXM 5.2). The pinned scenario profiles are exactly RWY.CLS, ATSA.ACT, SAA.ACT and NAV.UNS at scenario version 2.0 of the Digital NOTAM Specification 2.0, which is a DRAFT ('in preparation', validated by implementation) and is never described as an approved final standard; an Event stating any other scenario is typed and carried with profile_finding and no scenario rule is checked. The rule layer holds a bound slice to the rules it can be held to on its own — the binding rule (TEMPDELTA on a feature class the profile names) and the status rule (RWY.CLS.03, ER-01/ER-02, NAV.UNS.04) on the change's own structures; a structure carrying the REMARK 'Baseline data copy. Not included in the NOTAM text generation' (ATSA.ACT ER-04, SAA.ACT ER-06, NAV.UNS.08) restates the baseline and is kept, not judged — as findings, never repairs; the schema layer is normative_validation. NOTHING is resolved by this adapter: correction, cancellation, replacement and expiry are typed as the slice's own source assertion, and the resolved view at an instant is synapse_cdm.aixm_resolve, which takes explicit prior state. The event extension on a feature slice is read and not consumed (it stays in the residual at its position)
  • gml:ArcByCenterPoint, gml:CircleByCenterPoint, gml:Arc, gml:ArcString, gml:Circle, gml:CompositeCurve, gml:OrientableCurve, a CRS other than urn:ogc:def:crs:EPSG::4326 and urn:ogc:def:crs:OGC:1.3:CRS84, and a third dimension refuse the document by default with the element form and the source text named; under Aixm511Adapter(unsupported_geometry='report') the slice is an Entity with the form named in attributes.aixm and no PlanObject. No arc is replaced by a chord and no circle by a polygon
  • an Airspace whose geometry components use UNION, INTERS or SUBTR, or whose BASE components state different vertical limits, is typed component by component and produces no PlanObject: the CDM Area is one volume and composing one would be a derivation the source did not state. volume_projection on the block says why; validate_source names it
  • a vertical limit projects onto the CDM only where a VerticalUnit and a VerticalReference exist for it (FT/M against SFC/MSL/W84/STD, FL against STD); SM, a flight level against another reference, an unstated uom and the tokens UNL/GND/FLOOR/CEILING are carried typed with the reason they are not projected. Feet are never converted to metres and no datum is converted
  • a time slice with no validTime instant of its own (§4.4.8's cancellation with nilReason='inapplicable', an absent validTime, an indeterminate begin) can be an Entity only under Aixm511Adapter(as_of=AsOf(instant, basis)), whose instant becomes valid_from with the basis in source.transformations; without it the document is refused naming the slice. Nothing is stamped with the clock or the epoch
  • a feature of a pinned family without a gml:identifier is refused: identity is derived from the UUID the feature carries across documents (Feature Identification and Reference 1.0 §2.1), and a document-local gml:id would make the same feature two entities in two documents
  • xlink:href is resolved against the document and the caller's references table, one hop, never over a network; a URL is classified and not fetched; unresolved references are kept with their property, href and form under attributes.aixm.references and listed in unresolved_references
  • Timesheets, activation and availability structures are carried as typed validity, never resolved to instants; status on an Entity is set only when the slice states exactly one such structure and it carries no timeInterval, so an unconditional status is never asserted from a scheduled one
  • positions carry position_source: MANUAL — a surveyed, published coordinate is none of GNSS, INERTIAL or ESTIMATED — with the MSL elevation of an ElevatedPoint in vertical (its uom kept, reference MSL by the model's own definition of elevation) and alt_m None because MSL is not height above the ellipsoid
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged. evidence.available is true because 3.1.0 is the first release carrying this adapter and its pipeline generates the records for every shipped adapter and attaches them to the v3.1.0 Release as evidence-3.1.0.tar.gz, retrievable by a third party; it says nothing about what the wheel contains, and a tag that released nothing carries this sentence to nobody
  • of §3.5's five resource limits this adapter enforces THREE — max_input_bytes by the base class before decode and again by secure_xml before a parser exists, max_depth and max_objects in this module before any object is built — plus an element count the manifest schema has no field for. The other two are absent with their reasons in capabilities.limits.absent_because
  • XML is parsed with the standard library's expat through secure_xml and NOT with defusedxml, which is not a dependency of this package: a DOCTYPE is refused at its declaration before any entity is read, every entity reference other than the five predefined ones is refused, no external resource is fetched and XInclude is refused where it starts (tests/test_cdm_secure_xml.py). The tree is xml.etree.ElementTree's own, built through its TreeBuilder
  • this adapter reads AIXM 5.1.1 only: a document in the 5.1 or 5.2 namespace is refused at the root with its namespace named; AIXM 5.2 is a sibling adapter

aixm52 — AIXM 5.2​

Format. AIXM, 5.2 (XML Schema release 5.2.0, 17 January 2025; GML 3.2.1; AIXM Temporality Concept 1.1). Binding standard-encoding. No profile declared.

Message families implemented.

  • AIXMBasicMessage (5.2) / Airspace time slices — type, designator, name, geometry components (AirspaceVolume limits with references, horizontalProjection in the pinned Surface forms, contributor airspace; the 5.2 name and location of a volume carried verbatim), activation with schedules; one Entity per slice and a CONTROL_MEASURE PlanObject with an Area when the slice states a projectable BASE geometry; ingest
  • AIXMBasicMessage (5.2) / AirportHeliport time slices — designators, ICAO/IATA codes, type, field elevation, verticalDatum (free text in 5.2), timeZone, segmentedCircleMarker, ARP ElevatedPoint (the 5.2 property group: no verticalAccuracy), availability (operationalStatus, warning, schedules); one FACILITY Entity per slice; ingest
  • AIXMBasicMessage (5.2) / Runway and RunwayDirection time slices — designators, type, dimensions, depth, reference codes, bearings, TDZ elevation, slope, approach guidance, the airport / runway / starting element references, ManoeuvringAreaAvailability (closures) with schedules; one FACILITY Entity per slice; ingest
  • AIXMBasicMessage (5.2) / Navaid time slices — type, designator, name, codeICAOCountry, location ElevatedPoint, NavaidOperationalStatus with schedules, component equipment, served airport and runway direction references; one FACILITY Entity per slice; ingest
  • AIXMBasicMessage (5.2) / VerticalStructure time slices — name, designator, type, lighting and marking flags, placeName, dataAssessmentStatus, dimensions, every part with its verticalExtent, its 5.2 height and its point, linear or surface horizontal projection; one FACILITY Entity per slice; ingest

Exclusions and limitations, as declared.

  • the five families are Airspace, AirportHeliport, Runway, RunwayDirection, Navaid and VerticalStructure, with the AIXM 5.2 property groups pinned (the implementation record lists the 5.2 paths per family and the 5.1.1 → 5.2 differences); a feature of any other class (Unit, OrganisationAuthority, Route, Procedure …) becomes an Entity of type UNKNOWN carrying the GENERIC reading only — identity, interpretation, sequence and correction numbers, validTime, featureLifetime, the pinned simple properties the slice happens to state, and the ledger-bound complex elements (CARRIED_ELEMENTS: location, ARP, a repeated availability, activation, part, navaidEquipment, geometryComponent) carried source-verbatim at their block field — with every other property in the residual and no position or status, and validate_source names it; a member that is not a feature at all (no aixm:timeSlice) is carried whole in the residual. Within a family only the pinned properties are typed; the rest is residual — including the 5.2 AirspaceVolume name and location, which ride in the component's verbatim source and are not typed
  • No Digital NOTAM Event schema exists for AIXM 5.2: every published Event Schema revision (5.1-e, 5.1.1-f/-j/-k/-l/-m) targets http://www.aixm.aero/schema/5.1.1/event or …/5.1/event, and the publisher states 'The current specifications for … Digital NOTAM are based on AIXM 5.1.1' (https://aixm.aero/page/aixm-52, read 2026-09-20). This adapter therefore reads NO Digital NOTAM: no Event feature, no scenario profile (profiles is empty), no attributes.dnotam block and no scenario rule; a member in the AIXM 5.1.1 Event namespace inside a 5.2 document is named by validate_source, carried whole in the residual and never typed. Digital NOTAM is the AIXM 5.1.1 adapter's (aixm511, limitation digital-notam-profiles), on the AIXM 5.1.1 + Event Schema 2.0.m combination only; nothing here claims that the same extension works with 5.2
  • gml:ArcByCenterPoint, gml:CircleByCenterPoint, gml:Arc, gml:ArcString, gml:Circle, gml:CompositeCurve, gml:OrientableCurve, a CRS other than urn:ogc:def:crs:EPSG::4326 and urn:ogc:def:crs:OGC:1.3:CRS84, and a third dimension refuse the document by default with the element form and the source text named; under Aixm52Adapter(unsupported_geometry='report') the slice is an Entity with the form named in attributes.aixm and no PlanObject. No arc is replaced by a chord and no circle by a polygon
  • an Airspace whose geometry components use UNION, INTERS or SUBTR, or whose BASE components state different vertical limits, is typed component by component and produces no PlanObject: the CDM Area is one volume and composing one would be a derivation the source did not state. volume_projection on the block says why; validate_source names it
  • a vertical limit projects onto the CDM only where a VerticalUnit and a VerticalReference exist for it (FT/M against SFC/MSL/W84/STD, FL against STD); SM, a flight level against another reference, an unstated uom and the tokens UNL/GND/FLOOR/CEILING are carried typed with the reason they are not projected. Feet are never converted to metres and no datum is converted. An ElevatedPoint's verticalDatum is free text in 5.2 (TextNameType) and is carried as the text stated
  • a time slice with no validTime instant of its own (§4.4.8's cancellation with nilReason='inapplicable', an absent validTime, an indeterminate begin) can be an Entity only under Aixm52Adapter(as_of=AsOf(instant, basis)), whose instant becomes valid_from with the basis in source.transformations; without it the document is refused naming the slice. Nothing is stamped with the clock or the epoch
  • a feature of a pinned family without a gml:identifier is refused: identity is derived from the UUID the feature carries across documents (Feature Identification and Reference 1.0 §2.1), and a document-local gml:id would make the same feature two entities in two documents. The gml:identifier a 5.2 «object» may carry is a property of that object, never an identity
  • xlink:href is resolved against the document and the caller's references table, one hop, never over a network; a URL is classified and not fetched; unresolved references are kept with their property, href and form under attributes.aixm.references and listed in unresolved_references
  • Timesheets, activation and availability structures are carried as typed validity, never resolved to instants; status on an Entity is set only when the slice states exactly one such structure and it carries no timeInterval, so an unconditional status is never asserted from a scheduled one
  • positions carry position_source: MANUAL — a surveyed, published coordinate is none of GNSS, INERTIAL or ESTIMATED — with the MSL elevation of an ElevatedPoint in vertical (its uom kept, reference MSL by the model's own definition of elevation) and alt_m None because MSL is not height above the ellipsoid
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged. evidence.available is true because 3.1.0 is the first release carrying this adapter and its pipeline generates the records for every shipped adapter and attaches them to the v3.1.0 Release as evidence-3.1.0.tar.gz, retrievable by a third party; it says nothing about what the wheel contains, and a tag that released nothing carries this sentence to nobody
  • of §3.5's five resource limits this adapter enforces THREE — max_input_bytes by the base class before decode and again by secure_xml before a parser exists, max_depth and max_objects in the shared reader before any object is built — plus an element count the manifest schema has no field for. The other two are absent with their reasons in capabilities.limits.absent_because
  • XML is parsed with the standard library's expat through secure_xml and NOT with defusedxml, which is not a dependency of this package: a DOCTYPE is refused at its declaration before any entity is read, every entity reference other than the five predefined ones is refused, no external resource is fetched and XInclude is refused where it starts (tests/test_cdm_secure_xml.py). The tree is xml.etree.ElementTree's own, built through its TreeBuilder
  • this adapter reads AIXM 5.2 only: a document in the 5.1 or 5.1.1 namespace is refused at the root with its namespace named; AIXM 5.1.1 is the sibling adapter aixm511, and the two share one reader under two profiles (aixm511.Profile)

c2sim — C2SIM​

Format. C2SIM, SISO-STD-019-2020 v1.0 (Core + SMX) with SISO-STD-020-2020 (LOX); XML schema C2SIMArtifacts v1.0.1. Binding standard-encoding. No profile declared.

Message families implemented.

  • C2SIMInitializationBody — force sides, units and platforms (with source identifiers, entity classifications as source vocabulary, locations and organisational relationships) as Entities, Route map graphics as ROUTE PlanObjects; both directions
  • ReportBody / PositionReportContent — one TRACK_UPDATE Event per content, reporting entity, subject, position, time of observation, health; both directions
  • ReportBody / ObservationReportContent and TaskStatus — one STATUS_CHANGE Event per content, source status vocabulary verbatim; both directions
  • OrderBody / ManeuverWarfareTask — one PLAN_INJECT Event per order with the c2sim-order/1 payload, task action codes MoveToLocation and HoldInPlace only; both directions

Exclusions and limitations, as declared.

  • an initialisation's Person, NonMilitaryOrganization, CommunicationNetwork, Overlay, CulturalFeature, EnvironmentalObject, GeographicFeature, non-Route map graphic, Action and PlanPhaseReference produce no canonical object: each is carried whole in every object's residual at its own path under residual.data.MessageBody and named by validate_source. The typed classes are ForceSide, Unit, the four Platform kinds and the Route map graphic
  • AcknowledgementBody, PlanBody, RequestBody, ObjectInitializationBody, SystemAcknowledgementBody and SystemCommandBody are refused by name: session and protocol state live in the exercise client (examples/c2sim/exercise_client.py), never in the adapter
  • a ManeuverWarfareTask whose TaskActionCode is not MoveToLocation or HoldInPlace (decision D1) is refused with a diagnostic naming the two supported forms, on ingest and on egress; no other task is ever substituted
  • ActivityObservation, ResourceObservation and SubjectTypeObservation are carried whole under payload.c2sim.observations[].raw (typed: false); Health, Location and Name observations are typed
  • a SimulationTime instant is scenario seconds since the scenario epoch and resolves only against C2simAdapter(exercise=ExerciseClock(epoch, basis)); a RelativeTime never resolves here. An Event whose observed_at would need an unresolved instant is refused, naming the form; a task's start and end times are carried typed either way
  • affiliation is read from the own side's stated ForceSideRelation only when C2simAdapter(own_side=<uuid>) names it (FR, HO, NEUTRL; every other hostility code reads UNKNOWN with the code kept); without it every entity is UNKNOWN. Nothing is inferred from a name or a SIDC
  • elements and attributes outside the pinned vocabulary are preserved and listed on ingest but are not written back on egress, so an emitted document stays inside the schema the validator judges; a re-ingested round trip therefore lacks them, and the harness fixtures carry none
  • the APP-6 SIDC string a source states is carried verbatim as a classification and never becomes Entity.symbol, which is a 20-digit MIL-STD-2525D code; positions carry position_source: ESTIMATED, the understating reading legion applies to a simulation's fixes, and their MSL or AGL height is kept in vertical unconverted with alt_m None
  • egress of an Entity with no attributes.c2sim block is refused: the schema needs a UUID, at least one EntityType and, for a Unit, an EchelonCode, and none of these is invented from the CDM's own fields
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged. evidence.available is true because 3.1.0 is the first release carrying this adapter and its pipeline generates the records for every shipped adapter and attaches them to the v3.1.0 Release as evidence-3.1.0.tar.gz, retrievable by a third party; it says nothing about what the wheel contains, and a tag that released nothing carries this sentence to nobody
  • of §3.5's five resource limits this adapter enforces THREE — max_input_bytes by the base class before decode and again by secure_xml before a parser exists, max_depth and max_objects in this module before any object is built — plus an element count the manifest schema has no field for. The other two are absent with their reasons in capabilities.limits.absent_because
  • XML is parsed with the standard library's expat through secure_xml and NOT with defusedxml, which is not a dependency of this package: a DOCTYPE is refused at its declaration before any entity is read, every entity reference other than the five predefined ones is refused, no external resource is fetched and XInclude is refused where it starts (tests/test_cdm_secure_xml.py). The tree is xml.etree.ElementTree's own, built through its TreeBuilder

cat021 — ASTERIX CAT021​

Format. EUROCONTROL ASTERIX Category 021 — ADS-B Target Reports, Edition 2.6. Binding standard-encoding. No profile declared.

Message families implemented.

  • ASTERIX data blocks of category 021
  • the Reserved Expansion Field (Appendix A, Edition 1.5)

Exclusions and limitations, as declared.

  • ADS-B MOPS versions 0, 1 and 2 in full; version 3 (ED-102B / DO-260C) only partially, and mostly in the Reserved Expansion Field
  • Edition 2.6 states on its own cover that it is not backwards compatible to Edition 2.1 or earlier, and this adapter does not read those editions
  • leftovers are parked in Entity.attributes / Event.payload under source_extras (lossless.residual()), not in the origin-identifying container ARCHITECTURE.md §5 gives to P3 — the Part 1 stance that section rules for the adapters already shipped
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run and the release pipeline attaches it to the GitHub Release. evidence.available is true because the records for 2.1.2 are attached to the v2.1.2 Release and retrievable by a third party, and it says nothing about what the wheel contains
  • of §3.5's five resource limits this adapter enforces ONE — max_input_bytes, declared in capabilities.limits with its basis beside it and refused before decode by the base class (round P5). The other four are still absent, each with its own reason in capabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today

cat023 — ASTERIX CAT023​

Format. EUROCONTROL ASTERIX Category 023 — CNS/ATM Ground Station and Service Status Reports, Edition 1.3. Binding standard-encoding. No profile declared.

Message families implemented.

  • ASTERIX data blocks of category 023 — the nine data items Edition 1.3 defines

Exclusions and limitations, as declared.

  • the smallest specification pinned in this repository: nine data items, and nothing outside them is decoded
  • leftovers are parked in Entity.attributes / Event.payload under source_extras (lossless.residual()), not in the origin-identifying container ARCHITECTURE.md §5 gives to P3 — the Part 1 stance that section rules for the adapters already shipped
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run and the release pipeline attaches it to the GitHub Release. evidence.available is true because the records for 2.1.2 are attached to the v2.1.2 Release and retrievable by a third party, and it says nothing about what the wheel contains
  • of §3.5's five resource limits this adapter enforces ONE — max_input_bytes, declared in capabilities.limits with its basis beside it and refused before decode by the base class (round P5). The other four are still absent, each with its own reason in capabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today

cat034 — ASTERIX CAT034​

Format. EUROCONTROL ASTERIX Category 034 — Monoradar Service Messages, Edition 1.29. Binding standard-encoding. No profile declared.

Message families implemented.

  • ASTERIX data blocks of category 034 — the monoradar service message types

Exclusions and limitations, as declared.

  • the pinned edition is 1.29 and it is NOT the latest: fixtures/cat034/spec/cat034_pin.json records Edition 1.30 as available, and this adapter is written against 1.29
  • leftovers are parked in Entity.attributes / Event.payload under source_extras (lossless.residual()), not in the origin-identifying container ARCHITECTURE.md §5 gives to P3 — the Part 1 stance that section rules for the adapters already shipped
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run and the release pipeline attaches it to the GitHub Release. evidence.available is true because the records for 2.1.2 are attached to the v2.1.2 Release and retrievable by a third party, and it says nothing about what the wheel contains
  • of §3.5's five resource limits this adapter enforces ONE — max_input_bytes, declared in capabilities.limits with its basis beside it and refused before decode by the base class (round P5). The other four are still absent, each with its own reason in capabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today

cat048 — ASTERIX CAT048​

Format. EUROCONTROL ASTERIX Category 048 — Monoradar Target Reports, Edition 1.32. Binding standard-encoding. No profile declared.

Message families implemented.

  • ASTERIX data blocks of category 048

Exclusions and limitations, as declared.

  • the Reserved Expansion field is carried verbatim and never interpreted: no edition of this category defines its contents
  • leftovers are parked in Entity.attributes / Event.payload under source_extras (lossless.residual()), not in the origin-identifying container ARCHITECTURE.md §5 gives to P3 — the Part 1 stance that section rules for the adapters already shipped
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run and the release pipeline attaches it to the GitHub Release. evidence.available is true because the records for 2.1.2 are attached to the v2.1.2 Release and retrievable by a third party, and it says nothing about what the wheel contains
  • of §3.5's five resource limits this adapter enforces ONE — max_input_bytes, declared in capabilities.limits with its basis beside it and refused before decode by the base class (round P5). The other four are still absent, each with its own reason in capabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today

cat062 — ASTERIX CAT062​

Format. EUROCONTROL ASTERIX Category 062 — SDPS Track Messages, Edition 1.21. Binding standard-encoding. No profile declared.

Message families implemented.

  • ASTERIX data blocks of category 062
  • the Reserved Expansion Field (Appendix A, Edition 1.3)

Exclusions and limitations, as declared.

  • the input is already the output of a fusion process, so the CDM objects this adapter emits carry judgements a tracker made and this adapter neither repeats nor re-decides
  • items the specification marks implementation-dependent are parked verbatim and not interpreted
  • leftovers are parked in Entity.attributes / Event.payload under source_extras (lossless.residual()), not in the origin-identifying container ARCHITECTURE.md §5 gives to P3 — the Part 1 stance that section rules for the adapters already shipped
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run and the release pipeline attaches it to the GitHub Release. evidence.available is true because the records for 2.1.2 are attached to the v2.1.2 Release and retrievable by a third party, and it says nothing about what the wheel contains
  • of §3.5's five resource limits this adapter enforces ONE — max_input_bytes, declared in capabilities.limits with its basis beside it and refused before decode by the base class (round P5). The other four are still absent, each with its own reason in capabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today

cog — Cloud Optimized GeoTIFF header reader​

Format. GeoTIFF / Cloud Optimized GeoTIFF (OGC GeoTIFF 1.1, OGC COG 1.0), OGC GeoTIFF Standard 1.1 (19-008r4) and OGC Cloud Optimized GeoTIFF Standard 1.0 (21-026), on classic TIFF Revision 6.0; GDAL VRT as GDAL's driver documentation describes it. Binding standard-encoding. No profile declared.

Message families implemented.

  • classic GeoTIFF / Cloud Optimized GeoTIFF, one band a file: every directory, the GeoKeys, GDAL_METADATA and GDAL_NODATA read, block 0 of the full-resolution image decoded (none, LZW, Deflate, PackBits; predictors 1, 2 and 3); one ENVIRONMENTAL_OBSERVATION Event (imagery-product/1) when a sensing time is stated or supplied, else one ANNOTATION PlanObject
  • GDAL VRT, as an index: its footprint and its sources listed, never opened; one ANNOTATION PlanObject

Exclusions and limitations, as declared.

  • Array values are carried by reference — a locator, the shape and packing needed to open them, and a summary — and are not copied into the output.
  • the twin's wire_hex is the file's octets, the input its dict form is decoded from; they are identified by SourceRef.source_hash when the caller gives it and are not copied into any object
  • a DEM and a VRT state no instant, so the PlanObject carries no timestamp unless the caller supplies an as-of (CogAdapter(as_of=InjectedTime(instant, basis))), which lands at validity.observed_at with its basis in source.transformations. A band file whose metadata states a sensing time becomes an Event and is judged on it. The conformance suite's check J reads this id as the declared reason it may find no timestamp to judge
  • the values are read for one window only: block 0 of the full-resolution image (its north-west tile or first strip), clipped to the image, at most 1 MiB decoded; it is summarised in the stored values and carried inline when it holds at most 4096 cells (and, in an Event, when the file states its unit and no scale or offset). Every other block is checked to lie in the file and is not decoded; overview and mask directories are read as structure
  • a footprint is converted from EPSG:4326, EPSG:4269 (NAD83, stated as WGS84 without a datum shift) and the WGS84 UTM zones only, and a vertical system only from EPSG:5703 (NAVD88 height); every other system, a user-defined one, a rotation and more than one tiepoint are refused by name. A height is never converted to the ellipsoid: the datum stays beside it in the residual
  • classic TIFF only (BigTIFF refused by name); one sample a pixel; compression none, LZW, Deflate and PackBits (JPEG, LERC, ZSTD, LZMA, WebP and JPEG 2000 refused by name); predictors 1, 2 (integer samples) and 3 (Float32 and Float64); samples of 8, 16 or 32 bits signed or unsigned, Float32 and Float64
  • a VRT is read as an index: its size, SRS, GeoTransform, metadata and simple or complex sources, listed and never opened; a remote source, a DTD, an entity and any other element (a derived band, a pixel function, an overview) are refused by name
  • without band_file an object's id derives from what the file states: its coordinate system, size, north-west corner, cell, sample type and sensing interval (a VRT's: its system, size, corner, cell and source count), followed by the caller's source_hash digest when it gives one. With neither band_file nor source_hash, two band files of one granule that share a grid and a sensing time share an id; a caller that holds several bands of a granule passes band_file (and granule_id) or source_hash
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run, and the release pipeline generates the records for every shipped adapter and attaches them to the GitHub Release of the version it publishes. evidence.available is true because every published distribution that carries this adapter has that Release, so its records are retrievable by a third party; it says nothing about what the wheel contains

coops_csv — NOAA CO-OPS data API response (CSV and JSON) translator​

Format. NOAA CO-OPS data API response (datagetter), api.tidesandcurrents.noaa.gov/api/prod, read 2026-10-14. Binding standard-encoding. No profile declared.

Message families implemented.

  • NOAA CO-OPS datagetter response: the CSV form of water_level, air_pressure or wind, or the JSON form of water_level, one response per call under the caller's CoopsRequest; one ENVIRONMENTAL_OBSERVATION Event per sample carrying point-observation/1, and the station's Entity

Exclusions and limitations, as declared.

  • a response echoes none of the request's datum, units, time zone or interval, and the CSV form not its station: they are the caller's required CoopsRequest, and a JSON response naming another station is refused
  • time_zone lst_ldt is refused by name (DECISIONS L-11): daylight-saving local time needs a time-zone database; gmt is read as UTC, and lst with the caller's declared standard-time offset
  • the CSV form of water_level, air_pressure and wind and the JSON form of water_level are read; every other product, and the JSON form of air_pressure and wind, whose record keys the design record does not hold, are refused
  • the request's units (metric or english) is every value's unit, verbatim under the request parameter's namespace; no unit string is derived from it, and wind's degrees direction is the one value with a unit of its own
  • a blank field is refused blank-value: the design record does not hold how the API writes a missing sample, so this module neither reads a blank as a sentinel nor drops the reading
  • wind's second Direction column, the compass point, is text and not a measurement; it stays in each Event's residual row
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run, and the release pipeline generates the records for every shipped adapter and attaches them to the GitHub Release of the version it publishes. evidence.available is true because every published distribution that carries this adapter has that Release, so its records are retrievable by a third party; it says nothing about what the wheel contains

dis7 — DIS 7 Entity State PDU​

Format. DIS, 7 / IEEE 1278.1-2012 Entity State subset. Binding standard-encoding. No profile declared.

Message families implemented.

  • Entity State PDU (protocol version 7, PDU type 1, protocol family 1), 144 octets plus 0 to 255 variable parameter records of 16 octets; ingest
  • replay of the original octets from an unchanged Entity produced by this adapter; egress

Exclusions and limitations, as declared.

  • Entity State subset only: protocol version 7, PDU type 1, protocol family 1. Every other PDU type, protocol family and DIS version is refused, and no network transport, capture file or multi-PDU datagram is read
  • no IEEE certification is claimed, and acceptance under this subset is not validation of every reserved bit of the standard
  • the IEEE 1278.1-2012 text was not consulted: the layout authority is open-dis-python (https://github.com/open-dis/open-dis-python, BSD-2-Clause) at commit 732b6655bb47e34ccc73722eefe0f4706fd0032f. A comparison with it exists as an opt-in test and an exercise report; no report ships in the distribution
  • the state instant is supplied by the caller with its basis; the DIS timestamp is preserved and never converted. Affiliation is UNKNOWN for every force ID, and velocity is projected only for dead reckoning algorithms 2 to 5
  • egress replays the original octets of an unchanged Entity only; a fresh or edited Entity is refused
  • fixture_instance supplies the packaged fixtures' context (session unnamed, synthetic, the vectors' state instant and basis) and refuses synthetic=False. The harness and the conformance suite construct through it, so their verdict is defined for the packaged fixtures only; PDUs from another exercise need a caller-built adapter
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run, and the release pipeline generates the records for every shipped adapter and attaches them to the GitHub Release of the version it publishes. evidence.available is true because every published distribution that carries this adapter has that Release, so its records are retrievable by a third party; it says nothing about what the wheel contains

geojson — GeoJSON​

Format. GeoJSON, RFC 7946 (August 2016). Binding standard-encoding. No profile declared.

Message families implemented.

  • RFC 7946 Feature — one feature becomes one ANNOTATION PlanObject, or an OVERLAY_OBJECT Entity with no position when its geometry is null
  • RFC 7946 FeatureCollection — one object per feature, in the collection's order, with the collection's own members kept in every object's residual
  • FeatureCollection or Feature on egress, under the generic or the synapsecommand-exchange/1 export profile

Exclusions and limitations, as declared.

  • GeometryCollection is refused, not translated: geo.py keeps it out of the CDM union deliberately (a heterogeneous geometry has no single semantics for a consumer), so a feature carrying one refuses the whole document. The RFC's other six geometry types are all carried
  • a GeoJSON text whose top-level object is a geometry (RFC 7946 §3 permits it) is refused: it has no id and no properties to carry, so nothing identifies it. Wrap it in a Feature
  • a geometry whose coordinates array is empty is refused. RFC 7946 §3.1 lets a processor read it as a null geometry; this adapter does not turn a stated geometry into an absent one silently
  • a crs member at any level is refused. RFC 7946 §4 removed it; a document carrying one follows the 2008 specification, and no legacy profile is implemented here. Projected coordinates are never relabelled as WGS84
  • an empty FeatureCollection translates to no object, which is what it carries; its collection-level members then have no object to ride in and the preservation ledger reports them LOST for that document. Stated here so the empty result is never read as a filtered one
  • RFC 7946 states no instant for a Feature or a FeatureCollection, so no object carries a timestamp unless the caller supplies an as-of context (GeojsonAdapter(as_of=AsOf(instant, basis))), which lands at validity.observed_at (PlanObject) or valid_from (Entity) with its basis in source.transformations. The conformance suite's check J reads this id as the declared reason it has no timestamp to judge
  • bbox at every level is kept verbatim in the residual and is NOT projected to a canonical BoundingBox: PlanObject carries bounds only inside an Area, and geo.BoundingBox refuses an antimeridian-crossing box (west > east) by construction. Every bbox is noted in source.transformations, the antimeridian case as such
  • egress accepts PlanObject and Entity (an entity's position becomes a Point, or a null geometry when it has none); an Event or a Track is not compatible with the geo-object profile and egress refuses it rather than choosing a geometry for it
  • egress under the exchange profile refuses a source property already named sc:... rather than overwriting it; the sc: keys of a re-ingested exchange document are ordinary source properties on ingest (this adapter never reads its own export keys back as canonical meaning), so such a document exports under the generic profile only
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged. evidence.available is true because 3.1.0 is the first release carrying this adapter and its pipeline generates the records for every shipped adapter and attaches them to the v3.1.0 Release as evidence-3.1.0.tar.gz, retrievable by a third party; it says nothing about what the wheel contains, and a tag that released nothing carries this sentence to nobody
  • of §3.5's five resource limits this adapter enforces THREE — max_input_bytes and max_depth by the base class before decode, and max_objects (the feature count) in this module before any object is built — plus a position count the manifest schema has no field for. The other two are absent with their reasons in capabilities.limits.absent_because

geopackage — GeoPackage​

Format. GeoPackage, 1.4.0 (OGC 12-128r19). Binding standard-encoding. No profile declared.

Message families implemented.

  • GeoPackage 1.4.0 container (the octets of a .gpkg SQLite database) — one ANNOTATION PlanObject per feature row of every selected vector layer, in layer-name then primary-key order, or an OVERLAY_OBJECT Entity with no position for a row whose geometry is SQL NULL or empty
  • the parsed twin of a container (parse_payload's dict) — the same objects

Exclusions and limitations, as declared.

  • only GeoPackage 1.4.0 (user_version 10400, application_id GPKG) is read; any other user_version, and the GP10/GP11 application ids of 1.0 and 1.1, are refused as unsupported with the value reported. Earlier versions are not implemented and are not silently accepted
  • a selected layer's SRS must be WGS 84 by DEFINITION — EPSG:4326, OGC:CRS84 or EPSG:4979, judged on the WKT's root, datum, ellipsoid and authority; an 'undefined' definition (srs_id 0 or -1), a projected CRS or any other datum refuses the package with the declaration reported. Nothing is reprojected and no other CRS is relabelled
  • M ordinates are refused, never dropped and never read as height: a layer declaring m = 1 or m = 2 is inventoried as unsupported content (refused if selected by name), and a row carrying an XYM or XYZM geometry, or an envelope with an M range, refuses the package
  • GeometryCollection, the non-linear extension types (CircularString, CompoundCurve, CurvePolygon, MultiCurve, MultiSurface, Curve, Surface) and ExtendedGeoPackageBinary (flag X = 1) are outside the profile: a layer declared with such a type is inventoried as unsupported; a row of a GEOMETRY column carrying one refuses the package
  • raster tiles, gridded coverages, attributes-only tables and views are inventoried as unsupported content in every object's residual.data.package.inventory and are never read; a mixed package translates its selected vector layers only and every object says so
  • a container whose SQLite header says WAL mode (write/read version 2) is refused as WAL-dependent, because its committed content may be in a -wal file the octets do not include; wal_checkpointed=True is the caller's assertion that the file was checkpointed, recorded on every object
  • a GeoPackage states no observation time; gpkg_contents.last_change is the table's last-edit stamp and is carried as package metadata, never as a row's time. No object carries a timestamp unless the caller supplies an as-of context (GeopackageAdapter(as_of=AsOf(instant, basis))), which lands at validity.observed_at (PlanObject) or valid_from (Entity) with its basis in source.transformations. The conformance suite's check J reads this id as the declared reason it has no timestamp to judge
  • a Z ordinate is carried as the third coordinate element with the meaning the package declares and no other: under EPSG:4979 the SRS declares ellipsoidal height in metres; under EPSG:4326 or CRS84 the SRS declares no vertical axis and the value's datum and unit are undeclared — carried as sent, not asserted as height above the ellipsoid
  • ingest only: from_cdm is the base class's refusal (NotImplementedError), the manifest advertises no egress, and no GeoPackage is ever written. The cross-format path is the GeoJSON adapter's export (examples/geopackage_to_geojson)
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged. evidence.available is true because 3.1.0 is the first release carrying this adapter and its pipeline generates the records for every shipped adapter and attaches them to the v3.1.0 Release as evidence-3.1.0.tar.gz, retrievable by a third party; it says nothing about what the wheel contains, and a tag that released nothing carries this sentence to nobody
  • of §3.5's five resource limits this adapter enforces THREE — max_input_bytes and max_depth by the base class before decode, and max_objects (the row count) in this module before any row is fetched — plus a per-value size, a coordinate count and an output estimate the manifest schema has no field for. The other two are absent with their reasons in capabilities.limits.absent_because

gmti — STANAG 4607 GMTIF​

Format. STANAG 4607 / AEDP-4607 — NATO Ground Moving Target Indicator Format (GMTIF), AEDP-4607 Edition A Version 1. Binding standard-encoding. No profile declared.

Message families implemented.

  • segment types 1, 2, 3, 5, 6, 10, 12, 13 and the two Controlled-Extension slots 101 and 102

Exclusions and limitations, as declared.

  • the Controlled Extension FIELD DEFINITIONS are not implemented and cannot be: AEDP-4607's §L.4, which is where their field tables belong, reads "(TO BE PROVIDED)" in the promulgated Edition A Version 1
  • the standard itself declines to specify error handling (§2.2), so a malformed packet's treatment is this adapter's decision and is documented at the site rather than cited
  • leftovers are parked in Entity.attributes / Event.payload under source_extras (lossless.residual()), not in the origin-identifying container ARCHITECTURE.md §5 gives to P3 — the Part 1 stance that section rules for the adapters already shipped
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run and the release pipeline attaches it to the GitHub Release. evidence.available is true because the records for 2.1.2 are attached to the v2.1.2 Release and retrievable by a third party, and it says nothing about what the wheel contains
  • of §3.5's five resource limits this adapter enforces ONE — max_input_bytes, declared in capabilities.limits with its basis beside it and refused before decode by the base class (round P5). The other four are still absent, each with its own reason in capabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today

grib2 — GRIB2 message translator​

Format. GRIB2 (WMO FM 92 GRIB edition 2), GRIB edition 2, read against NCEP's WMO GRIB2 Documentation version 37.0.0 (2026-06-01). Binding standard-encoding. No profile declared.

Message families implemented.

  • GRIB edition 2 message: Sections 0 to 8 with Sections 4 to 7 repeated; grid templates 3.0 (latitude/longitude) and 3.30 (Lambert conformal), product templates 4.0 and 4.8, data representation templates 5.0, 5.3 and 5.41 decoded and 5.40 read in reference form; one ENVIRONMENTAL_OBSERVATION Event (gridded-field/1) per field

Exclusions and limitations, as declared.

  • Array values are carried by reference — a locator, the shape and packing needed to open them, and a summary — and are not copied into the output.
  • a Template 5.40 field's values are a JPEG 2000 codestream this module does not decode (DECISIONS U-02: no decoder outside the standard library): Sections 0 to 6 are read, Section 7 is checked to open with a codestream's SOC and SIZ markers, and the contract states the field by reference with no summary
  • the twin's wire_hex is the message's octets, the input its dict form is decoded from; they are identified by SourceRef.source_hash when the host injects it and are not copied into any object
  • exactly one GRIB2 message per call, as its octets or as its twin; a file of several messages, a gzip around one and an index file are not taken. synapse-decode unwraps a gzip and cuts a file into its messages, each with its ordinal and the octet it begins at
  • grid templates 3.0 and 3.30 (north-pole-centred, LaD a standard parallel, a spherical earth), product templates 4.0 and 4.8 (one time range), data representation templates 5.0, 5.3 (orders 1 and 2) and 5.41 (8- and 16-bit greyscale) are read; every other template, a predefined grid or bitmap, a quasi-regular grid, coordinate values after Section 4, a second Section 2 or 3, a scanning mode other than the i and j directions and a grid across 180 degrees are refused by name, as is GRIB edition 1
  • a parameter's name and unit and a surface's unit are stated only for the Code Table 4.2 and 4.5 rows this module lists, each with the file it was read from (GDAL's table files, its NCEP local table for NCEP's local rows, and NSSL's MRMS table for MRMS's); any other parameter keeps its discipline.category.number code with no unit, any other surface its code with no value, and a row whose unit column states a code's meanings (CFRZR) names the parameter and states no unit
  • the contract's level is the first fixed surface; a layer's second surface stays in the Event's residual with every other Template 4.x octet
  • Event.geometry is the outline of the grid POINTS, not of the cells around them: a lat/lon grid's corner points, a Lambert grid's edge points converted with the spherical inverse, at most 16 segments an edge and rounded to 10^-6 degree
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run, and the release pipeline generates the records for every shipped adapter and attaches them to the GitHub Release of the version it publishes. evidence.available is true because every published distribution that carries this adapter has that Release, so its records are retrievable by a third party; it says nothing about what the wheel contains

iem_n0q — IEM NEXRAD N0Q composite reader​

Format. IEM NEXRAD N0Q composite PNG (W3C PNG, IEM product composite_n0q), Portable Network Graphics (PNG) Specification (Third Edition), W3C Recommendation 24 June 2025; IEM composite_n0q at 12200 x 5400 cells, the grid IEM has published since 2014-08-08. Binding standard-encoding. No profile declared.

Message families implemented.

  • IEM NEXRAD N0Q composite PNG (n0q_YYYYMMDDHHMM.png), 12200 x 5400 8-bit palette indices, IHDR held to the product constant, every chunk's CRC checked, the image data inflated and the five filter types undone, index 0 missing and index i (i - 65) / 2 dBZ; one ENVIRONMENTAL_OBSERVATION Event (gridded-field/1) at the caller's archive slot, the values by reference with a dBZ summary

Exclusions and limitations, as declared.

  • Array values are carried by reference — a locator, the shape and packing needed to open them, and a summary — and are not copied into the output.
  • the grid is the IEM N0Q product constant — 12200 x 5400 cells of 0.005 degree in EPSG:4326, the archive's world file read as the centre of the north-west cell, so the outline runs from 126.0025 W 50.0025 N to 65.0025 W 23.0025 N — and the .wld beside an archive PNG is not read: a PNG of any other size, bit depth or colour type is refused. Which registration IEM means is not stated on its pages; the half-cell reading is this module's
  • a PNG states no observation time: observed_at is the archive file name's slot (UTC, minutes divisible by five), the composite's nominal time, which the caller supplies with its basis (IemN0qAdapter(slot=InjectedTime(instant, basis))); no radar's scan time is recoverable from the image. The tEXt gentime chunk is IEM's generation clock and is carried verbatim as product_version.production_time_verbatim, never as a time
  • index i is read as (i - 65) / 2 dBZ, so index 255 is 95.0 dBZ; IEM's composite documentation captions the ramp as -32 to 90 dBZ while its raster catalogue's table ends at 95, and the formula's value is emitted, not either page's ceiling
  • an object's id derives from the slot, followed by the caller's source_hash digest when it gives one: IEM re-publishes a slot's file under the same name, and without the digest two files of one slot share an id
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run, and the release pipeline generates the records for every shipped adapter and attaches them to the GitHub Release of the version it publishes. evidence.available is true because every published distribution that carries this adapter has that Release, so its records are retrievable by a third party; it says nothing about what the wheel contains

legion — Picogrid Legion​

Format. Picogrid Legion Platform API v3, v3. Binding standard-encoding. No profile declared.

Message families implemented.

  • Entity
  • Event
  • Track
  • Telemetry — the resources fixtures/legion/spec/openapi_pin.json pins

Exclusions and limitations, as declared.

  • a VENDOR API rather than a ratified standard: fixtures/legion/spec/openapi_pin.json records that it "can change between deploys, and its info.version demonstrably does not move when it does", so v3 names the endpoint family and not a frozen edition
  • ingest only — this adapter does not emit Legion documents and never acquires one: no HTTP client, no token, no cursor, no base URL
  • only the resources the pinned OpenAPI document names are in scope
  • leftovers are parked in Entity.attributes / Event.payload under source_extras (lossless.residual()), not in the origin-identifying container ARCHITECTURE.md §5 gives to P3 — the Part 1 stance that section rules for the adapters already shipped
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run and the release pipeline attaches it to the GitHub Release. evidence.available is true because the records for 2.1.2 are attached to the v2.1.2 Release and retrievable by a third party, and it says nothing about what the wheel contains
  • of §3.5's five resource limits this adapter enforces ONE — max_input_bytes, declared in capabilities.limits with its basis beside it and refused before decode by the base class (round P5). The other four are still absent, each with its own reason in capabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today

link16_gateway — SC Link16 Gateway report translator​

Format. SC Link16 Gateway, 1.0.0. Binding provisional-internal-profile. No profile declared.

Message families implemented.

  • SC Link16 Gateway 1.0.0 report (profile sc-link16-gateway/1.0.0), one per call, as UTF-8 JSON octets or a dict: one Entity, and one single-sample Track when the position is present and projected
  • egress, mode mirror (default): the same report reconstructed from this adapter's own Entity and Track
  • egress, mode export: one gateway report from an Entity and an optional single-sample Track under a runtime-supplied ExportContext

Exclusions and limitations, as declared.

  • the wire form is SC Link16 Gateway 1.0.0, an interface defined in this repository: a provisional internal profile bound to no normative document. Green gates prove agreement with that profile only
  • no JREAP C or Link 16 bytes, frames or J-series words are parsed or produced, and no native interoperability, radio participation, encryption, accreditation or certification is claimed. The native boundary lives outside this package and refuses with BLOCKED_EXTERNAL_EVIDENCE until a normative profile, independent byte vectors and a peer test exist
  • exactly one report per call, as UTF-8 JSON octets or as a dict; a stream, NDJSON, a list, text and the contract's lifecycle notices are refused (JSON_INVALID or SCHEMA_INVALID)
  • duplicate keys, a byte order mark, invalid UTF-8 and non-finite number literals are refused on octets only: a dict was parsed by its caller, who already lost them. The runtime bridge always passes octets
  • the contract's 1 MiB of UTF-8, depth 32 and 10 000 JSON value nodes are enforced here as LIMIT_EXCEEDED; past the manifest's 1 MiB and 64 containers the base class refuses first with InputTooLarge and InputTooDeep
  • SENSOR and UNKNOWN are CDM 3.1.0 members of PositionSource. Under cdm_schema="3.0.0" a report with either method yields an Entity with position null and no Track, marked POSITION_NOT_PROJECTED_CDM3, the report kept whole in the residual; every other report projects in full. The conformance suite judges the default projection only
  • a height stated as HAE in feet becomes metres (x 0.3048) in both vertical and alt_m, departing from the description of Position.vertical (never converted), because alt_m may stand only beside an HAE vertical in metres; the feet stay in residual.data.report. No other datum or unit is converted, and alt_m is null for each of them
  • the report's eight identity tokens project to the CDM's four: FRIENDLY, HOSTILE and NEUTRAL as they are, and UNKNOWN, PENDING, ASSUMED_FRIEND, SUSPECT and OTHER to UNKNOWN. The token stays in residual.data.report and is not written into attributes, which the contract forbids, although the Affiliation enumeration's own description says finer wording is kept there
  • kinematics.observed_at has no home on the CDM's Kinematics and stays in residual.data.report; the Track's sample time is position.observed_at, and valid_from is effective_at, never received_at
  • Entity.symbol is null: no symbol profile is defined for this contract, and confidence, valid_to and attributes stay unset too
  • the conformance suite builds this adapter without an ExportContext, so its egress evidence (check E) is mirror reconstruction of the same report; export mode is judged by this adapter's own tests, and docs/docs/cdm/link16-gateway.mdx is its contract. Neither mode transmits anything
  • every packaged fixture is synthetic and labelled so; none is a capture and none is a native byte vector. The six reports of the engineering handoff are carried byte-identical, and its six projections are kept under reference/ as a semantic oracle
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run, and the release pipeline generates the records for every shipped adapter and attaches them to the GitHub Release of the version it publishes. evidence.available is true because every published distribution that carries this adapter has that Release, so its records are retrievable by a third party; it says nothing about what the wheel contains
  • of the five resource limits the manifest has fields for, two are declared with their bases — max_input_bytes and max_depth — and three are absent with their reasons in capabilities.limits.absent_because; inside them the contract's own depth 32 and node bound of 10 000 are enforced as LIMIT_EXCEEDED

ndbc_stdmet — NDBC standard meteorological (stdmet) text translator​

Format. NDBC standard meteorological data (stdmet), NDBC Web Data Guide, Version 2.0 (June 2023). Binding standard-encoding. No profile declared.

Message families implemented.

  • NDBC standard meteorological text (Web Data Guide Version 2.0): one realtime, monthly or yearly historical stdmet file per call, as its octets or its parsed twin; one ENVIRONMENTAL_OBSERVATION Event per data row carrying point-observation/1, and the station's Entity

Exclusions and limitations, as declared.

  • exactly one stdmet file per call (a realtime, monthly or yearly historical file), as its octets or its parsed twin; a yearly .txt.gz is unwrapped by synapse-decode --container gzip. Other NDBC data types (.spec, .cwind, .ocean and the rest) are not this adapter's and their headers are refused
  • a stdmet file states neither its station nor the station's position (research-station-text F03): the station identifier is the caller's station_id argument, and the position comes only from a caller's StationTable, else the Entity's position is null. Nothing is joined from activestations.xml or another file
  • MM is read as missing only in a realtime file (a header with PTDY), and a run of 9s only in a historical file at the width research-station-text F02 observed for its column (WVHT, DPD, APD and TIDE 99.00, MWD 999, VIS 99.0, WTMP 999.0). Any other run of 9s in a historical file is refused undocumented-sentinel, and so is a real reading of that shape in a column whose sentinel width is not documented (a 999.0 hPa pressure, a 99 degree wind direction): the widths for WDIR, WSPD, GST, PRES, ATMP and DEWP are not established, so this module refuses rather than guesses. MM in a historical file is refused
  • the year is the width its header column names (four digits under #YY and YYYY, two under YY), and a two-digit year is read only as 98, 1998: the YY layout is recorded in a 1998 file only (research-station-text F01), so any other two-digit year is refused undocumented-year rather than given a century
  • a file with no units line (before 2007) states no unit, so each value is an Absence of cause unit_unknown and the number stays in the Event's residual row; nothing assumes the unit a later file states
  • each row is one instant, observed_at and both ends of validity.effective; the averaging windows the measurement descriptions give for a column (WSPD over eight minutes, PTDY over three hours) are not stated as intervals
  • NDBC's text files print no per-value quality flag (NDBC T80-10, December 2023), so every contract states quality_flags_basis instead of flags
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run, and the release pipeline generates the records for every shipped adapter and attaches them to the GitHub Release of the version it publishes. evidence.available is true because every published distribution that carries this adapter has that Release, so its records are retrievable by a third party; it says nothing about what the wheel contains

nexrad2 — NEXRAD Level II (Archive II) volume translator​

Format. NEXRAD Level II (Archive II), ICD 2620010J (Archive II/User) and ICD 2620002Y (RDA/RPG), Build 23.0. Binding standard-encoding. No profile declared.

Message families implemented.

  • NEXRAD Level II Archive II volume (ICD 2620010J, Build 23.0): the volume header, the bzip2 LDM records, the 134-segment metadata record (framed and counted) and message 31 radials (ICD 2620002Y Table XVII); one ENVIRONMENTAL_OBSERVATION Event per elevation number and the radar site's Entity per volume

Exclusions and limitations, as declared.

  • Array values are carried by reference — a locator, the shape and packing needed to open them, and a summary — and are not copied into the output.
  • the twin's wire_hex is the volume's octets, the input its dict form is decoded from; they are identified by SourceRef.source_hash when the host injects it and are not copied into any object
  • exactly one Archive II volume file per call, as its octets or as its twin; a real-time chunk (the _chunks bucket's records), a gzip or tar around the volume and an _MDM sidecar are not taken. synapse-decode unwraps a gzip or a named tar member before the adapter sees the volume
  • message 1 (the legacy radial, pre-Build 10), message 29 (model data, the _MDM record) and a radial whose Compression Indicator is 1 (bzip2) or 2 (zlib) are refused by name and not decoded; an archive version other than 06 or 07 is refused
  • the metadata record's messages (15, 32, 13, 18, 3, 5, 2) and the RDA status messages (2) among the radials are framed and counted by type in the site Entity's residual, not decoded; the VCP is read from each radial's VOL block, not from message 5
  • Event.geometry is the radar site's point, not the area a sweep covers: no gate or beam geometry is computed, and the gates' ranges are the contract's first_gate_range and gate_interval
  • every range ICD 2620002Y Tables XVII-A, -B, -E, -F and -H state for a field this module reads is a validation rule, so a volume a lenient reader would take can be refused; Table XVII-I's data ranges are not rules (they are a moment's typical values, note 20), so a moment's gate codes are converted with each radial's own scale and offset and the summary is not range-checked (narrowed 2026-10-16, the 3.5.0 release); a data block or moment the ICD does not name is refused, not skipped (note 9 recommends skipping it); spare and reserved octets are not read except the moment block's Reserved word, which is carried
  • the VOL block's ZDR Bias Estimate Weighted Mean is carried as the Integer*2 it is stated as: the ICD's note 33 on its scaling is not in the design record, so no unit is stated for it
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run, and the release pipeline generates the records for every shipped adapter and attaches them to the GitHub Release of the version it publishes. evidence.available is true because every published distribution that carries this adapter has that Release, so its records are retrievable by a third party; it says nothing about what the wheel contains

pntmap — PNTMAP​

Format. PNTMAP GNSS interference alert, not stated — see the limitations. Binding standard-encoding. Profiles PNT.

Message families implemented.

  • GNSS interference alert — one alert becomes an INTERFERENCE_SOURCE entity and a sc.pnt.gnss_interference.v1 event

Exclusions and limitations, as declared.

  • no document in this repository DEFINES the PNTMAP alert payload — FORMAT_COVERAGE.md carries no PNTMAP section — so there is no edition to name and format.version is null; the licence class rests on the payload being first-party rather than on a licensing sentence about the format
  • ingest only: this adapter does not emit PNTMAP alerts
  • leftovers are parked in Entity.attributes / Event.payload under source_extras (lossless.residual()), not in the origin-identifying container ARCHITECTURE.md §5 gives to P3 — the Part 1 stance that section rules for the adapters already shipped
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run and the release pipeline attaches it to the GitHub Release. evidence.available is true because the records for 2.1.2 are attached to the v2.1.2 Release and retrievable by a third party, and it says nothing about what the wheel contains
  • of §3.5's five resource limits this adapter enforces ONE — max_input_bytes, declared in capabilities.limits with its basis beside it and refused before decode by the base class (round P5). The other four are still absent, each with its own reason in capabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today

readsb_trace — readsb trace JSON (globe_history trace_full) translator​

Format. readsb trace JSON, readsb v3.16.17. Binding standard-encoding. No profile declared.

Message families implemented.

  • readsb trace JSON (README-json.md, trace jsons, readsb v3.16.17): one globe_history trace_full file per call, as its gzip octets or as the decompressed document in a dict; one Entity, one Track and one TRACK_UPDATE Event per file

Exclusions and limitations, as declared.

  • exactly one readsb trace file per call, as its gzip octets (one gzip member) or as the decompressed document in a dict; a day archive, a tar part, a list of traces and JSON text are not taken. synapse-decode takes one tar member by name
  • nothing is joined across files: a flight across UTC midnight is two files, two Tracks and one entity_id, and a new-leg flag is decoded as data and nothing is split on it. A Track's and its Event's ids derive from the address and the first and last instants, so two files of one airframe spanning the same two instants (two readsb instances' copies of one day, or a copy holding more points between them) give one track_id and one event_id: the id names the airframe's window, not the file, and files with different spans are different Tracks. Stitching, merging and leg-splitting are fusion's
  • TrackSample holds a position and an instant only, so a point's ground speed, element 5, flags, vertical rate, aircraft object, source, geometric altitude and rate, IAS and roll stay in the Entity's residual (residual.data.trace[i], sample i's point as stated), with the readings taken from them in attributes.readsb_samples, arrays keyed by the same index; only the last point's speed, track and vertical rate reach Entity.kinematics
  • a barometric altitude is carried as Position.vertical in feet against BARO and never as alt_m; only a geometric altitude reaches alt_m, converted from feet (x 0.3048). When element 3 is barometric, element 10's geometric altitude stays in the residual
  • the database fields r, t, desc, ownOp and year are carried verbatim in the residual and read for nothing; no packaged fixture states them, because every registration mark is a claim about a real allocation, so the shipped set is readsb's database-less form
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run, and the release pipeline generates the records for every shipped adapter and attaches them to the GitHub Release of the version it publishes. evidence.available is true because every published distribution that carries this adapter has that Release, so its records are retrievable by a third party; it says nothing about what the wheel contains

stanag4586 — STANAG 4586 DLI​

Format. STANAG 4586 — Standard Interfaces of UAV Control System (UCS), DLI telemetry, Edition 3. Binding standard-encoding. No profile declared.

Message families implemented.

  • DLI datagrams — the wrapped message set §3.3.1 defines, message 0101 and its companions

Exclusions and limitations, as declared.

  • Edition 4 is current (promulgated as AEP-84 Edition A) and is NOT implemented: FORMAT_COVERAGE.md records that nso.nato.int answers HTTP 403 on every route tried, that the mirror carrying this family lists exactly Editions 2 and 3, and that the commercial distributors holding Edition 4 serve it paywalled and DRM-wrapped. No sentence here claims an Edition 3 decoder reads an Edition 4 feed
  • ingest only: this adapter does not emit DLI
  • whether the 5-octet millisecond timestamp steps at a leap second is not stated by the document, and every object carries attributes.time_basis saying so
  • leftovers are parked in Entity.attributes / Event.payload under source_extras (lossless.residual()), not in the origin-identifying container ARCHITECTURE.md §5 gives to P3 — the Part 1 stance that section rules for the adapters already shipped
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run and the release pipeline attaches it to the GitHub Release. evidence.available is true because the records for 2.1.2 are attached to the v2.1.2 Release and retrievable by a third party, and it says nothing about what the wheel contains
  • of §3.5's five resource limits this adapter enforces ONE — max_input_bytes, declared in capabilities.limits with its basis beside it and refused before decode by the base class (round P5). The other four are still absent, each with its own reason in capabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today

stanag4609 — STANAG 4609 KLV​

Format. STANAG 4609 / MISP-2019.1 — the UAS Datalink Local Set, MISP-2019.1 (STANAG 4609 Edition 5 wrapper). Binding standard-encoding. No profile declared.

Message families implemented.

  • UAS Datalink Local Set packets (MISB ST 0601.14)
  • the VMTI Local Set (ST 0903.4) and the RVT Local Set (ST 0806.4) where a packet carries them

Exclusions and limitations, as declared.

  • ST 0601.14 is the authoritative tag table; ST 0601.19 is pinned as CONTEXT ONLY and is never a source of tag semantics here
  • a length-divergent item's original octets are carried verbatim so that egress is byte exact, which means this adapter reproduces a defect rather than correcting it
  • leftovers are parked in Entity.attributes / Event.payload under source_extras (lossless.residual()), not in the origin-identifying container ARCHITECTURE.md §5 gives to P3 — the Part 1 stance that section rules for the adapters already shipped
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run and the release pipeline attaches it to the GitHub Release. evidence.available is true because the records for 2.1.2 are attached to the v2.1.2 Release and retrievable by a third party, and it says nothing about what the wheel contains
  • of §3.5's five resource limits this adapter enforces ONE — max_input_bytes, declared in capabilities.limits with its basis beside it and refused before decode by the base class (round P5). The other four are still absent, each with its own reason in capabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today

stanag4676 — STANAG 4676 NITS​

Format. STANAG 4676 / AEDP-12 — NATO ISR Tracking Standard (NITS), AEDP-12 Edition B Version 2. Binding provisional-internal-profile. No profile declared.

Message families implemented.

  • NITSRoot documents — the 48 classes and 273 attributes AEDP-12 Edition B Version 2 defines

Exclusions and limitations, as declared.

  • Edition A (the STANAG 4676 Edition 1 generation) is read for the edition delta and is never a basis: Edition B §2.1.1.1 declares the two incompatible
  • the binary encoding of AEDP-12.1 Annex F is not implemented
  • leftovers are parked in Entity.attributes / Event.payload under source_extras (lossless.residual()), not in the origin-identifying container ARCHITECTURE.md §5 gives to P3 — the Part 1 stance that section rules for the adapters already shipped
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run and the release pipeline attaches it to the GitHub Release. evidence.available is true because the records for 2.1.2 are attached to the v2.1.2 Release and retrievable by a third party, and it says nothing about what the wheel contains
  • of §3.5's five resource limits this adapter enforces TWO — max_input_bytes, declared in capabilities.limits with its basis beside it and refused before decode by the base class (round P5), and max_depth, declared the same way and refused by parse_document immediately after the XML parse and before either reader recurses into the tree (2026-09-16). The other three are still absent, each with its own reason in capabilities.limits.absent_because; an object-count, decompression or wall-clock bound is not enforced here today
  • XML is parsed with the standard library's expat (pyexpat into an xml.etree.ElementTree tree, parse_document's _parse_xml) and NOT with defusedxml, which is not a dependency of this package (M's F5.5 ruling, round P5). Since F05 (2026-09-20) an EXTERNAL entity reference FAILS the parse at the reference and parameter-entity parsing is off, so an external DTD subset is never requested — both set on the parser rather than read off its defaults — but an INTERNAL entity IS expanded, and what stops an entity bomb is libexpat's own input-amplification limit rather than anything in this package. That protection belongs to the RUNTIME's expat build (2.4.0 and later, on by default), so a deployment on an older expat loses it without this package changing; max_input_bytes bounds the document either way. tests/test_cdm_parser_safety.py reads the linked version and takes every one of these readings rather than asserting them
  • the XML element names this adapter reads and writes are a PROVISIONAL internal profile (binding: provisional-internal-profile): AEDP-12's UML attribute names bound through one table (ELEMENT_NAMES) in no namespace, because the normative XSD is distributed through NATO national representatives (Ed B §B.5) and is not held here. Reader and writer agreeing through that table proves the profile is self-consistent, not that it is the standard's binding; FORMAT_COVERAGE.md marks every NITS row · provisional for the same reason. The verified normative binding is a separate, explicit mode (SYNAPSE_CDM_NITS_BINDING=normative) that validates every document read or emitted against the authorised schema through the local-resource hook SYNAPSE_CDM_NITS_XSD_DIR and FAILS BLOCKED_EXTERNAL_EVIDENCE without it — it never falls back to the profile, and no shipped fixture, golden or evidence record was produced under it

tacticalapi — TacticalAPI blue-force read side​

Format. TacticalAPI, rheinmetall.tactical_api.v0, commit 58661c9 (2026-09-01); no tag or release exists. Binding standard-encoding. No profile declared.

Message families implemented.

  • rheinmetall.tactical_api.v0.GetBlueForcesResponse
  • rheinmetall.tactical_api.v0.SubscribeBlueForceEventsResponse

Exclusions and limitations, as declared.

  • reads the two read-side responses of the BlueForceTracking service, GetBlueForcesResponse and SubscribeBlueForceEventsResponse, and nothing else: every other message of the contract (own pose, situation objects, every request, the write-side blue-force messages) and every type outside it is refused unsupported-message-type, naming the two. Ingest only; no encoder exists
  • the unit of ingest is one response wrapped in google.protobuf.Any (bytes) or its twin (dict), because a serialized message does not name its own type. gRPC framing, calls, sessions, stream bookkeeping and keep-alive timing are not read and not held: the caller receives each message and hands it over, and a stream is a sequence of calls
  • written against rheinmetall.tactical_api.v0 at upstream commit 58661c9 (2026-09-01), which has no tag or release; the embedded field table is generated from protoc's descriptor of those pinned files. A field a later revision adds is carried as an unknown field; a new upstream commit is a new pin and a new adapter version, never a silent update
  • the contract places the point on the WGS 84 ellipsoid and states no angular unit for latitude_coordinate and longitude_coordinate; they are read as decimal degrees, inferred from every other angle in the contract, not stated by it
  • point_location.course is in degrees with no stated north reference, and Kinematics.course_deg means degrees true: a course in [0, 360) is mapped to course_deg with the north reference ASSUMED true, an assumption course_basis states on every Entity it is applied to (R5, ruled 2026-10-06). A course outside that range, 360 included, is not mapped and not normalised; it stays in the typed block and validate_source names it
  • Entity.symbol is set only from a MIL-STD-2525D numeric code (catalog SYMBOL_CATALOG_MIL2525_D, first set 1 000 000 000 to 9 999 999 999, second set 0 to 9 999 999 999), unrewritten. Every other symbol — another catalog, the string form, a set out of range — is carried in the typed block unconverted and named by validate_source; no symbol is derived from the affiliation (R4, ruled 2026-10-06)
  • proto3 writes no scalar holding its default, so an unset coordinate pair and 0°N 0°E are the same bytes and a false bool reads as an unset one. A geo_point with neither coordinate on the wire yields no position, one with a single coordinate on the wire reads the other as 0.0 and position_basis says so, and blue_force_type flags that are not true give entity_type UNKNOWN, never a person or a unit. Likewise a Timestamp holding seconds 0 and nanos 0 (1970-01-01T00:00:00Z) is what a default-constructed one serialises to, so neither point_location.location_time nor last_contact_time holding it is read as a source time: the next choice stands, the basis says the zero Timestamp was passed over, validate_source names it, and its text stays in the typed block
  • encodings a lenient protobuf parser accepts and repairs are refused by name: a singular field twice, two members of one oneof, a named field with another wire type, an int32 or enum varint outside 32 bits, a bool other than 0 or 1, a varint whose tenth octet sets bits past the 64th, a tag written in more than five octets, and a field the well-known types Any, Timestamp, StringValue and DoubleValue do not define. Nothing is repaired
  • the read side marks no time field mandatory: valid_from and observed_at come from point_location.location_time, else last_contact_time, else the receipt instant from the injected clock, a zero Timestamp being passed over (proto3-zero-indistinguishable), and valid_from_basis and observed_at_basis say which. The CDM renders instants to the millisecond; the source text stays whole in the typed block. A deleted element gets no valid_to: the contract says only that the blue force is no longer present (R6, ruled 2026-10-06)
  • no TacticalAPI server, client or captured message has been exercised. Every payload is synthetic, and every one starts as protoc's own encoding of a text source against the pinned files; none was written from scratch by hand. Fourteen are protoc's bytes unchanged. Seven were changed afterwards by the fixture builder: three have hand-encoded fields appended, and four refusal payloads are protoc's bytes after one byte surgery each. protoc's own readings of the payloads are the only independent oracle
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run, and the release pipeline generates the records for every shipped adapter and attaches them to the GitHub Release of the version it publishes. evidence.available is true because every published distribution that carries this adapter has that Release, so its records are retrievable by a third party; it says nothing about what the wheel contains
  • of the five resource limits this adapter enforces three — max_input_bytes, max_depth and max_objects, each an implementation cap declared with its basis and refused before any object is built — plus two the manifest has no field for, declared beside max_objects: MAX_UNKNOWN_FIELDS (65 536 carried unknown fields per input) and MAX_CARRIED_COPY_CHARS (16 777 216 characters of compact JSON text, with ASCII escaping, of the message-level data carried across all the Entities and Events of one message, each copy counted). max_decompressed_bytes and max_parse_seconds are absent, each with its reason in capabilities.limits.absent_because

tak — Cursor-on-Target​

Format. Cursor-on-Target (TAK), not stated — see the limitations. Binding standard-encoding. No profile declared.

Message families implemented.

  • CoT atoms (a-.-...) — contact reports
  • CoT drawing shapes, on egress

Exclusions and limitations, as declared.

  • the CoT schema edition this adapter is written against is NOT STATED by any document in this repository — fixtures/tak/spec/tak_terms.json records the Base-Event Schema's own version as its publisher states it, which is a reading of that page and not a statement that this implementation targets it, so format.version is null rather than guessed
  • contact atoms only on ingest; CoT types outside a-.-... are out of scope
  • leftovers are parked in Entity.attributes / Event.payload under source_extras (lossless.residual()), not in the origin-identifying container ARCHITECTURE.md §5 gives to P3 — the Part 1 stance that section rules for the adapters already shipped
  • the evidence RECORD for this adapter is not IN the distribution: evidence/ is untracked and unpackaged, CI generates the set on every run and the release pipeline attaches it to the GitHub Release. evidence.available is true because the records for 2.1.2 are attached to the v2.1.2 Release and retrievable by a third party, and it says nothing about what the wheel contains
  • of §3.5's five resource limits this adapter enforces TWO — max_input_bytes, declared in capabilities.limits with its basis beside it and refused before decode by the base class (round P5), and max_depth, declared the same way and refused by this module immediately after the XML parse and before anything recurses into the tree (2026-09-16). The other three are still absent, each with its own reason in capabilities.limits.absent_because; an object-count, decompression or wall-clock bound is not enforced here today
  • XML is parsed with the standard library's xml.etree.ElementTree and NOT with defusedxml, which is not a dependency of this package (M's F5.5 ruling, round P5). An EXTERNAL entity is not resolved and an external DTD is not fetched — the parser never reads the external subset — but an INTERNAL entity IS expanded, and what stops an entity bomb is libexpat's own input-amplification limit rather than anything in this package. That protection belongs to the RUNTIME's expat build (2.4.0 and later, on by default), so a deployment on an older expat loses it without this package changing; max_input_bytes bounds the document either way. tests/test_cdm_parser_safety.py reads the linked version and takes every one of these readings rather than asserting them

STANAG 4676: the provisional profile and the normative mode​

stanag4676 declares binding: provisional-internal-profile. Its XML element names are AEDP-12's UML attribute names bound through one table (ELEMENT_NAMES) in no namespace, because the normative XSD is distributed through NATO national representatives (Ed B §B.5) and is not held in this repository or its wheel. Every fixture, golden and evidence record for this adapter was produced under that profile, and an emitted document says so in a comment on its first line. The · provisional qualifier on every NITS row of FORMAT_COVERAGE.md is the same statement.

The verified normative binding is a separate, explicit mode: SYNAPSE_CDM_NITS_BINDING=normative in the environment, or binding="normative" to the constructor. Under it every document read is validated against the authorised schema before anything interprets it, every document emitted is validated before it is handed over, and the adapter records what it validated against (binding_report). The mode needs the local-resource hook and FAILS BLOCKED_EXTERNAL_EVIDENCE without it — at construction, naming the first unmet step — and it never falls back to the profile. A document whose root is in a namespace is refused by the profile by name, and an unqualified document is refused by the normative mode by name, in both directions.

Status (2026-09-20): BLOCKED_EXTERNAL_EVIDENCE. No authorised XSD is available in this environment, so the normative binding is not verified for any document, and the normative_schema category reads ABSENT above. The acceptance procedure, in the order the resolver checks it:

  1. hook — set SYNAPSE_CDM_NITS_XSD_DIR to a directory outside the repository and outside any published package
  2. directory — that directory exists and is readable
  3. record — it holds xsd_pin.json recording, non-empty, edition, schema_revision, schema_revision_date, target_namespace, provenance, usage_rights, obtained_on, files — the edition, the schema's own revision number and date read from inside the XSD (AEDP-12.1 guide §D.1.1), the target namespace, the channel it was obtained through (DiWEB via a national representative, Ed B §B.5, or the APAN 4676 Community, guide §D.1), the usage rights that permit this use, and the date
  4. files — both stanag4676.xsd and stanag4774_confidentialitymetadatalabel.xsd are present beside the record and named in its files
  5. checksum — each file's SHA-256, recomputed, equals the recorded one
  6. validator — an XSD validator imports: xmlschema (MIT) or lxml (BSD-3-Clause); neither is a dependency of this package and the mode adds none
  7. validate — the document's root is <NITSRoot> in the recorded target namespace and the document validates against stanag4676.xsd with external entities, DTD loading and network access disabled in the validator

The hook is SYNAPSE_CDM_NITS_XSD_DIR; the record is xsd_pin.json beside stanag4676.xsd and stanag4774_confidentialitymetadatalabel.xsd, recording edition, schema_revision, schema_revision_date, target_namespace, provenance, usage_rights, obtained_on, files. Both files stay outside Git and outside any published package. When the procedure has run, the F07 exercise runner records it as a normative_schema report and only then may the manifest say normative-verified.