Part 1 left the pipeline with a stream of canonical track observations flowing onto the message bus. Each observation is an isolated atom — "source X reports object at position Y with velocity Z at time T". The fusion engine's job is to decide which observations refer to the same physical object, accumulate them into stable tracks with growing identity confidence, manage the lifecycle as observations cease or new ones arrive, and expose a queryable view of the world to the COP and downstream consumers. Part 2 is about building that engine.

The conceptual reference is Military Data Fusion Explained for the discipline overview, the JDL Data Fusion Model for the level mapping, and the pillar Complete Guide to Defense Data Fusion for the broader architectural framing.

Step 1: The Two-Stage Correlation Filter

The core decision of the fusion engine — whether an incoming observation is an update to an existing track or the birth of a new one — does not need to use one algorithm. The pattern that scales in production uses two stages: a cheap rule-based filter that handles the easy cases, and a probabilistic association engine invoked only when the rule layer is ambiguous.

The rule-based stage handles the 90% of observations that are unambiguous. For each incoming observation, it computes the set of candidate existing tracks within kinematic reach — a position-time gate. Identity priors filter further: an observation tagged "vessel" cannot match an "aircraft" track. Source compatibility filters too: an observation from a ground radar cannot match an air track of an underwater platform. Where the gate produces exactly one candidate that passes identity and source rules, the observation updates that candidate directly. Where the gate produces zero candidates, the observation initiates a tentative new track. Cheap, fast, explainable.

The probabilistic stage is invoked when the rule layer returns multiple candidates or when the track density is high enough that confident gating is impossible. Joint Probabilistic Data Association (JPDA) computes the likelihood that an observation belongs to each candidate track and updates each weighted by likelihood. Multiple Hypothesis Tracking (MHT) maintains multiple track hypotheses across observations, deferring association decisions until enough evidence accumulates. Both are computationally heavier and harder to tune; both are correct only for the cases where the rule layer was wrong to commit.

A specific pitfall worth highlighting: MHT generates an exponential number of hypotheses without pruning. The pruning policy — how many hypotheses to retain, when to merge, when to delete — is more important than the core algorithm. Default to aggressive pruning; tune outward only when operational evidence demands it.

Step 2: Tuning the Rule Layer

The rule layer is where most fusion engineering effort lands. The algorithm is simple; the tuning is craft.

The gate parameters that matter:

  • Kinematic gate size — how far an observation can be from the track's predicted position to still match. Too small misses real updates after sensor noise; too large produces false correlations in dense scenes.
  • Identity gate — which identity attributes must match (always: type taxonomy; sometimes: subtype, hull number, callsign).
  • Source-set rules — which sources can update which track types. Domain-specific (a maritime radar should not update an underwater track) and platform-specific (a SIGINT bearing-only contact may not associate to a kinematic track without bearing matching).
  • Time-since-last-update tolerance — observations against tracks that have been silent too long produce a new tentative track rather than re-associating with the old one.

Default values come from the source catalogue's accuracy and latency profiles. Operational tuning comes from replay against captured data, with metrics on false-correlation rate and miss-association rate. Procurement-grade fusion engines have these tuning knobs exposed for the operational team to adjust per deployment; bespoke programmes often hard-code the values and regret it when the deployment context shifts.

Step 3: When and How to Invoke Probabilistic Association

Probabilistic association is the right tool when rule-based gating cannot produce a confident single match. The signal that probabilistic is needed: the gate returns more than one candidate at a rate above (say) 5% in the operational scene.

The pragmatic invocation pattern:

JPDA for moderate density. When the gate returns 2-4 candidates per ambiguous observation, JPDA computes association likelihoods using kinematic priors (Mahalanobis distance from predicted position) and identity priors. Track updates are weighted by the likelihood; no single track gets a "definitive" update, but the most likely candidates accumulate the evidence faster.

MHT for hardest cases. When the gate returns many candidates and association ambiguity persists across observations, MHT defers the decision. It maintains hypotheses (alternative interpretations of which observation belongs to which track) and prunes by likelihood. After several observations the dominant hypothesis emerges and the others are deleted.

Combined output. Both algorithms produce updates that flow back into the same track store as rule-based updates. From the perspective of downstream consumers, all updates look identical; the difference is in the confidence and provenance metadata attached.

The implementation reality: well-tested open-source libraries exist for both JPDA and MHT (Stone Soup, FilterPy and adjacent tools). Most operational fusion engines wrap a tested library rather than implementing from scratch. The engineering effort is in the integration, the tuning, and the operational hardening — not the algorithm.

Step 4: The Track Lifecycle State Machine

Tracks have lifecycles. The state machine that governs them is one of the platform's most operationally consequential decisions: operators tolerate missing tracks but do not tolerate confidently-displayed stale tracks. The lifecycle is the boundary between trustworthy and untrustworthy display.

The state machine for the running example:

  • Tentative. First observation; awaiting confirmation. Not displayed in the operational COP unless an operator explicitly requests low-confidence visibility. Decays to deleted if no follow-up within a configurable window.
  • Confirmed. Two or more correlated observations within the kinematic-consistency window. Promoted from tentative. The default state for displayed tracks.
  • Mature. Confirmed and persistent for at least N minutes with consistent updates. Used by downstream analytics that need stable identity for pattern-of-life or behavioural analysis.
  • Fading. No update within the expected revisit interval for this source class. Display flagged as stale (dimmer symbol, age indicator). Configurable per source class — a 30-second-old maritime track is fine; a 30-second-old air track is fading.
  • Lost. No update for an extended period. Removed from active display but retained in the track store for audit and historical analysis.

The transitions are time-based and update-based, with both feeding a single decision tree. Every transition is logged with the trigger event (observation update, timeout expiry, operator override). The transition log feeds the event-sourced audit trail covered in Event Sourcing for Defense Audit Trails.

A practical detail: the lifecycle service is a separate process from the correlation engine. It subscribes to track-update events from correlation, computes lifecycle transitions, and publishes them as a separate stream on the bus. Decoupling lets the lifecycle policy evolve without touching the correlation engine.

Key insight: Lifecycle management is the layer that separates demo-grade fusion from operational fusion. A platform that produces correct tracks but never tells operators when a track has gone stale is a platform operators stop trusting. Build the lifecycle service before the fusion algorithm is fully tuned — it pays back every time a sensor link drops.

Step 5: The Track Store as Event-Sourced Read Model

Fusion outputs a stream of track updates and lifecycle transitions. The track store is the materialized view: the current state of every active track, queryable by the COP, by analytics, and by external APIs. The architectural decision worth making early is that the track store is a read model, not an authoritative source. The authoritative source is the event log on the message bus. The track store is rebuilt from the log on demand.

The benefits of this pattern:

Wipe and rebuild. The store can be cleared and rebuilt from the log without data loss. Schema migrations, performance tuning, and corrupted-data recovery all become routine rather than risky.

Multiple read models. A COP-optimized read model (geospatial-indexed, hot-track cache, low-latency reads) coexists with an analytics-optimized model (denormalized, batch-friendly) and an external-API model (filtered, classified per consumer). All are projections of the same underlying event stream.

Time-travel queries. "What did the platform believe at 14:32?" becomes trivial: replay the log up to 14:32 against a fresh projection. After-action review, training, and accreditation audits all benefit.

The implementation: PostgreSQL with PostGIS extension for geospatial queries (default for the running example). A Redis layer in front for sub-millisecond hot-track reads on the COP critical path. The relational store handles longer-tail queries and persistence guarantees. The detailed engineering view, including the indexing strategies that scale to billions of points, is in PostGIS for Defense Geospatial Data.

Step 6: Resist the Graph Database (For Now)

A predictable temptation in fusion design is to add a graph database "for relationships". Convoy detection, formation recognition, contact networks — these all sound graph-shaped. The temptation is to model them in Neo4j or equivalent and gain "natural" relationship queries.

The pragmatic counter: relationships between tracks are JDL Level 2 fusion, a separate concern from Level 1 track maintenance. Build Level 1 first, run it in operations for a year, and only then revisit Level 2 with the operational evidence in hand. The Level 2 relationships often turn out to need a different shape than the graph-database intuition predicted — temporal-relational rather than purely topological, classification-aware rather than open, expressed at higher abstraction than per-track edges.

The platforms that succeed start with PostGIS + Redis for the read model, prove fusion at Level 1, and add Level 2 capabilities as separate services consuming the same event stream. The platforms that fail add the graph database in week one and spend two years debugging the inappropriate abstraction.

Step 7: Test the Fusion Engine Against Reality

A fusion engine tested only with toy load passes integration tests and fails operations. The disciplines that catch problems before deployment:

Replay test harnesses. Captured sensor traces from real operations, replayed at full rate and at accelerated rate against the fusion engine. The traces are the regression test suite: any algorithm or schema change must produce equivalent or better results, not just on synthetic load.

Track-quality metrics in CI. False-correlation rate, miss-association rate, track-fragmentation rate, lifecycle transition timing. Every metric tracked over time; regressions gate the release. The metrics are evaluated against the replay traces, not against synthetic load.

Adversarial scenario testing. Spoofed AIS messages with implausible kinematics. Radar plots violating physics. Source dropouts at critical moments. The fusion engine must degrade gracefully under bad input — not crash, not produce confident-but-wrong tracks. The broader engineering pattern for adversarial robustness in defense is in Testing Mission-Critical C2 Systems.

Load and surge testing. 95th-percentile fusion latency under 500 ms at 10,000 observations/second; 99th-percentile under 1.5 s. Sustained for the duration of an operational rotation, not just for the marketing benchmark. The platform must have single-digit-percent CPU headroom for surge handling.

What's Next

Part 2 has built the engine. Two-stage correlation handles the easy and hard cases. The lifecycle state machine surfaces freshness to operators. The track store as event-sourced read model supports queries without becoming an authoritative source. The testing disciplines validate the layer against reality.

Part 3 goes deeper into the multi-INT case — combining SIGINT, IMINT, ELINT, OSINT, HUMINT, GEOINT, MASINT into the same fusion stream while preserving their semantic differences — and tackles the classification and releasability propagation that defense fusion uniquely requires.