Files
brain-of-reese/tests/e2e/test_pdf_strip_additive_selfheal.py
T
ducoterra 6ba46e735a
Build and Push Containers / build-and-push-app (push) Successful in 2m3s
Build and Push Containers / build-and-push-db (push) Successful in 21s
phase: 163_pdf_strip_additive_selfheal
All gates verified. Final report:

**Phase 163 — final verification pass (all 5 tasks already complete; verification-only run)**

- Verified D1–D4 in code: `page_strip_mode` column + migration 0027, `DocContent` absent-never-null rule keyed off `page_count`; `_persist_pdf_pages` render → atomic tmp+`os.replace` writes → stale-tail-last + `strip_class` stamp; `_regate_pdf_strip` on both unchanged paths (mirror gate, heal, repair, fail-soft, one INFO line only when acting); viewer mode branch + Text/Pages toggle (Text default, `aria-pressed`, no innerHTML, lazy imgs).
- `uv run pytest --cov=app --cov-report=term-missing` → **3796 tests, exit 0, coverage 99%** (>90%)
- `uv run pytest tests/e2e/test_pdf_strip_additive_selfheal.py -v --no-cov` → **5 passed** in isolation
- `test_pdf_pages_in_sources + test_pictorial_pdf + test_garbage_pdf` → 10 passed; `test_document_viewer(_context) + test_image_documents` → 20 passed
- `uv run ruff check .` clean; `uv run pyright` → 0 errors; alembic **0027 downgrade→upgrade CLI round-trip clean** (+ integration pins)
- Completion criteria: additive view w/ toggle ✅ · primary DOM byte-identity ✅ · write-first order/mid-write-failure/atomic pins ✅ · heal + repair E2E ✅ · zero vision/LLM on fast path (mock-captured) ✅ · non-qualifying payload byte-identity ✅ · docs pass ✅
- **Documentation**: README.md + AGENTS.md reviewed in full — the phase's updates are accurate; all config-table defaults cross-checked against `app/config.py` (no drift), every page route, script, and E2E command referenced exists, every `.env.example` var documented — **verified consistent, no changes needed**.
- Notable: live `Letumdei` repair is owner-runtime post-deploy per D5 (next production Sync self-heals; no live changes made); the modified `.agents/screenshots/doc_modal_scrollbar_1280.png` is an E2E-regenerated artifact left for the pipeline commit.
- **Next pending phase:** `164_chat_error_honesty`
2026-10-07 13:57:30 -04:00

1085 lines
48 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Phase 163 task 05 E2E (Playwright, mock-only): the additive PDF
strip, the byte-identical primary/plain classes, and the fast-path
self-heal — the ``Letumdei`` failure mode, reproduced and made
impossible.
Run in isolation (DB must be up: ``podman compose up -d db``):
uv run pytest tests/e2e/test_pdf_strip_additive_selfheal.py -v --no-cov
The dedicated suite for ``163_pdf_strip_additive_selfheal`` (A16 — one
Playwright file per phase, run in isolation). Pre-fix evidence
(2026-10-07, brain.reeseapps.com): ``Letumdei_ Heirs to the Imperium.pdf``
— 36 ``page_urls`` in the payload, ALL 36 page routes 404, 114 389
chars of genuine extracted text with exactly ONE sparse map page
(the pictorial class) — the viewer showed "Page N unavailable." on
every page with the text hidden behind the strip. Two stacked defects:
the pictorial class rendered the strip INSTEAD of its text (fixed by
the additive view, LOCKED A1/A6), and the copies were deleted before
the replacements were written, outside the DB transaction, so a later
rollback (or an external wipe) left the row over zero files with the
phase-147 fast path never re-rendering (fixed by write-first persist
+ the deterministic re-gate, LOCKED A4/A5). One local-directory source
(``strip_fixture``, the API-registered ``kind=local`` pattern) carries
three synthetic PyMuPDF PDFs — the live shape in miniature:
* ``manual.pdf`` — the PICTORIAL class (the Letumdei shape): 3 dense
prose pages + ONE sparse map-style page (<100 stripped chars, a
vector-drawn figure) → usable text layer, one gate candidate →
``page_strip_mode == "additive"``, ``page_count == 4``;
* ``scanned.pdf`` — the FALLBACK class (the phase-133 shape): two
pages whose ONLY text is the owner's XML-garbage line repeated 20× →
unusable layer → ``page_strip_mode == "primary"``, ``page_count == 2``;
* ``plain.pdf`` — clean dense text, ZERO sparse pages → no strip at
all (``page_count`` NULL, both strip keys absent from the payload).
App env: the conftest pattern with the phase-140 opt-in (``BOR_PDF_
PICTORIAL`` pinned EXPLICITLY ``1``) + the phase-148 ``BOR_PDF_PAGE_DIR``
pointed at a suite-private scratch dir (the heal deletes and re-creates
files THERE — the owner's ``~/bor-sources/pages`` default is never
touched) + ``BOR_IMPORT_EXTENSIONS`` carrying the ``pdf`` token (the
phase-126 convention). The page-directory homes are module-scoped so
the heal/repair tests mutate the exact dir the module app reads.
MOCK-ONLY suite: ``E2E_REAL_LLM=1`` is not supported for the
zero-LLM-call pin (assert 5 reads the mock's ``/v1/e2e/captured``
request log — the phase-123 house pattern for "ZERO chat calls").
Test → observable mapping (Playwright Mapping Rule):
1. ``test_additive_view`` — the ``manual.pdf`` modal: the content
payload stamps the class (``page_strip_mode == "additive"`` beside
the 4 ``page_urls``), the TEXT view opens by default (Summary panel
+ content visible — the map page's canned description RIDES the
shown text, LOCKED A1; the toggle's ``Text`` pressed, LOCKED A6)
with the strip mounted but hidden; pressing ``Pages`` shows the
4-figure strip and EVERY ``<img>`` loads (naturalWidth > 0 — the
route serves; no "unavailable" note anywhere); pressing ``Text``
back shows the text, hides the strip, and the strip NODE persists
(the same DOM element — probed by a dataset marker — with the same
4 loaded imgs: no re-render, no refetch).
2. ``test_primary_and_plain_doms`` — the ``scanned.pdf`` modal keeps
the phase-148 strip-only DOM byte-identically (payload
``page_strip_mode == "primary"``; NO ``.doc-view-toggle``, NO
``.doc-summary``, NO content block; 2 loaded ``.doc-page`` figures
with the ``Page N`` captions); the ``plain.pdf`` modal is the plain
text doc (raw content + Summary panel, ZERO ``.doc-pages`` /
``.doc-view-toggle`` nodes) and its payload carries NEITHER
``page_urls`` NOR ``page_strip_mode`` (the omission rule — the
non-qualifying payload is byte-identical to pre-phase).
3. ``test_heal_restores_deleted_copies`` — the live-loss state
reproduced: delete ALL ``pdf_page_dir/<manual-id>-p*.png`` (the row
still claims 4) → a page route 404s → run a sync over UNCHANGED
bytes (the fast path) → the four copies exist again (real PNGs),
the route serves 200 with PNG bytes, the row keeps ``page_count``
4 / mode ``additive``, the payload still carries ``page_urls`` +
``additive``, and the viewer's Pages view loads every img — the
exact D5 promise (a wipe cannot outlive one sync).
4. ``test_repair_clears_stale_strip`` — the stale-eligible state NO
current index produces: direct-DB seed sets ``plain.pdf``'s row to
``page_count`` 2 / mode ``additive`` and writes two stale copies on
disk → sync (still unchanged bytes) → both columns NULL (read
through the fixture session), the stale copies GONE, and the modal
shows the plain text doc (the strip is finished).
5. ``test_zero_llm_calls_on_heal_and_repair`` — the mock's request
log: the INITIAL index burned the vision passes it owes (≥1
``PICTORIAL_PAGE_MODE`` + ≥1 ``IMAGE_DESCRIPTION_MODE`` request —
the capture works and the premise is real), while the heal sync and
the repair sync each captured ZERO content/vision chat requests —
the re-gate is deterministic (render is CPU, LOCKED A5). The one
exempted request is the sync prelude's fixed ``ping`` model-health
probe (``app.rag.llm.check_models`` — every sync ever run pays it,
unchanged by this phase); anything else in the capture is a
violation.
House pattern: one module app over the shared E2E Postgres (its own
port, module env — the conftest session app is never started in this
isolated run, so no port clash). The five tests SHARE the module seed
(one source, three documents, one sync) and deliberately MUTATE shared
state (the page dir, then one row) in file order, so the shared
registry + KB is truncated ONCE, after the last test (a
module-granularity autouse — a per-test truncate would wipe the seed
from under its siblings), with a no-running-sync wait so a leaked run
cannot race it.
"""
from __future__ import annotations
import json
import os
import subprocess
import sys
import time
from collections.abc import Iterator
from datetime import datetime
from pathlib import Path
from typing import Any
import httpx
import pymupdf as fitz # PyMuPDF — the synthetic-fixture builder (the house recipe)
import pytest
from playwright.sync_api import Locator, Page, expect
from sqlalchemy import select, text
from app.config import Settings
from app.db import SessionLocal
from app.models import Document
from app.rag.pdf import (
extract_pdf_page_texts,
extract_pdf_text,
is_usable_pdf_text,
pictorial_pages,
render_pdf_pages,
)
from e2e.auth_helpers import login
from e2e.conftest import (
ADMIN_PASSWORD,
MOCK_PORT,
SESSION_SECRET,
USE_REAL_LLM,
_wait_http,
)
from e2e.mock_llm import IMAGE_DESCRIPTION_ANSWER, PICTORIAL_PAGE_ANSWER
REPO = Path(__file__).resolve().parents[2]
#: The local directory's NAME — the source name the registry stores for
#: a ``kind='local'`` source (the directory basename, the
#: test_local_directory_sources convention). The task's fixture name.
SOURCE_NAME = "strip_fixture"
MANUAL_PATH = "manual.pdf"
SCANNED_PATH = "scanned.pdf"
PLAIN_PATH = "plain.pdf"
MANUAL_TITLE = "Campaign Manual" # the metadata title (the Letumdei stand-in)
SCANNED_TITLE = "Scanned Plates" # the metadata title
PLAIN_TITLE = "Plain Notes" # the metadata title
#: The dense prose paragraph (500+ chars — over the 100-char sparseness
#: bar, so text pages are never gate candidates; the
#: test_pdf_pages_in_sources recipe).
DENSE_PARAGRAPH = (
"This manual covers the complete campaign, its muster rules, and the "
"supply checks a first-time commander should run before marching. The "
"train holds the two supply wagons, the field forge, the water cart, "
"eight cam locks for the tent pegs, fourteen spare stakes, two spare "
"axle bolts, and the signal-horn case. Work from a flat ridge with dry "
"ground, keep the squads sorted by banner, and read every dispatch "
"through before you begin so you know which standard is which. The "
"column marches roughly ten leagues a day once supplied, weighs under "
"twelve tonnes, and needs no further provision beyond the local levy."
)
assert len(DENSE_PARAGRAPH) > 500, "the dense paragraph must be 500+ chars"
#: The sparse map page's marker — ALL page 4's text layer carries (21
#: stripped chars, under the 100-char bar — the ONE gate candidate; the
#: figure is vector-drawn, exactly like the live page-36 map).
MAP_MARKER = "Map of the Imperium"
#: The phase-133 garbage line (the owner's exact shape) — 100% of the
#: scanned pages' text looks like tags, so ``is_usable_pdf_text`` fails
#: deterministically (the fallback class).
GARBAGE_LINE = "<illustrator:StartupProfile>Web</illustrator:StartupProfile>"
GARBAGE_LINES_PER_PAGE = 20
N_SCANNED_PAGES = 2
#: The stored map-page block (the phase-140 LOCKED A4 shape) — the
#: mock's canned ``PICTORIAL_PAGE_MODE`` reply, deterministic.
MAP_BLOCK = f"[Page 4 illustration: {PICTORIAL_PAGE_ANSWER}]"
#: The PNG signature (the route/seed byte assertions' magic number).
PNG_MAGIC = b"\x89PNG\r\n\x1a\n"
#: Phase 79 (task 04, full inventory): the conftest session app owns
#: its port in a combined run — this module app binds its own port
#: instead (a same-port second uvicorn dies on bind and would drive the
#: wrong server). Env-overridable.
APP_PORT = int(os.environ.get("E2E_APP_PORT_STRIPHEAL", "8177"))
APP_URL = f"http://127.0.0.1:{APP_PORT}"
MOCK_URL = f"http://127.0.0.1:{MOCK_PORT}"
#: The suite's LLM-request ledger (assert 5): every sync stores the
#: mock's chat-completions capture (``/v1/e2e/captured`` — the phase-123
#: house pattern) taken AROUND its own run under its name, so the
#: heal/repair syncs' ZERO-call pins read from the log the app itself
#: produced, not from a spy that never saw the real request.
LLM_CAPTURES: dict[str, list[dict[str, Any]]] = {}
# ---------------------------------------------------------------------------
# Fixture builders (the house PyMuPDF recipe — the three strip classes)
# ---------------------------------------------------------------------------
def _draw_map_figure(page: Any) -> None:
"""The vector map figure: a rectangle (the province) + a road line
with a two-stroke head — drawn, not embedded, so the text layer
stays the ONLY text and the embedded-image pipeline sees nothing."""
page.draw_rect(fitz.Rect(100, 120, 300, 220))
page.draw_line(fitz.Point(320, 170), fitz.Point(470, 170))
page.draw_line(fitz.Point(470, 170), fitz.Point(450, 158))
page.draw_line(fitz.Point(470, 170), fitz.Point(450, 182))
def _build_manual(path: Path) -> None:
"""The Letumdei shape in MINATURE (the pictorial class): three dense
prose pages + ONE sparse map-style page. Usable text layer with
exactly one gate candidate (page 4) → the ADDITIVE strip class."""
doc = fitz.open()
for i in range(1, 4):
p = doc.new_page()
rc = p.insert_textbox(
fitz.Rect(72, 72, 523, 772), f"Book {i}. {DENSE_PARAGRAPH}", fontsize=11
)
assert rc >= 0, f"the page-{i} paragraph must fit its text box"
p4 = doc.new_page()
p4.insert_text((72, 72), MAP_MARKER)
_draw_map_figure(p4)
doc.set_metadata({"title": MANUAL_TITLE})
doc.save(path)
doc.close()
def _build_scanned(path: Path) -> None:
"""The phase-133 fallback class: two pages whose ONLY text is the
XML-garbage line ×20 — the gate fails, so the page SCREENSHOTS are
the content (the PRIMARY strip class)."""
doc = fitz.open()
for page_num in range(1, N_SCANNED_PAGES + 1):
page = doc.new_page()
for i in range(GARBAGE_LINES_PER_PAGE):
page.insert_text((72, 72 + i * 14), f"{GARBAGE_LINE} p{page_num} l{i}")
doc.set_metadata({"title": SCANNED_TITLE})
doc.save(path)
doc.close()
def _build_plain(path: Path) -> None:
"""The negative class: two dense text pages, ZERO sparse candidates
— no strip ever (until the repair test seeds a stale one)."""
doc = fitz.open()
for i in (1, 2):
p = doc.new_page()
rc = p.insert_textbox(
fitz.Rect(72, 72, 523, 772), f"Note {i}. {DENSE_PARAGRAPH}", fontsize=11
)
assert rc >= 0, f"the page-{i} paragraph must fit its text box"
doc.set_metadata({"title": PLAIN_TITLE})
doc.save(path)
doc.close()
@pytest.fixture(scope="module")
def pdfs_dir(tmp_path_factory: pytest.TempPathFactory) -> Path:
"""The local directory source's root: the three fixture PDFs, built
ONCE (module-scoped). The premise pins (deterministic — computed
from the fixtures THEMSELVES, no hardcoded page lists): ``manual``
is usable-layer with candidates ``[4]`` (4 pages — the seed's
``page_count`` target, the Letumdei shape), ``scanned`` is
UNUSABLE-layer (the fallback class), ``plain`` is usable-layer with
ZERO candidates (no strip). Every page renders to a real PNG (the
pipeline's byte premise)."""
root = tmp_path_factory.mktemp("bor_p163_strip") / SOURCE_NAME
root.mkdir(parents=True)
min_chars = Settings.model_fields["pdf_pictorial_min_chars"].default
manual = root / MANUAL_PATH
scanned = root / SCANNED_PATH
plain = root / PLAIN_PATH
_build_manual(manual)
_build_scanned(scanned)
_build_plain(plain)
manual_texts = extract_pdf_page_texts(manual)
assert is_usable_pdf_text(extract_pdf_text(manual)), (
"the manual fixture must PASS the usability gate (the pictorial class)"
)
assert pictorial_pages(manual_texts, min_chars=min_chars) == [4], (
"the manual fixture's sparse-page premise broke: candidates="
f"{pictorial_pages(manual_texts, min_chars=min_chars)}"
)
assert not is_usable_pdf_text(extract_pdf_text(scanned)), (
"the scanned fixture's text layer must FAIL the usability gate "
"(the fallback class)"
)
assert is_usable_pdf_text(extract_pdf_text(plain))
assert pictorial_pages(
extract_pdf_page_texts(plain), min_chars=min_chars
) == [], "the plain fixture must carry ZERO sparse pages (the negative class)"
assert len(render_pdf_pages(manual)) == 4
assert len(render_pdf_pages(scanned)) == N_SCANNED_PAGES
assert len(render_pdf_pages(plain)) == 2
return root
@pytest.fixture(scope="module")
def scratch(tmp_path_factory: pytest.TempPathFactory) -> Path:
"""The suite-private app homes (pages dir, upload dir, checkouts,
images) — disposable with the module."""
return tmp_path_factory.mktemp("bor_p163_scratch")
@pytest.fixture(scope="module")
def page_dir(scratch: Path) -> Path:
"""The app's ``pdf_page_dir`` (``BOR_PDF_PAGE_DIR``) for this suite
— the heal test DELETES the manual doc's copies here and the re-gate
re-creates them; the owner's ``~/bor-sources/pages`` default is
never touched."""
return scratch / "pages"
# ---------------------------------------------------------------------------
# Module app (the conftest env pattern + the phase-140/148 knobs)
# ---------------------------------------------------------------------------
def _app_env(mock_llm: int, scratch: Path, page_dir: Path) -> dict[str, str]:
"""The conftest app env (leak guards included) with the phase-140
opt-in (``BOR_PDF_PICTORIAL`` EXPLICITLY on — the conftest pins it
off in ``os.environ`` for the pre-phase suites; this suite IS the
pictorial class + its kill-switch-mirroring re-gate) and the
phase-148 ``BOR_PDF_PAGE_DIR`` (suite-private — the heal mutates
this dir, and the app under test reads the same one)."""
env = dict(os.environ)
env.pop("DEBUGPY", None)
env["BOR_ENVIRONMENT"] = "e2e"
env["BOR_STATIC_DIR"] = str(REPO / "frontend")
env["BOR_LLM_BASE_URL"] = (
"https://aipi.reeseapps.com/v1"
if USE_REAL_LLM
else f"http://127.0.0.1:{mock_llm}/v1"
)
# Mock-calibrated gates (conftest pattern).
env["BOR_RELEVANCE_THRESHOLD"] = "0.30"
env["BOR_LEXICAL_SUPPORT_FLOOR"] = "0.15"
env["BOR_SOURCE_USEFULNESS_FLOOR"] = "0.15"
# Phase 67: instant retry waits + the code-default budget.
env["BOR_LLM_RETRY_DELAY"] = "0"
env["BOR_LLM_RETRIES"] = str(Settings.model_fields["llm_retries"].default)
env.setdefault(
"BOR_DATABASE_URL",
"postgresql+psycopg://reese:reese@localhost:5432/brain_of_reese",
)
env["BOR_ADMIN_PASSWORD"] = ADMIN_PASSWORD
env["BOR_SESSION_SECRET"] = SESSION_SECRET
# Leak guards (conftest pattern — the owner's local gitignored
# .env cannot leak the scope).
env["BOR_GIT_SOURCES"] = ""
env["BOR_DOCS_REPO"] = ""
env["BOR_SUGGESTIONS"] = json.dumps(Settings.model_fields["suggestions"].default)
env["BOR_INPUT_PLACEHOLDER"] = Settings.model_fields["input_placeholder"].default
env["BOR_FOOTER_TEXT"] = Settings.model_fields["footer_text"].default
# Phase 126: the import scope WITH the ``pdf`` token (the walk is
# blind to the fixtures without it).
env["BOR_IMPORT_EXTENSIONS"] = "md,markdown,txt,pdf"
# Phase 140: the pictorial toggle EXPLICITLY on (the opt-in —
# without it the whole premise is void).
env["BOR_PDF_PICTORIAL"] = "1"
# Phase 148: the rendered-page copies' home (the heal's delete/
# re-render target).
env["BOR_PDF_PAGE_DIR"] = str(page_dir)
# The embedded-image pipeline is out of scope (the figures are
# vector-drawn — no image docs either way).
env["BOR_IMAGES"] = "false"
env["BOR_UPLOAD_DIR"] = str(scratch / "uploads")
env["BOR_SOURCES_DIR"] = str(scratch / "checkouts")
env["BOR_IMAGE_DIR"] = str(scratch / "images")
return env
@pytest.fixture(scope="module")
def app_server(
mock_llm: int,
pdfs_dir: Path, # noqa: ARG001 — the dir's existence is the seed's job
scratch: Path,
page_dir: Path,
) -> Iterator[str]:
"""The app under test (all five tests): one module app with the
phase-140/148/163 env (see :func:`_app_env`)."""
proc = subprocess.Popen(
[
sys.executable,
"-m",
"uvicorn",
"app.main:app",
"--host",
"127.0.0.1",
"--port",
str(APP_PORT),
"--log-level",
"warning",
],
cwd=REPO,
env=_app_env(mock_llm, scratch, page_dir),
)
try:
_wait_http(f"{APP_URL}/api/health")
yield APP_URL
finally:
proc.terminate()
try:
proc.wait(timeout=10)
except subprocess.TimeoutExpired:
proc.kill()
@pytest.fixture(scope="module")
def app_url(app_server: str) -> str:
return app_server
# ---------------------------------------------------------------------------
# DB + sync + LLM-capture helpers (the house patterns)
# ---------------------------------------------------------------------------
def _truncate_all() -> None:
"""Fresh KB + registry (the E2E isolation pattern): the suites
share one Postgres, and a leftover row would corrupt the counts.
``sources_meta`` (the KB generation counter) resets with the KB."""
with SessionLocal() as db:
db.execute(
text(
"TRUNCATE chunks, documents, query_log, steering_notes, "
"kb_overview, git_sources, folder_summaries, sources_meta"
)
)
db.commit() # without the commit the TRUNCATE rolls back (the house pattern)
def _health_db(app_url: str) -> bool:
try:
return httpx.get(f"{app_url}/api/health", timeout=5).json()["db"] == "up"
except Exception: # noqa: BLE001 — unreachable is the skip case
return False
def _wait_sync_settled(base_url: str, timeout_s: float = 60.0) -> None:
"""No background sync may leak across tests (the run state lives in
the app's memory): wait for the app's sync status to be non-running
BEFORE the truncate (the phase-96 pattern)."""
with httpx.Client(base_url=base_url, timeout=5.0) as client:
r = client.post("/api/login", json={"password": ADMIN_PASSWORD})
assert r.status_code == 204, r.text
deadline = time.monotonic() + timeout_s
while time.monotonic() < deadline:
r = client.get("/api/sync/status")
assert r.status_code == 200, r.text
if r.json()["state"] != "running":
return
time.sleep(0.2)
raise AssertionError(f"a sync was still running at a test boundary: {base_url}")
@pytest.fixture(scope="module", autouse=True)
def _clean_kb(app_url: str) -> Iterator[None]:
"""Module-end KB cleanup (the phase-96 pattern, module granularity):
the five tests SHARE the module seed's one source + three documents
and MUTATE shared state (the page dir, then one row) in file order,
so there is NO per-test truncate; the shared KB is flushed ONCE,
after the last test. The pre-wait keeps a leaked sync from racing
the truncate."""
yield
_wait_sync_settled(app_url)
_truncate_all()
def _register_source(base_url: str, path: Path) -> None:
"""Register the local directory through the authenticated API (the
``test_local_directory_sources`` pattern — a plain directory is an
API/DB-only operation)."""
with httpx.Client(base_url=base_url, timeout=30.0) as client:
r = client.post("/api/login", json={"password": ADMIN_PASSWORD})
assert r.status_code == 204, r.text
r = client.post("/api/git-sources", json={"kind": "local", "path": str(path)})
assert r.status_code == 201, r.text
def _started_at(body: dict[str, Any]) -> float:
"""The status body's ``started_at`` as a wall-clock epoch (the
server stamps it in UTC; same host, same clock)."""
started = body.get("started_at")
if not started:
return 0.0
try:
return datetime.fromisoformat(str(started)).timestamp()
except ValueError:
return 0.0
def _capture_reset() -> None:
"""Clear the mock's chat-completions capture (the phase-123 house
endpoint) so the NEXT sync's LLM requests are exactly what the
capture holds afterwards. The MOCK-ONLY pin is skipped under
``E2E_REAL_LLM=1`` (no capture to read — assert 5 skips too)."""
if USE_REAL_LLM:
return
r = httpx.post(f"{MOCK_URL}/v1/e2e/captured/reset", timeout=5.0)
assert r.status_code == 200, r.text
def _capture_read(name: str) -> list[dict[str, Any]]:
"""Store the mock's current capture in the suite ledger under
*name* (see :data:`LLM_CAPTURES`)."""
if USE_REAL_LLM:
LLM_CAPTURES[name] = []
return []
r = httpx.get(f"{MOCK_URL}/v1/e2e/captured", timeout=5.0)
assert r.status_code == 200, r.text
captured = r.json()
LLM_CAPTURES[name] = captured
return captured
def _run_sync(
base_url: str, capture_name: str | None = None, timeout_s: float = 120.0
) -> dict[str, Any]:
"""Login + ``POST /api/sync`` + poll the status endpoint until THIS
run reaches a terminal state (the ``test_pdf_pages_in_sources``
pattern — with the stale-terminal freshness gate). When
*capture_name* is given, the mock's request capture is reset before
the POST and stored under that name once the run settles — the
sync's ENTIRE LLM footprint, bracketed (assert 5's lens)."""
_capture_reset()
with httpx.Client(base_url=base_url, timeout=30.0) as client:
r = client.post("/api/login", json={"password": ADMIN_PASSWORD})
assert r.status_code == 204, r.text
t0 = time.time()
r = client.post("/api/sync")
assert r.status_code == 202, r.text
saw_running = False
deadline = time.monotonic() + timeout_s
body: dict[str, Any] = {}
while time.monotonic() < deadline:
r = client.get("/api/sync/status")
assert r.status_code == 200, r.text
body = r.json()
state = body["state"]
if state == "running":
saw_running = True
elif state in ("success", "failed") and (
saw_running
or _started_at(body) >= t0 - 1.0 # same-host clock; 1 s tolerance
):
if capture_name is not None:
_capture_read(capture_name)
return body
time.sleep(0.1)
if capture_name is not None:
_capture_read(capture_name)
raise AssertionError(f"sync did not reach a terminal state: {body}")
def _doc_row(path: str) -> Document:
"""The fixture session's view of one source row (the DB-lens the
heal/repair asserts read through — ``expire_on_commit`` off means
the values are the row's, freshly queried per call)."""
with SessionLocal() as db:
doc = db.scalar(
select(Document).where(
Document.source == SOURCE_NAME, Document.path == path
)
)
assert doc is not None, f"the {path} row must exist"
db.expunge(doc)
return doc
def _payload(app_url: str, path: str) -> dict[str, Any]:
"""The document-content payload (the surface the viewer renders
from) as a dict — the ``page_urls`` / ``page_strip_mode`` key
presence rules are asserted on THIS JSON, not the DB."""
with httpx.Client(base_url=app_url, timeout=30.0) as client:
r = client.post("/api/login", json={"password": ADMIN_PASSWORD})
assert r.status_code == 204, r.text
r = client.get("/api/documents/content", params={"source": SOURCE_NAME, "path": path})
assert r.status_code == 200, r.text
return r.json()
# ---------------------------------------------------------------------------
# The module seed: register the local dir + one sync (all three PDFs),
# then assert the three-class DB + filesystem state
# ---------------------------------------------------------------------------
@pytest.fixture(scope="module")
def seeded(app_url: str, pdfs_dir: Path, page_dir: Path) -> Iterator[dict[str, Any]]:
"""Register the local directory source and run ONE real sync (the
index pass, its capture stored as ``LLM_CAPTURES["index"]``).
Asserts the post-index three-class contract: ``manual`` is the
pictorial class (``page_count`` 4, mode ``additive``, the canned
map block IN the content — the Letumdei shape), ``scanned`` the
fallback class (``page_count`` 2, mode ``primary``, the canned
screenshot descriptions, the garbage NOT stored), ``plain``
unqualified (both columns NULL) — and the page dir holds EXACTLY
the two qualifying docs' six copies (real PNGs, no plain copies, no
orphans). Yields the ids + the page dir."""
if not _health_db(app_url):
pytest.skip("Postgres not reachable — run `podman compose up -d db` first")
_truncate_all()
_register_source(app_url, pdfs_dir)
body = _run_sync(app_url, capture_name="index")
assert body["state"] == "success", body
detail = body["detail"]
assert detail["files"] == 3, detail
assert detail["added"] == 3, detail
assert detail["pruned"] == 0, detail
assert detail["errors"] == 0, detail
manual = _doc_row(MANUAL_PATH)
assert manual.title == MANUAL_TITLE
assert manual.page_count == 4, (
f"the pictorial-class row must carry its page count: {manual.page_count}"
)
assert manual.page_strip_mode == "additive", (
"the pictorial class (usable layer + sparse candidate) must stamp "
f"additive: {manual.page_strip_mode!r}"
)
# The phase-140 descriptions ride the stored content (Q&A parity) —
# the ONE map block is the live Letumdei shape in miniature.
assert "---PAGE-1---" in manual.content and "---PAGE-4---" in manual.content
assert MAP_BLOCK in manual.content, (
"the map page's canned description must be in the stored content"
)
assert manual.summary
scanned = _doc_row(SCANNED_PATH)
assert scanned.page_count == N_SCANNED_PAGES
assert scanned.page_strip_mode == "primary", (
"the fallback class (unusable layer) must stamp primary: "
f"{scanned.page_strip_mode!r}"
)
assert scanned.content.startswith("---PAGE-1---")
assert IMAGE_DESCRIPTION_ANSWER in scanned.content, (
"the fallback's content must be the canned page-screenshot descriptions"
)
assert GARBAGE_LINE not in scanned.content, (
"the garbage text layer must NOT be the stored content"
)
plain = _doc_row(PLAIN_PATH)
assert plain.page_count is None, "a zero-candidate PDF must not qualify"
assert plain.page_strip_mode is None
manual_id, scanned_id, plain_id = str(manual.id), str(scanned.id), str(plain.id)
# The filesystem contract: EXACTLY the two qualifying docs' copies
# (no plain copies, no orphans) — real, non-empty PNGs.
expected = sorted(
[f"{manual_id}-p{n}.png" for n in range(1, 5)]
+ [f"{scanned_id}-p{n}.png" for n in range(1, N_SCANNED_PAGES + 1)]
)
pngs = sorted(p.name for p in page_dir.glob("*.png"))
assert pngs == expected, f"the page dir holds {pngs}, expected {expected}"
for name in pngs:
data = (page_dir / name).read_bytes()
assert data[:8] == PNG_MAGIC and data, f"{name} is not a real PNG"
assert not list(page_dir.glob(f"{plain_id}-*")), (
"the non-qualifying PDF must not have page copies"
)
yield {
"manual_id": manual_id,
"scanned_id": scanned_id,
"plain_id": plain_id,
"page_dir": page_dir,
}
# ---------------------------------------------------------------------------
# Shared UI helpers
# ---------------------------------------------------------------------------
def _drill_to_source(page: Page, name: str) -> None:
"""Sources tree: top level → the source (the file table then holds
its direct files — all three fixtures sit at the directory root)."""
page.locator("#folders-tbody .folder-link").first.wait_for(state="visible")
page.click(f'#folders-tbody a.folder-link:text-is("{name}")')
expect(page.locator("#docs-tbody tr").first).to_be_visible(timeout=30_000)
def _open_doc_modal(page: Page, doc_path: str) -> Locator:
"""The house doc-modal idiom: the row's path link opens the
same-page modal (no new tab). Returns the content slot locator."""
before = len(page.context.pages)
page.locator(f'#docs-tbody a.doc-link:text-is("{doc_path}")').click()
assert len(page.context.pages) == before, "the row link must not open a new tab"
modal = page.locator("#doc-modal")
expect(modal).to_be_visible(timeout=30_000)
return page.locator("#doc-modal-content")
def _wait_img_loaded(img: Locator) -> None:
"""Wait until a LAZY ``<img>`` really loaded pixels: scroll it into
the viewport, await the browser's own ``decode()`` promise (it
rejects on a failed fetch — a 404 route), and assert
``naturalWidth > 0`` (a real PNG, not a zero-size error image)."""
img.scroll_into_view_if_needed()
img.evaluate("el => el.decode()")
natural = img.evaluate("el => el.naturalWidth")
assert natural > 0, f"the page image did not load (naturalWidth={natural})"
def _assert_figures(strip: Locator, title: str, doc_id: str, page_count: int) -> None:
"""The phase-148 figure contract inside a (visible) strip: exactly
*page_count* ``.doc-page`` figures, each with a LOADED lazy
``<img>`` (the route served a real PNG — not the "Page N
unavailable" note), the ``Page N of <title>`` alt, the exact 1-based
route src, and the ``Page N`` caption."""
figures = strip.locator(".doc-page")
expect(figures).to_have_count(page_count)
for i in range(page_count):
n = i + 1
fig = figures.nth(i)
img = fig.locator("img")
expect(img).to_have_count(1)
expect(img).to_have_attribute("loading", "lazy")
expect(img).to_have_attribute("alt", f"Page {n} of {title}")
expect(img).to_have_attribute("src", f"/api/documents/{doc_id}/pages/{n}")
_wait_img_loaded(img)
expect(fig.locator("figcaption.doc-page-num")).to_have_text(f"Page {n}")
# ---------------------------------------------------------------------------
# 1. The additive view: text first, the strip one toggle away, no
# refetch on flip-flop
# ---------------------------------------------------------------------------
def test_additive_view(page: Page, app_url: str, seeded: dict[str, Any]) -> None:
"""The ``manual.pdf`` modal — the ADDITIVE class (LOCKED A1/A6):
the content payload stamps the class (``page_strip_mode ==
"additive"`` beside the 4 ``page_urls``); the TEXT view opens by
default — Summary panel + content visible, the toggle's ``Text``
``aria-pressed="true"``, the strip mounted but hidden, the map
page's canned description RIDING the shown text (the text is never
hidden for the pictorial class); pressing ``Pages`` shows the
4-figure strip with EVERY img loaded (naturalWidth > 0 — the route
serves; no "unavailable" note anywhere) and hides the text view;
pressing ``Text`` back shows the text, hides the strip, and the
strip node is the SAME mounted DOM element (a dataset probe survives
the flip — no re-render) with its 4 imgs still loaded (no
refetch)."""
# The wire pin: the class is stamped next to the page_urls.
payload = _payload(app_url, MANUAL_PATH)
assert payload.get("page_strip_mode") == "additive", payload
assert payload.get("page_urls") == [
f"/api/documents/{seeded['manual_id']}/pages/{n}" for n in range(1, 5)
], payload
login(page, app_url) # lands on /sources.html
_drill_to_source(page, SOURCE_NAME)
expect(page.locator("#docs-tbody tr")).to_have_count(3)
content = _open_doc_modal(page, MANUAL_PATH)
expect(page.locator("#doc-modal-title")).to_have_text(MANUAL_TITLE)
# Default view: TEXT (LOCKED A6) — Summary panel + content visible,
# the strip mounted but hidden (its lazy imgs never fetched yet).
toggle = content.locator(".doc-view-toggle")
expect(toggle).to_have_count(1)
expect(toggle.get_by_role("button", name="Text")).to_have_attribute(
"aria-pressed", "true"
)
expect(toggle.get_by_role("button", name="Pages")).to_have_attribute(
"aria-pressed", "false"
)
expect(content.locator("pre.doc-raw")).to_be_visible()
expect(content.locator(".doc-summary")).to_be_visible()
expect(content.locator(".doc-pages")).to_be_hidden()
assert MAP_MARKER in content.inner_text(), "the text view shows the book's text"
assert PICTORIAL_PAGE_ANSWER in content.inner_text(), (
"the additive text view shows the indexed content INCLUDING the "
"map page's description (LOCKED A1 — the text is never hidden)"
)
# Pages: the strip shows, every copy loads, the text view hides.
toggle.get_by_role("button", name="Pages").click()
expect(content.locator(".doc-pages")).to_be_visible()
_assert_figures(content.locator(".doc-pages"), MANUAL_TITLE, seeded["manual_id"], 4)
assert "unavailable" not in content.inner_text(), (
"no page may show the 'Page N unavailable' note once the strip shows"
)
expect(content.locator("pre.doc-raw")).not_to_be_visible()
expect(content.locator(".doc-summary")).not_to_be_visible()
# Tag the strip's FIRST img so the flip-back can prove the node is
# the same DOM element (a re-render would build a fresh one).
first_img = content.locator(".doc-pages .doc-page img").first
first_img.evaluate("el => { el.dataset.p163probe = 'mounted'; }")
# Text: the reversal — text visible, strip hidden, the strip node
# STILL MOUNTED with its 4 loaded imgs (zero refetch).
toggle.get_by_role("button", name="Text").click()
expect(toggle.get_by_role("button", name="Text")).to_have_attribute(
"aria-pressed", "true"
)
expect(content.locator("pre.doc-raw")).to_be_visible()
expect(content.locator(".doc-pages")).to_be_hidden()
expect(content.locator(".doc-pages .doc-page img")).to_have_count(4)
assert (
content.locator(".doc-pages .doc-page img").first.evaluate(
"el => el.dataset.p163probe"
)
== "mounted"
), "flipping back must reuse the mounted strip (no re-render, no refetch)"
assert content.locator(".doc-pages .doc-page img").first.evaluate(
"el => el.complete && el.naturalWidth > 0"
), "the mounted imgs stay decoded across the flip (no reset)"
# ---------------------------------------------------------------------------
# 2. The primary class (byte-identical strip-only DOM) + the plain doc
# ---------------------------------------------------------------------------
def test_primary_and_plain_doms(page: Page, app_url: str, seeded: dict[str, Any]) -> None:
"""The two untouched shapes, pinned side by side. ``scanned.pdf``
(the fallback class, payload ``page_strip_mode == "primary"``)
keeps the phase-148 strip-only DOM byte-identically: NO
``.doc-view-toggle``, NO ``.doc-summary``, NO content block — just
the 2-figure strip, every img loaded with the ``Page N`` captions.
``plain.pdf`` (no strip) renders the plain text doc — the raw
content + the Summary panel, ZERO ``.doc-pages`` /
``.doc-view-toggle`` nodes — and its payload carries NEITHER
``page_urls`` NOR ``page_strip_mode`` (the ABSENT-never-null
omission rule: the non-qualifying payload is byte-identical to
pre-phase)."""
# The wire pins: primary stamped; both keys absent for plain.
payload = _payload(app_url, SCANNED_PATH)
assert payload.get("page_strip_mode") == "primary", payload
assert payload.get("page_urls") == [
f"/api/documents/{seeded['scanned_id']}/pages/{n}"
for n in range(1, N_SCANNED_PAGES + 1)
], payload
plain_payload = _payload(app_url, PLAIN_PATH)
assert "page_urls" not in plain_payload, plain_payload
assert "page_strip_mode" not in plain_payload, plain_payload
login(page, app_url) # lands on /sources.html
_drill_to_source(page, SOURCE_NAME)
# The primary class: the strip IS the view — no toggle, no Summary
# panel, no content block (the phase-148 DOM, byte-for-byte).
content = _open_doc_modal(page, SCANNED_PATH)
expect(page.locator("#doc-modal-title")).to_have_text(SCANNED_TITLE)
expect(content.locator(".doc-view-toggle")).to_have_count(0)
expect(content.locator(".doc-summary")).to_have_count(0)
expect(content.locator("pre.doc-raw")).to_have_count(0)
strip = content.locator(".doc-pages")
expect(strip).to_have_count(1)
expect(strip).to_be_visible()
_assert_figures(strip, SCANNED_TITLE, seeded["scanned_id"], N_SCANNED_PAGES)
# The plain doc: the pre-phase text rendering — no strip artifacts.
page.goto(f"{app_url}/sources.html")
_drill_to_source(page, SOURCE_NAME)
content = _open_doc_modal(page, PLAIN_PATH)
expect(page.locator("#doc-modal-title")).to_have_text(PLAIN_TITLE)
expect(content.locator(".doc-pages")).to_have_count(0)
expect(content.locator(".doc-view-toggle")).to_have_count(0)
expect(content.locator("pre.doc-raw")).to_have_count(1)
expect(content.locator("pre.doc-raw")).to_contain_text("---PAGE-1---")
expect(content.locator("pre.doc-raw")).to_contain_text("Note 2.")
expect(content.locator(".doc-summary")).to_have_count(1)
# ---------------------------------------------------------------------------
# 3. The heal: copies deleted under a stamped page_count → one
# unchanged-byte sync restores everything
# ---------------------------------------------------------------------------
def test_heal_restores_deleted_copies(
page: Page, app_url: str, seeded: dict[str, Any]
) -> None:
"""The live ``Letumdei`` failure mode, reproduced and healed: delete
ALL ``pdf_page_dir/<manual-id>-p*.png`` (the row still claims 4) →
a page route 404s (the exact live evidence) → run a sync over
UNCHANGED bytes (the phase-147 fast path) → the four copies exist
again (real PNGs), the route serves 200 with PNG bytes, the row
keeps ``page_count`` 4 / mode ``additive``, the payload still
carries ``page_urls`` + ``additive``, and the viewer's Pages view
loads EVERY img — the disk-level loss the owner saw cannot outlive
one sync (LOCKED A5, the D5 promise)."""
manual_id = seeded["manual_id"]
page_dir: Path = seeded["page_dir"]
copies = sorted(page_dir.glob(f"{manual_id}-p*.png"))
assert len(copies) == 4, f"the seed must leave 4 copies: {[p.name for p in copies]}"
for p in copies:
p.unlink()
assert not list(page_dir.glob(f"{manual_id}-p*.png")), "the wipe must be complete"
# The live-loss state on the wire: the row claims 4, the route 404s.
r = page.request.get(f"{app_url}/api/documents/{manual_id}/pages/1")
assert r.status == 404, f"the wiped copy must 404 before the heal: {r.status}"
# One sync over unchanged bytes — the fast path + the re-gate. The
# run's whole LLM footprint is captured (assert 5 consumes it).
body = _run_sync(app_url, capture_name="heal")
assert body["state"] == "success", body
detail = body["detail"]
assert detail["unchanged"] == 3, detail
assert detail["added"] == 0, detail
assert detail["errors"] == 0, detail
# The disk: the four copies exist again — real PNGs.
restored = sorted(page_dir.glob(f"{manual_id}-p*.png"))
assert [p.name for p in restored] == [
f"{manual_id}-p{n}.png" for n in range(1, 5)
], f"the heal left {[p.name for p in restored]}"
for p in restored:
data = p.read_bytes()
assert data[:8] == PNG_MAGIC and data, f"{p.name} is not a real PNG after heal"
# The route serves again; the payload keeps the strip + the class.
r = page.request.get(f"{app_url}/api/documents/{manual_id}/pages/1")
assert r.status == 200, f"the healed copy must serve: {r.status}"
assert r.headers["content-type"] == "image/png", r.headers
assert r.body()[:8] == PNG_MAGIC, "the healed route served non-PNG bytes"
payload = _payload(app_url, MANUAL_PATH)
assert payload.get("page_strip_mode") == "additive", payload
assert len(payload.get("page_urls", [])) == 4, payload
# The row (the fixture session's view): count + class intact.
row = _doc_row(MANUAL_PATH)
assert row.page_count == 4
assert row.page_strip_mode == "additive"
# The viewer, complete: every page image loads through the route.
login(page, app_url)
_drill_to_source(page, SOURCE_NAME)
content = _open_doc_modal(page, MANUAL_PATH)
content.locator(".doc-view-toggle").get_by_role("button", name="Pages").click()
expect(content.locator(".doc-pages")).to_be_visible()
_assert_figures(content.locator(".doc-pages"), MANUAL_TITLE, manual_id, 4)
assert "unavailable" not in content.inner_text(), (
"after the heal the viewer must show zero 'Page N unavailable' notes"
)
# ---------------------------------------------------------------------------
# 4. The repair arm: a stale page_count on a now-ineligible doc is
# cleared, with its copies
# ---------------------------------------------------------------------------
def test_repair_clears_stale_strip(
page: Page, app_url: str, seeded: dict[str, Any]
) -> None:
"""The stale-eligible state NO current index produces, seeded
direct-DB: ``plain.pdf``'s row gets ``page_count`` 2 + mode
``additive`` and two stale copies land on disk (the strip-shape a
pre-phase bug or a lowered ``pdf_pictorial_min_chars`` leaves
behind). One sync (the bytes stay unchanged) → the REPAIR arm: both
columns NULL again (read through the fixture session), the stale
copies GONE, and the modal shows the plain text doc — the strip is
finished. The other docs' strips are untouched."""
plain_id = seeded["plain_id"]
page_dir: Path = seeded["page_dir"]
# The seed: the row claims a strip its current gate would never set.
with SessionLocal() as db:
doc = db.scalar(
select(Document).where(
Document.source == SOURCE_NAME, Document.path == PLAIN_PATH
)
)
assert doc is not None
doc.page_count = 2
doc.page_strip_mode = "additive"
db.commit()
stale = [page_dir / f"{plain_id}-p{n}.png" for n in (1, 2)]
for p in stale:
p.write_bytes(b"STALE-PRE-PHASE-COPY") # not even a real PNG
body = _run_sync(app_url, capture_name="repair")
assert body["state"] == "success", body
detail = body["detail"]
assert detail["unchanged"] == 3, detail
assert detail["errors"] == 0, detail
# The row (the fixture session's view): both columns cleared.
row = _doc_row(PLAIN_PATH)
assert row.page_count is None, (
f"the repair arm must clear a stale page_count: {row.page_count}"
)
assert row.page_strip_mode is None, (
f"the repair arm must clear the mode with the count: {row.page_strip_mode}"
)
# The stale copies are gone; the other docs' copies untouched.
assert not list(page_dir.glob(f"{plain_id}-*")), (
"the repair arm must delete the stale copies"
)
assert len(list(page_dir.glob(f"{seeded['manual_id']}-p*.png"))) == 4, (
"the repair of one doc must not touch another doc's copies"
)
assert len(list(page_dir.glob(f"{seeded['scanned_id']}-p*.png"))) == 2
# The wire + the viewer: the strip is gone, the plain text doc is
# back (the same payload shape as test 2 pinned).
assert "page_urls" not in _payload(app_url, PLAIN_PATH)
login(page, app_url)
_drill_to_source(page, SOURCE_NAME)
content = _open_doc_modal(page, PLAIN_PATH)
expect(content.locator(".doc-pages")).to_have_count(0)
expect(content.locator(".doc-view-toggle")).to_have_count(0)
expect(content.locator("pre.doc-raw")).to_be_visible()
# ---------------------------------------------------------------------------
# 5. Zero LLM calls on the fast-path repair (LOCKED A5)
# ---------------------------------------------------------------------------
def test_zero_llm_calls_on_heal_and_repair(seeded: dict[str, Any]) -> None:
"""The mock's request log (the house capture pattern): the INITIAL
index burned the vision passes it owes — at least one
``PICTORIAL_PAGE_MODE`` request (the map page) and at least one
``IMAGE_DESCRIPTION_MODE`` request (the fallback screenshots), the
witnesses that the capture really sees the app's calls — while the
HEAL sync and the REPAIR sync each captured EXACTLY ZERO
chat-completions requests. The re-gate mirrors the gate
deterministically from the current bytes + settings: rendering is
CPU-only, so the self-heal burns zero LLM/vision calls (LOCKED A5)."""
if USE_REAL_LLM:
pytest.skip("the zero-call pin reads the mock's request capture")
index = LLM_CAPTURES.get("index")
heal = LLM_CAPTURES.get("heal")
repair = LLM_CAPTURES.get("repair")
assert index is not None and heal is not None and repair is not None, (
"the suite ledger must hold all three syncs' captures — run the tests in order"
)
dumped = json.dumps(index)
assert "PICTORIAL_PAGE_MODE" in dumped, (
"the initial index must have burned the pictorial vision pass — "
"without this witness the zero-call pin below is vacuous"
)
assert "IMAGE_DESCRIPTION_MODE" in dumped, (
"the initial index must have burned the fallback screenshot pass"
)
heal_content = [b for b in heal if not _is_health_probe(b)]
repair_content = [b for b in repair if not _is_health_probe(b)]
assert heal_content == [], f"the heal sync burned LLM calls: {_summarize(heal_content)}"
assert repair_content == [], (
f"the repair sync burned LLM calls: {_summarize(repair_content)}"
)
def _is_health_probe(body: dict[str, Any]) -> bool:
"""The sync prelude's fixed model-health ping (``app.rag.llm
.check_models`` — one non-streaming ``ping`` chat every sync ever
run pays, unchanged by phase 163). Exempted from the zero-call
pins; NOTHING else may appear in a heal/repair capture."""
msgs = body.get("messages") or []
return (
not body.get("stream")
and len(msgs) == 1
and msgs[0].get("content") == "ping"
)
def _summarize(captured: list[dict[str, Any]]) -> str:
"""A compact one-liner per captured request (its system-prompt
marker) for the failure messages — keeps a violation readable
without dumping whole prompt bodies."""
out = []
for body in captured:
msgs = body.get("messages", [])
first = str(msgs[0].get("content", ""))[:80] if msgs else "?"
out.append(f"chat(stream={bool(body.get('stream'))}): {first}")
return " | ".join(out)