1
0

Import UAPF package: lv-civdef-drone-threat-public-address (1).uapf

This commit is contained in:
2026-05-18 09:12:17 +00:00
parent eabcf2d4fd
commit 3da6362c49
15 changed files with 1509 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
# 00 — Incident Chronology: Rēzekne Drone Incident, 7 May 2026
> 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.
## Summary
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.
## Timeline
| 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. |
## Aftermath
- **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.
## 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.

View File

@@ -0,0 +1,51 @@
# 01 — Institutional Gap Analysis (AS-IS) and TO-BE Targets
> 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.
## Why this package exists
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.
## 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)?

66
docs/02-raci.md Normal file
View File

@@ -0,0 +1,66 @@
# 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.
## Actors
| 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 |
## 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.

View File

@@ -0,0 +1,114 @@
# 03 — UAPF-IP Integration
> Non-normative supporting document. Explains how this package binds to a
> UAPF-IP host/runtime and to an MCP surface. The normative integration
> contract lives in the manifest (`uapf.yaml`) and `resources/guardrails.yaml`.
> Reference: UAPF-IP `SPEC.md` v0.1 and `specification/06-mcp-integration.md`.
## 1. How this package plugs into a runtime
UAPF-IP separates the **runtime** (loads this package, orchestrates the flow)
from the **host** (provides the capabilities the flow needs). At session start
the runtime reads `requires_capabilities` from the manifest and verifies the
host can fulfil every one; if not, the session is refused.
### Capabilities this package requires
Declared in `uapf.yaml` under `requires_capabilities`:
| Capability | Namespace | Used for |
|---|---|---|
| `task.assign@1+` | reserved | Assigning field-response and case work items |
| `task.complete@1+` | reserved | Closing assigned work items |
| `task.escalate@1+` | reserved | Escalating the broadcast request (GAP G2 fallback) |
| `event.emit@1+` | reserved | Emitting incident domain events for audit |
| `ai.classify@1+` | reserved | Air-threat severity recommendation; disinfo classification |
| `ai.complete@1+` | reserved | Origin-attribution analysis assistance |
| `lv.gov.civdef.air_surveillance_feed@1+` | user-defined | Reading the radar/track feed |
| `lv.gov.civdef.cell_broadcast@1+` | user-defined | Triggering the public cell broadcast |
`task.*`, `event.*` and `ai.*` are reserved UAPF-IP v0.1 namespaces. The two
`lv.gov.civdef.*` capabilities are **user-defined** (reverse-DNS root, per the
UAPF-IP namespace rules) because no reserved namespace covers a national
cell-broadcast or a military surveillance feed. A host that operates the VUGD
cell-broadcast platform would publish the `lv.gov.civdef.cell_broadcast` schema
alongside it. (`notify.*` is reserved for UAPF-IP v0.2 but not yet specified, so
the cell broadcast cannot use it today.)
### Profiles
`profiles_supported` declares two UAPF-IP v0.1 profiles:
- **`uapf-ip-orchestrated`** — the BPMN flow with human tasks, parallel
branches and the field-response case is an orchestrated process.
- **`uapf-ip-sync-decision`** — each DMN decision (`Decision_AirThreatSeverity`,
`Decision_CellBroadcastScope`, `Decision_InterceptionAuthorization`) can be
evaluated synchronously in a single round-trip, independent of the flow.
## 2. Guardrails
`resources/guardrails.yaml` is the policy snapshot the runtime attaches to every
session (immutable for the session lifetime, UAPF-IP SPEC §6/§10). It is
referenced from the manifest via `guardrails: resources/guardrails.yaml`.
Key constraints, and why:
- `max_confidence_for_autocomplete: 0.0` — the AI may **never** autonomously
complete a step. In a national public-warning process every AI output is a
recommendation a human confirms. This is reinforced by
`metadata/policies.yaml` (`delegation.allowAgentDelegation: false`).
- `human_oversight.required_for` — cell-broadcast dispatch, interception
authorization, public communication and incident closure all require a human
(the NBS Joint Staff duty officer).
- `ai.forbidden_inputs` — classified radar tracks, residents' personal data and
source-identifying OSINT must never reach a model; `pii_redactor: required`.
- `audit.vc_signature_per_step: required`, `retention_years: 10` — every step
emits a DID-VC-signed CloudEvents record (UAPF-IP SPEC §7).
## 3. MCP endpoint
Per `specification/06-mcp-integration.md`, a UAPF package is exportable to an
MCP surface in **Package → MCP** mode. This package declares its MCP exposure in
the manifest under `exposure.mcp`:
```yaml
exposure:
mcp:
enabled: true
runnable: true
exposedEntrypoints:
- { process: Process_DroneThreatPublicAddress, tool: drone_threat_public_address.run }
- { decision: Decision_AirThreatSeverity, tool: air_threat_severity.evaluate }
- { decision: Decision_CellBroadcastScope, tool: cell_broadcast_scope.evaluate }
- { decision: Decision_InterceptionAuthorization, tool: interception_authorization.evaluate }
exposedArtifacts: [manifest, bpmn, dmn, cmmn, docs]
```
A conforming UAPF→MCP implementation importing this `.uapf` package MUST expose
the standard tool set — `uapf.describe`, `uapf.list`, `uapf.run_process`,
`uapf.evaluate_decision`, `uapf.resolve_resources`, `uapf.get_artifact`,
`uapf.validate` — and the standard resources `uapf://manifest/...`,
`uapf://bpmn/...`, `uapf://dmn/...`, `uapf://cmmn/...`, `uapf://policies/...`,
`uapf://bindings/...`.
The four `exposedEntrypoints` become directly runnable/evaluable tools:
`uapf.run_process` against `Process_DroneThreatPublicAddress`, and
`uapf.evaluate_decision` against each of the three decisions.
### MCP-reachable resource targets
Two binding targets in `resources/mappings.yaml` are themselves reached over
MCP, so the process composes with other MCP services:
- `agent.threat-assessment``type: ai_agent`, `endpoint: mcp://agents/civdef-threat-assessment`
- `mcp.osint-monitor``type: mcp_tool`, `endpoint: mcp://lv-civdef/osint-monitor`
All endpoints and `configRef` credential references in the mapping are
illustrative placeholders for this draft and must be set to real values before
any non-development use.
## 4. Status
The integration surface is declared but not deployed. `metadata/policies.yaml`
restricts `allowedEnvironments` to development and staging, and lifecycle status
is `draft`.

View File

@@ -0,0 +1,83 @@
# 04 — Validation Report
> Records the conformance status of this package against UAPF specification
> **v2.2.0** (repo `UAPFormat/UAPF-specification`, `VERSION` = 2.2.0).
## Result
```
BPMN tasks: 11 | DMN decisions: 3 | CMMN tasks: 9 | targets: 11 | bindings: 19
ERRORS: 0
WARNINGS: 0
RESULT: PASS — package is UAPF v2.2.0 conformant
```
## What was validated
Schema validation (`schemas/**`, JSON Schema draft 2020-12):
- `uapf.yaml` against `uapf-manifest.schema.json` — PASS
- `resources/mappings.yaml` against `resource-mapping.schema.json` — PASS
- `metadata/ownership.yaml` against `ownership.schema.json` — PASS
- `metadata/lifecycle.yaml` against `lifecycle.schema.json` — PASS
- `metadata/policies.yaml` against `policies.schema.json` — PASS
- `enterprise/enterprise.yaml` against `enterprise-index.schema.json` — PASS
Structural checks (`07-package-format.md`, `04-folder-structure.md`):
- Level-4 package has ≥1 `.bpmn` file, `resources/mappings.yaml`, and both
mandatory metadata files — PASS
Semantic rules (`11-semantic-validation.md`):
- SEM-001 BPMN/CMMN element references resolve — PASS
- SEM-002 DMN decision references resolve — PASS
- SEM-003 binding `targetId` values exist in `targets` — PASS
- SEM-009 no duplicate binding for the same source — PASS
- SEM-011 every cornerstone carries OMG diagram interchange (BPMNDI / DMNDI /
CMMNDI) — PASS
- SEM-004/005/006/010 (warnings) — none raised: every user task is bound, no
unused targets, declared `requiredCapabilities` match target capabilities,
all fallback targets resolve
YAML safety (`12-yaml-guidelines.md`): manifest `version` is a quoted string.
## How to re-validate
```
python3 validate.py <workspace-root> <path-to-UAPF-specification-repo>
```
`validate.py` is included at the workspace root. It loads the schemas directly
from a checkout of `UAPFormat/UAPF-specification` and implements the schema,
structural and SEM-001..011 rules.
## Two upstream issues found in the specification repository
This package follows the **normative specification text**, which
`specification/00-ssot.md` declares authoritative over any tool or example.
While validating, two defects were found in the spec repo itself — neither is a
defect in this package, but both are worth reporting to `UAPFormat`:
1. **Stale reference CLI.** `tools/uapf-cli/uapf.py` checks for `*.bpmn.xml`
files, but `specification/07-package-format.md` ("File naming") normatively
requires the `.bpmn` / `.dmn` / `.cmmn` extensions, and the canonical
examples (`examples/minimal-l4-package/bpmn/process.bpmn`,
`examples/approve-expense-l4/bpmn/approve-expense.bpmn`) use `.bpmn`.
Consequently the reference CLI wrongly rejects a spec-conformant Level-4
package with: `ERROR: Level 4 requires at least one *.bpmn.xml file`.
This package uses `.bpmn` / `.dmn` / `.cmmn` per the normative text.
2. **Malformed schema JSON.** `schemas/enterprise-index.schema.json` contains
regex patterns with raw `\.` and `\s` escapes that are not valid JSON
string escapes, so a strict JSON parser fails to load it
(`Invalid \escape: line 28`). The bundled `validate.py` works around this by
repairing the escapes on load; the upstream schema file should be fixed
(double the backslashes).
## Status
`lifecycle.status: draft`. Conformance is structural and semantic only — it
does **not** mean the modelled algorithm is operationally approved. The
institutional gaps and open policy questions in `01-institutional-gap-analysis.md`
must be resolved before any change to `approved`.