Skip to content

feat(ir): per-block provenance and parse_document - #28

Merged
chaliy merged 2 commits into
mainfrom
claude/project-thread-2rc0mr
Oct 27, 2026
Merged

chaliy merged 2 commits into
mainfrom
claude/project-thread-2rc0mr

Conversation

@chaliy

@chaliy chaliy commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

Requested by Михайло · project thread

What changed

Second step of IR v2: provenance for citations, and IR access for every format.

  • ir::Source on every block (except ThematicBreak), opt-in with MarkkitBuilder::track_sources(true):
    • HTML: absolute XPath of the element (/html[1]/body[1]/div[1]/p[2])
    • DOCX: 0-based body block index (w:p/w:tbl order; lists take the first item's index)
    • Spreadsheets: sheet name on heading + table, A1 range of the table (B2:C3)
    • page reserved for PDF
  • Markkit::parse_document[_sync] returns ParsedDocument (IR + title, format, warnings, stats) for HTML, DOCX and spreadsheets; ParsedDocument::render() gives the Extraction. extract_document is now parse_document + render, so the output is unchanged.
  • Off by default: no extra work, no source in JSON, Markdown identical with or without tracking.

Why

Roadmap item "Richer IR with provenance": RAG users need to cite where a chunk came from. Until now DOCX and spreadsheet IR could not be reached at all; only Markdown came out.

Before / After

Before: parse_html only; no positions.

After:

let m = Markkit::builder().track_sources(true).build();
let p = m.parse_document_sync(&xlsx, DocumentHint::default())?;
p.document.nodes[1].source() // Some(Source { sheet: Some("Data"), range: Some("B2:C3"), .. })
{"Paragraph":{"children":[{"Text":"b"}],"source":{"path":"/html[1]/body[1]/div[1]/p[2]"}}}

Risk

  • Low–Medium. IR API break (pre-1.0, same release as feat(ir): IR v2 with footnotes, definition lists, task lists, figures, table spans #24): block variants gain a source field, so patterns need ..; Node::paragraph / Node::heading constructors added.
  • Perf/DoS: XPath sibling indexes are cached per parent, O(depth) per block. html_security::source_tracking_many_siblings_is_linear covers 200k siblings.
  • New dependency edge ego-tree (already in the tree via scraper), gated by html.

Checklist

  • Tests added or updated (HTML XPath + nested list/blockquote, off-by-default/JSON, markdown unchanged, DOCX indexes, XLSX sheet/range, perf)
  • Backward compatibility considered (extract_* output unchanged; CHANGELOG notes IR break)
  • Knowledge updated (foundations/ir.md, foundations/architecture.md, log), docs/getting-started

Generated by Claude Code

@chaliy chaliy self-assigned this Oct 26, 2026
- ir::Source (path/index/sheet/range/page) on block variants, opt-in via
  MarkkitBuilder::track_sources
- HTML: absolute XPath with per-parent cached sibling indexes
- DOCX: body block index; spreadsheets: sheet + A1 range
- Markkit::parse_document[_sync] -> ParsedDocument (IR + metadata);
  extract_document = parse_document + render
@chaliy
chaliy force-pushed the claude/project-thread-2rc0mr branch from d66bea8 to 6957b1a Compare October 26, 2026 23:54
@chaliy
chaliy merged commit 11fdc87 into main Oct 27, 2026
11 checks passed
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