UKRAINE WAR LIVE

Methodology

Ukraine War Live is a fully automated, serverless OSINT aggregation platform. There is no human in the loop: no analyst writes, edits, curates, or approves any event on this site. It runs on Cloudflare's edge network and refreshes every 2 hours (00:00–22:00 UTC).

It is not real-time, predictive, or authoritative. Every event is a machine reading of a public news headline and should be treated as a lead, not a fact. Any casualty figures are numbers announced by one side in the war — Ukraine or Russia — passed through without independent checking. They are not confirmed death or injury tolls.

1. Data pipeline

  1. RSS ingestion. A fixed set of ~13 feeds (major international wires and Ukrainian outlets in English) is polled concurrently each run. Items older than 96 hours (4 days) are discarded; at most 45 unseen items proceed per run. Each pipeline keeps its own record of what it has already read, so the two never consume each other's articles.
  2. AI extraction. Headlines and short summaries are passed to a large language model (Llama 3.3 70B on Cloudflare Workers AI) at temperature 0.1 with a strict schema. The model is instructed never to invent a source URL and never to guess coordinates. Output is capped at 20 strike events and 12 ground events per run.
  3. Validation & geocoding. Malformed objects are dropped. Coordinates outside a Ukraine + western-Russia bounding box are nulled. For events the model left without coordinates, a fallback gazetteer resolves the place name: a small hand-curated table of oblast centres, front-line towns and Russian target cities, backed by ~6,000 populated places from open GeoNames data inside the map area. Positions are settlement-centroid precision; no geocoding API is called.
  4. Deduplication & corroboration. Two signatures per event — an exact source-URL hash, and a content signature that adapts to how precise the location is. A model-supplied point uses event type + 0.1° grid cell + 1-hour bucket. A coarse position (gazetteer centroid or none) with a named place uses event type + place slug + 3-hour bucket, so two outlets writing up the same strike on the same town collapse to one entry; with no place name it falls back to a normalised-headline hash. Buckets are 4 hours for territorial change and diplomacy. If either signature is already seen the event is dropped — and if that duplicate comes from a different outlet than the first report, it counts as independent corroboration, so at 2+ outlets the original event is promoted to High confidence. Signatures are kept for 30 days, with a 40,000-key cap.
  5. Archive. Surviving events are appended as NDJSON — one JSON object per line — to a per-pipeline, per-day key in Cloudflare KV, with a running day→count index. This is the uncapped canonical record, downloadable at /archive/<date>.
  6. Distribution. A merged JSON snapshot of the most recent 200 events per pipeline is cached to Cloudflare KV and served at /feed.json. No alerting, no social channels.

2. Confidence classification

Every event carries one tier, shown as the marker colour on the map.

TierMeaningColour
High confidenceSame event reported by 2+ independent outlets — in one run, or corroborated by a later rungreen
Official — UkraineAttributed to Ukraine's General Staff, Air Force, or regional officialsblue
Official — RussiaAttributed to the Russian Ministry of Defence or governmentviolet
News wireA single mainstream outlet, not attributed to either sideamber
OSINTGeolocated or analyst-sourced (e.g. Militarnyi, DeepState)grey
State mediaSourced to TASS / RIA / Sputnik and not independently confirmedred

3. Ground-operations pipeline

A separate worker, on its own schedule, with its own prompt, extracts only ground_engagement and territorial_change events — infantry, armour and artillery combat at named places, and settlements captured, lost, or claimed. It explicitly ignores airstrikes, missiles, drones, air defence, naval action, and diplomacy, which the main pipeline handles.

4. Front-line layer

The red occupied-territory shading is a third worker that pulls the current control map from DeepStateMap.live every 6 hours, keeps only the occupied / Crimea / ORDLO polygons, and caches the trimmed GeoJSON. The same worker also keeps a weekly snapshot and backfills ~7/14/30/60/90-day-old ones from DeepState's public history, which power the map's "compare front line to a past date" control. It can be several hours stale and is © DeepStateMap.live, CC BY-NC-SA 4.0. It is independent of the event pipeline.

5. Daily situation report

Once a day a fourth worker sends the previous day's archived events to the same language model and stores a short digest — one headline plus a few grouped bullets. Reports are kept indefinitely on the Daily page. Like everything else here it summarises only the machine-extracted events; it adds no outside knowledge.

6. Data architecture

7. Editorial policy

The platform is politically agnostic by construction. The extractor records attacker, target, and location regardless of the source's alignment, and applies the same confidence rules to every side. There is no affiliation with any government, military, or advocacy organisation. There are no ads and no third-party trackers; aggregate page-view counts are tallied first-party from a daily-rotating hash — no cookies, no third-party scripts, and the raw IP is never stored — with the totals published on the About page. Only public officials and official spokespeople are named; no private individuals.

8. Known limitations

9. Corrections & reuse

To flag an error, open an issue on the project repository. The code and data are released under CC BY-NC-SA 4.0 — non-commercial reuse with attribution, share alike — consistent with the DeepStateMap front-line data licence.