# Threat prioritization under uncertainty — delivery package

A decision-support prototype. It answers two different questions from one belief state:
**what to act on now**, and **where to look next**. Conflating those is the standard failure
mode, and separating them is the point of the artifact.

All data is simulated. Every constant is a synthetic placeholder and represents no real system.

---

## In order, by how much time you have

**Two minutes** — `demo.mp4`. Two minutes eleven seconds, no narration needed. Guided mode pauses
at each beat with a one-line note on what to watch.

**Five minutes** — `EXPLAINER.pdf`, three pages. The model, and pre-emptive answers to the three
questions a skeptical engineer asks: why uncertainty does not raise the score, why staleness is
variance growth rather than a penalty, and what the attention column actually computes.

**Fifteen minutes** — open `build/index.html` from a local web server and drive it yourself.
It is a static bundle, no backend, no network calls.

```bash
cd build && python3 -m http.server 8000    # then http://localhost:8000
```

(A plain `file://` open will not work — the engine runs in a Web Worker, which browsers require
to be served over HTTP.)

**Longer** — `source/`. Build and test instructions in `README.md`.

---

## What is in here

| Path | What it is |
|---|---|
| `demo.mp4` | 2:11 screen recording of the full scenario, including an operator override |
| `EXPLAINER.pdf` | 3-page technical explainer (`EXPLAINER.md` is the same text) |
| `README.md` | run instructions, layout, and the model in brief |
| `build/` | static production bundle, 240 KB |
| `source/` | full source archive |
| `screenshots/` | three key moments, in case video is inconvenient |
| `evidence/frames.json` | every frame of a headless scenario run |
| `evidence/test-output.txt` | full test output, 81 tests |

## The three screenshots, and why each one

1. **Sensor dropout.** Four tracks stop updating. Their action ranks hold — staleness never moves
   a mean — while their uncertainty grows eightfold and they climb the attention column.
2. **Deadline crossing.** A track peaks at rank 1, crosses its response deadline, and leaves the
   actionable list entirely. Nothing is scheduled at that moment; it is the dynamics. The naive
   time-to-impact baseline, ghosted in the third column, still ranks it near the top.
3. **Operator constraint.** A person suppresses the top-ranked track. The belief state is
   untouched — same score, same band — and the track immediately becomes the top attention
   priority, carrying the exact expected regret that excluding it introduced. The system does not
   argue with the operator; it carries out the instruction and reports the price.

## On reproducibility

Seeded throughout. `evidence/frames.json` was produced by a headless run with no browser; running
it again produces a byte-identical file. Scenario behaviours are asserted by tests rather than
described in prose, so a change that stops a behaviour from occurring fails the suite instead of
quietly becoming a different demo.

Human overrides go through the same event path as sensor reports, so an operator decision replays
identically and appears in the frame dump. That was deliberate: an override that could not be
replayed would be the one non-reproducible thing in the system.

## Scope

Deliberately not included: multi-source fusion, asset or interceptor assignment, geospatial views,
learned models. Every weight lives in one documented file (`src/engine/config.ts` in the source
archive) because the goal is a prioritization core that can be argued with, not one that hides its
reasoning.

The engine directory imports nothing outside itself — no React, no simulation code. It is
synchronous, deterministic given a seed, and can be run, tested, and challenged on its own.
