Skip to content

feat(diagrams): one box per page-band — capture 100 % of figures, model decides (T-080, closes T-078) - #161

Open
Ztein wants to merge 4 commits into
mainfrom
feat/t080-one-box-per-page
Open

feat(diagrams): one box per page-band — capture 100 % of figures, model decides (T-080, closes T-078)#161
Ztein wants to merge 4 commits into
mainfrom
feat/t080-one-box-per-page

Conversation

@Ztein

@Ztein Ztein commented Jul 22, 2026

Copy link
Copy Markdown
Owner

What

Replaces the chart-classification detector (union-find clustering, y-gap split, per-cluster floors, solid-fill gates) with one box per page-band: a page's vector content unions into one box per vertical band, and two bands are separate figures only when a body paragraph sits between them. No chart/not-chart judgement remains in code — the vision model decides what each box is, and T-081's structured is_figure skips the non-figures.

Closes T-080 and T-078 (the dropped bar/combo charts fell to the very gates this removes).

Bench — before → after

Live end-to-end runs (gemma-4-31B via Berget, 2026-07-22), caption coverage per scripts/coverage_bench:

Document main this PR Captured Skipped by model
boc-mpr-202410 58 % 100 % (26/26) 32 3
boj-outlook-2410 79 % 100 % (58/58) 55 4
riksbank-fsr-202505 3 charts dropped (T-078) 100 % (28/28) 38

Geometric coverage also 100 % on bis-ar-2024, fed-mpr-202407, riksbank-ppr-202503. Cost ~flat: 301→284 regions aggregate over seven corpus docs (BIS halves — multi-panel figures merge; BoC/Fed roughly double, exactly where main dropped 1 in 4 figures). Full-conversion cost: BoC 0.016 EUR, BoJ 0.030 EUR, FSR 0.019 EUR.

Decisions (bench-validated, no arbitrary limits)

  • Paragraph vs figure furniture: ≥ 20 words AND ≥ 2 lines AND sentence punctuation. Word counts alone overlap (BIS panel titles run 15–44 words); the punctuation test cuts junk 107→0 words. Numbers in diagrams.py comments + T-080 resolution.
  • Paragraph guard (new): a body paragraph ≥ 80 % inside a region is never suppressed from the body text — one-box bands can legitimately cover flowing text (measured 29/156/538 swallowed words on BoC/BoJ/BIS even per-band). Mild duplication beats silent deletion. Rescued prose 831/2016/9350 words, junk 0.
  • Page furniture: drawings spanning ≥ 90 % of a page dimension are filtered — a 5 px margin bar otherwise bridges every band into a full-page box.
  • Tables: table-owned drawings excluded before banding. A ruled table find_tables misses is now captured for the model instead of dropped (addresses the T-050 symptom).

Simpler, not detuned

_close/_cluster_rects/_split_by_y_gap, MERGE_DISTANCE, MIN_DRAWINGS_PER_CLUSTER, INTERNAL_Y_GAP_SPLIT all deleted; two bench-validated constants added (PARA_MIN_WORDS/LINES). Net −206/+277 including tests and docs.

Tests

  • Offline suite: 385 passed (contract updates: p68 stacked charts merge to one box; poi-pictures' 3 vector pictures band together; p70's ruled table is captured, not dropped — each documented in the test docstring).
  • Live suite: 9/9 passed; live baseline recorded in scripts/coverage_bench/BASELINE.md.

🤖 Generated with Claude Code

Ztein and others added 4 commits July 22, 2026 21:23
…ions, model decides (T-080)

Phase 2 of the capture-100% work; NOT mergeable until T-081 (structured describe)
lands, because the relaxation over-captures vector content on LibreOffice-rendered
Office docs and the fragile [SKIP] string lets one junk region leak. Validated on
native PDFs: BoC 58->100%, BoJ 79->100%, precise. Removes MIN_SOLID gate + the
solid machinery; keeps region-finding + size floor + table-dedup.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…en visuals (T-080)

Replaces union-find clustering + y-gap split + per-cluster floors with vertical
banding: a page's vector content unions into one box per band, and two bands
are separate figures only when a body paragraph sits between them. Captions and
source lines do not split — they belong to the figure and land inside the box.

Bench (BoC MPR 2024-10, BoJ Outlook 2024-10, BIS AR 2024, Fed MPR 2024-07,
Riksbank PPR 2025-03), geometric caption coverage:
- coverage 100 % on all five (main: BoC 58 %, BoJ 79 %)
- region counts bounded: 35/54/81/64/44 — aggregate 301→284 vs main over
  seven docs, no explosion (BIS halves: panels merge; BoC/Fed double where
  main dropped 1 in 4 figures)
- paragraph = >=20 words, >=2 lines, sentence punctuation (bench-validated:
  word counts alone overlap — BIS panel titles run 15-44 words; punctuation
  separates tick-label runs, junk 107->0 words)

A body paragraph inside a region is never suppressed from the body text
(text_block_in_region grows a text guard): one-box bands can legitimately
cover flowing text, and mild duplication beats silent deletion. Full-span
drawings (margin rules, borders) are filtered as page furniture so they
cannot bridge every band into a full-page box.

A ruled table that find_tables misses is now captured for the model instead
of dropped (T-050 symptom); tables the table path owns are excluded before
banding, as before.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…~flat

Live end-to-end runs (gemma-4-31B via Berget) recorded in
scripts/coverage_bench/BASELINE.md: BoC 26/26, BoJ 58/58 captions covered,
no misses; T-081 skips absorb over-capture cleanly (3/35, 4/59, no junk).
Live pipeline test updated to the one-box contract (p68 merges to one box).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…d and described live (28/28)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Ztein
Ztein enabled auto-merge (squash) July 22, 2026 20:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant