Skip to main content

PlanObject

Source fileschemas/plan_object.schema.json
$idhttps://synapsecommand.local/cdm/1.0.0/plan_object.schema.json
CDM schema version1.0.0
SHA-256 of source154bc7250bb0adfb7e1abde0ca0d9039b0cc13491d9bec7de4ec283d07303bb6

What we push OUT: a drawing a commander's plan puts on someone else's map.

Geometry is REQUIRED here, unlike on Event. An overlay with no geometry cannot be drawn, so an egress adapter would have to either invent a location or silently drop the object — and a COA sketch that quietly fails to appear on the TAK client is the worst of the three outcomes, because everyone assumes it arrived.

Fields

FieldTypeRequiredDescription
expires_atstring | nullnoWhen the drawing should disappear. None = until explicitly removed — which for a stale COA sketch on a live map is a decision, so state it. Default null. (pattern ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z$)
geometryPoint | LineString | PolygonyesGeoJSON, WGS84, [lon, lat] order. Required.
integrityIntegrity | nullnoPQC signature block — designed, not yet populated. Default null.
labelstring | nullnoWhat a client shows next to the drawing. None = unlabelled; never an empty string, which renders as a blank callout. Default null. (min length 1)
object_idstring (uuid)yes
object_kind"plan_object"no
object_typeObjectTypeyes
schema_versionstringnoSemver of the CDM this object was written against. Default "1.0.0".
sourceSourceRefyesWhich adapter produced this object. Required on every kind.
source_idsarray<SourceId>yesEvery external identifier this object is known by. At least one, on EVERY kind — see the class docstring. (min items 1)
styleobjectnoRendering HINTS, not requirements — stroke, fill, opacity, dash. A receiving client is free to ignore them, so nothing that changes MEANING may live here (an affiliation belongs on the entity, not in a colour).

:::info additionalProperties: false Unknown keys are rejected. That is safe only because the CDM pairs strictness with a declared escape hatch — Entity.attributes and Event.payload accept anything — so an adapter never has to choose between dropping a field and failing validation. :::

Referenced definitions

Every $ref on this page resolves to one of these, inlined here so the page is a complete reference and not a starting point for chasing pointers.

Integrity

DESIGNED, NOT IMPLEMENTED — the field the PQC signature will occupy.

No crypto happens in this package (tests/test_cdm_boundary.py asserts the package imports no crypto module). The field exists from day one so that turning signing on is a value change rather than a schema change: a schema change would be a MAJOR bump rippling through every store and every consumer, and would arrive exactly when the signing work is already late.

algorithm is a free string rather than an enum, naming what the platform's ledger already uses — ML-DSA-87 for entry signatures, SLH-DSA for checkpoints. Free, because the algorithm that replaces those is not knowable now, and an enum would make the migration a MAJOR bump for a value nobody reasons over programmatically.

All three fields or none. A block holding a signature with no algorithm is unverifiable, and an unverifiable signature that LOOKS present is worse than an absent one: it reads as assurance to everything downstream that does not check.

FieldTypeRequiredDescription
algorithmstringyese.g. ML-DSA-87, SLH-DSA-SHAKE-256s. (min length 1)
chain_hashstringyesHash binding this object to the chain. (min length 1)
signaturestringyes(min length 1)

additionalProperties: false — unknown keys are rejected. Source-specific fields belong in the declared extension bags (Entity.attributes, Event.payload).

LineString

FieldTypeRequiredDescription
coordinatesarray<array<number>>yes(min items 2)
type"LineString"no

additionalProperties: false — unknown keys are rejected. Source-specific fields belong in the declared extension bags (Entity.attributes, Event.payload).

ObjectType

What we push OUT — the egress direction, e.g. to TAK as a drawing object.

Closed vocabulary — a value outside this list is invalid, and UNKNOWN is a

member rather than a null wherever the enum has one.

Value
COA_SKETCH
ROUTE
CONTROL_MEASURE
ANNOTATION

Point

FieldTypeRequiredDescription
coordinatesarray<number>yes
type"Point"no

additionalProperties: false — unknown keys are rejected. Source-specific fields belong in the declared extension bags (Entity.attributes, Event.payload).

Polygon

FieldTypeRequiredDescription
coordinatesarray<array<array<number>>>yes(min items 1)
type"Polygon"no

additionalProperties: false — unknown keys are rejected. Source-specific fields belong in the declared extension bags (Entity.attributes, Event.payload).

SourceId

One external identifier for an object — the provenance mapping.

A list of these, not one, because the same object arrives from several systems: the same vessel is an MMSI to AIS, a track number to STANAG 4676 and a UID to TAK. Fusion joins them later; the adapter's job is to record which name its own system used, and never to overwrite another system's entry.

FieldTypeRequiredDescription
external_idstringyesThat system's own identifier. (min length 1)
systemstringyesThe external system, e.g. PNTMAP, TAK. (min length 1)

additionalProperties: false — unknown keys are rejected. Source-specific fields belong in the declared extension bags (Entity.attributes, Event.payload).

SourceRef

Which adapter produced this object, from which system, and whether it is real.

synthetic is required and has no default. Every fixture in this repository is synthetic and every scenario package is too (TR-12), and the platform keeps the synthetic and live layers apart over one interface — so an object that does not say which layer it belongs to cannot be filed. A default of false would silently promote exercise data to operational data, which is the dangerous direction; a default of true would silently demote live data and hide it from an operator. There is no safe default, so there is no default.

FieldTypeRequiredDescription
adapterstringyesAdapter name, e.g. pntmap. (min length 1)
adapter_versionstringyesAdapter semver. (min length 1)
syntheticbooleanyestrue for anything not from a real source (TR-12).
systemstringyesThe external system this came from. (min length 1)

additionalProperties: false — unknown keys are rejected. Source-specific fields belong in the declared extension bags (Entity.attributes, Event.payload).