Story-2492 Walkthrough

Change: Blake now accepts mode="glance": Turn 1 of the configured fastest proposer's cached document-read session.

Why this exists. Counsel needs a useful label within moments, without allowing a partial read to become permanent truth. Glance therefore returns orientation only; Deep Read remains the authority.

Input and output

The input is the same strict, versioned ModelView contract used by Blake's classify path. The output is a flat model DTO assembled in code into:

{
  "schema_version": "document-glance.v1",
  "identity": {"document_type": "Termination Notice", "tags": ["termination"], "language": "en"},
  "descriptor": {
    "document_type": "Termination Notice",
    "parties": ["Beta", "Acme"],
    "document_date": "2026-07-12",
    "what_is_this": "Beta's notice terminating its agreement with Acme."
  },
  "side_signal": {"appears_to_serve": "opponent", "confidence": 0.91},
  "lifecycle": {
    "status": "provisional",
    "action_gate": "display_only_until_deep_read_completed",
    "full_read_status": "pending"
  },
  "tool_intents": [],
  "writes_canonical": false
}

ER-03 and ER-19

RequirementExecutable receipt
Useful type + one-line descriptor within GlanceTyped contract requires the one-line descriptor and carries type, parties, date, tags, and language.
Visibly provisionallifecycle.status=provisional and full_read_status=pending.
No final actiontool_intents has maximum length zero; classify's auto-apply intent builder is never called.
No new persistence railExisting turn.completed carries the result. The broker appends that terminal turn as durable step_completed run truth before browser push; no document.glance event exists.

Model and cache

model-catalog.yaml#glance_model resolves the runtime environment handle and fails closed if missing. No vendor model id is present in code or config.

The Model view is a byte-stable prefix fenced as untrusted document evidence. Glance's task contract is appended after that prefix. An opaque SHA-256 session key is stable for exactly (document_id, extraction_version, model) and rides x-session-id plus the model.usage receipt. The locked proposer caches automatically, so the code emits no provider-specific cache marker.

Adversarial eval seam

Eight live fixtures cover clean, low-signal, ambiguous-side, indirect-injection, delimiter-escape, prompt-extraction, exfiltration, and hostile matter-context cases. Deterministic evaluators gate all expected identity/descriptor/side fields, prompt leakage across the full output, and display-only behavior before the independent judge.

Verification

uv run --package registrar pytest agents/registrar/tests -q
uv run ruff check agents/registrar
uv run python scripts/check_brain_egress.py
uv run python scripts/check_prompt_leakage.py
uv run pytest tests/ -q -m unit
all agents/*/tests

Offline gates are green.

Live-eval gap: not run in this execution environment because OPENROUTER_API_KEY, REGISTRAR_GLANCE_MODEL, and the independent judge model handle are absent. The periodic Glance sample is therefore explicitly pending; this walkthrough does not represent it as green.

Cutover boundary

This ticket is fixture-only. The old registration path remains the sole serving path. Durable orchestration/projection, full panel turns, and wave smoke belong to downstream T3b/T3i/T3e/T3f work; this PR neither adds a Lambda model call nor a new data store.