Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e30d594eea | ||
|
|
187b8c1500 |
@@ -1598,7 +1598,15 @@ def _call_fits_incident(
|
||||
Thin calls (no units/vehicles/coords) never reach this function —
|
||||
they are intercepted before it in correlate_call.
|
||||
"""
|
||||
idle_min = _incident_idle_minutes(inc, now) if now is not None else 9999.0
|
||||
# Gate comparisons in this function must use the unsigned distance, not the
|
||||
# signed value: the re-correlation sweep anchors `now` to the call's own
|
||||
# started_at, which can be earlier than the incident's last activity and
|
||||
# send the signed value negative — silently defeating every `idle_min`
|
||||
# gate below (content-divergence veto and the tactical default alike).
|
||||
# See `_idle_gate_minutes` docstring. The signed value is reported to
|
||||
# callers separately as `corr_incident_idle_min` (they compute it via
|
||||
# `_incident_idle_minutes` themselves) — nothing here needs it.
|
||||
idle_min = _idle_gate_minutes(inc, now) if now is not None else 9999.0
|
||||
inc_id = inc.get("incident_id", "?")
|
||||
|
||||
# ── 1. Unit overlap ───────────────────────────────────────────────────────
|
||||
|
||||
@@ -23,9 +23,10 @@ Three defects combined to produce it, and each has cases below:
|
||||
import pytest
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from app.config import settings
|
||||
import app.internal.incident_correlator as correlator_mod
|
||||
from app.internal.incident_correlator import (
|
||||
_run_decision, _is_thin_call, _idle_gate_minutes,
|
||||
_incident_at_capacity, _incident_span_minutes,
|
||||
_incident_at_capacity, _incident_span_minutes, _call_fits_incident,
|
||||
)
|
||||
|
||||
NOW = datetime(2026, 8, 20, 7, 0, 0, tzinfo=timezone.utc)
|
||||
@@ -221,6 +222,49 @@ def test_back_dated_thin_call_does_not_sail_through_the_recency_gate():
|
||||
assert _run_decision(_ctx(all_active=[future], recent=[future]))["action"] == "orphan"
|
||||
|
||||
|
||||
def test_back_dated_call_does_not_bypass_the_content_divergence_veto(monkeypatch):
|
||||
"""
|
||||
Same `9d376ffe` failure mode, but exercised directly against
|
||||
`_call_fits_incident` on a dispatch channel: unit overlap plus a
|
||||
back-dated call (incident updated 45 minutes AFTER the call's own
|
||||
`started_at`, which the sweep passes as `now`) used to make the signed
|
||||
idle -45, so `idle_min >= 15` read False and the content-divergence
|
||||
veto never ran — unit overlap alone forced the merge regardless of
|
||||
what the call was actually about. With the gate fixed to compare
|
||||
distance, idle_min is 45 (>= 15), the veto runs, and a divergent
|
||||
embedding (patched below so the assertion doesn't depend on numpy
|
||||
being installed in this environment) fails it.
|
||||
"""
|
||||
monkeypatch.setattr(correlator_mod, "_cosine_similarity", lambda a, b: 0.0)
|
||||
inc = _incident(idle_minutes=-45, units=["6-Adam"])
|
||||
inc["embedding"] = [1.0, 0.0]
|
||||
fits, signal = _call_fits_incident(
|
||||
inc, call_units=["6-Adam"], call_vehicles=[], call_coords=None,
|
||||
proximity_km=settings.location_proximity_km, is_dispatch=True,
|
||||
call_embedding=[0.0, 1.0], now=NOW,
|
||||
)
|
||||
assert (fits, signal) == (False, "content_divergence")
|
||||
|
||||
|
||||
def test_back_dated_call_on_tactical_channel_does_not_get_the_default():
|
||||
"""
|
||||
Tactical-channel counterpart: no unit/vehicle/location signal, so the
|
||||
function falls through to step 4's `idle_min < 20.0` default. A
|
||||
back-dated call (incident updated 45 minutes after the call's own
|
||||
started_at) used to read idle_min as -45, which is always < 20.0, so
|
||||
`tactical_default` fired unconditionally no matter how stale the
|
||||
incident actually was relative to this call. Fixed, idle_min is the
|
||||
45-minute distance, which is not < 20.0.
|
||||
"""
|
||||
inc = _incident(idle_minutes=-45)
|
||||
fits, signal = _call_fits_incident(
|
||||
inc, call_units=[], call_vehicles=[], call_coords=None,
|
||||
proximity_km=settings.location_proximity_km, is_dispatch=False,
|
||||
call_embedding=None, now=NOW,
|
||||
)
|
||||
assert (fits, signal) == (False, "tactical_idle")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 4. Hard caps — path-independent, because pairwise fit tests can't see shape
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -30,6 +30,15 @@
|
||||
{ "fieldPath": "ended_at", "order": "ASCENDING" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"//": "c2-core internal/dedup.py:84 — system_id == X AND started_at within a +/- window. Was live-failing on essentially every inbound call (server-26#84): dedup caught the FAILED_PRECONDITION and degraded to \"not a duplicate\", so double-heard transmissions were stored twice and would have been transcribed and correlated twice the moment an AI window opened. Created directly on c2-server 2026-08-28.",
|
||||
"collectionGroup": "calls",
|
||||
"queryScope": "COLLECTION",
|
||||
"fields": [
|
||||
{ "fieldPath": "system_id", "order": "ASCENDING" },
|
||||
{ "fieldPath": "started_at", "order": "ASCENDING" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"//": "c2-core internal/vocabulary_learner.py:290 — system_id == X AND ended_at >= cutoff. Backend only; was live but undeclared until 2026-08-23.",
|
||||
"collectionGroup": "calls",
|
||||
|
||||
Reference in New Issue
Block a user