correlator/intelligence: let 10-8s actually close incidents
Replay of 09-22 10:00-12:00 ET (server-26#170): 0 of 19 incidents resolved on a clear, 19 on the idle timer, although 25 transmissions said 10-8/clear. Three independent breaks: 1. Short clears never reached extraction. "45-9, I'm clear." is <=5 words, so extract_scenes skipped it before GPT and cleared_units stayed empty. A rule parser now names the unit when it precedes the status word (never guesses: "10-8, 10-8." / "CMT clear." clear nobody) and returns a minimal scene that links by unit overlap but cannot open an incident. 2. Clearance compared unit strings exactly, so "11-Adam" clearing never removed "11 Adam". Now by _normalize_unit key. 3. units_active collected "Desk", "Central", "Division", "unknown", plate phonetics — none of which ever clear, so all-clear could never pass. Only units carrying a number (and not a ten-code) are tracked now; the rest stay in `units` for matching. c2-core: 463 pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
6e82ee8579
commit
8eac32caf5
@@ -0,0 +1,43 @@
|
||||
"""
|
||||
Dispatch→10-8 lifecycle, as measured by the first replay (server-26#170):
|
||||
0 of 19 incidents resolved on a clear although 25 transmissions said one.
|
||||
Three independent breaks, each pinned here.
|
||||
"""
|
||||
from app.internal import incident_correlator as ic
|
||||
from app.internal.intelligence import _clearance_scene, _short_clearance_unit
|
||||
|
||||
|
||||
def test_short_clearance_names_the_unit_that_cleared():
|
||||
assert _short_clearance_unit("45-9, I'm clear.") == "45-9"
|
||||
assert _short_clearance_unit("Vehicle 1, clear.") == "Vehicle 1"
|
||||
assert _short_clearance_unit("11 Adam, clear") == "11 Adam"
|
||||
assert _short_clearance_unit("Car 12 10-8") == "Car 12"
|
||||
|
||||
|
||||
def test_short_clearance_never_guesses():
|
||||
for t in ("10-8, 10-8.", "CMT clear.", "10-8, I'm back now. Clear.",
|
||||
"10-8, thank you.", "Show us 10-8, post 4.", "7, Charlie Central.", "10-4."):
|
||||
assert _short_clearance_unit(t) is None, t
|
||||
|
||||
|
||||
def test_clearance_scene_cannot_open_an_incident():
|
||||
scene = _clearance_scene("45-9, I'm clear.", "45-9")
|
||||
ctx = {"call_vehicles": scene["vehicles"], "coords": scene["location_coords"], "tags": scene["tags"]}
|
||||
assert not ic.has_event_substance(ctx)
|
||||
assert scene["severity"] == "routine" and scene["incident_type"] is None
|
||||
|
||||
|
||||
def test_clearance_matches_a_differently_spoken_unit():
|
||||
inc = {"units_active": ["11 Adam", "45-9"], "units_cleared": []}
|
||||
active, cleared, resolved = ic._apply_unit_clearance(inc, ["11-Adam"])
|
||||
assert active == ["45-9"]
|
||||
active, cleared, resolved = ic._apply_unit_clearance(
|
||||
{"units_active": active, "units_cleared": cleared}, ["45 9"])
|
||||
assert active == [] and resolved
|
||||
|
||||
|
||||
def test_only_numbered_units_hold_an_incident_open():
|
||||
for junk in ("Desk", "Central", "Division", "sergeant", "unknown", "John", "Zebra", "10-8", "10 4"):
|
||||
assert not ic._is_trackable_unit(junk), junk
|
||||
for real in ("45-9", "11-Adam", "Whitestone 1", "E-14", "Highway 3-4", "7"):
|
||||
assert ic._is_trackable_unit(real), real
|
||||
Reference in New Issue
Block a user