Skip to content

Multiply capabilities: airspace incursion, pattern-of-life, formation/squawk/vertical-rate detectors, KML/CoT export#12

Open
cognis-digital wants to merge 2 commits into
mainfrom
feat/airspace-patterns-exporters-multiplier
Open

Multiply capabilities: airspace incursion, pattern-of-life, formation/squawk/vertical-rate detectors, KML/CoT export#12
cognis-digital wants to merge 2 commits into
mainfrom
feat/airspace-patterns-exporters-multiplier

Conversation

@cognis-digital

Copy link
Copy Markdown
Owner

Summary

Substantially multiplies adsbwatch's defensive / OSINT / situational-awareness capability. Everything is offline (no live feeds required), pure stdlib, and additive — the public API and all existing output are unchanged. New detectors are default-on and only fire on genuine signatures.

Scope (unchanged and enforced): descriptive airspace monitoring / force protection only. No targeting, no weapons, no effectors. CoT events are emitted as neutral/unknown air tracks (a-u-A), never a hostile designation — asserted by tests.

New anomaly detectors (adsbwatch.core)

  • squawk_change — a transponder changing into an emergency code (7500/7600/7700) mid-track (a crew declaring an emergency), distinct from a feed that merely starts on one.
  • impossible_vertical_rate — implausible climb/descent rate (feet/min) for one ICAO: a spoofed/corrupt altitude or data artifact.
  • formation — two distinct ICAOs holding tight in both horizontal distance and altitude across multiple co-timed reports.

New modules

  • adsbwatch.airspace — restricted-airspace / NOTAM incursion detection from offline zone fixtures: circle + ray-cast polygon zones, altitude band, active time window. One finding per (aircraft, zone).
  • adsbwatch.patternspattern-of-life analytics: per-aircraft profiles (dwell, track length, distinct callsigns/squawks, altitude range, bbox) and recurring visits near a point of interest.

New exporters (adsbwatch.intel)

  • KML — severity-styled placemarks for Google Earth / QGIS.
  • CoT (Cursor-on-Target) — events for ATAK / WinTAK / TAK Server as neutral tracks.

New CLI surface

  • adsbwatch airspace FEED --zones zones.json (+ geojson/kml/cot/json formats)
  • adsbwatch patterns FEED [--poi LAT,LON --poi-radius NM --poi-gap S --min-visits N]
  • adsbwatch scan --format kml|cot and adsbwatch scan --zones zones.json (folds incursions into a scan)

Tests & demos

  • Tests: 201 → 260 (5 new modules: detectors, airspace, patterns, KML/CoT, CLI). python -m pytest -q green.
  • Demos: 20 → 2421_airspace_incursion, 22_pattern_of_life, 23_kml_export, 24_cot_atak; all offline, exit 0, wired into run_all.py + the demo smoke test.
  • README + docs/DEMOS.md updated; version bumped to 0.4.0.

Note

This branch is based on the open impossible-kinematics PR (#5), so its commit appears here too; if #5 merges first this PR reduces to the single new commit.

Detector
- New impossible_kinematics detector in core.analyze(): flags a single ICAO
  whose consecutive geolocated reports imply a ground speed above a tunable
  ceiling (default 3500 kt) — a classic position-spoof / injected-track / cloned
  transponder signature. Public API stays stable: analyze() gains an optional
  kinematics_max_speed_kt kwarg (0/negative disables it) and scan gains --max-speed.
- decision.recommend() gains an advisory playbook for the new kind.

Bug fixes (found while adding edge-case tests)
- decision.load_sensor_events("") / whitespace crashed with an opaque
  JSONDecodeError because "" in "[{" is True in Python. Rewrote the CSV/JSON
  detection: empty/whitespace/None -> [], malformed input -> clear ValueError.
- intel._iso() crashed with OverflowError on an out-of-range epoch (garbage
  timestamp in a real feed), taking the whole GeoJSON/STIX export down. Now
  falls back to the sentinel timestamp.

Tests: 49 -> 201 passing (test_core_edge, test_kinematics, test_cli_errors,
test_intel_edge, test_decision_edge, test_feeds_edge, test_datafeeds).

Demos: 5 -> 20 scenarios; run_all.py + docs/DEMOS.md updated. Each exits 0 offline.
…/squawk-change/vertical-rate detectors, KML/CoT exporters

New defensive, offline situational-awareness features (all additive; public API
stable). Detectors are default-on and only fire on genuine signatures.

Detectors (adsbwatch.core):
- squawk_change: transponder changing *into* an emergency code mid-track
- impossible_vertical_rate: implausible climb/descent (spoofed/corrupt altitude)
- formation: two distinct ICAOs holding tight in distance + altitude over time

Modules:
- adsbwatch.airspace: offline restricted-airspace / NOTAM incursion detection
  (circle + ray-cast polygon zones, altitude band, active window)
- adsbwatch.patterns: pattern-of-life analytics (per-aircraft profiles,
  recurring visits near a point of interest, rolled-up summary)

Exporters (adsbwatch.intel):
- KML (Google Earth / QGIS, severity-styled placemarks)
- CoT / Cursor-on-Target (ATAK/TAK) as NEUTRAL/unknown air tracks (a-u-A) —
  situational awareness for a human, never a hostile/targeting designation

CLI:
- new subcommands: `airspace` (--zones), `patterns` (--poi/--poi-radius/...)
- `scan --format kml|cot` and `scan --zones` to fold incursions into a scan

Scope stays strictly defensive/OSINT/situational-awareness: descriptive only,
no targeting/weapons/effectors. Enforced by the decision-layer allow-list and
the neutral-affiliation CoT tests.

Tests: 201 -> 260 (5 new test modules). Demos: 20 -> 24 (offline, exit 0).
Docs + README updated; version 0.4.0.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant