Asymmetric counterpart to cold_start_grounding. Builds the
measurement substrate for the Phase B1 pipeline-override usefulness
gate. Lane is committed now (red baseline measured) so the fix is
landed against a fixed regression target.
The 2026-05-19 design review surfaced the bug this lane catches:
> pipeline overrode a runtime surface with a placeholder realizer
> surface because realized_plan.surface was non-empty, even though
> it contained '...'. The runtime audit log still held a different
> surface. This is the central fluency/design fault: the system
> can be "green" while user-facing selection, pipeline selection,
> and telemetry selection disagree.
The lane reproduces this exactly on the current main:
Surface "Soon is defined as ..." emitted on turn 2 of "What does
soon mean?" (where turn 1 grounded as pack correctly). Telemetry
recorded a different surface than the pipeline returned.
Initial red baseline (THIS commit):
no_placeholder_rate = 0.4444 (target after Phase B1: 1.00)
telemetry_consistency_rate = 0.4444 (target after Phase B1: 1.00)
warm_grounding_stability = 0.0000 (target after Phase B1: >=0.95)
Cold-start-grounding stays at 1.00 on its own metrics. The cold lane
measures routing, the warmed lane measures override discipline; they
are deliberately not the same.
Files:
evals/warmed_session_consistency/contract.md
What is measured, why, and the asymmetry with cold_start_grounding.
Documents the four binary per-turn signals (no_placeholder,
pipeline_match_telemetry, pipeline_match_walk, grounded_holds_on_warm)
and the per-case warm_grounding_stable invariant.
evals/warmed_session_consistency/public/v1/cases.jsonl
8 cases / 18 turns. Mix of:
- replay-the-same-prompt (catches override drift)
- mixed-intent sequences (catches OOV / pack interaction)
- cause-no-chain (must stay none across replays)
- what-does-x-mean (the warmed variant of the cold-start test)
evals/warmed_session_consistency/dev/cases.jsonl
2 representative cases for fast iteration.
evals/warmed_session_consistency/runner.py
Framework-compliant run_lane(cases, config=None) -> LaneReport.
Constructs ONE ChatRuntime + CognitiveTurnPipeline per case,
plays the turn sequence through them. Per-turn signals:
no_placeholder — surface free of ..., <pending>, <prior>
telemetry_match — pipeline result.surface == turn_log[-1].surface
grounding_match — actual_grounding == expected_grounding
Per-case signal:
warm_grounding_stable — every replayed prompt produces the same
grounding across turns
tests/test_warmed_session_lane.py
8 contract tests covering: case-set integrity, replay-pattern
presence, lane discovery, runner emits every required metric,
per-turn details carry all signals, and the warmed-runtime
invariant (static check that ChatRuntime is constructed
per-case, not per-turn and not module-scope).
NOT pinned in this commit (deliberate):
Threshold assertions are NOT in the test file. They will land in
Phase B1 alongside the pipeline-override usefulness gate. This
lane's role at present is to PROVIDE the regression target, not
to enforce it before the fix.
Verification: 8/8 lane tests green; the lane itself runs and emits
the red metrics documented above.
197 lines
6.2 KiB
Python
197 lines
6.2 KiB
Python
"""Warmed-session consistency eval lane runner.
|
|
|
|
Asymmetric counterpart to ``cold_start_grounding``. Constructs ONE
|
|
runtime + pipeline per case and plays a turn sequence through them,
|
|
asserting that pipeline overrides do not corrupt a runtime-grounded
|
|
answer and that telemetry-emitted surfaces match the pipeline's
|
|
final returned surface.
|
|
|
|
Framework contract: ``run_lane(cases, config=None) -> LaneReport``
|
|
where ``LaneReport.metrics`` is a dict and ``LaneReport.case_details``
|
|
is a list of per-case dicts.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
from typing import Any
|
|
|
|
from chat.runtime import ChatRuntime
|
|
from core.cognition.pipeline import CognitiveTurnPipeline
|
|
|
|
|
|
_PLACEHOLDER_MARKERS = (
|
|
"...",
|
|
"<pending>",
|
|
"<prior>",
|
|
" placeholder ",
|
|
)
|
|
|
|
|
|
def _has_placeholder(surface: str) -> bool:
|
|
if not isinstance(surface, str):
|
|
return False
|
|
return any(m in surface for m in _PLACEHOLDER_MARKERS)
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class TurnResult:
|
|
turn_index: int
|
|
prompt: str
|
|
surface: str
|
|
grounding_source: str
|
|
expected_grounding_source: str
|
|
grounding_match: bool
|
|
no_placeholder: bool
|
|
telemetry_match: bool
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class CaseResult:
|
|
case_id: str
|
|
category: str
|
|
invariants: tuple[str, ...]
|
|
turn_results: tuple[TurnResult, ...]
|
|
warm_grounding_stable: bool
|
|
|
|
|
|
@dataclass
|
|
class LaneReport:
|
|
metrics: dict[str, Any] = field(default_factory=dict)
|
|
case_details: list[dict[str, Any]] = field(default_factory=list)
|
|
|
|
|
|
def _run_case(case: dict[str, Any]) -> CaseResult:
|
|
"""Run one case's full turn sequence through a single warmed
|
|
runtime + pipeline pair."""
|
|
turns_spec = case.get("turns", [])
|
|
invariants = tuple(case.get("warm_invariants", (
|
|
"no_placeholder", "telemetry_match", "warm_grounding_stability"
|
|
)))
|
|
|
|
runtime = ChatRuntime()
|
|
pipeline = CognitiveTurnPipeline(runtime=runtime)
|
|
|
|
turn_results: list[TurnResult] = []
|
|
grounding_by_prompt: dict[str, list[str]] = {}
|
|
|
|
for idx, turn in enumerate(turns_spec):
|
|
prompt = turn["prompt"]
|
|
expected_grounding = turn["expected_grounding_source"]
|
|
|
|
result = pipeline.run(prompt, max_tokens=8)
|
|
actual_surface = result.surface
|
|
|
|
# Telemetry match: the most recent entry in runtime.turn_log
|
|
# must carry the same surface that the pipeline returned.
|
|
# Pipeline overrides that happen AFTER turn_log emission would
|
|
# produce a mismatch here.
|
|
last_event = (
|
|
runtime.turn_log[-1] if runtime.turn_log else None
|
|
)
|
|
telemetry_surface = (
|
|
last_event.surface if last_event is not None else ""
|
|
)
|
|
actual_grounding = (
|
|
getattr(last_event, "grounding_source", None) or "none"
|
|
if last_event is not None
|
|
else "none"
|
|
)
|
|
telemetry_match = actual_surface == telemetry_surface
|
|
|
|
no_ph = not _has_placeholder(actual_surface)
|
|
grounding_match = actual_grounding == expected_grounding
|
|
|
|
turn_results.append(TurnResult(
|
|
turn_index=idx,
|
|
prompt=prompt,
|
|
surface=actual_surface,
|
|
grounding_source=actual_grounding,
|
|
expected_grounding_source=expected_grounding,
|
|
grounding_match=grounding_match,
|
|
no_placeholder=no_ph,
|
|
telemetry_match=telemetry_match,
|
|
))
|
|
grounding_by_prompt.setdefault(prompt, []).append(actual_grounding)
|
|
|
|
# Warm-grounding stability: for any prompt that appears more than
|
|
# once in this case, every replay must produce the same grounding.
|
|
stable = all(
|
|
len(set(srcs)) == 1
|
|
for srcs in grounding_by_prompt.values()
|
|
if len(srcs) > 1
|
|
)
|
|
|
|
return CaseResult(
|
|
case_id=case["id"],
|
|
category=case.get("category", "uncategorised"),
|
|
invariants=invariants,
|
|
turn_results=tuple(turn_results),
|
|
warm_grounding_stable=stable,
|
|
)
|
|
|
|
|
|
def run_lane(cases: list[dict[str, Any]], config: Any = None) -> LaneReport: # noqa: ARG001
|
|
if not cases:
|
|
return LaneReport(metrics={}, case_details=[])
|
|
|
|
results = [_run_case(c) for c in cases]
|
|
|
|
total_turns = sum(len(r.turn_results) for r in results)
|
|
no_ph = sum(
|
|
1 for r in results for t in r.turn_results if t.no_placeholder
|
|
)
|
|
telem_match = sum(
|
|
1 for r in results for t in r.turn_results if t.telemetry_match
|
|
)
|
|
grounding_match = sum(
|
|
1 for r in results for t in r.turn_results if t.grounding_match
|
|
)
|
|
|
|
replayable_cases = [
|
|
r for r in results
|
|
if any(
|
|
sum(1 for t in r.turn_results if t.prompt == tp) > 1
|
|
for tp in {t.prompt for t in r.turn_results}
|
|
)
|
|
]
|
|
stable = sum(1 for r in replayable_cases if r.warm_grounding_stable)
|
|
|
|
metrics: dict[str, Any] = {
|
|
"cases": len(results),
|
|
"total_turns": total_turns,
|
|
"no_placeholder_rate": round(no_ph / total_turns, 4) if total_turns else 1.0,
|
|
"telemetry_consistency_rate": round(telem_match / total_turns, 4) if total_turns else 1.0,
|
|
"grounding_match_rate": round(grounding_match / total_turns, 4) if total_turns else 1.0,
|
|
"warm_grounding_stability": (
|
|
round(stable / len(replayable_cases), 4)
|
|
if replayable_cases else 1.0
|
|
),
|
|
}
|
|
|
|
case_details = [
|
|
{
|
|
"case_id": r.case_id,
|
|
"category": r.category,
|
|
"invariants": list(r.invariants),
|
|
"warm_grounding_stable": r.warm_grounding_stable,
|
|
"turns": [
|
|
{
|
|
"turn_index": t.turn_index,
|
|
"prompt": t.prompt,
|
|
"surface": t.surface,
|
|
"grounding_source": t.grounding_source,
|
|
"expected_grounding_source": t.expected_grounding_source,
|
|
"grounding_match": t.grounding_match,
|
|
"no_placeholder": t.no_placeholder,
|
|
"telemetry_match": t.telemetry_match,
|
|
}
|
|
for t in r.turn_results
|
|
],
|
|
}
|
|
for r in results
|
|
]
|
|
|
|
return LaneReport(metrics=metrics, case_details=case_details)
|
|
|
|
|
|
__all__ = ["run_lane", "LaneReport", "CaseResult", "TurnResult"]
|