intelligence: stop the police-channel default from typing content-free chatter (#138)
EXTRACTION_PROMPT's incident_type rule always returned "police" for anything on a police channel unless contradicted, so pure administrative chatter (post check-ins, roll call, bare acknowledgements) got a truthy incident_type and defeated the creation gate's "type" veto (_call_is_substanceless) ~82% of the time (measured server-26#138/CORRELATION_REVIEW_0914.md, confirmed against live 9-14 data: 9/9 type-veto examples checked all had severity "routine" — same population the severity rubric already correctly identifies as content-free, incident_type just wasn't using that signal). Rule now checks for actual event content FIRST, on every channel, before applying the channel-inference defaults; content-free traffic returns "unknown" (already normalizes to None) instead of a channel default, letting the existing gate correctly veto it. No correlator/gate code touched — CORRELATION_REVIEW_0914.md's own recommendation was to fix this in the prompt, not _call_is_substanceless, to avoid risking a real event getting gated out. Verified: 401 pass, 0 fail. Live effect to be confirmed against fresh traffic (AI features just re-enabled this session after being off since 9/14) — tracking in SESSION_STATE.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
fb0bb15c22
commit
3f69879437
@@ -66,7 +66,7 @@ Rules:
|
|||||||
- tags: describe WHAT happened, not WHERE. Specific, lowercase, hyphenated. Do not use location names, road names, talkgroup names, or place names as tags (wrong: "lower-macy's", "canvas-route-6", "route-202"; right: "suspect-search", "shoplifting", "vehicle-pursuit"). Do not repeat incident_type as a tag.
|
- tags: describe WHAT happened, not WHERE. Specific, lowercase, hyphenated. Do not use location names, road names, talkgroup names, or place names as tags (wrong: "lower-macy's", "canvas-route-6", "route-202"; right: "suspect-search", "shoplifting", "vehicle-pursuit"). Do not repeat incident_type as a tag.
|
||||||
- units: ONLY identifiers that appear verbatim in the transcript. Use speaker role inference to distinguish units being dispatched from units acknowledging — both should be included. Never infer or guess unit IDs not present in the text. If a unit ID format is given below, use it to recognise a unit spoken in a shortened or partial form (e.g. just the phonetic name alone) as the same unit — but still only extract what is actually said, never fabricate the full form.
|
- units: ONLY identifiers that appear verbatim in the transcript. Use speaker role inference to distinguish units being dispatched from units acknowledging — both should be included. Never infer or guess unit IDs not present in the text. If a unit ID format is given below, use it to recognise a unit spoken in a shortened or partial form (e.g. just the phonetic name alone) as the same unit — but still only extract what is actually said, never fabricate the full form.
|
||||||
- Do not invent details not present in the transcript.
|
- Do not invent details not present in the transcript.
|
||||||
- incident_type: let the talkgroup channel be your primary signal. Use "fire" ONLY if the talkgroup is clearly a fire/rescue channel OR the transcript explicitly describes active fire, smoke, flames, or structure fire activation. Police or EMS referencing a fire scene → use "police" or "ems". When the channel is a police channel and nothing in the transcript contradicts it, return "police" — do NOT fall back to "other" merely because the transmission is administrative. Reserve "other" for traffic that genuinely belongs to no emergency service (rail operations, public works, utility coordination). Reserve "unknown" for transcripts too garbled to place at all.
|
- incident_type: FIRST decide whether this transmission has any incident behind it at all, using the same bar as the "routine" severity rule below — pure administrative/status traffic with nothing describable happening: post/unit check-ins, roll call, bare acknowledgements ("10-4", "copy", "received"), records/report exchanges, "show me admin"/"show me available", a status ten-code with no event attached. If it is administrative/status-only, return "unknown" — this applies on EVERY channel, including a police channel; do not let the channel default override it (server-26#138: forcing a channel default onto content-free chatter is what let radio housekeeping open incidents). Only once real event content is present, let the talkgroup channel be your primary signal for WHICH type. Use "fire" ONLY if the talkgroup is clearly a fire/rescue channel OR the transcript explicitly describes active fire, smoke, flames, or structure fire activation. Police or EMS referencing a fire scene → use "police" or "ems". When the channel is a police channel, a real event is present, and nothing in the transcript contradicts it, return "police". Reserve "other" for a real event that genuinely belongs to no emergency service (rail operations, public works, utility coordination) — not for administrative chatter, which is "unknown" per above regardless of channel. Also reserve "unknown" for transcripts too garbled to place at all.
|
||||||
- severity: ALWAYS return one of the four values. Judge the underlying event, not how dramatic the words sound.
|
- severity: ALWAYS return one of the four values. Judge the underlying event, not how dramatic the words sound.
|
||||||
"routine" — administrative/status traffic with no incident behind it: mileage and transport logging, radio checks, acknowledgements, shift changes, track block/power requests, records lookups.
|
"routine" — administrative/status traffic with no incident behind it: mileage and transport logging, radio checks, acknowledgements, shift changes, track block/power requests, records lookups.
|
||||||
"minor" — a real but low-stakes call: lift assist, parking complaint, past-tense larceny report, noise complaint, welfare check.
|
"minor" — a real but low-stakes call: lift assist, parking complaint, past-tense larceny report, noise complaint, welfare check.
|
||||||
@@ -81,11 +81,8 @@ System: {system_id}
|
|||||||
Talkgroup: {talkgroup_name}
|
Talkgroup: {talkgroup_name}
|
||||||
{ten_codes_block}{vocabulary_block}{unit_format_block}{transcript_block}"""
|
{ten_codes_block}{vocabulary_block}{unit_format_block}{transcript_block}"""
|
||||||
|
|
||||||
# The incident_type enum offered to the model in EXTRACTION_PROMPT. Kept here
|
# "unknown" is deliberately absent — normalises to None, which is what lets
|
||||||
# rather than only in the prompt so a model that invents a value cannot write it
|
# the creation gate veto a content-free call (server-26#138).
|
||||||
# into incident.type. "unknown" is deliberately absent — it is a real answer
|
|
||||||
# from the model but not a usable type, and is normalised to None alongside
|
|
||||||
# anything unrecognised.
|
|
||||||
_VALID_INCIDENT_TYPES = frozenset({"fire", "ems", "police", "accident", "other"})
|
_VALID_INCIDENT_TYPES = frozenset({"fire", "ems", "police", "accident", "other"})
|
||||||
|
|
||||||
# Geographic bias radius for geocoding — half-width in degrees (~55 km)
|
# Geographic bias radius for geocoding — half-width in degrees (~55 km)
|
||||||
|
|||||||
Reference in New Issue
Block a user