CAL & Adapters
LOE 3 — Critical Abstraction Layer, protocol adapters, canonical data model, normalization, and sync
The Critical Abstraction Layer (CAL) normalizes all operational data sources into a stable canonical model. Protocol adapters translate source-specific formats (CoT XML, GeoJSON, KML, NOTAM, UDL) into typed canonical entities.
Architecture
External Sources (CoT, KML, NOTAM, UDL …)
│
▼
[Protocol Adapters] ←── adapters/
│ Raw → Canonical translation
▼
[Normalization Pipeline] ←── cal/normalization/
│ Provenance tagging, confidence scoring
▼
[Validation] ←── cal/validation/
│ Schema enforcement, timeliness checks
▼
[Sync/Cache] ←── cal/sync/
│ Local-first cache, delta sync, TTL eviction
▼
[Event Bus] ←── engine/core/event_bus.py
Adapter Framework
Base Adapter — adapters/base/base_adapter.py
All adapters extend BaseAdapter, which provides:
| Feature | Description |
|---|---|
| Health tracking | Automatic ingestion count, error count, last timestamp |
| Contract enforcement | Abstract methods: ingest(), validate(), schema() |
| Metrics | _record_ingestion_success(), _record_ingestion_error() |
Required Implementation:
class MyAdapter(BaseAdapter):
adapter_id = "my-adapter"
supported_formats = ["my-format"]
def ingest(self, raw: Any) -> list[Any]:
# Parse raw data → list of canonical entities
...
def validate(self, raw: Any) -> ValidationResult:
# Validate raw data structure → ValidationResult(valid, errors)
...
def schema(self) -> dict:
# Return JSON Schema describing expected input format
...
Protocol Adapters
CoT Adapter — adapters/cot/cot_adapter.py
Cursor on Target (CoT) is the primary tactical data format for military situational awareness.
| Property | Value |
|---|---|
adapter_id |
"cot" |
supported_formats |
["cot", "cot-xml"] |
| Status | ✅ Active — 186 lines |
Ingestion Logic:
- Parse XML input; validate root element is
<event> - Verify required attributes:
version,uid,type,time,start,stale - Extract
<point>child element withlat,lon,hae(altitude) - Map CoT type prefix to track type:
| CoT Type Prefix | Track Type |
|---|---|
a-f |
FRIENDLY |
a-h |
HOSTILE |
a-n |
NEUTRAL |
a-u |
UNKNOWN |
- Extract optional callsign from
<detail>/<contact>element - Build canonical Track entity with full metadata and provenance
Validation: Reports specific errors — wrong root element, missing point, missing required attributes, malformed XML.
GeoJSON Adapter — examples/sample-adapter/adapter.py
GeoJSON FeatureCollection adapter serves as both the reference implementation and active adapter.
| Property | Value |
|---|---|
adapter_id |
"sample-geojson" |
supported_formats |
["geojson"] |
| Status | ✅ Active — 264 lines |
Ingestion Logic:
- Parse JSON input (accepts
dict,bytes, orstr) - Validate FeatureCollection type and Feature array structure
- For each Feature with Point geometry:
- Extract coordinates
[lon, lat] - Map
track_typeproperty toTrackTypeenum - Extract optional:
callsign,altitude_m,heading_deg,speed_mps,timestamp,confidence - Calculate completeness score based on optional field presence
- Extract coordinates
- Build canonical
Trackentity withTrackPosition,EntityMetadata - Skip invalid features defensively — increment error count, continue processing
Expected GeoJSON Properties:
{
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": { "type": "Point", "coordinates": [-77.0, 38.9] },
"properties": {
"callsign": "VIPER-01",
"track_type": "friendly",
"altitude_m": 3048,
"heading_deg": 90,
"speed_mps": 200,
"confidence": 0.95
}
}]
}
KML Adapter — adapters/kml/kml_adapter.py
| Property | Value |
|---|---|
adapter_id |
"kml" |
supported_formats |
["kml"] |
| Status | 🔄 Phase 2 Stub |
Planned Features:
- KML 2.3 Placemark → Track entity
- NetworkLink streaming support
- Polygon features → Airspace/Threat zone entities
NOTAM Adapter — adapters/notam/notam_adapter.py
| Property | Value |
|---|---|
adapter_id |
"notam" |
supported_formats |
["notam", "notam-plain", "notam-aixm"] |
| Status | 🔄 Phase 2 Stub |
Planned Features:
- ICAO NOTAM plain text parsing
- AIXM 5.1 XML parsing
- Affected area geometry extraction
UDL Adapter — adapters/udl/udl_adapter.py
| Property | Value |
|---|---|
adapter_id |
"udl" |
supported_formats |
["udl", "udl-json"] |
| Status | 🔄 Phase 2 Stub |
Planned Features:
- Unified Data Library REST/JSON client with authentication
- Entity mapping to canonical types
- Streaming subscription support
CAL Components
Canonical Data Model — cal/models/
The canonical model is defined in sdk/contracts/canonical_models.py and consists of Pydantic v2 models with strict validation. See the API Reference for complete model documentation.
Normalization Pipeline — cal/normalization/
Multi-stage pipeline that transforms adapter output:
- Schema validation — Pydantic model enforcement
- Provenance tagging — Source ID, format, ingestion timestamp
- Confidence scoring — Based on source reliability and data completeness
- Timeliness tagging — Stale/fresh determination based on TTL
Validation — cal/validation/
Cross-source validation and conflict resolution:
- Schema enforcement against canonical model
- Confidence scoring based on source history
- Conflict resolution when multiple sources report the same entity
- Anomaly detection for out-of-bounds values
Sync/Cache — cal/sync/
Local-first data store with DDIL-optimized sync:
- In-memory cache with configurable TTL
- Delta sync protocol for link recovery
- Eviction policies based on staleness and priority
- Signed manifest verification for offline mission packages