Skip to content

Releases: Decent-Cybersecurity/synapsecommand-public

synapse-cdm 3.0.1

Choose a tag to compare

@github-actions github-actions released this 20 Sep 14:44

synapse-cdm 3.0.1

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.0.1
CDM version 3.0.0
SC-OES version 0.1.0
Adapter API version 3.0.0
manifest schema version 2.1.0

Major changes

The corrective of the tagged-never-published 3.0.0, and the first published release of the audit
remediation arc.
v3.0.0 was tagged on 2026-09-20 and its own release run (35506445471) refused
it in the build job: the gate job had run the suite green on the same commit, and the build job's
second run of it — in an interpreter that job had first loaded with twine and cyclonedx-bom,
whose dependency closure made every spawned parser worker import a Lark grammar and seven format
libraries before its first byte of input — crossed a wall-clock budget in one isolation test and
stopped, recording a count and no name. Nothing reached PyPI. What moved between 3.0.0 and 3.0.1
is the release workflow (the tooling now lives in a venv of its own, and condition 4 names the
tests it fails on), MIGRATIONS.md and version.py; the distribution is otherwise byte-for-byte
the tree v3.0.0 named, so everything below describes this release. MIGRATIONS.md's 3.0.1
section is the record, and no test budget moved to get here.

The audit remediation release. Between the 2.2.0 release of 2026-09-17 and this one, the
independent audit of 2026-09-19 raised nine findings against this package, F01 to F09, and every
one of them is answered in the tree at this tag: version compatibility is directional and rests
on frozen evidence rather than on major-number arithmetic; the lossless check's empty result is
no longer treated as proof, and a path-bound preservation ledger replaces it wherever an adapter
declares its field mappings; the conformance suite's parser deadline is a real, process-isolated
one; the published JSON Schema now states every constraint the Python models enforce; the STANAG
4676 adapter's wire binding is declared provisional in its manifest, its CLI row and its page;
resource limits are enforced where the platform can enforce them and refused where it cannot,
never claimed; evidence records carry five categories with the three external ones honestly
ABSENT; governance is an auditable derivation with a runbook; and the documentation is derived
from the tree and drift-checked. The register of all nine, with reproductions, tests, evidence
paths and what stays external, is docs/audit-remediation-report.md. Two things are removed or
narrowed, which is why this is a MAJOR on both of the first two axes — read the next two sections.

If you are upgrading from 2.2.0 — which is what the index serves — read this as the MAJOR it
is on both numbers.
If you are upgrading from 2.1.2 or earlier, read the 2.2.0 notes first: they
are the body of the v2.2.0 Release, and everything they describe is still here.

Why the number is 3.0.1

The number is the derived floor twice over: a PATCH from v3.0.0 for the corrective — an arc of
the release workflow, MIGRATIONS.md and version.py, which gates/bump_derivation.py derives
as PATCH with nothing unruled — on top of the MAJOR the 3.0.0 release commit typed over v2.2.0,
the first MAJOR since 2.0.0.
For that arc, gates/bump_derivation.py reads from v2.2.0 and
derives MAJOR from one shape signal —
lossless.unrepresented, an importable name removed with no alias, because the old name was a
claim of proof the function could not make — and from the units whose meaning changed and were
ruled MAJOR in MIGRATIONS.md's 3.0.0 section: version.compatible and version.parse (F01),
harness.run and evidence.badges (F02), suite.check_malformed and
suite.check_parser_robustness (F03), conformance.assess_a, conformance._validator and
models.Timestamp (F04), manifest.AdapterMetadata, Stanag4676Adapter and parse_document
(F05), harness.load_raw (F06) and evidence.EvidenceRecord (F07). The units the table cannot
classify on its own are every one ruled in that section, and the gate reads those rulings and
reports nothing unruled.

Package version 3.0.1 · CDM schema_version 3.0.0 · Adapter API 3.0.0 · manifest schema 2.1.0
· evidence schema 2.0.0.
The first two were level at the 3.0.0 release commit and are one PATCH
apart at this one, and the equality was a coincidence of two separately argued majors and not a
derivation
: the package moved on version.py's table for a
removed name and ruled meaning changes; the schema moved on MIGRATIONS.md's table because
finding F04 NARROWED the published contract (next section). ADAPTER_API_VERSION moved
2.1.0 -> 3.0.0 on VERSIONING.md §3's own row because AdapterMetadata.binding is required with
no default; the manifest schema moved 1.2.0 -> 2.0.0 for that required field and 2.0.0 -> 2.1.0 for
one added enum member; the evidence schema moved 1.0.0 -> 2.0.0 for three required fields. 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,
and tests/test_cdm_packaging.py sweeps the package for an assignment that would derive one number
from another.

What changed on the wire, and what a 2.2.0 consumer must do

The published schema is narrower, and that is the MAJOR. The four object schemas under
schemas/ carry pattern on every schema_version and adapter_version, pattern on
Entity.symbol and uniqueItems on Entity.ontology_types. Every one of those constraints
restates what the Python models enforced already, so no document this package ever emitted becomes
invalid — but a consumer validating with the published schema alone accepted
"adapter_version": "banana" under 2.1.0 and is refused it under 3.0.0, and the bump table in
MIGRATIONS.md puts a narrowed type on the MAJOR row for exactly that reader. No path was removed, no
required list grew, no enum member went. The 2.1.0 contract stays frozen under
tests/frozen/cdm/2.1.0/ beside the 3.0.0 one under tests/frozen/cdm/3.0.0/, and
tests/test_cdm_version_matrix.py shows the narrowing on the frozen bytes.

Every golden moved by one stamp. The 538 golden files under the package's fixtures/*/golden/
and the eight reference-position goldens under fixtures/adsb/local/ carry
schema_version: "3.0.0" and differ from 2.2.0's by that line alone; the harness reads the same
538 fixture verdicts, 0 failed, on every adapter. The fourteen examples under examples/ declare
3.0.0 too (they declared 2.0.0 through two minors): synapse conformance reads a document's
schema_version against this package's, and a document of another major is refused in its
structural dimension rather than read on trust.

What to change in a 2.2.0 consumer, in one place:

  • Rename lossless.unrepresented to lossless.value_presence_heuristic, and read its {} as
    "nothing seen", not as proof.
  • Expect version.compatible(written_with, read_by) to answer False for any pair a major apart
    (("2.1.0", "3.0.0") in either direction), False for a writer newer than the reader within a
    major, False for a minor nobody has frozen, and to raise ValueError on a malformed string
    (a trailing newline, a leading zero, a prefix, a sign). Use version.assess() for the verdict,
    the direction and the evidence it rests on. KNOWN_CONTRACTS reads ("2.0.0", "2.1.0", "3.0.0").
  • Declare binding= on every adapter's metadata: "standard-encoding" where the wire form is the
    cited document's own encoding, "provisional-internal-profile" with a limitation containing
    "provisional" where the element names or namespace were chosen locally. A provisional binding
    claims PROVISIONAL (new) and not VERIFIED.
  • Expect the harness's lossless column to FAIL on a ledger loss for an adapter that declares
    MAPPINGS, and the lossless-verified badge to read heuristic for one that does not.
  • Expect the suite's H and N checks to carry outcome codes in details, and N's
    over_time_bound strings to name a code rather than a duration; expect --startup-timeout,
    --diagnostics, --memory-limit-bytes and --cpu-limit-seconds on the suite's CLI, the last
    two refused with an explicit reason on a platform that cannot enforce them.
  • Expect the conformance tool to refuse a string boolean, a trailing newline in a version, a
    malformed UUID and a timestamp outside the wire form on the JSON path.
  • Expect --list-adapters to print a binding column; expect an evidence record to carry
    snapshot, evidence_categories and maturity_support, and a manifest to carry binding.
  • Nothing is migrated in place: manifests, schemas, evidence and goldens are regenerated from
    their sources.

Two maintainer rulings, applied in this release

Preservation maturity is declared to what the evidence proves. Eleven manifests declared L4
ROUNDTRIP VERIFIED on a basis sentence that cited the lossless check as evidence — and since
F02 that check, for an adapter with no declared field mappings, rests on the value-presence
heuristic: a source value present somewhere in the output is not a value that reached its path.
"Applicable information survives source -> CDM -> source" is precisely the claim the heuristic
cannot prove, so adsb, ais, cat021, cat023, cat034, cat048, cat062, gmti,
stanag4609, stanag4676 and tak declare L3 from this release, each basis sentence says why,
and tests/test_cdm_manifests.py holds a bidirectional adapter to L3 wherever the report's
`pres...

Read more

synapse-cdm 2.2.0

Choose a tag to compare

@github-actions github-actions released this 17 Sep 15:06

synapse-cdm 2.2.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 2.2.0
CDM version 2.1.0
SC-OES version 0.1.0
Adapter API version 2.1.0
manifest schema version 1.2.0

Major changes

The audit release. Between the 2.1.2 release of 2026-09-12 and this one, nothing was added to
what the package translates: the same fourteen adapters, the same 538 fixture verdicts, the same
six published CDM schemas at schema_version 2.1.0. What moved is what SOIF Part 1 — the Synapse
Open Interoperability Framework's Foundation & Assurance part, a private specification whose
section numbers this file cites as §N — exists to make checkable: two adapters that crashed on a
valid document nested a thousand elements deep now refuse it at a declared bound, and four more
declare the same bound; a maturity rung that eleven manifests typed is now computed by the
harness; an evidence record generated on one machine now reproduces on another; CI runs the suite
on every interpreter the package claims, lints, and runs the wheel gate on every push; the release
pipeline's witness verifier re-derives the digests it used to check for shape; the two npm
advisory exceptions are deleted on the trigger their own files named; no tracked file points a
reader at a private document; and every sentence the audit found false is corrected where it
stands. Nothing is removed, renamed or narrowed, so a 2.1.2 consumer keeps working without doing
anything — with the three refusals listed below, each of which replaces a crash or a wrong
exception on input no shipped fixture ever carried.

If you are upgrading from 2.1.2 — which is what the index serves — read this as the MINOR it
is.
If you are upgrading from 2.0.0, read the 2.1.2 notes first: they are the body of the
v2.1.2 Release, and everything they describe is still here.

Why the number is 2.2.0

The number is the derived floor, and for the first time since v2.1.0 it moved for content.
gates/bump_derivation.py reads the arc from v2.1.2 and derives MINOR from importable names
that did not exist at that tag, with nothing removed: adapter.InputTooDeep,
json_nesting_depth, container_depth, enforce_depth_bound, is_shipped and shipped; the
ROUNDTRIP_TOLERANCE, ROUNDTRIP_TRANSFORMS and roundtrip_reference() members of Adapter;
canonical.py, a new module; harness.select_fixtures and fixtures_required_message;
version.SEMVER_RE and is_semver; six *_MAX_DEPTH module constants; and a [lint] extra in
pyproject.toml, which is the table's optional-dependency row. The eighty-three units the table
cannot classify on its own — bodies that moved with no name added or removed, and import blocks
the gate keys by position — are every one ruled in MIGRATIONS.md's 2.2.0 section, and the gate
reads those rulings and reports nothing unruled. The two correctives before this release each
moved the number for a workflow's defect; this one moves it for what a consumer receives.

Package version 2.2.0 · CDM schema_version 2.1.0 · Adapter API 2.1.0. The first two are
unequal by a MINOR now, and that is the ordinary case and not a signal: the package moved on
version.py's table for new importable names; the schema moved by nothing, because no field and
no published schema changed, and no golden moved but the ten named below, by one citation string.
ADAPTER_API_VERSION moved 2.0.0 -> 2.1.0 on
VERSIONING.md §3's own row, for three additive members on the base class whose defaults are the
behaviour they replaced. synapse_cdm/version.py states the nine version axes and their
independence in one place, and tests/test_cdm_packaging.py sweeps the package for an assignment
that would derive one number from another. A package at 2.2.0 does not mean SC-OES 2.2:
SC_OES_VERSION is a third axis, still 0.1.0 and still a Draft.

What changed on the wire, and what a 2.1.2 consumer must do

Nothing on the wire. schema_version stays 2.1.0; git diff v2.1.2..HEAD -- schemas/ is
four files and five lines, every one a description string; and every golden file in the package
is byte-identical to the 2.1.2 release except ten under fixtures/klv/golden/ — the five VMTI
fixtures' .cdm.json and .parsed.cdm.json — in which the one string that quoted a private
round brief by path, the VMTI identity ruling every VMTI object carries in its attributes, now
says the ruling's source is private; no other byte of any golden moved (git diff v2.1.2..HEAD --numstat -- packages/cdm/synapse_cdm/fixtures/klv/golden is ten files, thirty-four lines each
way, every line that string). A 2.1.2 reader reads a 2.2.0 object unchanged, and
python -m synapse_cdm.schemas --check --out schemas reports CURRENT: schemas vs models at 2.1.0.

Three things a producer could do before and cannot now, each on input no shipped fixture, golden
or parsed twin ever carried:

  • A JSON document or dict nesting more than sixty-four containers is refused by adsb, ais,
    legion, pntmap and tak with adapter.InputTooDeep — a ValueError — before any decoder
    runs, and an XML document nesting more than sixty-four elements is refused by tak and
    stanag4676 the moment the tree is built. Before this release tak and stanag4676 raised
    RecursionError on a valid document about 7 KB deep, which is one of the four crash classes the
    conformance suite refuses to count as a refusal, and the four JSON adapters translated any depth
    the interpreter survived. Each of the six manifests now declares the bound as max_depth, with
    its basis; the other eight keep their declared reason for having none.
  • pntmap refuses a JSON value that is not an object — an array, a string, a number, null
    with one ValueError, where it surfaced an AttributeError from inside the decoder.
  • Every version field is held to one spelling. schema_version, SourceRef.adapter_version,
    a manifest's adapter_version and Event.oes.spec_version accept MAJOR.MINOR.PATCH with no
    leading zero, no prefix, no suffix and no surrounding whitespace — version.SEMVER_RE under
    fullmatch — where three of the four accepted 01.0.0 or a trailing newline. Every value this
    tree has ever written passes; the published schemas carry no new pattern, because a pattern on
    a published type is the schema table's "a type narrowed" and a MAJOR.

packages/cdm/synapse_cdm/MIGRATIONS.md's 2.2.0 section carries the records, unit by unit, and
the rulings the derivation rests on. There is no migration tooling, because there is nothing to
migrate.

Parser safety: a declared depth bound

The parser-safety policy — docs/docs/security/parser-safety.mdx, the page SECURITY.md names as
its home — gains its fifth reading beside the four of the 2.1.0 arc, and the JSON reading of
2026-09-17 in the prose beside them.
libexpat builds a tree of any depth without recursing, and everything the two XML adapters did
with the tree afterwards recursed once per level; on CPython 3.11 json.loads itself recurses
once per container and fails a little under a thousand deep. So the bound sits in front of the
decoder: the base class measures JSON text off its characters in one pass, decoded the way
json.loads would decode it, and a dict or list off its containers, and refuses past the declared
bound before any decoder runs; an XML tree stays the adapter's to measure, because only the
adapter holds it. Sixty-four is an implementation cap and every manifest says so — every CoT
fixture nests three elements deep, the deepest path AEDP-12's class model admits is eight
elements, no shipped JSON document nests more than seven containers, and sixty-four keeps every
walker under two hundred Python frames. Three malformed/ directories gain the payload that
exercises the change, so check H records the refusal on every run.

The harness computes L4

At 2.1.2 the harness's roundtrip column read SKIP for every adapter, because it compared JSON
structurally and every shipped emitter returns bytes, so every L4 in a manifest rested on a
per-adapter test the wheel does not carry — a typed rung, which §3.6's first sentence does not
admit. The column now compares egress octets under a tolerance each adapter declares and the
report prints: bytes, the default, means from_cdm(to_cdm(raw)) must equal
roundtrip_reference(raw) octet for octet; values means what was emitted is re-ingested and no
source value may be missing, with the adapter's declared transforms excused — the tolerance XML
needs, and the one tak and stanag4676 declare. The readings: 16, 11, 20, 17, 17, 41, 28, 16
and 63 byte fixtures octet-exact for adsb, ais, cat021, cat023, cat034, cat048,
cat062, gmti and stanag4609; 6 and 17 parsed twins value-complete for tak and
stanag4676; zero FAIL. Every adapter now computes maturity_eligible: L5 and every adapter
declares less — L3 for the three ingest-only adapters, L4 for the eleven emitters — and
tests/test_cdm_manifests.py derives the rung from a suite run and requires declared ≤ eligible.
A third word, an exemption under bytes, or a declaration on an ingest-only adapter is a
TypeError at import.

Evidence that reproduces elsewhere

A 2.1.2 evidence record carried the runner's absolute fixture directory and its source_commit
with a -dirty suffix, because the gate job wrote the conformance artefact into the checkout root
before the evidence step ran there, so synapse evidence verify from any other checkout reported
DIFFERS on three fields none of which ...

Read more

synapse-cdm 2.1.2

Choose a tag to compare

@github-actions github-actions released this 12 Sep 10:49

synapse-cdm 2.1.2

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 2.1.2
CDM version 2.1.0
SC-OES version 0.1.0
Adapter API version 2.0.0
manifest schema version 1.2.0

Major changes

SOIF Part 1 — Foundation & Assurance, and this is the release that ships it. Part 1 is not a
format and not a semantic layer: it is the machinery that makes a claim about an adapter checkable
by somebody who did not write it. An adapter now describes itself in a published manifest; a
fifteen-check conformance suite runs over any adapter in the roster; an evidence record states what
was measured, on which commit, against which versions, with a digest of every fixture the run read;
and the CDM gains the geometry, time, route, quality, provenance and residual primitives an adapter
needs in order to say what it actually translated. Nothing is removed, renamed or narrowed, so a
2.0.0 consumer keeps working without doing anything.

If you are upgrading from 2.0.0 — which is what the index served until this release — read this
as the MINOR it is.
Everything below is the arc from 2.0.0, because neither 2.1.0 nor 2.1.1 ever
reached anybody.

Why the number is 2.1.2 and not 2.1.0 or 2.1.1

Two tags were cut before this one, both were pushed, neither was published, and both stay where
they are.
They were refused by two different steps of this project's own release pipeline, and
both refusals were the same shape: a step whose behaviour depends on the ref, executed for the
first time on a tag ref.

  • v2.1.0, on commit b69a267, 2026-09-09. The gate job's last step was
    pip-audit --strict over the installed environment; that environment holds the release
    candidate at the tree's own version, --strict turns a distribution the index cannot resolve
    into a failure, and the index cannot carry 2.1.0 until the publish job — which needs the gate
    that just failed. A gate that required the publication it was gating. The repair scopes both
    audits to the release candidate's dependencies, excluding only synapse-cdm itself by name, and
    leaves every third-party line under --strict.
  • v2.1.1, on commit 4409115, 2026-09-10. Step 15 passed — the repair worked — and step 16
    of 17 refused it: the CodeQL gate asked for the code-scanning analyses of ${GITHUB_REF}, which
    on a tag push is refs/tags/v2.1.1, and no workflow in this repository can produce an analysis
    on a tag ref. The commit had two clean analyses on refs/heads/main; the ref filter excluded
    them. The repair makes the gate read the analyses of the commit it is gating, which is what
    the step's own name had promised since it was written.

Neither tag is moved, deleted or recreated: each remains permanently attached to its commit as a
release tag that released nothing, and 2.1.2 is the corrective. PUBLICATION.md's ledger records
what was actually uploaded, and nothing in this file claims an upload that has not happened.

What the arc closed is the class and not the two instances. gates/release_ref_rehearsal.py
replays every ref-dependent release step — the tag guard, the tag-names-the-version condition, the
annotated-tag check, the CodeQL query, the five tag-derived versions and the Release name — against
a named tag and commit while that tag is still local, and it is a mandatory act between tagging and
pushing. Its last check refuses any future use of GITHUB_REF in the release workflow that its own
covered-uses table does not name, so the next ref-dependent step fails on a laptop rather than on a
pushed tag. Its own test now derives the tag it rehearses from PACKAGE_VERSION, so the rehearsal
does not become the next thing a version bump surprises.

Between v2.1.1 and this tag the distribution itself moves by two files — MIGRATIONS.md and
version.py. gates/bump_derivation.py derives PATCH over that arc with nothing unruled, and
2.1.2 is that floor.

Package version 2.1.2 · CDM schema_version 2.1.0. The two numbers are unequal, and that is
the ordinary case and not a signal
: the schema moved on MIGRATIONS.md's table in the CDM round,
for optional primitives only; the package moved on version.py's table for the release; and then
the package moved twice more, two PATCHes the wire contract had no part in. They were level for one
day. synapse_cdm/version.py states the nine version axes and their independence in one place, and
tests/test_cdm_packaging.py sweeps the package for an assignment that would derive either number
from the other. A package at 2.1.2 does not mean SC-OES 2.1: SC_OES_VERSION is a third axis,
still 0.1.0 and still a Draft.

What changed on the wire, and what a 2.0.0 consumer must do

Nothing, and this is the release that says so with a gate rather than a promise. schema_version
moves 2.0.0 -> 2.1.0 and every addition behind it is an optional field or a model reached only
through one, so a 2.0.0 reader still reads a 2.1.0 object and a 2.0.0 object still validates against
the 2.1.0 models. The fourteen worked examples under spec/sc-oes/ are the witness: they still
declare schema_version 2.0.0 and they still validate.

What a producer gains is vocabulary, not obligation:

  • Geometry. synapse_cdm.geo carries Point, LineString, Polygon and their multi- forms,
    plus BoundingBox, VerticalPosition and VerticalExtent. A vertical position states its unit
    and its datum, because an altitude without a datum is a number and not a position.
  • Time. TemporalValidity and Period — when an assertion is held to be true, as distinct
    from when it was made.
  • Route and area. Route, RouteLeg, Waypoint, Area.
  • Quality and provenance. Quality, SourceHash, OperationalStatus, and seven added fields
    on SourceRef so that a CDM object can say which bytes it came from.
  • Residual data. Residual and lossless.classify(), which partitions every source leaf into
    six categories and lets an adapter carry what the CDM has no field for instead of dropping it
    silently.

packages/cdm/synapse_cdm/MIGRATIONS.md's 2.1.0 section carries the migration statement and the
derivation, entry by entry, and its 2.1.2 section carries this release's own record. There is no migration tooling, because there is nothing to migrate.

Adapter API v2, and every adapter now describes itself

ADAPTER_API_VERSION is 2.0.0 — the contract an adapter class is written against, additive over
v1 and renaming nothing. v2 adds four members: metadata, detect, validate_source and
capabilities. ARCHITECTURE.md §1 freezes it.

The visible half is the manifest. All fourteen adapters ship one under manifests/, validated
against schemas/manifests/adapter-manifest.schema.json at MANIFEST_SCHEMA_VERSION 1.2.0, and
python -m synapse_cdm.manifests --check reports CURRENT: manifests vs 14 shipped adapters at manifest schema 1.2.0. A manifest states the adapter's direction, its declared limits and where
each limit's number came from, its known limitations as structured records rather than sentences,
and what it does not support — so "this adapter handles that format" becomes a document a third
party can read without reading the code.

The Synapse Conformance Suite

python -m synapse_cdm.suite, also installed as synapse, runs fifteen checks, A through O,
over any adapter in the roster: identity, determinism, malformed input, parser robustness, resource
limits, streaming, temporal handling and the rest. Results come out as --format json and are
byte-identical across two sweeps of one tree, which is what makes them evidence rather than output.

SC-OES conformance is a separate and smaller thing and it is unchanged: python -m synapse_cdm.conformance, also cdm-conformance, reports five separately named dimensions with
PASS/FAIL/SKIP each, no aggregate score, and four exit codes a CI system can branch on. The
PNT Profile 0.1.0 remains the only profile with an executable rule of its own; against the
other six, dimension D is SKIP, which is a different fact from a failure and a different fact
again from a profile that does not exist. This work still creates no certification programme.

Evidence records

EVIDENCE_SCHEMA_VERSION 1.0.0, published as schemas/evidence/evidence.schema.json. synapse evidence generate --adapter X | --all writes one record per adapter: the manifest embedded whole,
the commit it was measured on, five version axes, the conformance report verbatim, the loss report,
and a SHA-256 of every fixture file the run read. synapse evidence verify <file> generates a NEW
record from the tree in front of it and compares field by field, masking only what is a measurement
of the run rather than of the tree — so reproducibility is a command and not an assertion. synapse badges derives shields.io endpoint files from those records and refuses to write one without a
record behind it.

The records are not in this distribution and not in the repository. They are produced by CI on
every run, uploaded, and attached to a release; each adapter's manifest declares
evidence.available: false until the release they are attached to exists. Thirty-nine
PROVENANCE.json records — one in every fixture directory a tracked test reads — say where the
fixture data came from.

Security, dependencies and the supply chain

  • SECURITY.md: the reporting path, and a parser-safety policy with declared limits on all
    fourteen adapters.
  • Secret scanning on the platform, .gitleaks.toml in the tree, an...
Read more

synapse-cdm 2.0.0 — SC-OES ships, and the wire contract moves with it

Choose a tag to compare

@decentcybersecurity decentcybersecurity released this 07 Sep 12:03

A major release, and what it adds is a semantic layer over the model this package has always carried. SC-OES — the SynapseCommand Operational Event Specification, v0.1.0 Draft — attaches operational-event semantics to a CDM object after source-format translation: what kind of assertion an event is, which governed semantic type it claims, what it relates to and with which role, and how sure its source was. It is a wire-semantic contract, not a new format and not a replacement for one.

Package version 2.0.0 · CDM schema_version 2.0.0. If you consume CDM objects this is a breaking change. The two numbers being equal is a coincidence of two independently justified major changes and not a derivation, and synapse_cdm/version.py states the six version axes and their independence in one place. A package at 2.0.0 does not mean SC-OES 2.0: SC_OES_VERSION is 0.1.0 and it is a Draft.

What a 1.x consumer must do. Two optional keys are what makes this a major: Event.oes, the SC-OES block, null unless the producer made an assertion; and Entity.ontology_types, a list of governed ontology identifiers, empty unless one was asserted. Both default to nothing, so legacy data is structurally representable without change — and that is not compatibility. The canonical objects are extra="forbid" and the published schemas are additionalProperties: false, so a 1.x strict reader meeting either key rejects the object rather than ignoring it; version.compatible("2.0.0", "1.0.0") is False, and that refusal is the message this major exists to carry. There is no migration tooling and none was written: packages/cdm/synapse_cdm/MIGRATIONS.md's 2.0.0 section carries the migration statements instead, because nothing was removed, renamed or narrowed.

What ships beside the two keys. The specification at spec/sc-oes/, sixteen documents plus a README; the SynapseCommand Operational Ontology, whose Turtle is the authority and whose JSON-LD context and packaged term registry are generated from it and drift-tested against it, with nothing at runtime parsing RDF; three packaged registries under synapse_cdm/registry/sc_oes/event_types.json, ontology_terms.json and profiles.json — which load through importlib.resources and need no checkout and no network; offline conformance tooling (python -m synapse_cdm.conformance, installed as cdm-conformance) reporting five separately named dimensions with no aggregate score and four exit codes; the pntmap adapter as a reference producer; fourteen worked examples, thirteen individual and one linked operational chain; and seven profile documents.

Dimension D is executable for exactly one profile. The PNT Profile 0.1.0 is the first profile with a conformance rule of its own; the other six are specification-only and dimension D against them is SKIP — a known profile with no executable rules, which is a different fact from a profile name that does not exist and a different fact again from an object that failed. A PASS drawn from an empty rule set would be a claim manufactured out of the absence of anything to check. The permitted claim names one assessed object and is not a certification: this work creates no certification programme.

The full notes are RELEASE_NOTES.md at this tag.

Derived from the tree at the tag, not remembered

  • The number is a person's over the gate's floor, and the gate says so itself. gates/bump_derivation.py on this tree reports declared 2.0.0 / declared_kind MAJOR / derived_kind MINOR, with the version rule MAJOR ruled for 1.8.0 → 2.0.0. It derives a MINOR floor from 697 signals across 558 distribution files — every file the arc moved carries at least one — because every signal it can prove is an addition and no importable name is removed. What decides the number is what the diff cannot reach: a third party's consumer written against 1.8.0 does not work against this distribution. docs/adr/0005-cdm-schema-version-impact.md argues it, and MIGRATIONS.md's 2.0.0 section carries the ruling. Ten units in the arc carry a person's ruling — seven MINOR, three PATCH — and pending.unruled is [], which is the pre-step the release procedure requires before a version number is typed.
  • Fourteen adapters, harness-verified: adsb, ais, cat021, cat023, cat034, cat048, cat062, gmti, stanag4609, stanag4676, tak (bidirectional); legion, pntmap, stanag4586 (ingest). 538 fixture verdicts, 0 failed; the workflow's gate ran them in both schema modes — harness PASS 14 adapters x 2 schema modes, 1076 fixture verdicts, 0 failed. The roster did not move this arc.
  • Six schemas, CURRENT at 2.0.0: cdm_object, entity, event, payload_gnss_interference, plan_object, track. python -m synapse_cdm.schemas --check --out schemas reports CURRENT: schemas vs models at 2.0.0, and the workflow's gate regenerated all six from outside the repository byte-identical.
  • Thirty pinned specification documents, pin_paths reading 30 present, 30 matched, 30 copies, 0 failedthe set 1.8.0 shipped, unmoved: git diff --name-only v1.8.0..v2.0.0 -- '*_pin.json' is empty. The parks table is empty for the second release runninggates/parks_table.py reads 13 rows — 0 open [], 13 closed [1…13], 0 set-claims, 0 failed.
  • The suite at the tag, as the runner saw it: 4429 passed, 78 skipped (condition 1, run 34117343838). A CI green is not a maintainer's green — the pinned specification documents are gitignored, so the clone skips the tests that read them; the skip list is in the step's log, printed with -rs.

Artefacts

Built once by run 34117343838, gated as that build, and uploaded as those same bytes over PyPI Trusted Publishing (OIDC, no API token) after the pypi environment's required reviewer approved.

4f0714f0015bec6309954016f7041b63c06b36539371f4495a4cfd2633d3c2e5  synapse_cdm-2.0.0-py3-none-any.whl
ab86ff396eda58d9d5c73a718f6bfd49b89001f7555fdb40bb7f16a9cc2ab8c5  synapse_cdm-2.0.0.tar.gz

PUBLICATION.md ledger entry 18 records the readings of each digest and the trusted-publisher values PyPI states for the attestations.

pip install synapse-cdm==2.0.0
python -m synapse_cdm.harness --list-adapters
python -m synapse_cdm.conformance --help

synapse-cdm 1.8.0 — MISB ST 0806.4's RVT Local Set on item 73, and an empty parks table

Choose a tag to compare

@decentcybersecurity decentcybersecurity released this 06 Sep 09:52

A minor release, and what it adds is one item and one document. MISB ST 0601 item 73 — the RVT Local Set — is decoded and carried, so a stanag4609 consumer whose packets nest a MISB ST 0806.4 set now receives it instead of an unread run of octets. And the MISP-2019.1 Motion Imagery Handbook, the last document this profile delegates to that was not on disk, is held and pinned: the parks table is empty at this release — thirteen rows, none of them open — the first time this package has shipped with nothing waiting on an acquisition.

Package version 1.8.0 · CDM schema_version 1.0.0. No schema moved: git diff v1.7.0..HEAD -- schemas/ returns nothing, which is the check that decided SCHEMA_VERSION stays where it is rather than an assumption that it would. Everything new reaches a consumer inside Entity.attributes, which the published entity schema declares additionalProperties: true.

If you ingest STANAG 4609 / MISB KLV, read the notes' first section. Nothing is removed and no key changes shape. A packet that carries no item 73 yields exactly the object 1.7.0 yielded, byte for byte; a packet that carries one yields the same object with four more attributes keys on it — rvt_local_set, rvt_basis, rvt_mapping_not_taken, rvt_embedded_set_policy — and a matching rvt key on the parsed twin. Eight elements that have a CDM home are deliberately not mapped into one and ride in attributes as ST 0806.4 names them; emitting a POI as a second Entity or an AOI as a geometry is a modelling decision no clause of either document makes, so it is written down as a proposal and not taken.

Park 10 closed on a reading rather than on code: the Handbook is ruled a companion on its own Scope page — "The MISP succinctly states requirements, while the Motion Imagery Handbook discusses principles underlying requirements more thoroughly" — 124 pages carrying one shall and naming no Common Metadata System, so no row of FORMAT_COVERAGE.md moved on its account.

The full notes are RELEASE_NOTES.md at this tag. The number is the gate's: gates/bump_derivation.py classifies the arc since v1.7.0 as MINOR with the floor at 1.8.0, derived from 100 signals across 37 distribution files, and the twelve units in the arc that carry a person's ruling are ruled in MIGRATIONS.md's 1.8.0 section — which is what pending.unruled == [] before a number was typed means.

Derived from the tree at the tag, not remembered

  • Fourteen adapters, harness-verified: adsb, ais, cat021, cat023, cat034, cat048, cat062, gmti, stanag4609, stanag4676, tak (bidirectional); legion, pntmap, stanag4586 (ingest). 538 fixture verdicts, 0 failed; the workflow's gate ran them in both schema modes — harness PASS 14 adapters x 2 schema modes, 1076 fixture verdicts, 0 failed.
  • Six schemas, CURRENT at 1.0.0: cdm_object, entity, event, payload_gnss_interference, plan_object, track.
  • Thirty pinned specification documents, pin_paths reading 30 present, 30 matched, 30 copies, 0 failed — three more than 1.7.0 shipped: MISB ST 0806.4 and both editions of the Motion Imagery Handbook.
  • The suite at the tag, as the runner saw it: 3671 passed, 78 skipped (condition 1, run 34024813207). A CI green is not a maintainer's green — the pinned specification documents are gitignored, so the clone skips the tests that read them; the skip list is in the step's log, printed with -rs.

Artefacts

Built once by run 34024813207, gated as that build, and uploaded as those same bytes over PyPI Trusted Publishing (OIDC, no API token) after the pypi environment's required reviewer approved.

527789dedc6f8ada07f1989b6e8603a2caf4c83b3ffb1c32d3cbda2e9a77dd91  synapse_cdm-1.8.0-py3-none-any.whl
ba4599a8e1ea155efdf2c523f6b7416b236ccb361c56c356d18e31564a35d2b7  synapse_cdm-1.8.0.tar.gz

PUBLICATION.md ledger entry 17 records the six readings of each digest and the trusted-publisher values PyPI states for the attestations.

pip install synapse-cdm==1.8.0
python -m synapse_cdm.harness --list-adapters

synapse-cdm 1.7.0

Choose a tag to compare

@decentcybersecurity decentcybersecurity released this 05 Sep 22:25

A minor release, and what it adds is one thing said three ways: the stanag4609 adapter now emits objects about something other than the platform that sent the packet. MISB ST 0601 item 74 becomes DETECTION events and Track objects; item 94 becomes entries in Entity.source_ids that name the sensor and the platform as devices rather than as a packet; and every object carries a per-packet reading of MISB ST 0902.8's minimum metadata set. Three parks closed for it — 6, 11 and 12 — and the adapter roster did not move.

Package version 1.7.0 · CDM schema_version 1.0.0. No schema moved: git diff v1.6.0..HEAD -- schemas/ returns nothing, which is the check that decided SCHEMA_VERSION stays where it is rather than an assumption that it would. Everything new reaches a consumer either in a field the models already declare (source_ids, and Track and Event themselves) or inside Entity.attributes, which the published entity schema declares additionalProperties: true.

If you ingest STANAG 4609 / MISB KLV, read the notes' first section. Nothing is removed and no key changes shape, but a payload that used to yield one Entity and one Event can now yield several objects, and code that assumes one packet is one pair will see more than it expects. A track is keyed on VTracker LS Tag 1, the 128-bit UUID ST 0903.4 defines, and never on the VTarget Pack's Target ID Number.

The full notes are RELEASE_NOTES.md at this tag. The number is the gate's: gates/bump_derivation.py classifies the arc since v1.6.0 as MINOR with the floor at 1.7.0, and the twelve units in the arc that carry a person's ruling are ruled in MIGRATIONS.md's 1.7.0 section — none of the twelve by the release round itself, which is what pending.unruled == [] before a number was typed means.

Derived from the tree at the tag, not remembered

  • Fourteen adapters, harness-verified: adsb, ais, cat021, cat023, cat034, cat048, cat062, gmti, stanag4609, stanag4676, tak (bidirectional); legion, pntmap, stanag4586 (ingest). 524 fixture verdicts, 0 failed; the workflow's gate ran them in both schema modes — harness PASS 14 adapters x 2 schema modes, 1048 fixture verdicts, 0 failed.
  • Six schemas, CURRENT at 1.0.0: cdm_object, entity, event, payload_gnss_interference, plan_object, track.
  • The suite at the tag, as the runner saw it: 3645 passed, 75 skipped (condition 1, run 33994319036). A CI green is not a maintainer's green — the pinned specification documents are gitignored, so the clone skips the tests that read them; the skip list is in the step's log, printed with -rs.

Artefacts

Built once by run 33994319036, gated as that build, and uploaded as those same bytes over PyPI Trusted Publishing (OIDC, no API token) after the pypi environment's required reviewer approved.

aea8852f1353c4ef073670588ba4e2064d8202fb753502f702cc16b76bfae250  synapse_cdm-1.7.0-py3-none-any.whl
1f717b61223f9506f859b8581c2e4f597af1cdc5c4830c7033f655c1b92377d5  synapse_cdm-1.7.0.tar.gz

PUBLICATION.md ledger entry 16 records the six readings of each digest and the trusted-publisher values PyPI states for the attestations.

pip install synapse-cdm==1.7.0
python -m synapse_cdm.harness --list-adapters

synapse-cdm 1.6.0

Choose a tag to compare

@decentcybersecurity decentcybersecurity released this 05 Sep 11:11

A minor release, and the whole of it is the stanag4609 adapter reading more of the document it was already reading: eighteen ST 0601.14a items are promoted on the document's own printed worked examples where 1.5.0 promoted only what one pinned stream attested, the time scale is named as MISB ST 0603.5 names it, Position.alt_m is filled from the two ellipsoid-height items and never from mean sea level, and Kinematics.course_deg is filled at all.

Package version 1.6.0 · CDM schema_version 1.0.0. No schema moved: the diff over schemas/ since v1.5.0 is empty. Everything new reaches a consumer either in a field the models already declare (alt_m, course_deg) or inside Entity.attributes, which the published entity schema declares additionalProperties: true.

If you ingest STANAG 4609 / MISB KLV, read the notes' first section. attributes.time_basis lost its timescale key and gained eight; Event.observed_at and Entity.valid_from apply items 136 and 137 when a packet carries them and are otherwise byte-equal on every pre-existing golden; alt_m is filled from tag 104 or 75 (HAE) and never tag 15 (MSL); course_deg is filled from tag 112; fourteen IMAPB items and the Wavelengths List pack ride in attributes under the document's names; parks 5 and 3 closed and ST 0603.5 is pinned.

The full notes are RELEASE_NOTES.md at this tag. The number is the gate's: gates/bump_derivation.py classifies the arc since v1.5.0 as MINOR with the floor at 1.6.0, and the fifteen units it refused to classify are ruled in MIGRATIONS.md's 1.6.0 section — five MINOR and ten PATCH by the gate's own parse.

Derived from the tree at the tag, not remembered

  • Fourteen adapters, harness-verified: adsb, ais, cat021, cat023, cat034, cat048, cat062, gmti, stanag4609, stanag4676, tak (bidirectional); legion, pntmap, stanag4586 (ingest). 496 fixture verdicts, 0 failed; the workflow's gate ran them in both schema modes — harness PASS 14 adapters x 2 schema modes, 992 fixture verdicts, 0 failed.
  • Six schemas, CURRENT at 1.0.0: cdm_object, entity, event, payload_gnss_interference, plan_object, track.
  • The suite at the tag, as the runner saw it: 3533 passed, 73 skipped (condition 1, run 33961018594). A CI green is not a maintainer's green — the pinned specification documents are gitignored, so the clone skips the tests that read them; the skip list is in the step's log, printed with -rs.

Artefacts

Built once by run 33961018594, gated as that build, and uploaded as those same bytes over PyPI Trusted Publishing (OIDC, no API token) after the pypi environment's required reviewer approved.

7e6e87d20ce2e9919e0cc6861c45c1025af952f1199bf917b348c0d66d3364ee  synapse_cdm-1.6.0-py3-none-any.whl
825dbfda66505491e0b5181017672143d1654622fad3078a356a0b01a4ffc40e  synapse_cdm-1.6.0.tar.gz

PUBLICATION.md ledger entry 15 records the six readings of each digest and the trusted-publisher values PyPI states for the attestations.

pip install synapse-cdm==1.6.0
python -m synapse_cdm.harness --list-adapters

v1.5.0

Choose a tag to compare

@decentcybersecurity decentcybersecurity released this 04 Sep 17:44

A minor release, and the whole of it is one capability: the stanag4609 adapter now reads the
MISB ST 0102.12 Security Metadata Local Set nested under ST 0601 item 48, and says on every
object it emits what basis it had for the marking it carries — or for carrying none.

Package version 1.5.0 · CDM schema_version 1.0.0. No schema moved: no field was added,
removed or retyped, and git diff v1.4.1..HEAD -- schemas/ returns nothing, which is the check
that decided SCHEMA_VERSION stays where it is rather than an assumption that it would.

What a stanag4609 Entity now carries

Two keys, under attributes.

security_metadata — present only when the packet carried ST 0601 item 48. It holds the
decoded ST 0102.12 local set: all seventeen elements of §6.7's Table 2 are read — tags 1–14,
22, 23 and 24, of which six are Required, eight are Context and three are Optional. Each element
carries its decoded value together with its octets, its stated length, its presence class and the
clause that governs it. A malformed element is refused with its octets parked while the other
sixteen decode
.

security_metadata_basis — present on every object, marked or not. Its state is a token
from a closed set: UNLABELLED (no item 48), PARTIAL (a security set was present and not all
six Required elements decoded), COMPLETE-ON-REQUIRED (a security set was present and every
Required element decoded). Beside it the record carries the carrier and its clauses, the pinned
copy the element layer was read from by SHA-256, the clause pointers that govern this case, the
required tags present and absent, any advisories and refusals, and one pointer to the argument.

No marking is ever defaulted. confidentiality_ruling reads CARRIED AND NEVER INVENTED: a
security_classification outside §6.7's five listed values is carried with no label and an
advisory names the clause; a packet with no item 48 emits no security_metadata key at all,
because §6.5 says "the absence of Security Metadata does not signify Motion Imagery Data as
Unclassified"
; and an element that cannot be decoded is refused, never guessed.

Tag 13's UTF-16 byte order is composed from three documents — RFC 2781 §4.3 for the BOM rule,
MISB ST 0107.3's ST 0107.2-02 for the no-BOM baseline, and ST 0102.12 §6.1.13 for
everything else about the element — because ST 0102.12 states no byte order anywhere in its own
voice.

Why this is a MINOR, and the gate derived it rather than being told

gates/bump_derivation.py classifies the diff over the distribution's own contents between
v1.4.1 and this tree against version.py's PACKAGE_VERSION table. It reports MINOR over
173 signals across 92 distribution files, and the floor is 1.5.0.
adapters/klv_security_codec.py is a new importable module and fixtures/klv/ gains seven
payloads that extend a fixture set — both MINOR rows. Eight units the table could not decide
carry Bump rulings
in MIGRATIONS.md's 1.5.0 section, four MINOR and four PATCH, and the gate
reads them back and refuses one that outlives its case.

The first text pin

IETF RFC 2781, UTF-16, an encoding of ISO 10646 (February 2000), is pinned at
fixtures/klv/spec/rfc2781.txtthe first document this repository pins that is not a PDF.
The RFC Editor issues no PDF for it. It is a held document and not a delegation, so the delegated
tally is unchanged at fourteen in scope and nine held, and like every pinned specification it
is gitignored and not redistributed.

Derived off the tagged tree (release condition 4)

Fourteen adapters, from --list-adapters in the run summary: adsb, ais, cat021,
cat023, cat034, cat048, cat062, gmti, legion, pntmap, stanag4586, stanag4609,
stanag4676, tak458 fixture verdicts, 0 failed. The whole of the increase over 1.4.1 is
stanag4609's, which moves from twenty to forty-six.

Six schemas, regenerating byte-identical from the models: cdm_object, entity, event,
payload_gnss_interference, plan_object, track.

Suite at the tag, on the runner: 3468 passed, 72 skipped. A CI green is not a maintainer's —
the pinned specification documents are gitignored, so a fresh clone skips the tests that read
them, and the skip list is printed with -rs in the "Condition 1" step.

Artefacts

Built once by run 33888828645,
gated as that build, and uploaded as those same files through PyPI Trusted Publishing over OIDC
with no token anywhere in the workflow.

23fd8cf8ea2545bf1e53d6bef1adb0dfb0a80de10650663ea2d4655fe205ef85  synapse_cdm-1.5.0-py3-none-any.whl
54916e8d0bc24ca18e24cdebd12b75de23a0a694a176d1f3816c576a97103059  synapse_cdm-1.5.0.tar.gz

4 526 344 bytes and 2 398 792 bytes. PUBLICATION.md ledger entry 14 records these digests read
back from six independent places, together with both runs the v1.5.0 tag produced.

pip install synapse-cdm==1.5.0
python -m synapse_cdm.harness --list-adapters

For what 1.4.1 was — one KLV framing refusal changing its exception class — see the 1.4.1 release.

v1.4.1

Choose a tag to compare

@decentcybersecurity decentcybersecurity released this 04 Sep 07:51

A patch release. One refusal changes its exception class, two messages change what they cite, and
no importable name is added, removed or retyped.

Package version 1.4.1 · CDM schema_version 1.0.0. No schema moved and the diff over
schemas/ since 1.4.0 is empty, which is the check that decided SCHEMA_VERSION stays where it is
rather than an assumption that it would.

The one change a caller can see

klv_codec.decode_ber_length now raises KLVFramingError for a BER length whose first octet is
0x80, where it raised UnderivableFromPinnedCopy. KLVFramingError is a ValueError and
UnderivableFromPinnedCopy is a NotImplementedError, so they share no base but Exception:
a caller catching UnderivableFromPinnedCopy to handle indefinite lengths must catch
KLVFramingError instead.
Nothing else about the function moved — the same inputs are accepted
and every length it decodes decodes to the same value.

SMPTE ST 336:2017 §5.3 states what the octet means, no held MISB document defines the alternative
end-finding method the standard's condition requires, so the bytes are wrong and the decoder now
says so. Note the scope: ST 336 permits 0x80 — the refusal is the MISB profile's.

The long-form ceiling message now cites ST 336:2017 §5.3 NOTE 1 and ISO/IEC 8825-1 §8.1.3.5(c);
BER_LENGTH_OF_LENGTH_MAX is unmoved at 127 and that tighter bound of 126 is recorded and
deliberately not enforced, because X.690 is not held and the text sits in an informative annex.

Park 8 — SMPTE ST 336 — closed on both editions, obtained free from the publisher's own library.
Register entries KLV 11 and KLV 13 closed with it.

Why this is a PATCH

gates/bump_derivation.py classifies the diff over the distribution between v1.4.0 and this tree
and reports PATCH over 14 signals. Two units the table cannot decide carry Bump rulings in
MIGRATIONS.md's 1.4.1 section — decode_ber_length and _CEILING_RESIDUE, both PATCH — and the
gate reads them back and refuses one that outlives its case. The number is derived, not chosen.

Derived off the tagged tree (release condition 4)

Fourteen adapters, from --list-adapters in the run summary: adsb, ais, cat021, cat023,
cat034, cat048, cat062, gmti, legion, pntmap, stanag4586, stanag4609, stanag4676,
tak432 fixture verdicts, 0 failed, unchanged from 1.4.0 because this release adds no
fixture and removes none.

Six schemas, regenerating byte-identical from the models: cdm_object, entity, event,
payload_gnss_interference, plan_object, track.

Suite at the tag, on the runner: 3403 passed, 69 skipped. A CI green is not a maintainer's — the
pinned specification PDFs are gitignored, so a fresh clone skips the tests that read them, and the
skip list is printed with -rs in the "Condition 1" step.

Artefacts

Built once by run 33847019240,
gated as that build, and uploaded as those same files through PyPI Trusted Publishing over OIDC with
no token anywhere in the workflow.

1d0b021f61fd089852ce2be3e5928853542e54a69d89e00d831b958e3e0d75a4  synapse_cdm-1.4.1-py3-none-any.whl
09ca1652c3b03f6134de7e39dd7c9c1499e015457c77f87405a76ebd6f494344  synapse_cdm-1.4.1.tar.gz

4 152 919 bytes and 2 254 352 bytes. PUBLICATION.md ledger entry 13 records these digests read
back from six independent places, together with the run that produced them.

pip install synapse-cdm==1.4.1

For what 1.4.0 was — STANAG 4586 telemetry ingest — see the 1.4.0 release.

v1.4.0

Choose a tag to compare

@decentcybersecurity decentcybersecurity released this 30 Aug 17:22

A MINOR release: STANAG 4586 telemetry ingest — one new adapter, its codec and its fixture set. No wire contract moved.

Artefacts (workflow build digests — the comparison basis):

  • synapse_cdm-1.4.0-py3-none-any.whl — sha256 006e5f0e8b8557d91c7cf90da1e5a6fd0341d8f398bab6617a1802e4ac1dd9f3
  • synapse_cdm-1.4.0.tar.gz — sha256 3f16e818d92af4a69721c248110eab16e9dbf8f75fd9bf9201981e09f97635e2

14 adapters registered. stanag4586 is the fourteenth shipped and #15 by ordinal — the ordinal table numbers specifications as well as adapters, and #9 (stanag5527) is a row set with no adapter, so a roster of fourteen occupies fifteen ordinals. Ingest-only: legion, pntmap, stanag4586; the other eleven bidirectional. 6 schemas, SCHEMA_VERSION 1.0.0 unmoved — the diff over schemas/ since v1.3.0 is empty. gates/bump_derivation.py classified this bump MINOR over 46 signals: the number was derived from the packaged diff, not chosen.

The adapter is built on STANAG 4586 Edition 3, which is not the current edition — Edition 4 could not be obtained, so the adapter declares the edition it actually read. The document defines 166 field-table messages in 27 functional groups; 48 of them, across 9 groups, are command uplink and out of scope by an enumerated ruling, 4 are decoded field by field, and every other message has its wrapper read and its data octets parked verbatim with its type recorded.

Suite at the tag: 3467 total, CI 3400 passed / 67 skipped. A CI green is not a maintainer's green — the pinned specification PDFs are gitignored, so a clone carries the pin records and not the documents and skips the tests that read them.

Built and gated in run 33307299409, published to PyPI over OIDC with attestations, deployment operator-approved 2026-08-30T17:18:53Z. Served-equals-built verified across six independent readings: the gate's --export-dist, the handover artefact (0d77928a… uploaded and downloaded), a local hash of that artefact, the publish job's pre-upload hashes, the in-toto DSSE subject digests, and the bytes PyPI now serves.