Uh oh!
There was an error while loading. Please reload this page.
Spec 0.7 — pdf-inspector rescue candidate + semantic retrieval - #1
Draft
NagariaHussain wants to merge 1 commit into
Draft
Spec 0.7 — pdf-inspector rescue candidate + semantic retrieval#1NagariaHussain wants to merge 1 commit into
NagariaHussain wants to merge 1 commit into
Conversation
Specs only, slices 32-35. No implementation. Both tracks were validated by offline spikes against the real corpus (Obstetrics and Gynaecology 180pp, Nephrology 398pp) before speccing; every threshold in the specs comes from those measurements. pdf-inspector (32-33) enters as a free, deterministic remediation candidate behind a structure guard — never as the baseline parser. It scores 0.997 content_recall vs pymupdf4llm's 0.666 (n=120), but on the obs-gyn manual it drops headings 132 -> 10 and list items 320 -> 0, which would silently flatten the section tree since sectionize splits on '#'. parser_artifacts cannot detect this; its patterns are tuned to pymupdf4llm's failure signatures. Hence structure_preserved() as a hard eligibility gate, plus a short-circuit that skips the paid VLM/cleanup passes when the free candidate already clears pass_threshold. Semantic retrieval (34-35) adds a LanceDB vector index over generated Wiki Documents. Today's search_sections substring-matches the query against title/hierarchy_path and never reads a body — measured 0.000 recall@10 across 180 generated questions. Vector scores 0.794 vs 0.611 for full-text; default RRF hybrid measured *worse* than pure vector (0.728), so 0.7 ships vector only. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ck1Fqm4WELZj2GDFQSx5CW
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Specs only — slices 32–35. No implementation.
Why?
Two gaps, both measured against the real corpus before writing anything.
Remediation pays an LLM to fix what a free parser already fixes. Every page goes through the remediation pass, so a 398-page manual costs ~800 model calls. But on the pages the harness flags, a deterministic Rust parser (
pdf-inspector) recovers the text almost perfectly at ~5ms/page and zero cost —content_recall0.565 → 0.998 onreviewpages.Nothing can find content by meaning.
search_sectionssubstring-matches the whole query againsttitle/hierarchy_pathand never reads a body. Measured over 180 generated questions: recall@10 = 0.000. Not weak — zero.What?
pdf-inspectoradaptersearch_wikiagent toolTwo independent tracks: 32→33 and 34→35. Land 32 first.
How?
pdf-inspector is a candidate, never the baseline.
pymupdf4llmstays the baseline. Inspector output is only ever adopted per-page, through the existing best-of-N adoption inremediate.py.This is the load-bearing decision. Inspector scores 0.997
content_recallvs 0.666 (n=120) — but on the obs-gyn manual it drops headings 132 → 10 and list items 320 → 0, while inflating table rows 35 → 220.sectionizesplits on#, so adopting that would silently flatten the section tree while every score in the UI went up.parser_artifactscan't catch it — its patterns are tuned to pymupdf4llm's failure signatures.So
structure_preserved()becomes a hard eligibility gate. Calibrated on the measurement, it rejects 36/60 obs-gyn adoptions and 7/60 on Nephrology — it blocks the document where inspector destroys structure and admits the one where it doesn't.Because inspector is free and computed before the paid candidates, a page it already carries past
pass_thresholdskips the VLM and cleanup calls entirely. That's the cost win.Retrieval ships pure vector, not hybrid. Vector 0.794 recall@10 vs 0.611 full-text; default RRF hybrid measured worse than vector alone (0.728) because weak FTS ranking drags the fusion down. Vector's margin is +0.32 on semantic and +0.20 on vague queries, ~0 on keyword — keyword is already covered by frappe-wiki's existing FTS5 index.
Index target is
Wiki Document. Embeddings vialitellm.embedding(already a dependency). Five scatteredWiki Document.contentwriters consolidate behind onestore.set_wiki_content()funnel, mirroring 0.6'sset_section_markdownmove.Notes
main, notdevelop—developisn't on the remote and the project guide says it has unrelated history.images.py:71-103Case 1 is already dead code (its marker fires 0 times across all 578 pages of both manuals), andpymupdf4llmsilently invokes Tesseract OCR on hundreds of pages.🤖 Generated with Claude Code
https://claude.ai/code/session_01Ck1Fqm4WELZj2GDFQSx5CW