Radar CFAR ship detection on water; optical ship detection plus berth occupancy along mapped piers for moored warships; aircraft as change vs a multi-scene median on mapped aprons. Match detections to AIS/ADS-B positions within distance/time windows.
Next pre-alpha. One new all-weather signal, one analytic win, and the two things needed before anything goes public.
ShippedM · 2–4 daysneeds: EARTHDATA_TOKEN secret
Night lights (VIIRS Day/Night Band)
Sees blackouts, blacked-out bases, new lit construction and front-line activity every night, at any latitude and through most smoke; would have shown the Crimea blackout directly.
Plan
Sources
NASA Black Marble VNP46A1 daily (LAADS / LANCE NRT), VIIRS DNB
Method
Daily radiance per site (sum and median in the box, cloud- and moon-masked), 30-day rolling baseline, z-score anomaly; flag drops > 50% (blackout) and new persistent lit area. Region-scale boxes for Crimea, Gaza, Lebanon, Sudan, Ukraine front.
Outputs
data/nightlights/<site>.csv, nightly before/after plates, flags into the alert stream
Done when
Reproduces the 23–24 Oct Crimea blackout and the Gaza/Lebanon baselines; runs nightly unattended.
Risks
NASA Earthdata login token needed (free); moonlight and snow-glare corrections; 500 m pixels are coarse for single bases.
In progressS · ≤1 day
Dark-ship flags (radar ship with no AIS)
A ship the radar sees that is not broadcasting is a story in itself — sanctions evasion, warships, smuggling.
Plan
Sources
Sentinel-1 detections, AIS log
Method
For each radar ship detection, search AIS within 500 m and ±30 min of the pass. No match and length > 40 m → dark candidate. Suppress known fixed objects (persistent at the same spot in > 70% of passes).
Outputs
dark flag on objects.csv, per-site dark count, plate colour coding
Done when
AIS logging runs continuously; one week of dark-ship candidates reviewed by hand at Hormuz, Bandar Abbas, Tartus, Hodeidah.
Risks
AIS logging is sampled (~50 min of each hour) — gaps would create false "dark", so detections without AIS heard in the window are marked NO-COVERAGE, not dark.
Depends on
Ship & aircraft counts with AIS / ADS-B identities
ShippedS · ≤1 day
Alerts (push / email)
Stop polling; hear about flags within an hour.
Plan
Sources
FIRMS watch, night lights, detections, dark ships
Method
One alert rule file (site, signal, threshold, quiet hours). A GitHub Action posts new flags to email and a push channel (ntfy.sh topic or Slack/Signal webhook), de-duplicated per site per 6 h.
A FIRMS flag at any site reaches Kevin's phone within one run of the watch.
Risks
Alert fatigue — start with Flagged-only and per-site mute.
ShippedS · ≤1 day
Provenance — hash and timestamp every drop
Proves what we knew and when — matters if a finding (e.g. the Wainwright timing) is challenged.
Plan
Method
On every commit that adds data or a SITREP, write a manifest of SHA-256 hashes; timestamp it with OpenTimestamps (Bitcoin, free) and optionally anchor the daily root hash on Algorand. Verification script and a public "proofs" page listing each SITREP's hash and anchor.
SITREP 001–004 hashed and timestamped retroactively; new SITREPs stamped automatically.
Risks
Algorand anchoring needs a funded account; OpenTimestamps needs no account.
v0.9.0
Change, baselines, review
See through cloud and polar night; know what normal looks like; put a human decision on every published flag.
PlannedL · 1–2 weeks
Radar change detection (Sentinel-1)
The only way to watch Arctic/NWS sites until February and cloudy sites year-round.
Plan
Sources
Sentinel-1 RTC (same orbit stacks)
Method
Group passes by relative orbit; log-ratio and multi-temporal coefficient-of-variation per pixel against a 6-pass baseline; flag compact changes (new structures, vehicles parks, vessels, burn/ground scars). Optional: coherence from SLC via ASF HyP3 (free) for construction and earthworks.
Outputs
change maps per site, flagged blobs with area, plates
Done when
Detects known changes (Wainwright burn scar, Hormuz shipping shifts) and stays quiet at static sites for a week.
Risks
Speckle; orbit geometry differences; snow and freeze/thaw signals in the Arctic.
PlannedM · 2–4 days
Trend lines & 12-month baselines
"Unusual" should mean unusual for that site and season.
Plan
Method
Backfill 12 months of counts (ships, aircraft, FIRMS, night lights) per site; per-site seasonal median and percentile bands; frontend sparkline and chart per site; flags use percentile, not fixed thresholds.
Outputs
data/baselines/<site>.json, site page charts
Done when
Every active site page shows a 12-month line with today's value against its band.
Risks
Compute time for backfill (run in chunks); repo size — store aggregates, not imagery.
Depends on
Ship & aircraft counts with AIS / ADS-B identities, Night lights (VIIRS Day/Night Band)
PlannedM · 2–4 days
Analyst review queue
Every published claim traceable to a human call; builds labelled data to cut false positives.
Plan
Method
Private review page lists new flags/detections with plate thumbnails; confirm / dismiss / note. Decisions stored as a CSV committed to the repo (or Artifact database); detectors learn per-site suppressions from dismissals.
Outputs
data/review/decisions.csv, review page, suppression list
Done when
All flags in a week reviewed in < 20 minutes total.
Risks
Static site cannot write — needs a small backend (VPS) or GitHub API form.
Depends on
Alerts (push / email)
PlannedM · 2–4 days
Lead → story tracking — confirm stories that follow our leads, and our lead time
Leads are the product. Today nothing records when a story lands on one of our leads, so "we had it first" is anecdote. Track each open lead until a published story confirms (or kills) it, and record the time delta between our lead's publication and the story: "RWI had it 31 h before CBC". It shows the value of the journalist hold, and it is the basis for a public track record.
Plan
Sources
Web news search for each open lead (place names, aircraft tails, coordinates turned into place names, key terms), GDELT DOC 2.0 API (free) as a first pass, Analyst / journalist reports through account/lead-status.php (already live) and reports/lead-status.yaml
Method
A scheduled agent run every 3 hours takes each open or carried lead and searches recent news (since the lead was published, minus 24 h). It proposes matches with a short reason and a confidence. A human confirms on the Leads board; nothing is marked automatically. A confirmed match records the story URL, outlet, publication time and the delta against the lead's public time (and its desk time, if it was held). It separates "story confirms the lead" from "story mentions the place". Leads stale after 30 days without a match.
Outputs
reports/lead-stories.yaml: lead id, story URL, outlet, published, delta_public_h, delta_desk_h, confirmed_by, Leads board and report pages: 'Story: CBC, 31 h after our lead' chip, a running track record (median lead time, share of leads that became stories)
Done when
The 3-hourly run proposes matches for every open lead; at least one confirmed story with its time delta shows on the site.
Risks
False matches (same place, different event): proposals are never auto-confirmed. Paywalled outlets may need a journalist's confirmation. Search cost: cap queries per run, and drop stale leads.
Depends on
Analyst review queue
v0.10.0
Warnings & interference
Signals that tell us where to look before something happens, and first-pass news correlation without manual searching.
ResearchM · 2–4 days
GPS jamming & spoofing map
Strong, under-used indicator around the Baltic, Kaliningrad, Black Sea and Gulf.
Aggregate share of aircraft with degraded navigation integrity per H3 hex per day; flag hexes above threshold near watchlist sites. Needs all aircraft, not just military → bulk daily ADS-B dumps.
Outputs
data/gnss/<date>.csv, daily map, site flags
Done when
Reproduces known jamming areas (Kaliningrad, eastern Med) for a test week.
Risks
Data volume (daily global dumps are GBs) — likely a VPS job.
PlannedM · 2–4 daysneeds: FAA NOTAM API key (optional)
Navigation warnings & NOTAMs
Live-fire areas, missile tests and closures are announced in advance — they tell us where to look.
Plan
Sources
NGA Maritime Safety Information broadcast warnings (NAVAREA IV/XII, HYDROLANT/HYDROPAC), NAV CANADA / FAA NOTAMs
Method
Pull warnings daily, parse coordinates and dates, intersect with watchlist boxes and zones; show active warnings on site pages and in SITREPs.
Outputs
data/warnings/<date>.json, site-page panel
Done when
Active warnings appear for Black Sea, Baltic and Atlantic exercise areas.
Risks
Free-text coordinate parsing; FAA NOTAM API needs a key.
PlannedM · 2–4 days
Automated first-pass news correlation
Today the CORRELATED / PARTIAL / NOT IN NEWS tags are done by hand.
For each flag, query GDELT events within 25 km and ±48 h; rank articles; propose a tag with links. Analyst confirms in the review queue.
Outputs
news candidates per flag, proposed tags in SITREP drafts
Done when
Proposed tags agree with manual tags on SITREPs 001–004 for ≥ 70% of items.
Risks
GDELT geocoding noise; language coverage.
Depends on
Analyst review queue
v0.10.5
Source quality (new free feeds)
Fix the limits capabilities.yaml admits to — cloud-inflated change scores, flares vs fires, gaps between fire passes, unnamed aircraft, partial range picture — with free sources first. Ordered by value per day of work.
ShippedM · 2–4 days
Cloud mask that catches fair-weather cumulus
The SCL-only mask passes small cumulus as clear and inflates change scores (SITREP 015: a 55% "change" at Rzeszów on a pass marked 100% clear was cloud; SITREP 008: CFB Gander 0.32 from broken cumulus and shadow). Every optical change flag depends on this.
Plan
Sources
OmniCloudMask (open-source model; red, green and NIR at 10 m — bands pickup.py already fetches), Sentinel-2 SCL (kept as a first pass)
Method
Run OmniCloudMask on each chip after SCL; mark cloud and cloud shadow, dilate, and recompute site_clear_frac. Add the planned brightness test as a cheap fallback. Re-score the last 30 days and compare flags before/after.
Outputs
cloud probability per chip, corrected site_clear_frac and change_vs_baseline in manifests
Done when
Rzeszów 27 Oct and Gander (SITREP 008) re-score as cloudy / low-confidence; no clear-sky pass in the pilot set loses more than 5% of its clear area.
Risks
Model inference time on Actions runners (CPU) — batch per run or move to the VPS; check the model's licence before shipping.
In progressL · 1–2 weeks
Tasking — custom runs over chosen targets
Ad hoc passes are run by editing trigger files by hand. Analysts (and later paying clients) need to task all sources, or a relevant set, over one or more targets for a window, from the dashboard.
Phase 1 (0.8.2): sources.yaml + scripts/task.py + the Task workflow; the site's Task page (admin only) dispatches it through the GitHub API. Phase 2: accounts request, admin approves. Phase 3: credits per source × target, held on submit, settled on completion.
Outputs
data/tasks/<id>/ (task.json, status.json, outputs per target and source), Task page and per-task results page on the site
Risks
Actions minutes per task; privacy — client targets limited to sites and areas, single-aircraft or single-vessel follows stay admin-only.
In progressS · ≤1 dayneeds: EOG account (free registration)
Tell gas flares from fires (VIIRS Nightfire temperatures)
FIRMS "cannot tell a strike from a brush fire or a flare", so routine heat is a hand-kept list (firms_persistent / known_heat). Nightfire estimates each hot spot's temperature: flares run ~1,600–2,000 K, vegetation fires far cooler.
Plan
Sources
VIIRS Nightfire (VNF) — Earth Observation Group, Colorado School of Mines; free with registration
Method
Pull nightly VNF detections inside watch boxes; join to FIRMS hits within 750 m / same night; label hits flare-like, fire-like or unknown. Build a flare catalogue per site from persistence + temperature and use it in place of the hand list.
Outputs
heat class per FIRMS hit, data/firms-watch/flares.csv, routine-heat logic driven by data
Done when
Ras Laffan, Bandar Abbas, Abqaiq and Kharg classify as flares on ≥90% of matched nights with no hand list.
Risks
No explicit open licence found — use values internally to classify; ask EOG before republishing VNF fields. Night passes only.
PlannedM · 2–4 days
Geostationary fire detections (minutes, not passes)
FIRMS "misses short events between passes". Geostationary satellites look every 5–15 min, so a strike or short fire shows as a time series, and a single FIRMS dot can be confirmed or ruled out.
Plan
Sources
GOES-19 (East) / GOES-18 (West) ABI fire product (ABI-L2-FDC) on NOAA AWS Open Data, Meteosat FRP-PIXEL (EUMETSAT LSA SAF), Himawari wildfire product (JAXA P-Tree; registration) for East Asia
Method
Hourly job pulls fire pixels inside watch boxes for the matching satellite; store first/last seen and peak FRP per event; link to FIRMS hits. Show duration on the Thermal page and in SITREP heat lines.
Outputs
data/geo-fire/events.csv, duration and onset time per heat event
Done when
For the SITREP 014 Arava fire, onset and end times are within 15 min of the three polar passes.
Risks
~2 km pixels (Americas), ~3 km (Meteosat) — confirms, does not locate; NOAA data public domain, LSA SAF and JAXA need registration and attribution.
PlannedS · ≤1 day
Name aircraft beyond the Canadian and US registers
Many MILAIR and Watch rows carry only a hex code or no type (e.g. "ae6875", the old "aa9024 (, other)"). A hex lookup gives type, operator and registration for military and foreign aircraft too.
Plan
Sources
adsbdb.com API (free), hexdb.io (free), existing TC CCAR / FAA registry lookups first
Method
After the registry lookups, query unknown hex codes once, cache results in data/registry/hex.csv with a 30-day TTL, and fill type / operator / country in MILAIR, Watches and tracks.
Outputs
data/registry/hex.csv, fewer unnamed rows
Done when
Unnamed military rows in MILAIR and Area Watches fall by at least half over a week.
Risks
Community data, sometimes wrong — keep the source per field; respect rate limits.
PlannedM · 2–4 days
Range and restricted-airspace activity (US)
Vegas and Mojave Watches see only part of range traffic ("most range traffic does not broadcast ADS-B"). Knowing a range or TFR was active turns "something was here" into "the range was hot".
Plan
Sources
FAA TFR list (tfr.faa.gov), FAA special-use airspace schedules (sua.faa.gov)
Method
Daily pull of TFRs and SUA activation times for airspace overlapping Watch boxes; attach to each Watch day and to low-pass / landing rows near ranges.
Outputs
data/airspace/active.csv, a 'range active' line in Watches
Done when
Nellis / Groom / China Lake Watch days show which ranges were scheduled active.
Risks
No formal public API for SUA schedules — check FAA terms before scraping; US only.
Depends on
Navigation warnings & NOTAMs
PlannedS · ≤1 dayneeds: EARTHDATA_TOKEN secret (already used for night lights)
Plain explanations for flagged change
Many "Undetermined change" and heat flags have an ordinary cause (wildfire, flood, storm). Checking a few free event feeds first saves a manual look and stops false leads.
Plan
Sources
NASA EONET (natural events), Copernicus Emergency Management Service activations, NASA OPERA DIST-ALERT (land disturbance in North America; Earthdata)
Method
For each flagged site, query events within 25 km and ±3 days; add a "possible cause" line to the flag and to the Today feed; never clear a flag automatically.
Outputs
cause notes on flags in manifests and ALERTS
Risks
Coarse event footprints — a cause note is a hint, not an explanation.
ResearchS · ≤1 day
Sub-metre radar where open archives have it
Sentinel resolution (10 m) cannot count aircraft or small vessels; free open SAR archives sometimes cover a watched base.
Plan
Sources
Umbra Open Data (AWS), Capella Open Data (AWS)
Method
Weekly index of both STAC catalogues against watchlist boxes; when a new scene covers a site, make a plate and add it to the place page and Today feed.
Outputs
data/open-sar/index.csv, plates per covered site
Risks
Coverage is wherever the vendors chose to image — opportunistic, not a feed. Check each collection's licence (some CC BY) and credit the vendor.
ResearchM · 2–4 daysneeds: GFW API token (free self-registration); a licence decision
Dark vessels and AIS gaps (Global Fishing Watch)
Our dark-ship check is rare and unconfirmed because AIS coverage ends offshore. GFW already matches Sentinel-1 vessel detections to AIS globally and publishes AIS-disabling events.
Plan
Sources
Global Fishing Watch API v3 (SAR vessel detections; AIS gap events; vessel identity)
Method
Query detections and gap events inside naval and port watch boxes daily; merge with our CFAR detections; mark agreement.
Outputs
data/detections/gfw.csv, confirmed / unconfirmed dark candidates
Risks
CC BY-NC 4.0 — non-commercial only, no public commercial licence. Fine for free public SITREPs and journalist leads; must stay out of corporate deliverables unless GFW grants a custom licence. Fishing-focused, so naval coverage varies.
ResearchM · 2–4 daysneeds: OpenSky research access (application); a licence decision
Deeper flight history (OpenSky Network)
More receivers and a long historical archive would fill gaps in hindcasts and Watches. Does not fix the Arctic (only paid satellite ADS-B — Spire, Aireon — does).
Plan
Sources
OpenSky Network historical database (Trino)
Method
Use for hindcasts only at first; compare coverage against adsb.lol for three past events.
Outputs
hindcast flight pulls with an OpenSky source tag
Risks
Licence is for non-profit research, education or government use — commercial use needs a negotiated agreement.
vside-feeds
Side feeds (ntfy)
Small personal push feeds on the same alert plumbing — quick wins, any order.
PlannedS · ≤1 day
Feed: earthquakes near watch sites
Shallow quakes near watchlist sites as a push; first half of the seismic item.
Plan
Sources
USGS earthquake GeoJSON feeds (free)
Method
Hourly pull of USGS feed; shallow (< 10 km) events within 50 km of a site push to ntfy.
Outputs
ntfy pushes, data/seismic/*.csv
Depends on
Alerts (push / email)
PlannedS · ≤1 day
Feed: military aircraft over Calgary
Fun and useful — a push when a military callsign crosses the Calgary area.
Plan
Sources
adsb.lol /v2/mil (already logged)
Method
Filter the hourly ADS-B log for positions within ~60 km of YYC; push new callsigns (dedupe per aircraft per day).
Outputs
ntfy pushes
Depends on
Alerts (push / email)
PlannedS · ≤1 dayneeds: Gmail connected to the scheduled task
Feed: ATIP / OIC inbox
Know the moment an ATIP release or OIC letter lands.
Plan
Sources
Gmail (connector)
Method
Scheduled check of Gmail for new mail from ATIP offices / OIC; push sender + subject only.
Outputs
ntfy pushes
Risks
Keep message bodies out of pushes (public topic).
Depends on
Alerts (push / email)
PlannedS · ≤1 day
Feed: news spikes at watch sites
Early warning when reporting about a watch site jumps — a preview of auto-news.
Plan
Sources
GDELT DOC 2.0 API (free)
Method
Hourly article counts per site keyword set; push when the count exceeds 3× its 7-day hourly median.
Outputs
ntfy pushes
Depends on
Alerts (push / email)
vterms
Terms & licensing
Take the draft Terms of Use (v0.1, live on the site as a draft) to in-force, and build what they promise.
The Terms can't take effect until the open [DECISION]/[TBD] items are settled and a lawyer has read them.
Plan
Method
Set the effective date; add a contact address for licensing, verification and legal notices; confirm aisstream.io redistribution terms before offering AIS-derived feeds; decide on a French version; legal review.
Outputs
docs/TERMS.md v1.0
Done when
No [DECISION] or [TBD] markers remain and the draft banner comes off.
PlannedS · ≤1 day
Terms: public-facing cleanup
The draft on the site shows internal notes ("Items marked [DECISION] need Kevin's call", amber markers).
Plan
Method
Strip internal notes and markers from the rendered page (the repo copy keeps them), or remove them when v1.0 lands.
Outputs
terms.html
Depends on
Terms: open decisions
ShippedS · ≤1 day
Privacy policy
Required by Terms section 16 before any account or verification data is collected. Draft placeholder v0.1 (PIPEDA / Alberta PIPA) is on the site; open decisions and legal review remain.
Plan
Outputs
docs/PRIVACY.md, privacy.html
Done when
Published and linked from the footer and the Terms.
PlannedS · ≤1 day
Attribution on every output
Terms section 9 credit line plus required Copernicus / NASA / OSM credits on every SITREP, chart and imagery export.
Plan
Method
Generate the credit strings in the pipeline and stamp them on plates, PDFs and exports.
Outputs
plates, SITREP PDFs, exports
PlannedS · ≤1 day
ODbL-derived datasets kept separate
Databases derived from OpenStreetMap or adsb.lol must carry ODbL terms, not RWI's non-commercial terms.
Plan
Method
Publish ODbL-derived tables in their own folder with an ODbL notice; keep RWI value-added layers apart.
Outputs
data/odbl/*, licence notices
In progressL · 1–2 weeks
Journalist & student accounts
The free licence (Terms section 5) needs signup, verification and personal API keys.
Plan
Method
Signup with verification evidence (press card, association membership, newsroom email, published work; student email or enrolment), annual re-verification, personal API keys with rate limits, commercial-licence enquiry path.
Outputs
accounts, API keys
Depends on
Privacy policy, Terms: open decisions
v0.11.0
Extra sensors & coverage
Fill remaining sensor gaps and extend the base register beyond Canada.
PlannedS · ≤1 day
Seismic events
Large explosions and nuclear tests (Punggye-ri) show up on seismometers.
Plan
Sources
USGS earthquake API (free), EMSC
Method
Pull events daily; shallow events near watchlist sites flagged; add Punggye-ri as a site.
Outputs
data/seismic/*.csv, flags
Done when
Feed runs daily; historic test (2017) reproduced as a check.
ResearchM · 2–4 days
Industrial activity from air quality (Sentinel-5P)
NO₂/SO₂ over refineries, LNG and smelters shows shutdowns and restarts after strikes.
Weekly mean column over infrastructure sites vs baseline; flag sustained drops.
Outputs
data/s5p/<site>.csv
Risks
~5 km pixels — only big facilities; wind and cloud effects.
PlannedS · ≤1 day
Satellite pass prediction
Board shows when the next usable image of each site is due, so ad hoc requests have an honest ETA.
Plan
Sources
CelesTrak TLEs for Sentinel-1/2, Landsat, NOAA-20/21, Suomi-NPP; Open-Meteo cloud forecast
Method
Propagate orbits (skyfield) for 72 h, intersect with site boxes and swath widths; add cloud forecast.
Outputs
next-pass table per site
PlannedL · 1–2 weeks
Coverage beyond Canada
Full registers for the US, NATO allies, Russia and China, built and verified the same way as Canada.
Plan
Method
Source lists (government, OSM military=*, Wikidata), place boxes, verify every box against first imagery, tag region/CCMD/country/program; roll out in batches of ~50.
Outputs
watchlist additions with verified flags
Risks
Watchlist size vs Actions run time — move heavy jobs to the VPS.