LLM correlation tier decides only 3.5% of links, and the dominant fast/thin path records no fit signal #35

Open
opened 2026-08-23 03:20:35 -04:00 by logan · 5 comments
Owner

Now that server-26#24 surfaced the LLM fields, the correlation dump can answer what the LLM tier actually does. Over 309 linked calls (2026-08-23, full AI window):

field value
corr_llm_action populated 11 of 309 (3.5%) — 8 orphan, 3 link
corr_consensus rules_only 154, absent 122, agreed 22, tiebreak 11
corr_path fast/thin 194, new 98, fast/disambig 8, fast/single 6, unit-continuity 3
corr_fit_signal populated 14 of 309 — unit_overlap 12, location_proximity 1, tactical_default 1

This is not a malfunction — it is the design working exactly as written, and the design means the consensus machinery has almost no influence over what gets correlated. llm_correlator.decide() (internal/llm_correlator.py:224-231) returns None on three conditions:

if not settings.gemini_api_key:  return None
if ctx["is_thin_call"]:          return None
if not ctx["recent"]:            return None

The second skips 194 calls (63% of all links, every fast/thin). The third skips most of the 98 new decisions. Between them roughly 94% of traffic never reaches the LLM, which is precisely the 3.5% observed.

Why that matters: fast/thin is simultaneously the most common correlation path and the least audited one. It gets no LLM opinion, and it writes no corr_fit_signal — hence 295 of 309 calls carry no fit signal at all, and the "fit_signal distribution" panel in the admin debug view is empty. server-26#22 bounded the damage from thin-call attach with incident_max_calls / incident_max_duration_minutes, and those caps are holding (nothing in this dump exceeds 40 calls or 120 minutes). But the decision itself is still made by a rule with no recorded reasoning.

The thin-call skip is defensible on its face — a call with no transcript, units or coords gives an LLM nothing to reason about. The question this data raises is whether the cost of the tier is justified when it decides 3.5% of links, and whether fast/thin should be emitting a fit signal so the path that makes most of the decisions is at least reviewable.

Two directions, either is a real improvement:

  • Make fast/thin record a corr_fit_signal (even a literal thin_auto_attach) so the debug view stops looking broken and the dominant path becomes auditable.
  • Reconsider the tier's cost/benefit: on current traffic it fires 11 times per 309 calls, of which 11 needed a tiebreak. Either widen what reaches it or drop it and spend the budget on extraction quality (server-26#5, and the titling issue filed alongside this one).

Measured on the 2026-08-23 window; correlation flags were switched back off afterwards.

Now that server-26#24 surfaced the LLM fields, the correlation dump can answer what the LLM tier actually does. Over 309 linked calls (2026-08-23, full AI window): | field | value | |---|---| | `corr_llm_action` populated | **11 of 309 (3.5%)** — 8 `orphan`, 3 `link` | | `corr_consensus` | `rules_only` 154, absent 122, `agreed` 22, `tiebreak` 11 | | `corr_path` | `fast/thin` **194**, `new` 98, `fast/disambig` 8, `fast/single` 6, `unit-continuity` 3 | | `corr_fit_signal` populated | 14 of 309 — `unit_overlap` 12, `location_proximity` 1, `tactical_default` 1 | This is not a malfunction — it is the design working exactly as written, and the design means the consensus machinery has almost no influence over what gets correlated. `llm_correlator.decide()` (`internal/llm_correlator.py:224-231`) returns None on three conditions: ```python if not settings.gemini_api_key: return None if ctx["is_thin_call"]: return None if not ctx["recent"]: return None ``` The second skips 194 calls (63% of all links, every `fast/thin`). The third skips most of the 98 `new` decisions. Between them roughly 94% of traffic never reaches the LLM, which is precisely the 3.5% observed. Why that matters: `fast/thin` is simultaneously the **most common** correlation path and the **least audited** one. It gets no LLM opinion, and it writes no `corr_fit_signal` — hence 295 of 309 calls carry no fit signal at all, and the "fit_signal distribution" panel in the admin debug view is empty. server-26#22 bounded the damage from thin-call attach with `incident_max_calls` / `incident_max_duration_minutes`, and those caps are holding (nothing in this dump exceeds 40 calls or 120 minutes). But the decision itself is still made by a rule with no recorded reasoning. The thin-call skip is defensible on its face — a call with no transcript, units or coords gives an LLM nothing to reason about. The question this data raises is whether the *cost* of the tier is justified when it decides 3.5% of links, and whether `fast/thin` should be emitting a fit signal so the path that makes most of the decisions is at least reviewable. Two directions, either is a real improvement: - Make `fast/thin` record a `corr_fit_signal` (even a literal `thin_auto_attach`) so the debug view stops looking broken and the dominant path becomes auditable. - Reconsider the tier's cost/benefit: on current traffic it fires 11 times per 309 calls, of which 11 needed a tiebreak. Either widen what reaches it or drop it and spend the budget on extraction quality (server-26#5, and the titling issue filed alongside this one). Measured on the 2026-08-23 window; correlation flags were switched back off afterwards.
Author
Owner

Referenced by board minutes #42 (2026-08-23).

The CMO (#41) flagged this as the gap between BUSINESS_MODEL.md §3.4's claim that correlation "works today" and what is actually running: the LLM tier decides only 3.5% of links, so correlation is degraded, not broken - but §3.4 sells correlation as one of the four things genuinely worth $99/mo on day one.

The board did not add this to the revenue gate (padding a gate with product bugs is how gates stop being believed), but recorded the CMO's position that it must be fixed before the first walk-in demo, not after. Correlation is the differentiator being sold; a 3.5% LLM decision rate is not a demo you want to give.

Note the related §4.5 "retired Gemini model IDs" concern is stale in the good direction - config.py:47-48 shows the migration already landed (closed via #14). This issue is not that.

**Referenced by board minutes #42 (2026-08-23).** The CMO (#41) flagged this as the gap between `BUSINESS_MODEL.md` §3.4's claim that correlation "works today" and what is actually running: the LLM tier decides only 3.5% of links, so correlation is **degraded, not broken** - but §3.4 sells correlation as one of the four things genuinely worth $99/mo on day one. The board did **not** add this to the revenue gate (padding a gate with product bugs is how gates stop being believed), but recorded the CMO's position that it must be fixed **before the first walk-in demo**, not after. Correlation is the differentiator being sold; a 3.5% LLM decision rate is not a demo you want to give. Note the related §4.5 "retired Gemini model IDs" concern is **stale in the good direction** - `config.py:47-48` shows the migration already landed (closed via #14). This issue is not that.
Author
Owner

Update from the 2026-08-25 standing correlation pass: this is largely fixed, with one residual.

Fixed since filing:

  • The fast/thin path now records corr_fit_signal="thin_recency" (incident_correlator.py:972), so it is no longer silent about how it decided.
  • admin.py:258-261 tallies corr_path, corr_consensus and corr_llm_action, so the distribution is now measurable rather than inferred.

Residual — the tally still undercounts the LLM tier. A tiebreak that returns link writes no corr_path at all: llm_correlator.py:203 returns the decision, and incident_correlator.py:1433 sets corr_path only on the new branch. So every LLM-decided link lands in the tally as null.

That is the exact direction that would make this issue's original 3.5% figure look worse than reality — the tier may be deciding materially more than the tally shows, and we cannot tell which until the link branch writes its path too.

Suggest keeping this open, narrowed to: set corr_path on the link branch, and re-measure the distribution afterwards before drawing any conclusion about the tier's real share.

**Update from the 2026-08-25 standing correlation pass: this is largely fixed, with one residual.** Fixed since filing: - The fast/thin path now records `corr_fit_signal="thin_recency"` (`incident_correlator.py:972`), so it is no longer silent about how it decided. - `admin.py:258-261` tallies `corr_path`, `corr_consensus` and `corr_llm_action`, so the distribution is now measurable rather than inferred. **Residual — the tally still undercounts the LLM tier.** A tiebreak that returns **link** writes no `corr_path` at all: `llm_correlator.py:203` returns the decision, and `incident_correlator.py:1433` sets `corr_path` only on the `new` branch. So every LLM-decided *link* lands in the tally as null. That is the exact direction that would make this issue's original 3.5% figure look worse than reality — the tier may be deciding materially more than the tally shows, and we cannot tell which until the link branch writes its path too. Suggest keeping this open, narrowed to: set `corr_path` on the link branch, and re-measure the distribution afterwards before drawing any conclusion about the tier's real share.
Author
Owner

The 3.5% figure is an over-count, not a measurement — found by the static correlation pass, unattended run 2026-08-30. Commenting rather than filing separately, because this is about the number this issue is built on.

llm_correlator.py:322 returns rules_decision on any Gemini failure. routers/upload.py:156-158 then unconditionally stamps corr_consensus="tiebreak" and a corr_llm_action — even though no LLM decision won, and in the failure case none was ever produced. admin.py:260 tallies exactly that field.

So every failed tiebreak is counted as an LLM decision. The true LLM share of links is ≤3.5%, and the gap between the real figure and 3.5% is precisely the Gemini failure rate — which is itself unmeasured and is the more useful number of the two. A tier failing open and being recorded as if it had decided is also how tier is DISABLED stays invisible in the aggregate: a dead model ID or a billing lapse degrades silently into the rules path while the dashboard still reports LLM participation.

Before this issue's premise is acted on, the counter needs to distinguish LLM decided from LLM was asked and failed. Otherwise any work to raise the LLM share is measured against an instrument that cannot show it moving.

Static reading only, no live data this run — the tally at admin.py:260 is assumed to be the source of the 3.5% quoted here, which was not confirmed against a live dashboard.

**The 3.5% figure is an over-count, not a measurement — found by the static correlation pass, unattended run 2026-08-30.** Commenting rather than filing separately, because this is about the number this issue is built on. `llm_correlator.py:322` returns `rules_decision` on **any** Gemini failure. `routers/upload.py:156-158` then unconditionally stamps `corr_consensus="tiebreak"` and a `corr_llm_action` — even though no LLM decision won, and in the failure case none was ever produced. `admin.py:260` tallies exactly that field. So every **failed** tiebreak is counted as an LLM decision. The true LLM share of links is **≤3.5%**, and the gap between the real figure and 3.5% is precisely the Gemini failure rate — which is itself unmeasured and is the more useful number of the two. A tier failing open and being recorded as if it had decided is also how `tier is DISABLED` stays invisible in the aggregate: a dead model ID or a billing lapse degrades silently into the rules path while the dashboard still reports LLM participation. Before this issue's premise is acted on, the counter needs to distinguish *LLM decided* from *LLM was asked and failed*. Otherwise any work to raise the LLM share is measured against an instrument that cannot show it moving. Static reading only, no live data this run — the tally at `admin.py:260` is assumed to be the source of the 3.5% quoted here, which was not confirmed against a live dashboard.
Author
Owner

Re-scope - this issue's premise has partly drifted. Verified at 29c2fb1, unattended run 2026-08-31.

The half that is fixed: the fast/thin path is no longer silent. incident_correlator.py:964-974 now writes corr_fit_signal: "thin_recency" and corr_candidates, so the dominant path does record why it decided what it decided. The original framing - "the dominant fast/thin path records no reasoning" - is no longer true and should not be carried into another sitting as though it were.

The half that is still true: corr_llm_reasoning is never persisted on the rules_only consensus branch (upload.py:142). When the rules tier decides without consulting the LLM, no reasoning field is written at all, so that population is unauditable after the fact.

Suggested retitle: corr_llm_reasoning is not persisted on the rules_only consensus branch, leaving that population unauditable.

The "3.5% of links" figure in the current title is from an older dump and has not been re-measured since. Treat it as stale until a fresh correlation dump is taken.

**Re-scope - this issue's premise has partly drifted. Verified at `29c2fb1`, unattended run 2026-08-31.** The half that is **fixed**: the `fast/thin` path is no longer silent. `incident_correlator.py:964-974` now writes `corr_fit_signal: "thin_recency"` and `corr_candidates`, so the dominant path does record why it decided what it decided. The original framing - "the dominant fast/thin path records no reasoning" - is no longer true and should not be carried into another sitting as though it were. The half that is **still true**: `corr_llm_reasoning` is never persisted on the `rules_only` consensus branch (`upload.py:142`). When the rules tier decides without consulting the LLM, no reasoning field is written at all, so that population is unauditable after the fact. **Suggested retitle:** *`corr_llm_reasoning` is not persisted on the rules_only consensus branch, leaving that population unauditable.* The "3.5% of links" figure in the current title is from an older dump and has not been re-measured since. Treat it as stale until a fresh correlation dump is taken.
Author
Owner

Do not action the 3.5% figure — the instrument that produced it is broken. Filed as #96, unattended run 2026-09-01.

Every scene of a multi-scene call writes corr_debug onto the same call doc with partial keys, last-write-wins (incident_correlator.py:1321), and admin.py:292-295 tallies per call. So this issue's "the LLM tier decides 3.5% of links" is a per-call blend of several scenes' decisions, not a per-link rate, and it cannot be converted into one after the fact. corr_path may come from one scene while corr_consensus / corr_llm_action come from another.

The tier could be deciding materially more or materially less than 3.5%. Any tuning aimed at raising its share would be steering by a broken gauge, and multi-scene calls are exactly the population where over-split (#5) and over-merge live.

This issue stays open — the underlying question is real and unanswered. But it is now blocked on #96: fix the per-scene debug record first, re-measure, then decide. Referencing #96 here so the number is not read at face value in the meantime.

**Do not action the 3.5% figure — the instrument that produced it is broken. Filed as #96, unattended run 2026-09-01.** Every scene of a multi-scene call writes `corr_debug` onto the same call doc with partial keys, last-write-wins (`incident_correlator.py:1321`), and `admin.py:292-295` tallies per call. So this issue's "the LLM tier decides 3.5% of links" is a **per-call blend of several scenes' decisions, not a per-link rate**, and it cannot be converted into one after the fact. `corr_path` may come from one scene while `corr_consensus` / `corr_llm_action` come from another. The tier could be deciding materially more or materially less than 3.5%. Any tuning aimed at raising its share would be steering by a broken gauge, and multi-scene calls are exactly the population where over-split (#5) and over-merge live. **This issue stays open — the underlying question is real and unanswered.** But it is now blocked on #96: fix the per-scene debug record first, re-measure, then decide. Referencing #96 here so the number is not read at face value in the meantime.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: logan/server-26#35