1
0
This commit is contained in:
2026-05-18 14:05:37 +03:00
parent 3da6362c49
commit ed1d44e94a
16 changed files with 1686 additions and 867 deletions

View File

@@ -1,60 +1,33 @@
# 00 — Incident Chronology: Rēzekne Drone Incident, 7 May 2026
# 00 — Incident Chronology (7 May 2026, Rezekne)
> Non-normative supporting document. Compiled from public reporting
> (LSM / eng.lsm.lv, Apollo, TV3, Meduza, Defense News, The Globe and Mail,
> Wikipedia "2026 Ukrainian drone incursions into Baltic states"). Times are
> local (EEST) and approximate where the public record is approximate.
This package is modelled from the **public chronology** of the drone incident
over eastern Latvia on the night of 6–7 May 2026. No classified or operational
source was used.
## Summary
## Public-source timeline
During the night of 6–7 May 2026, several unmanned aerial vehicles entered
Latvian airspace from the direction of Russia. Two drones came down on Latvian
territory; one exploded at a fuel-storage facility in Rēzekne (~40 km from the
Russian border), damaging four empty oil tanks. No casualties. The drones are
assessed as stray Ukrainian long-range drones diverted off course — Ukraine's
foreign minister later linked the diversion to Russian electronic-warfare
jamming. The incident triggered a political crisis: the Defence Minister and,
days later, the Prime Minister resigned.
| Phase | What happened (public reporting) |
|-------|----------------------------------|
| Detection | Several unmanned aerial vehicles, assessed as originating from Russian territory, entered Latvian airspace near the eastern border. |
| Tracking | NBS surveillance tracked the objects; at least two drones came down on Latvian territory, one near Rezekne. |
| Impact | A drone struck near a fuel-storage facility in the Rezekne area; no casualties were publicly reported. |
| Public notification | The public cell-broadcast early-warning message reached the Rezekne population **approximately 40 minutes** after the threat was apparent — the central failure this package addresses. |
| Aftermath | The Ministry of Defence publicly committed to **revising the inter-institutional notification algorithms** so that a public alert is issued without comparable delay. |
## Timeline
## Why this is modelled as a UAPF package
| Time (7 May) | Event |
|---|---|
| ~03:30 | VUGD receives several 112 calls about a possible fire at the oil-storage facility on Komunāla iela, Rēzekne. |
| 04:09 | Cell-broadcast warning issued to residents of Ludza and Balvi districts, at NBS request. |
| 04:43 | Cell-broadcast warning issued to Rēzekne district — roughly 40 minutes after Ludza/Balvi. Rēzekne city residents report having already heard/seen drones overhead about an hour before receiving the alert. |
| ~05:30 | NBS announces that two UAVs have crashed on Latvian territory; NBS, State Police and VUGD units deploy to the sites. |
| Morning | One crash site confirmed at the Rēzekne oil-storage base. A second crash site is not yet identified (later associated with the Viļāni area, west of Rēzekne). A possible third drone is believed to have exited Latvian airspace. |
| Daytime | Flights restricted up to ~6 km altitude in the eastern border region; commercial aviation unaffected. Schools closed in Rēzekne and Ludza; remote learning in Balvi. French NATO Baltic Air Policing jets scrambled during the alert. |
| ~08:20–08:51 | NBS declares the air-threat alert ended for Balvi, Ludza and Rēzekne districts. |
| 12:00 | Press conference in Rēzekne (AM / NBS / State Police). |
| ~18:00 | Eastern-region flight restrictions lifted. |
| Daytime | Government Crisis Management Council convenes. PM Siliņa states the threat is "a consequence of Russia's war in Ukraine" and asks the Ministry of Defence to clarify why cell-broadcast warnings were issued only after the crash was reported. |
The incident is not a technology failure — the cell-broadcast platform worked.
It is a **process and decision-rights failure**: the algorithm that converts
"NBS sees a threat" into "VUGD dispatches a public broadcast" was slow and
under-specified. That is exactly the class of problem UAPF exists to make
explicit, inspectable and improvable: a BPMN process, the DMN decisions inside
it, the CMMN follow-up case, and the resource bindings that say who does what.
## Aftermath
## Scope boundary
- **10 May 2026** — Defence Minister Andris Sprūds resigns. He had already
survived an April Saeima no-confidence-style vote (43 for dismissal, 50
against).
- **~14 May 2026** — Prime Minister Evika Siliņa resigns; the government falls.
- The Foreign Ministry summoned Russia's chargé d'affaires; Ukraine's foreign
minister later acknowledged the drones were Ukrainian and attributed the
diversion to Russian electronic warfare.
- The Ministry of Defence committed to **review and improve the public
notification / inter-institutional information-exchange algorithms**. The
Rēzekne incident was designated a central scenario for the "Pilskalns" civil
protection exercise.
In scope: detection → classification → notification decision → broadcast →
interception authorisation → field response → origin investigation →
after-action.
## Prior incidents in the same series (context)
- **7 September 2024** — A Russian "Shahed"-type drone fell in Gaigalava
parish, Rēzekne district. After-action commitments were made then to speed
up public notification.
- **25 March 2026** — A stray Ukrainian drone crashed in Krāslava district
(Dobročina); a parallel drone struck a power-station chimney in Estonia.
- **3 May 2026** — Air-threat cell broadcasts in Alūksne, Balvi, Ludza,
Rēzekne and Krāslava (~3.5 h); no drone crossed the border.
The 7 May incident is therefore the **fourth comparable event in ~20 months**,
which is why the failure is framed publicly as an algorithm/process failure
rather than a one-off.
Out of scope: NBS internal sensor doctrine, NATO BAP internal procedures,
and the criminal investigation, which are referenced only as handoffs.

View File

@@ -1,51 +1,24 @@
# 01 — Institutional Gap Analysis (AS-IS) and TO-BE Targets
# 01 — Institutional Gap Analysis
> Non-normative supporting document. This is the analytical core of the package:
> it maps each publicly-reported coordination failure to a specific element of
> the BPMN / DMN / CMMN models, so the revised algorithm can be designed against
> a concrete baseline.
Gaps identified in the **as-is** algorithm, derived from the public chronology.
Each gap is addressed by a specific element of this package and is referenced
from `resources/mappings.yaml` and the diagrams.
## Why this package exists
| ID | Gap (as-is) | Addressed by (to-be) |
|----|-------------|----------------------|
| **G1** | No explicit object-classification step — "is it a drone, and how sure are we?" was implicit. | `Decision_ObjectClassification` makes class **and confidence** explicit before any threat call. |
| **G2** | Public-broadcast authority was a **single point of failure**: one request from NBS Joint Staff was the only trigger, with no timed fallback. | `Task_AuthorizeBroadcast` carries a 3-minute timeout with a proposed escalation to the Crisis Management Centre (KVC). *Not yet institutionally agreed.* |
| **G3** | Message wording was composed under time pressure. | `Decision_CellBroadcastScope` selects a **pre-approved template** (`MSG_*`); guardrail GR-4 forbids free-text public messaging. |
| **G4** | No bounded, threat-graded **time target** for dispatch — the 40-minute delay had no SLA to breach. | `Decision_NotificationUrgency` outputs `broadcastSlaSeconds`; see `03-notification-timing-sla.md`. |
| **G5** | No automatic detection that the SLA had been missed. | Non-interrupting **SLA-breach boundary timer** on `Task_DispatchBroadcast``Task_EscalateSla`. |
| **G6** | Alert footprint was coarse — not matched to the drones' predicted path. | `Decision_CellBroadcastScope` builds the footprint from `corridorMunicipalities`. |
| **G7** | Interception safety criteria were not written down or inspectable. | `Decision_InterceptionAuthorization` gates engagement on positive hostile ID, over-populated-area and debris-zone-clear, in that priority order. |
| **G8** | Follow-on civil decisions (school closures, resident enquiries) had no owner. | CMMN stage `Stage_FieldResponse` (`HT_MunicipalEnquiries`); IZM recorded as a consulted party in `02-raci.md`. |
After the 7 May 2026 Rēzekne incident the Ministry of Defence stated publicly
that the inter-institutional **information / notification algorithms** must be
reviewed and improved. The problem reported by municipalities and crisis-management
officials was not a single mistake but a **structural misalignment**: no single,
shared, machine-checkable description of who decides what, when, and on which
inputs. UAPF exists precisely to hold that description as versioned, reviewable
artifacts. This package is the AS-IS baseline.
## Residual / open
## Gap register
| # | Reported gap (public record) | Where it lives in the model | TO-BE target |
|---|---|---|---|
| G1 | Cell-broadcast reached Rēzekne city only after residents had already seen/heard the drones; ~40-min lag vs Ludza/Balvi. | `Task_RequestBroadcast``Task_CellBroadcast` | Tighten the trigger so the request is driven by the **predicted corridor**, not by confirmed overflight. `Decision_CellBroadcastScope` already takes `corridorMunicipalities` — make corridor pre-alerting mandatory at `threatLevel = elevated`. |
| G2 | Single point of failure: the alert fires only on an explicit NBS request. NBS stated the alert was not sent to Rēzekne because the "incident duration was too short"; the Interior Minister stated VUGD was ready but "a clear algorithm was not triggered". | `Task_RequestBroadcast` (documented GAP) | Define an explicit fallback authority and a time-boxed escalation: if NBS does not issue / decline a request within N minutes of a confirmed corridor, a named role (KVC duty) may trigger. Model as a boundary timer event on `Task_RequestBroadcast` in v0.2. |
| G3 | Message content too thin — "possible threat" with no nature-of-threat detail; residents phoned municipalities asking whether tanks or drones were coming. | `Decision_CellBroadcastScope` output `messageTemplate` | Replace generic text with typed templates (`MSG_DRONE_IMMINENT`, `MSG_DRONE_POSSIBLE`, `MSG_AIRSPACE_MONITORING`) carrying threat type, recommended action and an information URL. Templates are an output column in the DMN table. |
| G4 | No unified action algorithm across institutions; municipalities reported missing communication with state institutions and unclear ownership (AM vs VARAM vs IZM). | `Task_NotifyAgencies`; `resources/mappings.yaml` | A single resource mapping with explicit RACI per element (this package), reviewed jointly. Notification to KVC, IeM and municipal commissions modelled as a **parallel** branch so it cannot be skipped. |
| G5 | Information on number/origin/landing sites of the drones was unavailable for ~5 hours. | CMMN `Stage_Investigation` (`HT_TechExam`, `HT_OriginAttribution`) | Make investigation a first-class case stage with explicit milestones and an information-publishing cadence, not an ad-hoc activity. |
| G6 | ~3-day delay before clear public acknowledgement of the drones' (Ukrainian) origin created a perception of concealment. | CMMN `HT_OriginAttribution`, `HT_DisinfoMonitor`, `HT_Press` | Decouple "confirm origin" from "inform public": publish what is known on a fixed cadence; disinformation monitoring runs in parallel from the start. |
| G7 | Interception not attempted; criteria ("all safety criteria") were not transparent or pre-agreed. | `Decision_InterceptionAuthorization` | Make the safety criteria an explicit, inspectable DMN table (civilian risk, debris fall-zone, positive ID, firing-position readiness, BAP availability) rather than a verbal judgement. |
| G8 | School-closure and resident-guidance decisions lacked timely recommendations from IZM. | `Task_LocalResponse` (IZM consulted) | Bind IZM as a consulted resource on `Task_LocalResponse` with a pre-agreed guidance template issued automatically at `threatLevel >= elevated`. |
## Modelling stance
- The BPMN / DMN / CMMN in v0.1.0 deliberately model the **AS-IS** algorithm
*plus* the minimum corrections needed for it to be internally consistent
(parallel notification, typed messages, explicit interception table).
- Items requiring a **policy decision** — notably G2 (fallback trigger
authority) — are flagged in `docs/02-raci.md` and left as open questions for
v0.2; they must not be silently encoded by a process author.
- Nothing here is operationally approved. Lifecycle status is `draft`.
## Open questions for the institutional steward
1. **G2** — Who is the named fallback authority if NBS does not act within the
escalation window, and what is the window length?
2. Should cell-broadcast corridor pre-alerting be automatic at
`threatLevel = elevated`, or remain a human decision?
3. Is the cell-broadcast platform owned operationally by VUGD only, or jointly
with VARAM for the early-warning evolution? This changes the `Task_CellBroadcast`
binding.
4. What is the mandated public-information cadence during an active incident
(G5/G6)?
- **G2 escalation authority** is a *proposal*. Whether KVC may authorise a
public broadcast when NBS Joint Staff is unreachable is an institutional and
legal question, not a modelling one, and is flagged for review.
- SLA values in `03-notification-timing-sla.md` are **proposed defaults** for
validation against NBS/VUGD operational reality.

View File

@@ -1,66 +1,26 @@
# 02 — RACI Matrix
> Non-normative supporting document. Human-readable view of the bindings in
> `resources/mappings.yaml`. R = Responsible, A = Accountable, C = Consulted,
> I = Informed. The machine-readable source of truth is the resources cornerstone.
R = Responsible, A = Accountable, C = Consulted, I = Informed.
Bindings in `resources/mappings.yaml` express the **R** column; this matrix
adds the A/C/I context that a single-target binding cannot.
## Actors
| Activity | NBS Joint Staff | NBS Air Def. | VUGD | State Police | NMPD | Municipal | MoD | KVC | IeM / IZM |
|----------|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
| Classify & assess threat | R/A | I | I | – | – | I | I | C | – |
| Determine notification & scope | R/A | – | C | – | – | I | I | C | – |
| Authorise public broadcast | R/A | – | I | – | – | I | I | C* | I |
| Dispatch cell-broadcast | A | – | R | – | – | I | I | I | I |
| Escalate SLA breach | C | – | I | – | – | I | I | R/A | I |
| Authorise interception | R/A | C | – | – | – | – | C | I | – |
| Execute interception | A | R | – | – | – | – | I | I | – |
| Field response | C | – | R | R | R | R | I | A | I |
| Origin investigation | R | – | – | C | – | – | A/C | I | I |
| Public communication | C | – | – | – | – | I | R/A | C | I |
| After-action review | C | C | C | C | C | C | A | R | C |
| Code | Institution / system |
|---|---|
| NBS-SURV | NBS air surveillance and radar network |
| NBS-JS | NBS Joint Staff, operational duty |
| NBS-AD | NBS air-defence units (pretgaisa aizsardzība) |
| NATO-BAP | NATO Baltic Air Policing mission |
| VUGD | VUGD operational duty / 112 |
| CB-SYS | Cell-broadcast system (operated by VUGD) |
| VP | State Police operational duty |
| KVC | Crisis Management Centre |
| AM | Ministry of Defence |
| IeM | Ministry of the Interior |
| VARAM | Ministry of Smart Administration and Regional Development |
| IZM | Ministry of Education and Science |
| MUN-CP | Municipal civil-protection commissions |
| GOV-CC | Government Crisis Management Council |
\* KVC as Consulted today; the proposed G2 fallback would make KVC **R** for
authorising the broadcast on NBS Joint Staff timeout.
## Process steps (BPMN)
| Step | A | R | C | I |
|---|---|---|---|---|
| Classify object & track trajectory | NBS-JS | NBS-SURV | — | — |
| Assess air threat severity | NBS-JS | — | — | — |
| Determine cell-broadcast scope & message | NBS-JS | — | KVC, VARAM | — |
| Issue cell-broadcast request to VUGD | NBS-JS | — | — | — |
| Trigger cell broadcast | VUGD | CB-SYS | — | — |
| Notify KVC, IeM & municipal commissions | — | NBS-JS | — | KVC, IeM, MUN-CP |
| Evaluate interception | NBS-JS | — | AM, NBS-AD, NATO-BAP | — |
| Coordinate interception (BAP / PGA) | — | NBS-AD, NATO-BAP | — | — |
| Activate local civil-protection response | MUN-CP | VP | IZM | — |
| Declare threat ended / all-clear | NBS-JS | CB-SYS | — | — |
| Field response & origin investigation (case) | KVC | — | — | — |
## Case tasks (CMMN)
| Task | A | R | C |
|---|---|---|---|
| Localise & search crash sites | — | NBS-JS | VP |
| Site safety & fire suppression | — | VUGD | — |
| Scene security & access control | — | VP | — |
| Resident enquiries via municipal commissions | — | MUN-CP | — |
| Technical examination of debris | — | NBS-JS | — |
| Origin attribution & EW-diversion analysis | NBS-JS | — | AM |
| Disinformation monitoring & correction | — | AM | — |
| Press conference / public information | AM | — | KVC |
| Cross-institutional after-action review | AM | KVC | — (GOV-CC informed) |
## Known accountability ambiguities (do not resolve in a process draft)
- **Cell-broadcast trigger:** "A" sits with NBS-JS for the *request*, with VUGD
for *execution*. The public failure (G2) is the gap *between* these two "A"s.
A revised algorithm needs an explicit fallback "A" — currently unassigned.
- **Cell-broadcast platform stewardship:** assigned here to VUGD; VARAM may hold
a co-stewardship role for the early-warning system evolution. Confirm before
v0.2.
- **Public-information tempo:** "A" for `HT_Press` is AM, but during the 7 May
incident the perceived delay (G6) suggests the cadence itself needs an owner
and a mandated interval.
**Consulted parties not in `mappings.yaml`:** VARAM (cell-broadcast platform
policy), IZM (school-closure guidance), the State Border Guard, and the
Government Crisis Management Council (informed at national level).

View File

@@ -0,0 +1,46 @@
# 03 — Notification Timing & SLA Model
The 7 May 2026 incident's defining failure was a **~40-minute** gap between a
visible air threat and the public cell-broadcast reaching Rezekne. This package
treats notification speed as a **first-class, modelled quantity** rather than an
implicit expectation.
## The SLA chain
1. `Decision_NotificationUrgency` takes `threatLevel` and the estimated minutes
until the object could reach people, and outputs:
- `notificationTier``immediate | priority | standard | none`
- `broadcastSlaSeconds` — the **maximum** time allowed from authorisation to
confirmed dispatch.
2. `Task_DispatchBroadcast` (VUGD) carries a **non-interrupting boundary timer**
armed at `broadcastSlaSeconds`.
3. If dispatch is not confirmed before the timer fires, `Task_EscalateSla`
runs **in parallel** — it does not cancel the broadcast, it escalates the
delay to the Crisis Management Centre so a human intervenes.
## Proposed SLA defaults
| Threat level | Lead time | Tier | `broadcastSlaSeconds` | Rationale |
|--------------|-----------|------|----------------------:|-----------|
| critical | any | immediate | 120 | Object inside airspace, closing on people. |
| high | ≤ 15 min | immediate | 180 | Little lead time; alert must precede impact. |
| high | > 15 min | priority | 300 | Lead time exists; brief verification window. |
| elevated | any | priority | 600 | Threat present, not yet tracking toward people. |
| low | any | standard | 1800 | Advisory only. |
| none | – | none | 0 | No public broadcast. |
Against these defaults, the Rezekne broadcast (~2400 s) breached even the most
lenient non-zero SLA **by an order of magnitude**. Under this model the boundary
timer would have fired at 120–180 s and escalated to KVC ~38 minutes earlier.
## Guardrail
`broadcastSlaSeconds` is a **hard floor for escalation, not a target for
dispatch** (guardrail GR-3). Dispatch should normally be far faster; the SLA is
the line past which the absence of a broadcast becomes its own incident.
## Open for validation
The table values are **modelling proposals**. They need calibration against
real NBS classification timelines and VUGD cell-broadcast dispatch latencies
before the package can leave `draft`.

View File

@@ -0,0 +1,50 @@
# 04 — UAPF-IP Integration
How a UAPF-IP (Integration Profile) host runs this package.
## Profiles
The manifest declares `uapf-ip-orchestrated` and `uapf-ip-sync-decision`:
- **orchestrated** — the host executes the BPMN process, calling host
capabilities (`task.assign`, `task.complete`, `task.escalate`, `event.emit`,
`timer.schedule`) and evaluating DMN decisions at each business-rule task.
- **sync-decision** — any of the six decisions can be evaluated standalone, as
a synchronous request/response, without running the process.
## Exposed entrypoints
`exposure.mcp.exposedEntrypoints` maps the process and each decision to an MCP
tool name, e.g. `interception_authorization.evaluate`. A UAPF-IP host with MCP
exposure enabled publishes these as callable tools. `runnable: true` permits
process execution, not only inspection.
## Required capabilities
`requires_capabilities` lists what the host must provide. Beyond the generic
task/event capabilities, this package needs:
- `timer.schedule@1+` — to arm the SLA-breach boundary timer.
- `ai.classify@1+`, `ai.complete@1+` — for the advisory threat-assessment agent.
- `lv.gov.civdef.air_surveillance_feed@1+`, `lv.gov.civdef.cell_broadcast@1+`
domain capabilities that wrap the NBS surveillance feed and the VUGD
cell-broadcast platform.
A host missing a required capability must refuse to load the package rather
than degrade silently.
## Guardrail enforcement
Every capability call is checked against `resources/guardrails.yaml` before and
after execution. The load-bearing guardrails: AI is advisory only (GR-1), no
autonomous use of force (GR-2), the SLA boundary timer may not be disabled
(GR-3), and public messaging is human-authored from templates (GR-4). A
violation **blocks** the call and is written to the audit trail.
## Decision/process boundary
The host owns orchestration, capability brokering, audit and guardrail
enforcement. The package owns **only** the logic — process shape, decision
tables, case structure and resource bindings. The package contains no
credentials; the placeholders in `resources/mappings.yaml` are resolved by the
host from its own secret store.

View File

@@ -0,0 +1,42 @@
# 05 — Validation Report
Package: `lv.civdef.drone-threat-public-address` v0.3.0
Date: 2026-05-18 · Tool: `validate.py`
## Result: 19 / 19 checks passed
### Structural
- All three cornerstone files (BPMN, DMN, CMMN) are well-formed XML.
- All six YAML files parse.
- `uapf.yaml` validates against `uapf-manifest.schema.json` (UAPF v2.2.0).
### Model integrity
- BPMN: 26 flow nodes; every `sequenceFlow` source/target resolves.
- DMN: exactly 6 decisions; every `informationRequirement` href resolves.
- CMMN: 11 human tasks across 3 stages.
### Quality gates added in v0.3.0 (these are the v0.2.0 defects)
- **Every DMN decision carries a `<description>`.** v0.2.0 had none.
- **No declared-but-unused decision inputs.** Every `requiredInput` of every
decision is used as a decision-table input column or in an output
expression. This is the check that proves the v0.2.0 interception defect —
`positiveHostileId` declared but never tested — is fixed.
- **Every `mappings.yaml` binding resolves to a real diagram element**, and
every `targetId` resolves to a declared target. The resource↔process linkage
is now machine-checkable.
## What is *not* validated here
- **Semantic correctness of the modelled algorithm** — whether these are the
right institutions, thresholds and SLAs — is an institutional review
question, tracked in `01-institutional-gap-analysis.md`.
- **DMN completeness/overlap** of `FIRST`-hit tables is not formally verified;
each table ends with a catch-all rule so no input is left without an output.
- Diagram interchange (DI) renders cleanly in `dmn-js` / `bpmn-js` / `cmmn-js`;
visual review in the target viewer is still recommended.
## Reproduce
```
python3 validate.py # exits non-zero on any failure
```