Część 1 pozostawiła pipeline ze strumieniem kanonicznych obserwacji śladów płynących na szynę wiadomości. Każda obserwacja jest izolowanym atomem — „źródło X raportuje obiekt na pozycji Y z prędkością Z w czasie T". Zadaniem silnika fuzji jest zdecydować, które obserwacje odnoszą się do tego samego obiektu fizycznego, zakumulować je w stabilne ślady z rosnącą pewnością tożsamości, zarządzać cyklem życia, gdy obserwacje ustają lub pojawiają się nowe, oraz udostępnić odpytywalny widok świata dla COP i konsumentów downstream. Część 2 dotyczy budowy tego silnika.
Konceptualnym punktem odniesienia jest Fuzja danych wojskowych — wyjaśnienie dla przeglądu dyscypliny, Model fuzji danych JDL dla mapowania poziomów, oraz artykuł filarowy Kompletny przewodnik po fuzji danych obronnych dla szerszego kontekstu architektonicznego.
Krok 1: dwuetapowy filtr korelacji
Podstawowa decyzja silnika fuzji — czy nadchodząca obserwacja jest aktualizacją istniejącego śladu, czy narodzinami nowego — nie musi opierać się na jednym algorytmie. Wzorzec, który skaluje się w produkcji, używa dwóch etapów: taniego filtra opartego na regułach, który obsługuje proste przypadki, oraz probabilistycznego silnika asocjacji uruchamianego tylko wtedy, gdy warstwa reguł jest niejednoznaczna.
Etap oparty na regułach obsługuje 90% obserwacji, które są jednoznaczne. Dla każdej nadchodzącej obserwacji oblicza zbiór kandydujących istniejących śladów w zasięgu kinematycznym — bramkę pozycyjno-czasową. Priory tożsamości filtrują dalej: obserwacja oznaczona jako „jednostka pływająca" nie może pasować do śladu „statek powietrzny". Kompatybilność źródeł filtruje też: obserwacja z radaru naziemnego nie może pasować do śladu powietrznego platformy podwodnej. Gdy bramka produkuje dokładnie jednego kandydata przechodzącego reguły tożsamości i źródła, obserwacja aktualizuje tego kandydata bezpośrednio. Gdy bramka produkuje zero kandydatów, obserwacja inicjuje nowy ślad tymczasowy. Tanio, szybko, wyjaśnialnie.
Etap probabilistyczny jest uruchamiany, gdy warstwa reguł zwraca wielu kandydatów lub gdy gęstość śladów jest na tyle wysoka, że pewne bramkowanie jest niemożliwe. Joint Probabilistic Data Association (JPDA) oblicza prawdopodobieństwo, że obserwacja należy do każdego śladu kandydującego, i aktualizuje każdy z nich ważony prawdopodobieństwem. Multiple Hypothesis Tracking (MHT) utrzymuje wiele hipotez śladów na przestrzeni obserwacji, odraczając decyzje asocjacyjne aż do zgromadzenia wystarczających dowodów. Obie metody są obliczeniowo cięższe i trudniejsze w strojeniu; obie są poprawne tylko dla przypadków, w których warstwa reguł nie powinna była się angażować.
Konkretna pułapka warta podkreślenia: MHT generuje wykładniczą liczbę hipotez bez przycinania. Polityka przycinania — ile hipotez zachować, kiedy łączyć, kiedy usuwać — jest ważniejsza niż sam algorytm rdzeniowy. Domyślnie stosuj agresywne przycinanie; strojuj w stronę luźniejszą tylko wtedy, gdy operacyjne dowody tego wymagają.
Krok 2: strojenie warstwy reguł
Warstwa reguł to miejsce, w którym ląduje większość inżynierskiego wysiłku fuzji. Algorytm jest prosty; strojenie to rzemiosło.
Parametry bramki, które mają znaczenie:
- Rozmiar bramki kinematycznej — jak daleko obserwacja może być od przewidywanej pozycji śladu, by wciąż pasować. Zbyt mały pomija rzeczywiste aktualizacje po szumie sensora; zbyt duży produkuje fałszywe korelacje w gęstych scenach.
- Bramka tożsamości — które atrybuty tożsamości muszą się zgadzać (zawsze: taksonomia typu; czasem: podtyp, numer kadłuba, kryptonim).
- Reguły zestawu źródeł — które źródła mogą aktualizować jakie typy śladów. Specyficzne dla domeny (radar morski nie powinien aktualizować śladu podwodnego) i specyficzne dla platformy (kontakt SIGINT tylko-namiarowy może nie asocjować się ze śladem kinematycznym bez dopasowania namiaru).
- Tolerancja czasu od ostatniej aktualizacji — obserwacje wobec śladów, które milczały zbyt długo, produkują nowy ślad tymczasowy, zamiast ponownie asocjować się ze starym.
Wartości domyślne pochodzą z profili dokładności i latencji katalogu źródeł. Strojenie operacyjne pochodzi z odtwarzania na przechwyconych danych, z metrykami współczynnika fałszywych korelacji i współczynnika błędnych asocjacji. Silniki fuzji klasy zamówieniowej mają te pokrętła strojenia odsłonięte dla zespołu operacyjnego, by mógł je dostosować per wdrożenie; programy dedykowane często wpisują wartości na sztywno i żałują tego, gdy kontekst wdrożenia się zmienia.
Krok 3: kiedy i jak uruchamiać asocjację probabilistyczną
Asocjacja probabilistyczna to właściwe narzędzie, gdy bramkowanie oparte na regułach nie potrafi wyprodukować pewnego pojedynczego dopasowania. Sygnał, że potrzebna jest probabilistyka: bramka zwraca więcej niż jednego kandydata przy częstości powyżej (powiedzmy) 5% w scenie operacyjnej.
Pragmatyczny wzorzec wywołania:
JPDA dla umiarkowanej gęstości. Gdy bramka zwraca 2–4 kandydatów na niejednoznaczną obserwację, JPDA oblicza prawdopodobieństwa asocjacji, używając priorów kinematycznych (odległość Mahalanobisa od przewidywanej pozycji) i priorów tożsamości. Aktualizacje śladów są ważone prawdopodobieństwem; żaden pojedynczy ślad nie otrzymuje „definitywnej" aktualizacji, ale najbardziej prawdopodobni kandydaci gromadzą dowody szybciej.
MHT dla najtrudniejszych przypadków. Gdy bramka zwraca wielu kandydatów, a niejednoznaczność asocjacji utrzymuje się przez kolejne obserwacje, MHT odracza decyzję. Utrzymuje hipotezy (alternatywne interpretacje tego, która obserwacja należy do którego śladu) i przycina je według prawdopodobieństwa. Po kilku obserwacjach dominująca hipoteza wyłania się, a pozostałe są usuwane.
Połączony wynik. Oba algorytmy produkują aktualizacje, które wracają do tego samego track store co aktualizacje oparte na regułach. Z perspektywy konsumentów downstream wszystkie aktualizacje wyglądają identycznie; różnica leży w dołączonych metadanych pewności i proweniencji.
Rzeczywistość implementacyjna: dobrze przetestowane biblioteki open source istnieją dla JPDA i MHT (Stone Soup, FilterPy oraz narzędzia sąsiednie). Większość operacyjnych silników fuzji opakowuje sprawdzoną bibliotekę, zamiast implementować od zera. Wysiłek inżynierski leży w integracji, strojeniu i utwardzaniu operacyjnym — nie w samym algorytmie.
Krok 4: maszyna stanów cyklu życia śladu
Ślady mają cykle życia. Maszyna stanów, która nimi rządzi, to jedna z najbardziej operacyjnie istotnych decyzji platformy: operatorzy tolerują brakujące ślady, ale nie tolerują pewnie wyświetlanych nieaktualnych śladów. Cykl życia to granica między godnym i niegodnym zaufania wyświetlaniem.
Maszyna stanów dla bieżącego przykładu:
- Tymczasowy (tentative). Pierwsza obserwacja; oczekuje na potwierdzenie. Niewyświetlany w operacyjnym COP, chyba że operator jawnie zażąda widoczności niskiej pewności. Zanika do usunięcia, jeśli nie pojawi się kontynuacja w konfigurowalnym oknie.
- Potwierdzony (confirmed). Dwie lub więcej skorelowanych obserwacji w oknie spójności kinematycznej. Promowany z tymczasowego. Domyślny stan dla wyświetlanych śladów.
- Dojrzały (mature). Potwierdzony i trwały przez co najmniej N minut ze spójnymi aktualizacjami. Wykorzystywany przez analitykę downstream wymagającą stabilnej tożsamości do analizy wzorców aktywności lub analizy behawioralnej.
- Zanikający (fading). Brak aktualizacji w oczekiwanym interwale rewizyty dla tej klasy źródła. Wyświetlanie oznaczone jako nieaktualne (przyciemniony symbol, wskaźnik wieku). Konfigurowalne per klasa źródła — ślad morski sprzed 30 sekund jest w porządku; ślad powietrzny sprzed 30 sekund zanika.
- Utracony (lost). Brak aktualizacji przez dłuższy okres. Usuwany z aktywnego wyświetlania, ale zachowywany w track store dla audytu i analizy historycznej.
Przejścia są oparte na czasie i na aktualizacjach, oba zasilają wspólne drzewo decyzyjne. Każde przejście jest logowane wraz z wyzwalaczem (aktualizacja obserwacji, wygaśnięcie limitu czasu, nadpisanie operatora). Log przejść zasila ślad audytu event sourcing omówiony w Event Sourcing dla śladów audytu w obronności.
Szczegół praktyczny: serwis cyklu życia jest odrębnym procesem od silnika korelacji. Subskrybuje zdarzenia aktualizacji śladów z korelacji, oblicza przejścia cyklu życia i publikuje je jako odrębny strumień na szynie. Rozprzęgnięcie pozwala polityce cyklu życia ewoluować bez ingerencji w silnik korelacji.
Kluczowy wniosek: Zarządzanie cyklem życia to warstwa, która oddziela fuzję klasy demo od fuzji operacyjnej. Platforma, która produkuje poprawne ślady, ale nigdy nie mówi operatorom, kiedy ślad stał się nieaktualny, to platforma, której operatorzy przestają ufać. Zbuduj serwis cyklu życia przed pełnym strojeniem algorytmu fuzji — zwraca się za każdym razem, gdy łącze sensora pada.
Krok 5: track store jako event-sourced read model
Fuzja produkuje strumień aktualizacji śladów i przejść cyklu życia. Track store to widok zmaterializowany: bieżący stan każdego aktywnego śladu, odpytywalny przez COP, analitykę i zewnętrzne API. Decyzja architektoniczna warta podjęcia wcześnie to taka, że track store jest read modelem, nie autorytatywnym źródłem. Źródłem autorytatywnym jest log zdarzeń na szynie wiadomości. Track store jest odbudowywany z logu na żądanie.
Zalety tego wzorca:
Wyczyść i odbuduj. Magazyn można wyczyścić i odbudować z logu bez utraty danych. Migracje schematu, strojenie wydajności i odzyskiwanie po uszkodzeniu danych stają się rutynowe, a nie ryzykowne.
Wiele read modeli. Read model zoptymalizowany pod COP (z indeksem geoprzestrzennym, cache'em gorących śladów, niskim opóźnieniem odczytów) współistnieje z modelem zoptymalizowanym pod analitykę (zdenormalizowanym, przyjaznym dla batcha) oraz modelem zewnętrznego API (filtrowanym, klasyfikowanym per konsument). Wszystkie są projekcjami tego samego strumienia zdarzeń.
Zapytania time-travel. „W co platforma wierzyła o 14:32?" staje się trywialne: odtwórz log do 14:32 wobec świeżej projekcji. Przegląd po działaniu, szkolenie i audyty akredytacyjne — wszystko zyskuje.
Implementacja: PostgreSQL z rozszerzeniem PostGIS dla zapytań geoprzestrzennych (domyślnie dla bieżącego przykładu). Warstwa Redis przed nim dla sub-milisekundowych odczytów gorących śladów na ścieżce krytycznej COP. Magazyn relacyjny obsługuje zapytania długiego ogona i gwarancje persystencji. Szczegółowy widok inżynierski, w tym strategie indeksowania skalujące się do miliardów punktów, znajduje się w PostGIS dla geoprzestrzennych danych obronnych.
Krok 6: oprzyj się bazie grafowej (na razie)
Przewidywalna pokusa w projektowaniu fuzji to dodanie bazy grafowej „dla relacji". Wykrywanie konwojów, rozpoznawanie formacji, sieci kontaktów — wszystko to brzmi jak graf. Pokusą jest zamodelowanie tego w Neo4j lub równoważniku i zyskanie „naturalnych" zapytań relacyjnych.
Pragmatyczna kontra: relacje między śladami to fuzja Poziomu 2 JDL, odrębna kwestia od utrzymania śladów Poziomu 1. Zbuduj najpierw Poziom 1, prowadź go w operacjach przez rok, i dopiero wtedy wróć do Poziomu 2 z dowodami operacyjnymi w ręku. Relacje Poziomu 2 często okazują się wymagać innej formy, niż przewidywała intuicja bazodanowo-grafowa — bardziej czasowo-relacyjnej niż czysto topologicznej, świadomej klasyfikacji niż otwartej, wyrażanej na wyższym poziomie abstrakcji niż krawędzie per ślad.
Platformy, które odnoszą sukces, zaczynają od PostGIS + Redis dla read modelu, dowodzą fuzji na Poziomie 1 i dodają zdolności Poziomu 2 jako odrębne serwisy konsumujące ten sam strumień zdarzeń. Platformy, które zawodzą, dodają bazę grafową w pierwszym tygodniu i spędzają dwa lata na debugowaniu niewłaściwej abstrakcji.
Krok 7: testuj silnik fuzji wobec rzeczywistości
Silnik fuzji testowany tylko zabawkowym obciążeniem przechodzi testy integracyjne i zawodzi w operacjach. Dyscypliny, które wyłapują problemy przed wdrożeniem:
Harnessy odtwarzania (replay). Przechwycone ślady sensorowe z rzeczywistych operacji, odtwarzane z pełną szybkością i z przyspieszeniem wobec silnika fuzji. Ślady stanowią pakiet testów regresji: każda zmiana algorytmu lub schematu musi produkować równoważne lub lepsze wyniki, nie tylko na obciążeniu syntetycznym.
Metryki jakości śladów w CI. Współczynnik fałszywych korelacji, współczynnik błędnych asocjacji, współczynnik fragmentacji śladów, timing przejść cyklu życia. Każda metryka śledzona w czasie; regresje blokują wydanie. Metryki są ewaluowane wobec śladów odtwarzania, nie wobec obciążenia syntetycznego.
Testowanie scenariuszy adwersarialnych. Sfałszowane wiadomości AIS z nieprawdopodobną kinematyką. Plamki radarowe naruszające fizykę. Zaniki źródeł w krytycznych momentach. Silnik fuzji musi degradować się płynnie pod złym wejściem — nie zawieszać się, nie produkować pewnych-ale-błędnych śladów. Szerszy wzorzec inżynierski odporności adwersarialnej w obronności znajduje się w Testowanie krytycznych systemów C2.
Testy obciążenia i nagłych skoków. 95. percentyl latencji fuzji poniżej 500 ms przy 10 000 obserwacjach/sekundę; 99. percentyl poniżej 1,5 s. Utrzymywane przez czas trwania zmiany operacyjnej, nie tylko dla benchmarka marketingowego. Platforma musi mieć jednocyfrowy procent zapasu CPU na obsługę nagłych skoków.
Co dalej
Część 2 zbudowała silnik. Dwuetapowa korelacja obsługuje przypadki łatwe i trudne. Maszyna stanów cyklu życia uwidacznia świeżość operatorom. Track store jako event-sourced read model obsługuje zapytania bez stawania się źródłem autorytatywnym. Dyscypliny testowe walidują warstwę wobec rzeczywistości.
Część 3 wchodzi głębiej w przypadek multi-INT — łączenie SIGINT, IMINT, ELINT, OSINT, HUMINT, GEOINT, MASINT w ten sam strumień fuzji przy zachowaniu ich semantycznych różnic — i podejmuje propagację klasyfikacji i dopuszczenia do udostępnienia, którą fuzja obronna unikalnie wymaga.