Cam 2 in my demo's night shift holds a real fall, my classifier scores it at 0.99, and the engine still declines to call it a fall. It emits ROUTE TO HUMAN at low confidence, writes the reason into the Decision Ledger, and leaves the scoreboard reading 1 of 2 real falls caught.
Vigil is the fall-detection intelligence layer I built for senior living: privacy-preserving radar features in, one of ALERT, SUPPRESS, or ROUTE TO HUMAN out, with a filable reason on every one. The night shift it replays is synthetic by construction, twelve labeled events across a Memory Care East Wing between 02:00 and 06:00, seeded so the run repeats. I wrote the two-occupant room in on purpose, because the case a demo normally edits out is the one I wanted on screen.
The event I wrote into Cam 2 so it would break my own engine
I authored Cam 2 as a genuine fall in the ground-truth labels, in a bedroom (Room 221 in the incident record) with two people present. The four-feature classifier, fusing floor proximity, impact energy, descent drop and radar cross-section, returns a calibrated P(fall) of 0.99 on it.
What I could not give it was the second target. Single-person tracking sits outside V1 coverage, so a confident score computed over a two-occupant room is confident about nothing in particular. The deterministic policy gate returns ROUTE TO HUMAN and writes the reason on the dashboard as a sentence rather than a threshold dump: "2 targets in room: Single-person tracking out of V1 coverage -> routed to staff check at LOW confidence (not asserted as a fall)."
The naive incumbent I benchmark against has no such problem. Its whole rule is that any fast or low motion is a fall, so it fires on Cam 2 and, on this single event, looks better than mine.
routed to staff check at LOW confidence (not asserted as a fall)". Above it the 02:54 row reads ALERT for Cam 3 Bathroom, and below it 02:04 reads SUPPRESS for Cam 1 Bedroom on a masked ceiling fan.">
The Cam 2 tile reads "Low Confidence → Human Check" while Cam 3 carries the confirmed long-lie. The route and the confirmed alert sit on adjacent rows in the same ledger.
Why I kept the model's number out of the verdict
I designed the cascade so the deterministic tests run first and the model's score is consulted last, and Cam 2 is where that costs me something. The temporal narrative verifier ahead of it is plain Python requiring all four conditions inside one 8-second window, with standing established in the opening fifth: standing above 1.2 m, a drop past 0.6 m paired with a peak velocity above 1.8 m/s, a sustained broadband impact measured as a three-frame rolling mean above 0.50 so a single-frame spike cannot satisfy it, and the centroid actually reaching below 0.30 m. Only after all four hold does the gate check breathing confirmation and P(fall) against a fixed 0.70 floor that the model does not set. A model can never manufacture an alert on its own in this cascade; it advises, and the code decides.
Cam 2 never becomes a fall claim at all. A separate rule in the same gate intercepts a multi-occupancy event and sends it to a staff check on the model's score alone, rather than letting a high score turn into an assertion. I would rather a nurse walk to Room 221 because the system said "go look" than have her learn that "Fall Detected" sometimes means two people were moving and the math got optimistic.
The scoreboard I did not round up
I typed 1/2 into the Shift Results card myself, and it was the least comfortable line of copy in the build. Two real falls occurred in this shift: the engine alerted on one and routed the other to a human. Counting the route as a catch would have been one string change and a 2/2 nobody would have audited.

The routed fall is logged as a route. The scoreboard does not promote it to a catch, and the 0.0 and the 100% belong to the fixed 360-event synthetic set behind them.
The one it did assert is Cam 3, the bathroom long-lie (Room 118B in the incident modal). The centroid runs from 1.53 m standing to 0.119 m, breathing present, no recovery: ALERT at 0.99 confidence, 4.8 seconds of floor time, escalation armed at CNA now, Charge Nurse at 90 seconds, DON at 180. The panel shows impact-to-alert as 7 seconds, which the gate computes from the configured hold timer instead of clocking it, so I quote it as displayed and nothing more.
That room is the reason I built on radar at all. Nineteen US states have enacted laws governing cameras in nursing-home rooms, generally permitting them in a resident's room with consent, while bathrooms stay excluded in practice on privacy grounds. Radar features carry no image, which is what lets them sit in the highest-risk room, the one place a camera is not a usable option.

Cam 3 · Bathroom, where the room id first appears: the dispatch payload, the escalation ladder, and the incident note composed from the structured audit evidence.
I spent longer on one ledger sentence than on the classifier
I rewrote that Cam 2 ledger line more times than I tuned the model that produced its 0.99, and every suppression got the same treatment. Cam 6 · Bedroom is the one I show people. The record does not say "no fall detected"; it names the target as non-human on the deciding feature, a radar cross-section of 0.27, under the human minimum. That is a therapy dog with a horizontal aspect ratio of 1.7, moving low across a resident's floor and dropping the centroid the way a fall does, and the ledger says so in a sentence a charge nurse can read without me in the room. The rest carry their deciding value the same way: Cam 10 · Bathroom logs a hard sit whose 3.31 m/s burst matches a real fall's as "Velocity burst but centroid settled at 0.44 m (seat height), not floor; no hard impact", and Cam 1 · Bedroom logs a ceiling fan as fixed-location clutter at (1.5, 1.5, 2.45 m), masked on that room's own calibration map.

A suppression opens to the same depth as an alert: the deciding feature value, in the record, for the event where nothing happened.
A state survey asks why the panel did not light up, in a specific room, at a specific minute, and "the model was under threshold" is not a filable answer. So the shift audit exports every alert, route and suppression with the feature values that decided it. The clinical incident note is composed separately from that structured evidence, and drops to a deterministic template when no provider is reachable, which is what the note on my screen is.
What made the refusal affordable
I only got to refuse on Cam 2 because the engine had spent the rest of the night not crying wolf. Across the shift it produced 1 alert, 1 route, 10 suppressions and 0 false alarms, while the naive baseline produced 9 alerts of which 7 were false. Alarm fatigue, not sensitivity, is the documented reason these deployments fail, with off-the-shelf sensors running 5 to 15 false alarms per room per day until night staff mute the panel and the system detects nothing at all.
On a fixed set of 360 labeled, noisy synthetic events, a run I re-checked more than once because the numbers came back looking too clean, my cascade reports 1.0 recall and 1.0 confounder specificity against the baseline's 0.167, with 40 of 40 multi-occupancy falls routed to a human correctly.
The objection to that pair of 1.0s is one I will make before a reviewer does: the fusion weights were fit on the demo's own scenario generators, the same ones that produce the golden set, so it is an internal-consistency result, not production accuracy and not clinical validation. The 0.0 false alarms per room per day on that set assumes 30 benign triggers per room; a real pilot targets under 2 per room per day after shadow-mode calibration.
What I stopped believing about sensitivity
I started this thinking the hard engineering was in catching the fall. The naive baseline scores the same 1.0 recall as my cascade and is still worthless, because at 0.167 specificity it buries the one true alert under seven false ones. The expensive engineering is all in the refusal: the clutter map that knows a fan's voxel, the sustained-impact test that will not accept a single-frame spike, and a gate written so a surveyor rather than a model can read why the system did what it did. I have put the whole shift, ledger and audit included, in the Vigil demo.
Half of older adults who lie on the floor for more than an hour die within six months, and that number is why I did not soften Cam 2 into a catch. A night nurse who has learned to distrust a panel mutes it, and then the mortality number is the one deciding the outcome. I would rather hand her one alert, one "go look," ten written reasons for the silence, and the plain admission that on Cam 2 the system knew something happened and could not prove what.