correlator: remove is_dispatch and the tactical fit path entirely (#134)
Full removal, not a hardcoded flag: _is_dispatch_channel, _DISPATCH_TG_RE, the is_dispatch parameter, and _call_fits_incident's tactical branch are gone. One evaluation path for every channel. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Tbknwttzou4s46PAykmtix
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
0473e6a583
commit
b1884852d5
@@ -111,55 +111,17 @@ async def upload_call_audio(
|
||||
|
||||
def _recent_incident_on_same_talkgroup(ctx: dict) -> bool:
|
||||
"""
|
||||
True when one of the already-loaded recent incidents is running on this
|
||||
call's own system + talkgroup AND was active within the last
|
||||
`settings.tg_dispatch_thin_idle_minutes` minutes. Covers the "unit
|
||||
dispatched on the dispatch channel, thin acknowledgement 10-30s later"
|
||||
case: the ack carries no substance of its own but plainly belongs to the
|
||||
job just opened.
|
||||
True when a recent incident is running on this call's own system +
|
||||
talkgroup, within `settings.tg_dispatch_thin_idle_minutes` (5 min) —
|
||||
applied uniformly regardless of the talkgroup's name (server-26#134).
|
||||
Covers "unit dispatched, thin ack 10-30s later": the ack has no
|
||||
substance of its own but plainly belongs to the job just opened.
|
||||
|
||||
Always uses `settings.tg_dispatch_thin_idle_minutes` (5 min), regardless
|
||||
of what the talkgroup is named. An earlier version of this branched on
|
||||
`_is_dispatch_channel` (mirroring incident_correlator.py's fast/thin idle-
|
||||
window selection) to use a longer 15-minute window on anything not
|
||||
literally named "dispatch"/"patched"/"primary" — owner correction,
|
||||
2026-09-13, from direct scanning experience: a talkgroup named "tac"/
|
||||
"tactical" genuinely does see materially different traffic only during a
|
||||
real incident, and that's rare; the overwhelming majority of traffic on
|
||||
ANY monitored channel — including high-risk stops and pursuits — runs on
|
||||
the main channel regardless of what it's named. `_is_dispatch_channel`'s
|
||||
string-match is a naming-convention guess, not a detector of actual
|
||||
channel behavior, and trusting it here meant a busy single-channel
|
||||
department not literally named "dispatch" would silently get the more
|
||||
permissive window and reproduce #115's original bug. One constant,
|
||||
applied uniformly, is the safer default; a real low-volume channel is the
|
||||
rare case, not the norm, so erring toward the tighter window costs little.
|
||||
NOT applied to incident_correlator.py's own fast/thin selection (out of
|
||||
scope for this pass — a bigger, decision-changing surface, worth its own
|
||||
review rather than changing under this fix).
|
||||
|
||||
This used to be a plain "does any recent incident exist on this
|
||||
talkgroup" check against a 2-hour window (`correlation_window_hours`).
|
||||
Measured live in production (server-26#115, CORRELATION_REVIEW_0912.md,
|
||||
window #3): on a busy dispatch channel producing 3-13 incidents per 2h,
|
||||
that condition is satisfied almost unconditionally, so the surrounding
|
||||
LLM-orphan gate never fired on exactly the channels it exists to
|
||||
protect (0/24 target-shaped calls gated in a 4h window). The docstring's
|
||||
own intent was always "10-30 seconds", not "hours" — a few minutes is
|
||||
the right shape.
|
||||
|
||||
Reads ctx["recent"] — the same window-filtered candidate list the rules
|
||||
engine already loaded — so this adds no Firestore read.
|
||||
|
||||
Known limitation (server-26#115): ctx["recent"] is derived from
|
||||
`all_active` in `_build_context` — incidents with `status=="active"`
|
||||
for the call's org, with over-capacity incidents already dropped by
|
||||
`_drop_capped` — not a full scan of the `incidents` collection. A
|
||||
same-talkgroup incident that has already auto-resolved (no longer
|
||||
"active") or hit `incident_max_calls`/`incident_max_duration_minutes`
|
||||
will NOT appear here even though it is chronologically recent. A proper
|
||||
fix needs a dedicated Firestore query that is not status/capacity
|
||||
filtered — a new read, out of scope for this pass.
|
||||
Reads ctx["recent"] (the rules engine's own candidate list — no extra
|
||||
Firestore read). That list is status=="active" incidents only, so an
|
||||
already-resolved or capacity-capped same-talkgroup incident won't be
|
||||
seen here even if chronologically recent (server-26#115, unresolved —
|
||||
would need a dedicated non-status-filtered query).
|
||||
|
||||
Whether this limitation explains the 2/24 unexplained gate misses in the
|
||||
window #3 measurement is UNANSWERED, not confirmed either way — a prior
|
||||
|
||||
Reference in New Issue
Block a user