correlator: judge each scene on its own embedding + severity (#80, #95) #105

Merged
logan merged 1 commits from fix/scene-context-leak-80-95 into main 2026-09-06 17:49:24 -04:00
Owner

Closes #80, closes #95.

intelligence.py writes only the primary scene's embedding and severity to calls/{id}. _build_context read them back off the call doc, so every non-primary scene of a multi-scene call was correlated against scene 1's semantic vector and severity rung — a scene about a different event scored on the embedding path against the wrong incident, and could inherit a minor/moderate/major severity it never had, clearing the creation gate on borrowed weight. Same defect and same fix as the #87 coords leak.

Changes

  • _build_context / preview_correlation / correlate_call: take embedding and severity as params; drop the call_doc.get() fallbacks.
  • upload.py: both scene loops pass scene["embedding"] / scene["severity"]; _correlate_with_consensus forwards them. No-scene unclassified branch passes neither (judged thin, correct).
  • recorrelation_sweep: passes the call doc'sole-call re-link, link-only).
  • intelligence.py: SCENE DETECTION prompt tightened toward one scene (#5, partial) — MULTIPLE only for genuinely separate events, "when unsure, one scene", plus a not-a-new-scene list. - test_incident_identity.py: +2 regression t

Testing: full c2-core suite green (295 passed) on a sandboxed Linux venv. drb-correlation-review verdict: ship after a pytest run (done).

Not closed here — tracked separately: #102 (llm_correlator._call_block still reads the whole-call transcript per scene — remaining leg), #103 (divergence veto on Nss stale severity). #5 prompt change isunmeasured — needs a scoped correlation-only window with Summaries/Vocab off.

Closes #80, closes #95. intelligence.py writes only the primary scene's embedding and severity to calls/{id}. _build_context read them back off the call doc, so every non-primary scene of a multi-scene call was correlated against scene 1's semantic vector and severity rung — a scene about a different event scored on the embedding path against the wrong incident, and could inherit a minor/moderate/major severity it never had, clearing the creation gate on borrowed weight. Same defect and same fix as the #87 coords leak. Changes - _build_context / preview_correlation / correlate_call: take embedding and severity as params; drop the call_doc.get() fallbacks. - upload.py: both scene loops pass scene["embedding"] / scene["severity"]; _correlate_with_consensus forwards them. No-scene unclassified branch passes neither (judged thin, correct). - recorrelation_sweep: passes the call doc'sole-call re-link, link-only). - intelligence.py: SCENE DETECTION prompt tightened toward one scene (#5, partial) — MULTIPLE only for genuinely separate events, "when unsure, one scene", plus a not-a-new-scene list. - test_incident_identity.py: +2 regression t Testing: full c2-core suite green (295 passed) on a sandboxed Linux venv. drb-correlation-review verdict: ship after a pytest run (done). Not closed here — tracked separately: #102 (llm_correlator._call_block still reads the whole-call transcript per scene — remaining leg), #103 (divergence veto on Nss stale severity). #5 prompt change isunmeasured — needs a scoped correlation-only window with Summaries/Vocab off.
logan added 1 commit 2026-09-06 17:49:08 -04:00
intelligence.py writes only the primary scene's embedding and severity to
calls/{id}. _build_context read them back off the call doc, so every
non-primary scene of a multi-scene call was correlated against scene 1's
semantic vector and severity rung: a scene about a different event scored
on the embedding path against the wrong incident, and could inherit a
minor/moderate/major severity it never had, clearing the creation gate on
borrowed weight. Same defect and same fix as the #87 coords leak.

- _build_context / preview_correlation / correlate_call: take embedding and
  severity as params; drop the call_doc.get() fallbacks. A scene that
  passes none has none, and is judged thin on its own signal.
- upload.py: both scene loops pass scene["embedding"] / scene["severity"];
  _correlate_with_consensus forwards them. The no-scene unclassified branch
  passes neither (correct: no scene, judged thin).
- recorrelation_sweep: passes the call doc's stored values explicitly
  (whole-call re-link, link-only, so a borrowed severity cannot create).
- intelligence.py: SCENE DETECTION prompt tightened toward one scene
  (server-26#5, partial) - MULTIPLE only for genuinely separate events,
  "when unsure, one scene", plus a not-a-new-scene list.
- test_incident_identity.py: +2 regression tests mirroring the #87 test.

Full c2-core suite green (295 passed). #5 prompt change is unmeasured -
needs a scoped correlation-only window. Known remaining legs, tracked
separately: llm_correlator._call_block still reads the whole-call
transcript per scene; content-divergence veto skips on a None embedding.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
logan merged commit c4656a9607 into main 2026-09-06 17:49:24 -04:00
logan deleted branch fix/scene-context-leak-80-95 2026-09-06 17:49:27 -04:00
Sign in to join this conversation.