phase: 140_pictorial_pdf_pages
Build and Push Containers / build-and-push-app (push) Successful in 2m26s
Build and Push Containers / build-and-push-db (push) Successful in 12s

Everything is verified green. Final report:

## Phase 140 final verification pass — report

- Verified all 4 tasks already complete (code in working tree, task files in `complete/`): `pictorial_pages` gate + 2 settings (`BOR_PDF_PICTORIAL`, `BOR_PDF_PICTORIAL_MIN_CHARS` + validator), `PICTORIAL_PAGE_MODE`/`describe_pdf_page` seam + `render_pdf_pages` page selector + mock branch, `_pictorial_pdf_pass` in `_index_pdf_file` with log-only counters, dedicated E2E. No code changes needed.
- Test results (exact commands):
  - `uv run pytest --cov=app --cov-report=term-missing` → **3320 passed, 11 skipped, 0 failed; TOTAL 99%** (>90% gate)
  - `uv run pytest tests/e2e/test_pictorial_pdf.py -v --no-cov` → **3 passed in isolation** (Playwright, mock-only)
  - Pre-existing suites unedited: `test_pdf_support.py` 6 passed; `test_garbage_pdf.py` 2 passed + 1 skipped (owner fixture); `test_pdf_image_context.py` 4 passed
  - `uv run ruff check .` → All checks passed; `uv run pyright` → 0 errors
- Completion criteria:
  1. IKEA tar import repro — pinned by 2 integration tests; **skipped loudly here** (`test_sources/ikea_instructions.tar` absent on this machine — verified repo-wide; same house convention as completed phase-133 HNB tests; runs real on the owner's machine). Equivalent logic fully covered by unit pins on synthetic IKEA-class (vector-drawn, zero-raster) PDFs.
  2. Chat grounded on described page — **green** (E2E test b: phrase-only-in-illustration question, PDF in `done.sources`, answer echoes the block)
  3. Clean-text no-op (zero vision calls) + garbage precedence pin — **green** (`test_zero_candidates_is_a_noop` unit; `test_garbage_pdf_with_pictorial_on_takes_the_fallback_not_the_pass` integration, verified alone)
  4. `BOR_PDF_PICTORIAL=0` byte-identical — **green** (unit pin on synthetic PDF; IKEA variant runs on owner's machine)
  5. Full gate + E2E isolation + pre-existing suites — **green** (above)
  6. ruff + pyright — **clean**
  7. Commit/phase-move — delegated to harness per run rules (left in working tree: 16 modified + 8 new files, uncommitted)
- Deviations: none beyond the expected owner-fixture skips (11, all pre-existing fixture-missing skips, including 2 IKEA).
- Next pending phase: **none** — `todo/` holds only 140; 139 is already complete.
This commit is contained in:
2026-09-30 19:16:35 -04:00
parent a86544a083
commit 9633eb7653
45 changed files with 3895 additions and 36 deletions
+20 -4
View File
@@ -989,8 +989,10 @@ def test_import_summary_log_line_includes_summary_counters(
sits between ``summary_errors`` and ``dates_updated``; the
phase-106 date-refresh counter, the phase-122 ``images_failed``
counter, the phase-137 ``image_context_backfilled`` counter (next
to ``images_failed``), and the phase-133 ``pdfs_screenshotted``
counter sit after ``dates_updated``, before ``formats``."""
to ``images_failed``), the phase-133 ``pdfs_screenshotted``
counter, and the phase-140 ``pdfs_pictorial`` /
``pdf_pictorial_pages`` counters (next to ``pdfs_screenshotted``)
sit after ``dates_updated``, before ``formats``."""
s = ImportSummary()
s.files, s.added, s.chunks, s.embed_batches = 3, 3, 5, 4
s.summaries, s.summary_errors = 2, 1
@@ -999,6 +1001,8 @@ def test_import_summary_log_line_includes_summary_counters(
s.images_failed = 0
s.image_context_backfilled = 2
s.pdfs_screenshotted = 1
s.pdfs_pictorial = 2
s.pdf_pictorial_pages = 5
s.formats = {"md": 1, "yaml": 2}
with caplog.at_level(logging.INFO, logger="app.importer"):
s.log()
@@ -1007,7 +1011,8 @@ def test_import_summary_log_line_includes_summary_counters(
"import: summary files=3 added=3 updated=0 unchanged=0 pruned=0 errors=0 "
"chunks=5 embed_batches=4 summaries=2 summary_errors=1 summary_backfilled=1 "
"dates_updated=0 images_failed=0 image_context_backfilled=2 "
"pdfs_screenshotted=1 formats=yaml:2,md:1"
"pdfs_screenshotted=1 pdfs_pictorial=2 pdf_pictorial_pages=5 "
"formats=yaml:2,md:1"
)
@@ -1636,6 +1641,11 @@ def test_on_chunk_progress_pdf_branch_reports_content_chunks(
images=True,
image_dir=str(tmp_path / "images"),
import_extensions="md,txt,pdf",
# Phase 140: the pre-phase-140 shape pin — this fixture's pages
# are sparse (the default-ON pictorial pass would append
# illustration blocks and add vision calls); the pass is
# covered in tests/unit/test_pictorial_import.py.
pdf_pictorial=False,
)
try:
summary = asyncio.run(
@@ -1742,12 +1752,18 @@ def _pdf_settings(tmp_path: Path, images: bool = False) -> Settings:
silently skip the PDF) with the image knobs at their test values
(``images`` off unless pinned otherwise — the fallback's own vision
calls need no image copy, only the phase-122 embedded-image pass
does)."""
does). Phase 140: ``pdf_pictorial`` is pinned OFF — these suites
pin the PRE-phase-140 content shape (their fixture pages are
sparse — under the 100-char bar — so the default-ON pictorial
pass would append illustration blocks and move the byte-exact
pins; ``tests/unit/test_pictorial_import.py`` covers the pass
itself, with the kill switch in both states)."""
return Settings(
_env_file=None, # pyright: ignore[reportCallIssue] (kwarg exists at runtime)
import_extensions="md,txt,pdf",
images=images,
image_dir=str(tmp_path / "images"),
pdf_pictorial=False,
)