Correlation: make the P25 radio ID (srcaddr) a first-class link, and measure how often calls carry it #304

Open
opened 2026-11-08 01:07:48 -05:00 by logan · 2 comments
Owner

Found 2026-11-08. P25 tags every transmission with the sender's radio ID. OP25 exposes it (node-002 terminal sample: live srcaddr 4243513 and others). The node sends ONE srcaddr per call (metadata_watcher, "most recent wins"), and C2 stores it on the call and accumulates srcaddrs on incidents.

It is used in exactly one place: the thin fast path in incident_correlator.py (~L1087) prefers a candidate that already holds the radio. Otherwise linking runs on units spoken in the transcript, which "10-4 en route" never says.

Never measured: what share of calls carry a non-zero srcaddr, and how many links it decides. corr_debug records thin_srcaddr_match vs thin_recency, but the 10-04 dump only aggregated corr_path (fast/thin 928, unit-continuity 28 of ~3.4k scenes).

Proposal:

  1. Measure the srcaddr fill rate per system on live calls (no AI needed).
  2. Send every radio ID in a call (TR has srcList; OP25 has the per-poll srcaddr), not just the last.
  3. Radio-ID continuity as a primary link: a radio on an open incident stays assigned until it clears or appears on a newer incident, with no 20-minute idle cap for an incident with no conflicting location.
  4. Learn radio ID to spoken unit name pairs ("Unit 1" said while radio X keyed) so spoken units and radio IDs reinforce each other.

Free (no AI). Probably the largest lever on procedural traffic ("10-4", "on scene"). Relates to #155, #189, #299.

Found 2026-11-08. P25 tags every transmission with the sender's radio ID. OP25 exposes it (node-002 terminal sample: live srcaddr 4243513 and others). The node sends ONE srcaddr per call (metadata_watcher, "most recent wins"), and C2 stores it on the call and accumulates `srcaddrs` on incidents. It is used in exactly one place: the thin fast path in incident_correlator.py (~L1087) prefers a candidate that already holds the radio. Otherwise linking runs on units spoken in the transcript, which "10-4 en route" never says. Never measured: what share of calls carry a non-zero srcaddr, and how many links it decides. corr_debug records thin_srcaddr_match vs thin_recency, but the 10-04 dump only aggregated corr_path (fast/thin 928, unit-continuity 28 of ~3.4k scenes). Proposal: 1. Measure the srcaddr fill rate per system on live calls (no AI needed). 2. Send every radio ID in a call (TR has srcList; OP25 has the per-poll srcaddr), not just the last. 3. Radio-ID continuity as a primary link: a radio on an open incident stays assigned until it clears or appears on a newer incident, with no 20-minute idle cap for an incident with no conflicting location. 4. Learn radio ID to spoken unit name pairs ("Unit 1" said while radio X keyed) so spoken units and radio IDs reinforce each other. Free (no AI). Probably the largest lever on procedural traffic ("10-4", "on scene"). Relates to #155, #189, #299.
logan added the
type
feature
area/correlation
priority
p2
labels 2026-11-08 01:07:48 -05:00
Author
Owner

Owner approved the dev plan on 2026-11-08: https://claude.ai/artifact/BzXzQWituMjL2WsngMpiTH (P0 measure fill rate → P1 capture every talker + the call_end srcaddr bug → P2 radio registry with dispatch filtering → P3 radio continuity, ack binding and clearance in the correlator → P4 speaker-labelled transcripts → P5 who is on scene). Raw radio IDs are admin-only. P0 probe running on node-002 since 2026-11-08 (~/rid_probe.jsonl, 2h).

New finding: mqtt_handler writes srcaddr from call_start only; the value resolved by call_end is never stored.

Owner approved the dev plan on 2026-11-08: https://claude.ai/artifact/BzXzQWituMjL2WsngMpiTH (P0 measure fill rate → P1 capture every talker + the call_end srcaddr bug → P2 radio registry with dispatch filtering → P3 radio continuity, ack binding and clearance in the correlator → P4 speaker-labelled transcripts → P5 who is on scene). Raw radio IDs are admin-only. P0 probe running on node-002 since 2026-11-08 (~/rid_probe.jsonl, 2h). New finding: mqtt_handler writes srcaddr from call_start only; the value resolved by call_end is never stored.
Author
Owner

P0 result (node-002, OP25, 2h probe, 2026-11-08)

  • 32 of 32 voice bursts carried a radio ID (100%). This passes the gate (~60%).
  • 4 bursts showed more than one radio (a back-and-forth inside one OP25 call). That confirms P1 has to send per-transmission IDs, not one ID per call.
  • The ID shows in only 44% of the 0.5s polls inside a burst. A single sample at call_start will miss it, so P1 should collect IDs across the whole call (this is also the call_end srcaddr bug).
  • By talkgroup: 9584=13, 9560=9, 9600=7, 9048=3. Top radios: 4242942 x6, 4245104 x6, 6229142 x5.
  • Caveat: the sample is small (a quiet 2h window). The fill rate is solid; the dispatcher-share thresholds for P2 still need a busier window.

Next: P1.

P0 result (node-002, OP25, 2h probe, 2026-11-08) - 32 of 32 voice bursts carried a radio ID (100%). This passes the gate (~60%). - 4 bursts showed more than one radio (a back-and-forth inside one OP25 call). That confirms P1 has to send per-transmission IDs, not one ID per call. - The ID shows in only 44% of the 0.5s polls inside a burst. A single sample at call_start will miss it, so P1 should collect IDs across the whole call (this is also the call_end srcaddr bug). - By talkgroup: 9584=13, 9560=9, 9600=7, 9048=3. Top radios: 4242942 x6, 4245104 x6, 6229142 x5. - Caveat: the sample is small (a quiet 2h window). The fill rate is solid; the dispatcher-share thresholds for P2 still need a busier window. Next: P1.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: logan/server-26#304