fix(pipeline): back-stamp served surface onto TurnEvent — close T13 telemetry-consistency red

CognitiveTurnPipeline emits TurnEvent inside runtime.chat() and only THEN
applies the #96 fail-closed surface resolution (resolve_surface) and the #97
logos-morph override — so an overridden turn's telemetry recorded a surface
the user never saw. warmed_session_consistency telemetry_consistency_rate was
0.9444 on main (fast-lane red since #96 e0d1b475): an audit/replay trust break
(Absolute Provenance).

Add ChatRuntime.finalize_turn_surface, a sibling to finalize_turn_trace_hash:
the pipeline owns the final surface decision, so it back-stamps the resolved
surface onto turn_log[-1] immediately after the trace-hash back-stamp.
trace_hash byte-identity is preserved — it folds the pre-decoration surface,
not the served surface.

Scope: telemetry-consistency half of T13 only.
- Decision (2), the goldtether over-refusal, is orthogonal to the red and
  OPEN pending ruling (ledger) — recommend AGAINST a query-type cue bypass
  (fail-open / ADR-0252-retired cue-table pattern); prefer routing
  open-geometry-but-pack-grounded surfaces to the existing hedge arm.
- Durable-sink deferral tracked as R7.

telemetry_consistency_rate 0.9444 -> 1.0 (10/10 warmed_session tests green).

[Verification]: uv run core test --suite smoke -q in core-wt-t13serve @ HEAD — 180 passed in 133.17s, exit 0; warmed_session lane 10/10 green.
This commit is contained in:
Shay 2026-07-22 21:28:39 -07:00
parent bf80bc7f55
commit 5a343b49e9
3 changed files with 84 additions and 1 deletions

View file

@ -1195,6 +1195,53 @@ class ChatRuntime:
cand, source_turn_trace=trace_hash
)
def finalize_turn_surface(
self,
surface: str,
articulation_surface: str | None = None,
) -> None:
"""Back-stamp the pipeline's final *served* surface onto the turn.
Weekly-audit T13 (2026-07-22): ``ChatRuntime.chat`` seals a
``TurnEvent`` with the runtime-owned surface, but
``CognitiveTurnPipeline`` applies the Shadow-Coherence /
logos-morph surface authority AFTER ``chat`` returns. The
telemetry record therefore captured a surface the user never
saw ``TurnEvent.surface != pipeline.run().surface`` breaking
the ``warmed_session_consistency`` telemetry-consistency invariant
and audit/replay trust (Absolute Provenance).
The pipeline owns the final surface decision, so exactly like
``finalize_turn_trace_hash`` back-stamps the pipeline-owned
``trace_hash`` it back-stamps the resolved surface here after
``resolve_surface`` + logos-morph. Mirrors that method's
contract: operates on the most recent ``TurnEvent`` (main or
refusal-stub path), no-ops when unchanged or when no turn exists.
NOTE: the opt-in external telemetry sink (``attach_telemetry_sink``)
still receives the pre-override event, the same provisional-then-
back-stamped limitation ``finalize_turn_trace_hash`` carries today
(default sink is ``None`` no-op). Deferring the single sink
emission to the pipeline serve boundary which would repair both
surface and ``trace_hash`` in the durable stream is tracked as a
follow-up (audit ledger R7), not bolted onto this red-fix.
"""
if not self.turn_log:
return
from dataclasses import replace
last_event = self.turn_log[-1]
updates: dict[str, str] = {}
if surface != last_event.surface:
updates["surface"] = surface
if (
articulation_surface is not None
and articulation_surface != last_event.articulation_surface
):
updates["articulation_surface"] = articulation_surface
if updates:
self.turn_log[-1] = replace(last_event, **updates)
def first_admitted_recognizer(self):
if not self.config.recognition_grounded_graph:
return None

View file

@ -808,6 +808,16 @@ class CognitiveTurnPipeline:
# ``source_turn_trace``. See runtime.finalize_turn_trace_hash.
self.runtime.finalize_turn_trace_hash(trace_hash)
# Weekly-audit T13 (2026-07-22) — back-stamp the pipeline's final
# *served* surface onto the same TurnEvent, sibling to the
# trace_hash back-stamp above. ``resolve_surface`` + the logos-morph
# authority (above) can override the runtime-owned surface AFTER
# ``runtime.chat`` sealed the TurnEvent, so without this the
# telemetry record disagrees with the served bytes
# (warmed_session_consistency telemetry_consistency_rate < 1.0;
# breaks audit/replay trust — Absolute Provenance).
self.runtime.finalize_turn_surface(surface, articulation_surface)
# B4 producer: capture the leeway the response path already decided —
# observational only (reads the runtime's introspection-only accrual and
# the response's reach level; never alters the surface, never gates).

View file

@ -175,7 +175,15 @@ fail-closed determinism). Execution status:
first-match pack semantics unchanged outside the morph rule.
- [ ] **R6** — one rule type only (`he_morph_v0.plural_abstain`);
construct-state / prep+case / aspect deferred.
- [ ] **T13 (main regression, serving-provenance — needs its own fix PR):
- [ ] **R7** (opened by the T13 fix, 2026-07-22) — the opt-in telemetry SINK
stream (`attach_telemetry_sink`) still receives the pre-override `TurnEvent`
(pre-resolution surface + empty `trace_hash`) — the same provisional-then-
back-stamped limitation `finalize_turn_trace_hash` already carries. A single
deferred sink emission at the pipeline serve boundary would repair BOTH
surface and `trace_hash` in the durable stream. Deferred (default sink is
`None`, so no live consumer is affected today); own PR when a sink consumer
lands.
- [x] **T13 (main regression, serving-provenance — telemetry half FIXED):
fast lane is red on main** (was 0-red 2026-07-16):
`tests/test_warmed_session_lane.py::TestPipelineOverrideGateInvariants::test_telemetry_consistency_rate_is_one`
fails at 0.9444 (17/18). Verified pre-existing on unmodified main (fails
@ -197,3 +205,21 @@ fail-closed determinism). Execution status:
the pack surface never claimed geometric certification). Note: smoke does
not cover this lane, and GitHub Actions are dead signals — nothing gates
fast-lane red on main right now.
**Resolution (2026-07-22, PR `fix/telemetry-serve-boundary`):**
- **(1) FIXED** — `ChatRuntime.finalize_turn_surface` back-stamps the
pipeline's resolved surface onto `turn_log[-1]`, a sibling to
`finalize_turn_trace_hash`, called from `pipeline.py` immediately after
the trace-hash back-stamp. Lane green: `telemetry_consistency_rate`
0.9444 → 1.0 (10/10 warmed_session tests pass). `trace_hash` byte-identity
preserved — it folds the pre-decoration surface, not the served surface.
- **(2) OPEN — needs Shay's ruling.** Orthogonal to the red (telemetry now
matches whatever is served, refusal or not). Recommend **AGAINST** a
query-type "definitional/epistemic" classifier bypass: that fails a
geometric coherence gate OPEN on a lexical cue — the fail-open / cue-table
pattern ADR-0252 retired and INV-34 / fail-closed forbid. Principled
alternative: route open-geometry-but-**pack-grounded** surfaces to the
existing hedge-injection arm (`authoritative=False`, honestly hedged),
discriminated by grounding *provenance* (structural), not question type.
Own focused PR + real-data (not synthetic) validation.
- Durable-sink residual tracked as **R7** above.