correlator: gate LLM-orphan against rules-new instead of escalating to tiebreak (#115) #125
@@ -141,6 +141,14 @@ def _call_is_substanceless(ctx: dict) -> bool:
|
|||||||
"""
|
"""
|
||||||
from app.internal import incident_correlator
|
from app.internal import incident_correlator
|
||||||
|
|
||||||
|
# The incident-creation gate skips the has_event_substance check entirely
|
||||||
|
# when a type resolved (incident_correlator._run_decision ~:1397), so a
|
||||||
|
# typed call — fire/medical/etc. — opens an incident on substance we do not
|
||||||
|
# re-check here. reassignment=True is dispatch pulling a unit onto a NEW
|
||||||
|
# job (units are blanked at :296 for exactly that reason): the strongest
|
||||||
|
# new-incident signal in the pipeline. Either one means "keep the tiebreak".
|
||||||
|
if ctx.get("incident_type") or ctx.get("reassignment"):
|
||||||
|
return False
|
||||||
if (ctx.get("call_severity") or "routine") in ("moderate", "major"):
|
if (ctx.get("call_severity") or "routine") in ("moderate", "major"):
|
||||||
return False
|
return False
|
||||||
if incident_correlator.has_event_substance(ctx):
|
if incident_correlator.has_event_substance(ctx):
|
||||||
|
|||||||
@@ -133,6 +133,25 @@ async def test_call_with_vehicles_is_not_gated():
|
|||||||
m_tiebreak.assert_called_once()
|
m_tiebreak.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
|
async def test_call_with_resolved_incident_type_is_not_gated():
|
||||||
|
# The creation gate skips has_event_substance when a type resolved, so a
|
||||||
|
# typed call (fire/medical/…) opens an incident on substance the gate does
|
||||||
|
# not re-check — it must keep the tiebreak, not be dropped.
|
||||||
|
m_apply, m_tiebreak = await _run_consensus(
|
||||||
|
_preview("new", {}, ctx={"incident_type": "fire"}), _llm("orphan"),
|
||||||
|
)
|
||||||
|
m_tiebreak.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
|
async def test_reassignment_call_is_not_gated():
|
||||||
|
# reassignment=True is dispatch pulling a unit onto a NEW job (units are
|
||||||
|
# blanked for exactly that reason) — the strongest new-incident signal.
|
||||||
|
m_apply, m_tiebreak = await _run_consensus(
|
||||||
|
_preview("new", {}, ctx={"reassignment": True}), _llm("orphan"),
|
||||||
|
)
|
||||||
|
m_tiebreak.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
async def test_recent_incident_on_same_talkgroup_is_not_gated():
|
async def test_recent_incident_on_same_talkgroup_is_not_gated():
|
||||||
ctx = {
|
ctx = {
|
||||||
"system_id": "sys-1",
|
"system_id": "sys-1",
|
||||||
|
|||||||
Reference in New Issue
Block a user