fix(trail): extract provenance per document for list results (closes #149) - #162
Merged
rajfirke merged 3 commits intoSep 3, 2026
Merged
Conversation
_extract_provenance ran on the list itself rather than each element. Lists have no .metadata, so every document in a retrieved batch was logged with provenance_status=MISSING and no freshness check. Pair each content item with its own element when extraction produced one item per element, and fall back to the previous whole-result behaviour when the counts do not line up.
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 free
to 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.
What does this PR do?
_track_resultcalled_extract_provenanceon the wholeresult. When a decorated functionreturns a list of Documents, the list itself has no
.metadata, so provenance came backNonefor every document in the batch.
Reproduced on
mainwith two documents carrying distinct sources and dates:After this change:
The second document is from 2020 and now correctly flags
STALE. Previously it passed silently,which is the compliance consequence the issue describes.
Why not a plain
zip(result, items)The issue suggests zipping
resultwithitems. That is correct for the common case butmisbehaves with a custom
content_extractor: if the extractor reshapes the batch,zippairseach content item with an unrelated document's provenance, attributing the wrong source to the
wrong content.
zipalso truncates silently when lengths differ.So the pairing is guarded by an explicit rule in a new
_extract_provenanceshelper:resultis a list or tuple and extraction produced exactly one item per element, readprovenance from each element.
resultas a whole and share it, which is exactly the previous behaviour.The helper always returns exactly one provenance per content item, so the loop uses
zip(..., strict=True). Any future mismatch raises instead of silently dropping records.This means every non-list path keeps its current behaviour: a single Document still reads its own
.metadata, astr/dict/Noneresult behaves as before, and an extractor that collapses abatch into one string falls back rather than guessing. All four cases have tests.
Checklist
ruff check src/ tests/passesruff format --check src/ tests/passesmypy src/provena/passespytestpasses with no failuresFour new tests in
TestContextTrailTrack: per-document provenance from a list, per-documentfreshness (the
FRESH/STALEsplit above), a single non-list Document still reading its ownmetadata, and a reshaping extractor falling back without mispairing. The two list tests fail on
unfixed source; the other two are regression guards for the paths deliberately left unchanged,
so they pass either way. Full suite goes 514 to 518 passing, skips unchanged.
Related Issues
Fixes #149