Found by the standing correlation pass on the unattended run of 2026-08-27, reviewing d18e4f0 before it shipped.
d18e4f0 put transcript correction behind a Firestore flag (transcript_correction_enabled) so that an "STT-only" evaluation window is actually STT-only and its spend can be attributed (#76, #45). That part is correct and the flag defaults to True.
The problem is that the flag is not what it looks like. It reads as a pure cost lever. It is not.
The coupling
The corrector is also the noise gate. It is the only thing that sets not_speech, and transcription.py returns None, [] for any call it flags. _is_degenerate is explicitly documented as catching a narrower set — two hard-coded repetition shapes — while the corrector catches novel ones.
With transcript_correction_enabled = false, not_speech is hard-coded False, so:
Recogniser noise that only the corrector would have caught now reaches extract_scenes as a real transcript.
It comes back with no units, no tags, no location, no severity.
_is_thin_call is therefore True.
The fast/thin path attaches it to the most recent incident on the talkgroup with no fit check (incident_correlator.py:962-970).
So correction off + correlation on pushes over-merging, via exactly the mechanism CORRELATION_REVIEW_0820.md named as mechanism A.
Why it was not fixed in the same commit
Splitting noise detection out of the corrector is a change to the transcription path, not to the flag plumbing #76 was about. Landing it inside an untested-against-live-traffic refactor of the spend gates would have coupled two risks that should be evaluated separately. The flag defaults to True and both flags are off in production, so nothing is currently exposed.
What to do
Short term, operational, and already written down: never open an evaluation window with correction off and correlation on. Recorded in DEFERRED.md and in the comment above the flag in feature_flags.py.
Long term: move not_speech detection out of transcript_correction.correct() so the noise gate survives the corrector being switched off. Then this flag really is a pure cost lever.
Refs #76, #45, #5. DEFERRED.md carries the matching row.
Found by the standing correlation pass on the unattended run of 2026-08-27, reviewing `d18e4f0` before it shipped.
`d18e4f0` put transcript correction behind a Firestore flag (`transcript_correction_enabled`) so that an "STT-only" evaluation window is actually STT-only and its spend can be attributed (#76, #45). That part is correct and the flag defaults to True.
**The problem is that the flag is not what it looks like.** It reads as a pure cost lever. It is not.
## The coupling
The corrector is also the **noise gate**. It is the only thing that sets `not_speech`, and `transcription.py` returns `None, []` for any call it flags. `_is_degenerate` is explicitly documented as catching a narrower set — two hard-coded repetition shapes — while the corrector catches novel ones.
With `transcript_correction_enabled = false`, `not_speech` is hard-coded False, so:
1. Recogniser noise that only the corrector would have caught now reaches `extract_scenes` as a real transcript.
2. It comes back with no units, no tags, no location, no severity.
3. `_is_thin_call` is therefore True.
4. The `fast/thin` path attaches it to the most recent incident on the talkgroup **with no fit check** (`incident_correlator.py:962-970`).
So **correction off + correlation on pushes over-merging**, via exactly the mechanism `CORRELATION_REVIEW_0820.md` named as mechanism A.
## Why it was not fixed in the same commit
Splitting noise detection out of the corrector is a change to the transcription path, not to the flag plumbing #76 was about. Landing it inside an untested-against-live-traffic refactor of the spend gates would have coupled two risks that should be evaluated separately. The flag defaults to True and both flags are off in production, so nothing is currently exposed.
## What to do
Short term, operational, and already written down: **never open an evaluation window with correction off and correlation on.** Recorded in `DEFERRED.md` and in the comment above the flag in `feature_flags.py`.
Long term: move `not_speech` detection out of `transcript_correction.correct()` so the noise gate survives the corrector being switched off. Then this flag really is a pure cost lever.
Refs #76, #45, #5. `DEFERRED.md` carries the matching row.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Found by the standing correlation pass on the unattended run of 2026-08-27, reviewing
d18e4f0before it shipped.d18e4f0put transcript correction behind a Firestore flag (transcript_correction_enabled) so that an "STT-only" evaluation window is actually STT-only and its spend can be attributed (#76, #45). That part is correct and the flag defaults to True.The problem is that the flag is not what it looks like. It reads as a pure cost lever. It is not.
The coupling
The corrector is also the noise gate. It is the only thing that sets
not_speech, andtranscription.pyreturnsNone, []for any call it flags._is_degenerateis explicitly documented as catching a narrower set — two hard-coded repetition shapes — while the corrector catches novel ones.With
transcript_correction_enabled = false,not_speechis hard-coded False, so:extract_scenesas a real transcript._is_thin_callis therefore True.fast/thinpath attaches it to the most recent incident on the talkgroup with no fit check (incident_correlator.py:962-970).So correction off + correlation on pushes over-merging, via exactly the mechanism
CORRELATION_REVIEW_0820.mdnamed as mechanism A.Why it was not fixed in the same commit
Splitting noise detection out of the corrector is a change to the transcription path, not to the flag plumbing #76 was about. Landing it inside an untested-against-live-traffic refactor of the spend gates would have coupled two risks that should be evaluated separately. The flag defaults to True and both flags are off in production, so nothing is currently exposed.
What to do
Short term, operational, and already written down: never open an evaluation window with correction off and correlation on. Recorded in
DEFERRED.mdand in the comment above the flag infeature_flags.py.Long term: move
not_speechdetection out oftranscript_correction.correct()so the noise gate survives the corrector being switched off. Then this flag really is a pure cost lever.Refs #76, #45, #5.
DEFERRED.mdcarries the matching row.