Skip to content

v1.10.0 — Variant C figure_ids hard constraint + normalize BS3+BS4

Choose a tag to compare

@thematteroftime thematteroftime released this 23 May 04:38
· 153 commits to main since this release

Highlights since v1.9.2

  • Variant C — figure_ids hard constraint ships as v1.10's headline change. Picks the winner of a 3-variant × 9-paper × 3-audit-cycle test (33 LLM runs across 3 git worktrees).
  • normalize_ocr_latex BS3+BS4 lifts verifier accuracy across all variants by collapsing LaTeX escape sequences (\%%) and Unicode super/subscripts (³3).
  • 3-cycle audit committee (each cycle = 3 specialist auditors in parallel) caught 5 bugs in variant C, all fixed before ship.
  • 280/280 tests pass (+25 from v1.9.2's 255).

Full report: docs/v1_10_variant_comparison.md · External reference survey: docs/v1_10_external_reference.md

Variant C — figure_ids hard constraint

Before v1.10, figure embedding in the rendered output depended on the LLM voluntarily writing Fig. N literally in the prose. On figure-rich papers (ML papers with ≥10 figs, materials reviews with ≥20 figs), the LLM cited <30% of available figures, and the s09 binding silently dropped the rest.

Variant C makes figure citation a schema-level + verifier-level constraint:

  • GroundedClaim.figure_ids: list[str] — schema field tells the binding which figures the claim cites.
  • Prompt rule — for each figure listed in section_figures, the LLM must emit a claim with figure_ids=["Fig. N"] AND include the literal Fig. N / 图N in text.
  • Verify advisory — accepted claims whose figure_ids don't appear literally in text get recorded as figure_hint_unmet for audit visibility (claim still kept).
  • Figure-retry pass — when ≥50% of available figures aren't mentioned post-verify, one strengthened LLM call adds them. Three swap guards (parity with retry-when-short β#3): more figures AND ≥1 verifier-accepted claim AND required-mention coverage not regressed.
  • Env-gated whitelistLAZY_PAPER_FIGURE_ID_WHITELIST=1 strips unknown fig_ids; default OFF because cycle 1+2 evidence (reading original PDFs) shows "unknown" fig_ids are usually s04_figures OCR-vs-paper-actual numbering misalignment, NOT LLM hallucination.

Validation — 33 LLM runs across 3 variants

M2 figure embed ratio (true distinct-figure count, not panels)

Paper available A (env tuning) B (cap tiering) C (figure_ids)
ali2025_flash 26 5 (19%) 4 (15%) 26 (100%)
he2023 8 4 (50%) 7 (88%) 8 (100%)
meng2024 7 4 (57%) 5 (71%) 7 (100%)
hif_1 (Adv Mat 62p) 20 2 (10%) 4 (20%) 20 (100%)
hif_2 (DALL-E 2) 17 3 (18%) 5 (29%) 17 (100%)

M1 zero-variance probe (meng2024 × 3 runs)

Variant per run mean stdev
baseline (v1.9.2) 10117 / 12742 / 13666 12175 1503
A 12819 / 12065 / 12521 12468 310
B 13740 / 13012 / 12002 12918 713
C 12703 / 13525 / 12849 13026 358

All 3 variants stay well below the spec §7 floor (baseline stdev = 1503).

M4 TestCase scores

TestCase (max) baseline A B C
meng2024 T1 ch01 benchmark recovery (17) 9 / 9 / 9 (stdev 0) 5 / 9 / 9 (stdev 1.88) 5 / 17 / 15 (stdev 5.25) 9 / 9 / 9 (stdev 0)
ali2025_flash T4 ch14 comparison depth (5) 4 / 3 4 3 5
chai2026 T6 ch01 (4) 4 / 4 3 3 4
yang2025 T2 ch01 (3) 3 / 3 3 3 3
meng2024 T3 ch10 (5) 3 / 3 / 5 4 / 5 / 4 5 / 4 / 4 4 / 4 / 4

Variant C is the only variant that preserves the meng2024 T1 = 9/9/9 zero-variance achievement of v1.9.x AND breaks baseline on ali2025_flash T4 (4 → 5).

Why not Variant A or B

  • A (env tuning) introduces M4 variance (stdev 1.88 on T1) and Auditor 1 caught a content-quality error in cycle 2 (called PbZrO₃ "lead-free" — chemical-naming mistake). The env tuning is real lift; it'll be recommended in .env.example as a LAZY_PAPER_MIN_SECTION_CHARS=1200 LAZY_PAPER_BEST_OF_N=3 combo, not as a separate variant flag.
  • B (cap tiering) had the worst M4 variance (stdev 5.25 — can reach 17/17 peak but unstable) AND lowered M3 coverage rate (meng2024: A 71% vs B 64%; gaur2022: A 53% vs B 34%). cap=12 spreads LLM attention too thin. Deferred to v1.11 for redesign as dynamic cap = min(comparator_count, 10).

normalize_ocr_latex BS3+BS4

Auditor 2 (cycle 1) inventoried 4 normalize blindspots causing 41-74 verifier false-rejects per s08 run. Cycle 2 broke them into BS1-4 with asymmetric fix difficulty:

  • BS3 — LaTeX escape sequences: \%, \&, \_, \^, \$ lose their leading backslash so they match the LLM's unescaped quote.
  • BS4 — Unicode super/subscript folding: NFKD decomposes ³3, 2. Greek letters (α/β/π) NOT decomposed. NFKD doesn't fold U+2212 / U+2013 / U+2014 to ASCII -, so an explicit _UNICODE_DASH substitution follows.
  • BS1+BS2 (letter-spaced subscript) deferred to v1.11 due to inherent OCR↔LLM asymmetry.

11 unit tests in stages/_common/tests/test_normalize.py lock in the new behavior.

3 audit cycles — caught & fixed bugs in variant C

Cycle Auditor Bug Fix commit
1 Auditor 3 figure_ids advisory ran on rejected claims (double-report) 2e30e1c
1.5 Auditor 3.2 figure-retry missing C-1 coverage guard 0cc056d
1.5 Auditor 3.2 figure-retry missing C-2 min-accepted guard 0cc056d (same)
2 Auditor 2 advisory entries inflated audit log's "verifier_rejects" count 535d035
3 Final ship gate env-gated whitelist needed for cycle 3 visibility e3cb9e1

3 cycles ran the audit committee in parallel (each cycle = 3 specialist auditors with non-overlapping scopes, reading original PDFs + code + reference docs).

Side effects

  • M2_figures_embedded metric (scripts/collect_variant_metrics.py) was inflating values by counting <img> tags (which includes every panel of a multi-panel figure). Fixed to count <figure> blocks (one per distinct figure). Cycle 1 caught this — earlier "17/17 = 100%" readings on multi-panel-heavy papers were panel-count artifacts.
  • New M2_figures_hallucinated_count field surfaces s04_figures ↔ LLM numbering misalignment (v1.11 #2 candidate fix).
  • M4 TestCase scores are deterministic (regex + size + fuzzy substring — no LLM judge), so baseline recheck took 0 LLM cost and confirmed zero drift from v1.9.x scores.

Deferred to v1.11 (ranked by ROI)

# Item Complexity
1 normalize_ocr_latex BS1+BS2 (letter-spaced subscript) M
2 s04_figures caption-aware numbering (fix OCR vs paper number misalign) M
3 prompt comparator gap — Jiang/Ma et al. systematically missed M
4 template-vs-paper subject-mismatch graceful degrade L
5 Variant B redesign: dynamic cap = min(comparator_count, 10) S
6 real-time LLM cost meter into metrics.yaml (M6) S
7 DOCX HYPERLINK dead-code fix (thread sources into renderers) M
8 _merge_drafts 60-char prefix + (author, value) dedup S
9 6 hardcodes → env vars S

Release trail (since v1.9.2)

  • v1.9.2 — 8-bug fix + 18-paper validation
  • v1.10.0 — Variant C ship + normalize BS3+BS4 + 3-cycle audit

Full details: CHANGELOG.md