Repository navigation
synapse-cdm 3.3.0
synapse-cdm 3.3.0
Rendered by synapse release-notes from the tree at this release's tag. Every
section below except major changes is a derivation; that one is quoted from
RELEASE_NOTES.md, which is written by a person. MIGRATIONS.md condition 4 is
unchanged by this file: it is still a person's, and this only makes the nine
mechanical fields impossible to mistype.
Versions
| axis | version |
|---|---|
| package version | 3.3.0 |
| CDM version | 3.0.0 |
| SC-OES version | 0.1.0 |
| Adapter API version | 3.1.0 |
| manifest schema version | 2.1.0 |
Major changes
The TacticalAPI blue-force read side release. Between the 3.2.0 release of 2026-10-06 and this
one, the tree gained one adapter module, tacticalapi, and the registry moved from twenty to
twenty-one. It reads one response of the TacticalAPI blue-force tracking service
(rheinmetall.tactical_api.v0, upstream commit 58661c9) — a GetBlueForcesResponse snapshot or
a SubscribeBlueForceEventsResponse stream update, as a serialized google.protobuf.Any or as its
parsed twin — into one Entity and one Event per blue force, in list order. It ships with its
wire reader tacticalapi_codec, pinned synthetic fixtures with their goldens and protoc's own
readings of every payload, a field-level preservation ledger (MAPPINGS), a structured residual on
every object, declared and enforced input bounds, a manifest, and a harness and conformance
reading of CONFORMANT. Nothing on the wire moved: SCHEMA_VERSION stays 3.0.0, no model, enum or
published schema changed, and no golden of the twenty that predate the arc moved by a byte. The
design record is docs/tacticalapi-implementation.md, which ships in nothing; MIGRATIONS.md's
3.3.0 section is the record of what the distribution carries.
If you are upgrading from 3.2.0, nothing you read or write changes. A 3.2.0 reader reads a
3.3.0 object unchanged, and version.compatible("3.0.0", "3.0.0") is the same answer it was. No
member of the Adapter contract moved, so an adapter subclass written against 3.2.0 keeps working.
Of the package's own dependency declarations only the [lint] extra's pin moved, ruff 0.16.7 →
0.16.9, a development tool nothing in the package imports.
Why the number is 3.3.0
The number is the derived floor: a MINOR from v3.2.0. gates/bump_derivation.py --json,
run before any number was typed, reported the arc as {"kind": "MINOR", "number": "3.3.0", "unruled": []}. The floor comes from the public names the arc added and from nothing removed —
the TacticalapiAdapter subclass with its wire reader tacticalapi_codec and the tacticalapi
fixture set — and the one unit the table cannot decide on its own,
pyproject.toml:optional-dependencies (the [lint] extra's ruff pin, moved in place by the
dependency unit that reached main on 2026-10-06), is ruled PATCH in MIGRATIONS.md's 3.3.0
section, which the gate reads and reports nothing unruled. Over the arc the gate's table decides
186 signals, 102 MINOR and 84 PATCH, and the one ruling decides the rest (--json at the tag
lists 187).
Package version 3.3.0 · CDM schema_version 3.0.0 · Adapter API 3.1.0 · manifest schema 2.1.0
· evidence schema 2.0.0. The first two are three MINORs apart, the third for the ordinary
reason: the surface grew and the contract did not. python -m synapse_cdm.schemas --check --out schemas reads CURRENT: schemas vs models at 3.0.0 and python -m synapse_cdm.manifests --check
reads CURRENT: manifests vs 21 shipped adapters at manifest schema 2.1.0.
ADAPTER_API_VERSION, MANIFEST_SCHEMA_VERSION and EVIDENCE_SCHEMA_VERSION did not move in this
arc. SC-OES, the Operational Ontology and the profile versions did not move: SC_OES_VERSION is
still 0.1.0 and still a Draft. synapse_cdm/version.py states the nine version axes and their
independence.
The tacticalapi adapter, and what it is measured to do
In FORMAT_COVERAGE.md's ordinal table tacticalapi is #22.
It is the twenty-first registered adapter and carries ordinal 22 because ordinal 9 was issued to a
specification that has no adapter: the ordinal is not the roster count.
| Adapter | Specification / profile | Direction | What ships |
|---|---|---|---|
tacticalapi |
TacticalAPI (rheinmetall.tactical_api.v0, upstream commit 58661c9 of 2026-09-01, which has no tag or release), the blue-force read side only: GetBlueForcesResponse and SubscribeBlueForceEventsResponse |
ingest | one response → one Entity and one Event per blue force; the wire reader tacticalapi_codec with the contract's field table embedded; the tacticalapi fixture set |
What it reads. One already-received response per call, as octets or as the dict a
.parsed.json fixture holds; both forms go through one twin and give the same objects. gRPC
framing is not read, and the adapter holds no session, reads no network and keeps nothing between
two calls, so a stream is a sequence of calls. Each blue force becomes an Entity — position in
WGS 84 decimal degrees, speed, a course in [0, 360) as course_deg with the north reference
assumed true and said so, a symbol only from a MIL-STD-2525D numeric code, and the message and
entry exactly as stated in the typed block tacticalapi-blueforce/1 — and an Event,
TRACK_UPDATE, or STATUS_CHANGE for a deleted entry, which is a status and never an invented
valid_to. Affiliation reads UNKNOWN, because the message carries no affiliation field, unless
the caller supplies one keyword-only as TacticalapiAdapter(affiliation=...). Every field the
contract does not name is carried in the structured residual that every Entity and every Event
carries, and never dropped.
What it refuses, by name. Every refusal the codec and the adapter raise is a
TacticalapiRefused, a ValueError whose code is one of the codec's 31 reason codes: every other message of the contract and every
other type; a response whose header does not report success; a blue force without an identity;
a coordinate out of range; encodings a lenient protobuf parser accepts and repairs — a singular
field twice, two members of one oneof, a named field with another wire type, an out-of-range or
overlong varint; a truncated input; and more unknown fields, objects or carried text than the
declared bounds. A payload above the declared 4 195 328-octet bound is refused by the base class
before the decoder runs, and nothing is repaired. The adapter's tests assert the refusals by
name, on the eight committed payloads under fixtures/tacticalapi/malformed/ and on inputs the
tests generate.
Where its behaviour comes from. The contract's ten interface definition files, pinned at
upstream commit 58661c9 outside every repository and found through
SYNAPSE_CDM_TACTICALAPI_PROTO_DIR; the maintainer ruled that the Eclipse Public License 2.0
governs them. The adapter embeds only their field names, field numbers and enum values, and both
copies of NOTICE state that derivation; no other text of the files is carried, and the files are
neither in this repository nor in the wheel. Every payload is synthetic and starts as protoc's own
encoding of a text source against the pinned files. The adapter declares the licence class OPEN.
This repository is not affiliated with, endorsed by or reviewed by the interface's publisher, and
the name says which published contract the adapter reads: it is kept, on the maintainer's ruling,
without seeking the publisher's written consent.
External interoperability is a separate conclusion, and it is NOT claimed
Local implementation completion and external interoperability completion are two conclusions.
The first is reached for tacticalapi and this release claims it. The second is not claimed
anywhere in the tree: no TacticalAPI server, client or captured message has been exercised, and no
exchange with any system is asserted.
- The five evidence categories, as generated by
python -m synapse_cdm.evidence generate --adapter tacticalapion this tree — the records themselves are generated, gitignored, and
attached by a Release rather than committed:internal_fixturePRESENT;self_round_trip
NOT_APPLICABLE, since the adapter is ingest only;independent_expectedABSENT;
normative_schemaABSENT;independent_endpointABSENT. - The comparison with the pinned contract is a test that needs the pinned files and
protoc,
and it does not run in CI. The two tests that rebuild every generated fixture and compare the
embedded field table with the pinned descriptor read the directory
SYNAPSE_CDM_TACTICALAPI_PROTO_DIRnames; no workflow sets it, so in CI they record
BLOCKED_EXTERNAL_EVIDENCErather than passing. - Declared maturity is L3 and claim status VERIFIED, read from
manifests/tacticalapi.json.
L4 is not declared: there is no egress direction for information to be lost in. evidence.availableistrueontacticalapifrom this release. The adapter landed
declaringfalse— "it becomes true at the first release that attaches them" — and
tests/test_cdm_evidence.pyholds the field to the newest release tag's tree. The release
commit flipped it, with a limitation sentence that names no version, the formdis7's took at
3.2.0:.github/workflows/publish.ymlgenerates the records for every shipped adapter and
attaches them to the Release of the version it publishes. What the field does NOT say: nothing
about the wheel's contents, and nothing about the three external categories.
What changed for a 3.2.0 consumer
- Nothing on the wire. No field, enum, schema or golden of the twenty that predate the arc
moved;git diff v3.2.0 -- schemas/is empty. - A new adapter,
tacticalapi, with the keyword-onlyaffiliation=argument, and a new
fixture directory,fixtures/tacticalapi/;--list-adaptersreports twenty-one and the
harness replaystacticalapiwith--adapter tacticalapiand no--fixtures. No other
adapter's verdict moved. NOTICEgains one paragraph, in both copies, stating that the embedded field table derives
from interface definition files the Eclipse Public License 2.0 governs. The wheel's licence
metadata does not move:licensestaysApache-2.0andlicense-filesstaysLICENSEand
NOTICE.- The
[lint]extra pins ruff 0.16.9. The rule set the workflows read from it was measured
unchanged under the new version (MIGRATIONS.md's 3.3.0 section, the paragraph that begins THE
RUFF RECORD).
What else moved
- The wheel gate knows the new modules.
gates/wheel_install.pydecides each of the five new
test modules on one of its two lists, and itslicencescheck asserts the derivation statement
in the installed wheel'sNOTICE;tests/test_cdm_packaging.pyasserts it offline in both copies.
Three gate modules of the arc's own,gates/tacticalapi_field_table.py,
gates/tacticalapi_contract_comments.pyandgates/protoc_text.py, regenerate the embedded
field table and check that no text of the pinned files reached the arc's files. - The dependency unit of 2026-10-06 landed by hand, as one signed-off commit: the ruff pin
above;react,react-domand@types/reactat^19.3.0and threeoverridesfloors in
docs/package.json(serialize-javascript,fast-uriandshell-quote), which now carries
fifteenoverridesentries; andanchore/sbom-actionat v0.24.3 at its four sites in
publish.ymlandrc-build.yml.security/exceptions/GHSA-vfj7-8cjw-p6xm.json, the one
exception, still exceptsbraces, which has no fixed release, until 2026-12-04, with the
maintainer as owner. All of the documentation site's dependencies are build-time and ship in
nothing. - Five open items found on the way are recorded and not fixed here, in the implementation
record's "Open items":adapter.wire_sizeraisesUnicodeEncodeErrorfor astrholding a
lone surrogate before any adapter can refuse it;adapter.wire_sizeand
adapter.container_depthtake a value's type fromisinstance, so an in-process object whose
__class__claims octets, text, adictor alistraises there; the adapter's
validate_sourcewrites a refusal's text whole; no test raises a plainValueErroron the path
ofvalidate_sourcethat handles one; and a releasedmemoryviewleaves the codec's entry
points, and the host'swire_size, with Python's ownValueErrorand no reason code. None
touches a claim of this release: four need an input only an in-process caller can build, and
the fifth is a test the arc did not write.
Twenty-one adapters at 3.3.0, all harness-verified
python -m synapse_cdm.harness --adapter <name> --schemas schemas --json, run over the roster
with no --fixtures on this tree, and every verdict read from the run. The table is the live registry, and tests/test_cdm_release.py::test_the_release_notes_roster_table_is_the_registry requires both directions to agree. python -m synapse_cdm.harness --list-adapters prints 21 adapters registered. Declared maturity and claim status are read from manifests/<name>.json.
| Adapter | Direction | Fixture verdicts | Declared maturity | Claim |
|---|---|---|---|---|
adsb |
bidirectional | 32 | L3 | VERIFIED |
ais |
bidirectional | 22 | L3 | VERIFIED |
cat021 |
bidirectional | 40 | L3 | VERIFIED |
cat023 |
bidirectional | 34 | L3 | VERIFIED |
cat034 |
bidirectional | 34 | L3 | VERIFIED |
cat048 |
bidirectional | 82 | L3 | VERIFIED |
cat062 |
bidirectional | 56 | L3 | VERIFIED |
gmti |
bidirectional | 32 | L3 | VERIFIED |
legion |
ingest | 6 | L3 | VERIFIED |
pntmap |
ingest | 4 | L3 | VERIFIED |
stanag4586 |
ingest | 24 | L3 | VERIFIED |
stanag4609 |
bidirectional | 126 | L3 | VERIFIED |
stanag4676 |
bidirectional | 34 | L3 | PROVISIONAL |
tak |
bidirectional | 12 | L3 | VERIFIED |
geojson |
bidirectional | 4 | L4 | VERIFIED |
geopackage |
ingest | 8 | L3 | VERIFIED |
c2sim |
bidirectional | 10 | L4 | VERIFIED |
aixm511 |
ingest | 10 | L3 | VERIFIED |
aixm52 |
ingest | 10 | L3 | VERIFIED |
dis7 |
bidirectional | 6 | L4 | VERIFIED |
tacticalapi |
ingest | 10 | L3 | VERIFIED (new in the 3.3.0 arc) |
596 fixture verdicts, 0 failed across the twenty-one, against the published 3.0.0 schemas —
the 586 that 3.2.0 shipped, unchanged, plus 10 from the new set. The two readings the wheel gate
takes, its resources and harness checks, run on this tree from a directory outside the
repository, read 21 adapters, 617 fixture files and 21 adapters x 2 schema modes, 1192 fixture verdicts, 0 failed;
gates/wheel_install.py takes the same readings off the installed wheel in the release workflow.
The lossless column reads PASS on every JSON fixture and a stated SKIP on every non-JSON one,
and FAIL on none, on a declared ledger for pntmap, the five of the 3.1.0 arc, dis7 and
tacticalapi, and on the value-presence heuristic, said so, for the other thirteen. The three L4
declarations (geojson, c2sim, dis7) rest on a ledger that reports no loss over a self round
trip under the adapter's declared tolerance; every other declaration is L3.
Nine schema files, regenerated from the models by python -m synapse_cdm.schemas and
byte-identical to the committed ones: entity, event, track, plan_object,
payload_gnss_interference and cdm_object under schemas/, manifests/adapter-manifest and
evidence/evidence and evidence/exercise beside them. None of the nine moved in this arc.
Published by CI over OIDC, as 1.1.0 through 3.2.0 were
No API token. .github/workflows/publish.yml builds on the tagged tree, gates that build with
gates/wheel_install.py --mutation-check, runs twine check --strict, checks that the tag names
the tree's PACKAGE_VERSION, and uploads those same files through PyPI Trusted Publishing after a
required reviewer approves the pypi environment. PUBLICATION.md ledger entry 6 records the
configuration, and entry 24 records the 3.2.0 upload.
Artefacts
An sdist and a wheel, built once by the workflow, gated as that build, and uploaded as those same
files. Their SHA-256 digests are recorded in PUBLICATION.md's ledger together with the
workflow run that produced them. The GitHub Release additionally carries both SBOMs, the evidence
set, the conformance report, the witness record and these notes — so the evidence a claim rests
on is retrievable with the release rather than only as a workflow artefact with a retention
window.
They are deliberately not committed here, for the reason this file has given since 1.1.0. A digest
is a property of one build rather than of the tree: two builds of one tree have identical payloads
but differ in their generated metadata, so a digest written here before the tag would not be the
digest of the file PyPI serves, and one written after the tag could never be inside the tree the tag
names. 1.3.0 measured that the hard way — a local build and the published wheel came out at the
same byte count and were different files — so the digests to compare a download against are the
workflow's, never a rebuild's. Everything else in this document is readable off that tree, which is
what condition 4 of the release procedure asks for.
pip install synapse-cdm==3.3.0
python -m synapse_cdm.harness --list-adaptersAdapter status
21 adapters ship in this distribution. declared is the rung the
adapter's manifest claims; eligible is the rung this release's conformance
sweep allows it. A declared rung above an eligible one is a defect, not a note.
| adapter | version | direction | declared | eligible | claim | result |
|---|---|---|---|---|---|---|
adsb |
1.0.0 | bidirectional | L3 | L5 | VERIFIED | CONFORMANT |
ais |
1.0.0 | bidirectional | L3 | L5 | VERIFIED | CONFORMANT |
aixm511 |
1.0.0 | ingest | L3 | L5 | VERIFIED | CONFORMANT |
aixm52 |
1.0.0 | ingest | L3 | L5 | VERIFIED | CONFORMANT |
c2sim |
1.0.0 | bidirectional | L4 | L5 | VERIFIED | CONFORMANT |
cat021 |
1.0.0 | bidirectional | L3 | L5 | VERIFIED | CONFORMANT |
cat023 |
1.0.0 | bidirectional | L3 | L5 | VERIFIED | CONFORMANT |
cat034 |
1.0.0 | bidirectional | L3 | L5 | VERIFIED | CONFORMANT |
cat048 |
1.0.0 | bidirectional | L3 | L5 | VERIFIED | CONFORMANT |
cat062 |
1.0.0 | bidirectional | L3 | L5 | VERIFIED | CONFORMANT |
dis7 |
1.0.0 | bidirectional | L4 | L5 | VERIFIED | CONFORMANT |
geojson |
1.0.0 | bidirectional | L4 | L5 | VERIFIED | CONFORMANT |
geopackage |
1.0.0 | ingest | L3 | L5 | VERIFIED | CONFORMANT |
gmti |
1.0.0 | bidirectional | L3 | L5 | VERIFIED | CONFORMANT |
legion |
1.0.0 | ingest | L3 | L5 | VERIFIED | CONFORMANT |
pntmap |
1.0.0 | ingest | L3 | L5 | VERIFIED | CONFORMANT |
stanag4586 |
1.0.0 | ingest | L3 | L5 | VERIFIED | CONFORMANT |
stanag4609 |
1.0.0 | bidirectional | L3 | L5 | VERIFIED | CONFORMANT |
stanag4676 |
1.0.0 | bidirectional | L3 | L5 | PROVISIONAL | CONFORMANT |
tacticalapi |
1.0.0 | ingest | L3 | L5 | VERIFIED | CONFORMANT |
tak |
1.0.0 | bidirectional | L3 | L5 | VERIFIED | CONFORMANT |
Security status
| control | state |
|---|---|
| GitHub secret scanning | active |
| Secret-scanning push protection | active |
| Private vulnerability reporting | active |
| Secret scanning in CI (gitleaks) | active |
| No secret in the repository's history | active |
| Input bounds on every adapter | active |
| Parser-safety policy | active |
| Resource isolation of the conformance worker | active |
| Streaming input | not provided |
Verification of the integrity block |
not provided |
| Signed commits | active |
| Dependabot alerts and the dependency graph | active |
| Dependabot security updates | active |
| Dependabot version updates | active |
| Dependency review on pull requests | active |
| Python dependency audit | active |
npm dependency audit over docs/ |
active |
Pinned floors on transitive npm dependencies of docs/ |
active |
| CodeQL, with a gate that fails the build | active |
| SBOM, two formats | active |
| Build attestation, no long-lived key | active |
| Documented, time-bounded security exceptions | active |
| Secret-scanning non-provider patterns | not enabled in this round |
| Secret-scanning validity checks | not enabled in this round |
| Cryptographic signing of CDM objects | not provided |
| Defence against a producer asserting false semantics | not provided |
- CodeQL, this release's run: 0 result(s), 0 blocking at or above 7.0; gate exit 0 over 4 analysis file(s) of e3acf78
pip-audit, this release's run: No known vulnerabilities found; strict, over 43 third-party distribution(s), ignore-vuln flags in force: [--ignore-vuln GHSA-vfj7-8cjw-p6xm]- Security exceptions in force: 1 —
GHSA-vfj7-8cjw-p6xm.json
Known limitations
Stated by the adapters themselves, in their manifests. This is not a survey of what
the package cannot do; it is what each adapter says it does not do.
adsb
- 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.jsonrecords as priced, soformat.versionis 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.payloadundersource_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.availableis true because the records for 2.1.2 are attached to thev2.1.2Release 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 incapabilities.limitswith 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 incapabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today
ais
- 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.jsonrecords both without naming the edition this implementation targets, soformat.versionis 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.payloadundersource_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.availableis true because the records for 2.1.2 are attached to thev2.1.2Release 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 incapabilities.limitswith 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 incapabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today
aixm511
- {'id': 'pinned-families', 'notes': None, 'severity': None, 'summary': '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, andvalidate_sourcenames 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', 'unsupported_paths': []} - {'id': 'digital-notam-profiles', 'notes': None, 'severity': None, 'summary': "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_findingand 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 issynapse_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)", 'unsupported_paths': []} - {'id': 'unsupported-geometry-refused', 'notes': None, 'severity': None, 'summary': "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 inattributes.aixmand no PlanObject. No arc is replaced by a chord and no circle by a polygon", 'unsupported_paths': []} - {'id': 'composite-volumes-not-drawn', 'notes': None, 'severity': None, 'summary': '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_projectionon the block says why;validate_sourcenames it', 'unsupported_paths': []} - {'id': 'vertical-projection-by-member', 'notes': None, 'severity': None, 'summary': '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', 'unsupported_paths': []}
- {'id': 'cancelled-slice-needs-as-of', 'notes': None, 'severity': None, 'summary': "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 becomesvalid_fromwith the basis insource.transformations; without it the document is refused naming the slice. Nothing is stamped with the clock or the epoch", 'unsupported_paths': []} - {'id': 'identifier-required', 'notes': None, 'severity': None, 'summary': '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', 'unsupported_paths': []}
- {'id': 'references-one-hop', 'notes': None, 'severity': None, 'summary': "xlink:href is resolved against the document and the caller's
referencestable, one hop, never over a network; a URL is classified and not fetched; unresolved references are kept with their property, href and form underattributes.aixm.referencesand listed inunresolved_references", 'unsupported_paths': []} - {'id': 'schedules-not-resolved', 'notes': None, 'severity': None, 'summary': 'Timesheets, activation and availability structures are carried as typed validity, never resolved to instants;
statuson 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', 'unsupported_paths': []} - positions carry
position_source: MANUAL— a surveyed, published coordinate is none of GNSS, INERTIAL or ESTIMATED — with the MSL elevation of an ElevatedPoint invertical(its uom kept, reference MSL by the model's own definition ofelevation) andalt_mNone 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.availableis 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 thev3.1.0Release asevidence-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_bytesby the base class before decode and again bysecure_xmlbefore a parser exists,max_depthandmax_objectsin 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 incapabilities.limits.absent_because - XML is parsed with the standard library's expat through
secure_xmland NOT withdefusedxml, 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 isxml.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
- {'id': 'pinned-families', 'notes': None, 'severity': None, 'summary': "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, andvalidate_sourcenames 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 AirspaceVolumenameandlocation, which ride in the component's verbatim source and are not typed", 'unsupported_paths': []} - {'id': 'digital-notam-not-available', 'notes': None, 'severity': None, 'summary': "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 (
profilesis empty), noattributes.dnotamblock and no scenario rule; a member in the AIXM 5.1.1 Event namespace inside a 5.2 document is named byvalidate_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", 'unsupported_paths': []} - {'id': 'unsupported-geometry-refused', 'notes': None, 'severity': None, 'summary': "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 inattributes.aixmand no PlanObject. No arc is replaced by a chord and no circle by a polygon", 'unsupported_paths': []} - {'id': 'composite-volumes-not-drawn', 'notes': None, 'severity': None, 'summary': '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_projectionon the block says why;validate_sourcenames it', 'unsupported_paths': []} - {'id': 'vertical-projection-by-member', 'notes': None, 'severity': None, 'summary': "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
verticalDatumis free text in 5.2 (TextNameType) and is carried as the text stated", 'unsupported_paths': []} - {'id': 'cancelled-slice-needs-as-of', 'notes': None, 'severity': None, 'summary': "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 becomesvalid_fromwith the basis insource.transformations; without it the document is refused naming the slice. Nothing is stamped with the clock or the epoch", 'unsupported_paths': []} - {'id': 'identifier-required', 'notes': None, 'severity': None, 'summary': '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', 'unsupported_paths': []}
- {'id': 'references-one-hop', 'notes': None, 'severity': None, 'summary': "xlink:href is resolved against the document and the caller's
referencestable, one hop, never over a network; a URL is classified and not fetched; unresolved references are kept with their property, href and form underattributes.aixm.referencesand listed inunresolved_references", 'unsupported_paths': []} - {'id': 'schedules-not-resolved', 'notes': None, 'severity': None, 'summary': 'Timesheets, activation and availability structures are carried as typed validity, never resolved to instants;
statuson 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', 'unsupported_paths': []} - positions carry
position_source: MANUAL— a surveyed, published coordinate is none of GNSS, INERTIAL or ESTIMATED — with the MSL elevation of an ElevatedPoint invertical(its uom kept, reference MSL by the model's own definition ofelevation) andalt_mNone 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.availableis 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 thev3.1.0Release asevidence-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_bytesby the base class before decode and again bysecure_xmlbefore a parser exists,max_depthandmax_objectsin 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 incapabilities.limits.absent_because - XML is parsed with the standard library's expat through
secure_xmland NOT withdefusedxml, 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 isxml.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
- {'id': 'untyped-object-class', 'notes': None, 'severity': None, 'summary': "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.MessageBodyand named byvalidate_source. The typed classes are ForceSide, Unit, the four Platform kinds and the Route map graphic", 'unsupported_paths': []} - {'id': 'unsupported-message-body', 'notes': None, 'severity': None, 'summary': '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', 'unsupported_paths': []} - {'id': 'pinned-task-forms', 'notes': None, 'severity': None, 'summary': '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', 'unsupported_paths': []}
- {'id': 'untyped-observations', 'notes': None, 'severity': None, 'summary': 'ActivityObservation, ResourceObservation and SubjectTypeObservation are carried whole under
payload.c2sim.observations[].raw(typed: false); Health, Location and Name observations are typed', 'unsupported_paths': []} - {'id': 'simulation-time-needs-a-clock', 'notes': None, 'severity': None, 'summary': "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", 'unsupported_paths': []} - {'id': 'affiliation-needs-own-side', 'notes': None, 'severity': None, 'summary': "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", 'unsupported_paths': []} - {'id': 'extension-not-reemitted', 'notes': None, 'severity': None, 'summary': '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', 'unsupported_paths': []}
- 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 carryposition_source: ESTIMATED, the understating reading legion applies to a simulation's fixes, and their MSL or AGL height is kept inverticalunconverted withalt_mNone - egress of an Entity with no
attributes.c2simblock 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.availableis 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 thev3.1.0Release asevidence-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_bytesby the base class before decode and again bysecure_xmlbefore a parser exists,max_depthandmax_objectsin 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 incapabilities.limits.absent_because - XML is parsed with the standard library's expat through
secure_xmland NOT withdefusedxml, 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 isxml.etree.ElementTree's own, built through its TreeBuilder
cat021
- 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.payloadundersource_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.availableis true because the records for 2.1.2 are attached to thev2.1.2Release 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 incapabilities.limitswith 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 incapabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today
cat023
- the smallest specification pinned in this repository: nine data items, and nothing outside them is decoded
- leftovers are parked in
Entity.attributes/Event.payloadundersource_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.availableis true because the records for 2.1.2 are attached to thev2.1.2Release 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 incapabilities.limitswith 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 incapabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today
cat034
- the pinned edition is 1.29 and it is NOT the latest:
fixtures/cat034/spec/cat034_pin.jsonrecords Edition 1.30 as available, and this adapter is written against 1.29 - leftovers are parked in
Entity.attributes/Event.payloadundersource_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.availableis true because the records for 2.1.2 are attached to thev2.1.2Release 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 incapabilities.limitswith 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 incapabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today
cat048
- 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.payloadundersource_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.availableis true because the records for 2.1.2 are attached to thev2.1.2Release 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 incapabilities.limitswith 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 incapabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today
cat062
- 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.payloadundersource_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.availableis true because the records for 2.1.2 are attached to thev2.1.2Release 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 incapabilities.limitswith 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 incapabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today
dis7
- 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_instancesupplies the packaged fixtures' context (sessionunnamed, synthetic, the vectors' state instant and basis) and refusessynthetic=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.availableis 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
- {'id': 'geometry-collection', 'notes': None, 'severity': None, 'summary': "
GeometryCollectionis refused, not translated:geo.pykeeps 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", 'unsupported_paths': []} - {'id': 'bare-geometry', 'notes': None, 'severity': None, 'summary': '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', 'unsupported_paths': []}
- {'id': 'empty-coordinates', 'notes': None, 'severity': None, 'summary': 'a geometry whose
coordinatesarray 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', 'unsupported_paths': []} - {'id': 'legacy-crs', 'notes': None, 'severity': None, 'summary': 'a
crsmember 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', 'unsupported_paths': []} - {'id': 'empty-collection', 'notes': None, 'severity': None, 'summary': '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', 'unsupported_paths': []}
- {'id': 'no-source-time', 'notes': None, 'severity': None, 'summary': "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 atvalidity.observed_at(PlanObject) orvalid_from(Entity) with its basis insource.transformations. The conformance suite's check J reads this id as the declared reason it has no timestamp to judge", 'unsupported_paths': []} - {'id': 'bbox-not-projected', 'notes': None, 'severity': None, 'summary': '
bboxat every level is kept verbatim in the residual and is NOT projected to a canonicalBoundingBox:PlanObjectcarries bounds only inside anArea, andgeo.BoundingBoxrefuses an antimeridian-crossing box (west > east) by construction. Every bbox is noted insource.transformations, the antimeridian case as such', 'unsupported_paths': []} - egress accepts
PlanObjectandEntity(an entity'spositionbecomes a Point, or a null geometry when it has none); anEventor aTrackis 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; thesc: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.availableis 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 thev3.1.0Release asevidence-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_bytesandmax_depthby the base class before decode, andmax_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 incapabilities.limits.absent_because
geopackage
- {'id': 'version-1-4-0-only', 'notes': None, 'severity': None, 'summary': 'only GeoPackage 1.4.0 (
user_version10400,application_idGPKG) is read; any otheruser_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', 'unsupported_paths': []} - {'id': 'wgs84-only', 'notes': None, 'severity': None, 'summary': "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", 'unsupported_paths': []}
- {'id': 'measured-geometry', 'notes': None, 'severity': None, 'summary': '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', 'unsupported_paths': []}
- {'id': 'geometry-collection-and-extended-types', 'notes': None, 'severity': None, 'summary': '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', 'unsupported_paths': []}
- {'id': 'non-vector-content', 'notes': None, 'severity': None, 'summary': "raster tiles, gridded coverages, attributes-only tables and views are inventoried as unsupported content in every object's
residual.data.package.inventoryand are never read; a mixed package translates its selected vector layers only and every object says so", 'unsupported_paths': []} - {'id': 'wal-dependent', 'notes': None, 'severity': None, 'summary': "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
-walfile the octets do not include;wal_checkpointed=Trueis the caller's assertion that the file was checkpointed, recorded on every object", 'unsupported_paths': []} - {'id': 'no-source-time', 'notes': None, 'severity': None, 'summary': "a GeoPackage states no observation time;
gpkg_contents.last_changeis 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 atvalidity.observed_at(PlanObject) orvalid_from(Entity) with its basis insource.transformations. The conformance suite's check J reads this id as the declared reason it has no timestamp to judge", 'unsupported_paths': []} - {'id': 'z-meaning-as-declared', 'notes': None, 'severity': None, 'summary': "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", 'unsupported_paths': []}
- ingest only:
from_cdmis 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.availableis 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 thev3.1.0Release asevidence-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_bytesandmax_depthby the base class before decode, andmax_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 incapabilities.limits.absent_because
gmti
- 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.payloadundersource_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.availableis true because the records for 2.1.2 are attached to thev2.1.2Release 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 incapabilities.limitswith 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 incapabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today
legion
- a VENDOR API rather than a ratified standard:
fixtures/legion/spec/openapi_pin.jsonrecords that it "can change between deploys, and its info.version demonstrably does not move when it does", sov3names 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.payloadundersource_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.availableis true because the records for 2.1.2 are attached to thev2.1.2Release 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 incapabilities.limitswith 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 incapabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today
pntmap
- 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.versionis 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.payloadundersource_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.availableis true because the records for 2.1.2 are attached to thev2.1.2Release 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 incapabilities.limitswith 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 incapabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today
stanag4586
- Edition 4 is current (promulgated as AEP-84 Edition A) and is NOT implemented: FORMAT_COVERAGE.md records that
nso.nato.intanswers 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_basissaying so - leftovers are parked in
Entity.attributes/Event.payloadundersource_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.availableis true because the records for 2.1.2 are attached to thev2.1.2Release 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 incapabilities.limitswith 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 incapabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today
stanag4609
- 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.payloadundersource_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.availableis true because the records for 2.1.2 are attached to thev2.1.2Release 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 incapabilities.limitswith 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 incapabilities.limits.absent_because; a depth, object-count, decompression or wall-clock bound is not enforced here today
stanag4676
- 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.payloadundersource_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.availableis true because the records for 2.1.2 are attached to thev2.1.2Release 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 incapabilities.limitswith its basis beside it and refused before decode by the base class (round P5), andmax_depth, declared the same way and refused byparse_documentimmediately 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 incapabilities.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 (
pyexpatinto anxml.etree.ElementTreetree,parse_document's_parse_xml) and NOT withdefusedxml, 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_bytesbounds 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· provisionalfor 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 hookSYNAPSE_CDM_NITS_XSD_DIRand 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
- {'id': 'blue-force-read-side-only', 'notes': None, 'severity': None, 'summary': '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', 'unsupported_paths': []} - {'id': 'capture-envelope', 'notes': None, 'severity': None, 'summary': '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', 'unsupported_paths': []}
- {'id': 'pinned-commit-v0', 'notes': None, 'severity': None, 'summary': "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", 'unsupported_paths': []}
- {'id': 'coordinate-unit-not-stated', 'notes': None, 'severity': None, 'summary': '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', 'unsupported_paths': []}
- {'id': 'course-reference-not-stated', 'notes': None, 'severity': None, 'summary': 'point_location.course is in degrees with no stated north reference, and
Kinematics.course_degmeans degrees true: a course in [0, 360) is mapped tocourse_degwith the north reference ASSUMED true, an assumptioncourse_basisstates 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 andvalidate_sourcenames it', 'unsupported_paths': []} - {'id': 'symbol-2525d-only', 'notes': None, 'severity': None, 'summary': '
Entity.symbolis 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 byvalidate_source; no symbol is derived from the affiliation (R4, ruled 2026-10-06)', 'unsupported_paths': []} - {'id': 'proto3-zero-indistinguishable', 'notes': None, 'severity': None, 'summary': '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_basissays so, andblue_force_typeflags that are not true giveentity_typeUNKNOWN, 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_sourcenames it, and its text stays in the typed block', 'unsupported_paths': []} - {'id': 'non-canonical-encoding-refused', 'notes': None, 'severity': None, 'summary': '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', 'unsupported_paths': []}
- {'id': 'source-time-optional', 'notes': None, 'severity': None, 'summary': 'the read side marks no time field mandatory:
valid_fromandobserved_atcome 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), andvalid_from_basisandobserved_at_basissay which. The CDM renders instants to the millisecond; the source text stays whole in the typed block. A deleted element gets novalid_to: the contract says only that the blue force is no longer present (R6, ruled 2026-10-06)', 'unsupported_paths': []} - {'id': 'no-endpoint-exercised', 'notes': None, 'severity': None, 'summary': "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", 'unsupported_paths': []}
- {'id': 'evidence-availability', 'notes': None, 'severity': None, 'summary': '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.availableis 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', 'unsupported_paths': []} - {'id': 'resource-limits', 'notes': None, 'severity': None, 'summary': 'of the five resource limits this adapter enforces three —
max_input_bytes,max_depthandmax_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 besidemax_objects:MAX_UNKNOWN_FIELDS(65 536 carried unknown fields per input) andMAX_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_bytesandmax_parse_secondsare absent, each with its reason incapabilities.limits.absent_because', 'unsupported_paths': []}
tak
- the CoT schema edition this adapter is written against is NOT STATED by any document in this repository —
fixtures/tak/spec/tak_terms.jsonrecords 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, soformat.versionis null rather than guessed - contact atoms only on ingest; CoT types outside
a-.-...are out of scope - leftovers are parked in
Entity.attributes/Event.payloadundersource_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.availableis true because the records for 2.1.2 are attached to thev2.1.2Release 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 incapabilities.limitswith its basis beside it and refused before decode by the base class (round P5), andmax_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 incapabilities.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.ElementTreeand NOT withdefusedxml, 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_bytesbounds 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
Conformance summary
Checks A–O of the Synapse Conformance Suite over every
shipped adapter, from this release's own sweep.
| adapter | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | result |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
adsb |
PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | SKIP | PASS | PASS | CONFORMANT |
ais |
PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | SKIP | PASS | PASS | CONFORMANT |
aixm511 |
PASS | PASS | PASS | PASS | SKIP | PASS | PASS | PASS | PASS | PASS | PASS | PASS | SKIP | PASS | PASS | CONFORMANT |
aixm52 |
PASS | PASS | PASS | PASS | SKIP | PASS | PASS | PASS | PASS | PASS | PASS | PASS | SKIP | PASS | PASS | CONFORMANT |
c2sim |
PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | SKIP | PASS | PASS | CONFORMANT |
cat021 |
PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | SKIP | PASS | PASS | PASS | SKIP | PASS | PASS | CONFORMANT |
cat023 |
PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | SKIP | PASS | PASS | PASS | SKIP | PASS | PASS | CONFORMANT |
cat034 |
PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | SKIP | PASS | PASS | PASS | SKIP | PASS | PASS | CONFORMANT |
cat048 |
PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | SKIP | PASS | PASS | PASS | SKIP | PASS | PASS | CONFORMANT |
cat062 |
PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | SKIP | PASS | PASS | PASS | SKIP | PASS | PASS | CONFORMANT |
dis7 |
PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | SKIP | PASS | PASS | PASS | SKIP | PASS | PASS | CONFORMANT |
geojson |
PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | SKIP | PASS | PASS | SKIP | SKIP | PASS | CONFORMANT |
geopackage |
PASS | PASS | PASS | PASS | SKIP | PASS | PASS | PASS | PASS | SKIP | PASS | PASS | SKIP | PASS | PASS | CONFORMANT |
gmti |
PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | SKIP | PASS | PASS | CONFORMANT |
legion |
PASS | PASS | PASS | PASS | SKIP | PASS | PASS | PASS | PASS | PASS | PASS | PASS | SKIP | SKIP | PASS | CONFORMANT |
pntmap |
PASS | PASS | PASS | PASS | SKIP | PASS | PASS | PASS | PASS | PASS | PASS | PASS | SKIP | SKIP | PASS | CONFORMANT |
stanag4586 |
PASS | PASS | PASS | PASS | SKIP | PASS | PASS | PASS | SKIP | PASS | PASS | PASS | SKIP | PASS | PASS | CONFORMANT |
stanag4609 |
PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | SKIP | PASS | PASS | PASS | SKIP | PASS | PASS | CONFORMANT |
stanag4676 |
PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | SKIP | PASS | PASS | CONFORMANT |
tacticalapi |
PASS | PASS | PASS | PASS | SKIP | PASS | PASS | PASS | PASS | PASS | PASS | PASS | SKIP | PASS | PASS | CONFORMANT |
tak |
PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | SKIP | PASS | PASS | CONFORMANT |