feat: add the regression corpus for broad coverage - #7
Merged
Conversation
The corpus answers one question: does a change alter output anywhere it should not. Mathematics is incidental. Breadth and volume are the point, which makes it a regression net rather than a set of chosen fixtures. Sources are PubMed Central open access, arXiv, Project Gutenberg, govdocs1 and Wikipedia. Every licence was read from the document's own metadata or the publisher's stated terms: PMC from each file's JATS ali:license_ref, arXiv per paper from its OAI record, and the remaining three from published policy. 1,816 documents are permissively licensed and are vendored. 1,459 carry ShareAlike, NonCommercial, or terms granting redistribution to the publisher alone, so the corpus records their source and licence without hosting them. arXiv shows the split plainly: a CC-BY paper is vendored, while one under the arXiv perpetual non-exclusive licence grants distribution to arXiv rather than to us. The bytes stay out of git, as the corpus already does for binaries. The regression directories join scripts/corpus-patterns.txt and .gitignore, so publish_corpus.py carries them to the bucket. Path-scoped entries leave ordinary .xml and .html fixtures elsewhere untouched. scripts/fetch_regression.py obtains the vendored bytes from their sources and verifies each against the sha256 the corpus was built from. govdocs1 publishes shards rather than files, so those entries name the shard and the member, and a shard is downloaded once for every member taken.
tobocop2
force-pushed
the
feat/regression-corpus
branch
from
August 14, 2026 02:57
a372a66 to
998db29
Compare
tobocop2
marked this pull request as ready for review
August 14, 2026 02:59
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.
Important
@Goldziher, one decision needed before merge: 314 MB of PubMed Central XML.
README.mdsays text formats are committed to git. This change breaks that rule once, for the PubMed Central slice: 712 full-text JATS files totalling 314 MB. Committing them would take the repository from roughly 72 MB to about 390 MB, and every clone would carry it forever.They are routed to the bucket instead, by one path-scoped entry,
jats/regression/, inscripts/corpus-patterns.txtand.gitignore. An ordinary.nxmlelsewhere in the tree is unaffected.Nothing else bends the rule. The other 133 text documents, 7.7 MB of govdocs1 HTML and text, are committed as the README requires.
Reverting is one line: delete that entry from both files, run
python3 scripts/fetch_regression.py --include jats/regression, and commit the result. Say which you prefer.A broad corpus of ordinary documents, used to answer one question: does a change alter output anywhere it should not. Mathematics is incidental here. Breadth and volume are the point, which is what makes it a regression net rather than a set of chosen fixtures.
3,275 documents from five sources: PubMed Central open access, arXiv, Project Gutenberg, govdocs1 and Wikipedia.
Licensing, read rather than assumed
Every licence came from the document's own metadata or the publisher's stated terms:
ali:license_refThe result splits into the two lanes
LICENSES.mdalready defines:arXiv shows the split plainly. A paper released under CC-BY is vendored. A paper under the arXiv perpetual non-exclusive licence grants distribution rights to arXiv rather than to us, so the corpus records it and does not host it.
Nothing is excluded. Both lanes are in
REGRESSION_PROVENANCE.md, which lists all 3,275 with source, licence and how the licence was determined.Where the bytes go
Text is committed, as the corpus does: 133 govdocs1 HTML and text files, 7.7 MB, each verified against the sha256 it was built from. The binaries need no new pattern, since the existing
*.pdf,*.epub,*.doc,*.xlsand*.pptentries already carry them to the bucket.One exception, and it is the only rule bent here. The PubMed Central slice is 712 full-text JATS files totalling 314 MB. Committing it would quadruple a clone, so
jats/regression/is added toscripts/corpus-patterns.txtand.gitignore, path-scoped so an ordinary.nxmlelsewhere is unaffected. Say the word and it goes into git instead.No ground truth, by design
These documents have no upstream ground truth: they are raw published files. Deriving it by running the extractor would record today's output as the definition of correct, and a later regression would then match the golden file and pass.
The value here is differential. Two builds run over the same documents and the outputs are compared, which catches a change that alters output anywhere it should not, without anyone stating the right answer in advance.
Getting the bytes in
scripts/regression-objects.jsoncarries a source, sha256 and size for each of the 1,816. A download whose digest does not match is written to<path>.mismatchand reported, so a source that changed upstream cannot quietly become the fixture.govdocs1 publishes 486 MB shards rather than individual files, so those 400 entries name the shard and the member inside it. A shard is downloaded once and every member taken from it before it is discarded.
Verified
Both fetch paths were run against the real sources: three PMC articles through the direct path, and four govdocs1 members extracted from a shard, all digests matching.
scripts/test_publish_corpus.pypasses, 31 tests.