# EPUB validation and repair lab, version 1.0.0

Nine original, small EPUB test files: one complete two-chapter book and eight
variants with one deliberate change each. They are fixtures for teaching,
debugging and regression testing, not a representative sample of real books
or a complete conformance suite. Some EPUBs are deliberately invalid.

All original text, artwork and build files are reusable under CC0 1.0. No
attribution link, account or payment is required. See LICENSE.txt for scope.

## What the results mean

manifest.json records EPUBCheck 5.4.0 results separately from the Epublys
structural verdict, warnings, lightweight output check and any repair.
An Epublys `valid: true` is not a claim of EPUB conformance: warnings can coexist
with it, and the duplicate-XHTML-ID and compressed-mimetype examples expose
checks the structural validator does not perform. The reference checker is
EPUBCheck; the dated results are not certification or a guarantee of store
acceptance, accessibility or appearance in a reader.

The compressed-mimetype case is also a reference-checker blind spot in this
recording: EPUBCheck 5.4.0 reports no errors or warnings even though the first
ZIP entry has compression method 8 (DEFLATE). The Epublys lightweight check
rejects it; the full structural check does not. The EPUB container requirement
still forbids compression of mimetype; see the dated W3C specification:
https://www.w3.org/TR/2026/CRD-epub-34-20261002/#sec-zip-container-mime
A checker reporting no diagnostics does not override that requirement.

The exact Epublys source commit, validator SHA-256, comparison source and options
are recorded in the manifest. These are measured local engine results. Network
admission, account entitlements, daily allowances and browser UI are separate;
the public website's free operations still have daily limits.

Missing-language auto-fix inserts `en` (English). It does not infer the book's
language: inspect and correct it manually for other books. Missing containers,
missing content and broken references require manual work or a fresh source.
A checker pass does not recreate a lost chapter.

Recorded repair files came from the engine. Only their local/central ZIP DOS
date and time fields were normalised to 1980-01-01 00:00:00 (DOS timestamps
do not store a timezone). Entry names,
order, CRCs, compression methods and compressed payload bytes were preserved.
The timestamp-normalised files were checked again with EPUBCheck. All other
sample archive dates and metadata dates are fixed for reproducibility.

## Inspect or reuse the files

Each case has its own `.epub`; `repairs/` contains the three recorded repairs.
Use the manifest's mutation path and before/after values to inspect the change.
Moving a ZIP entry and changing its compression method are archive changes,
not changes to its uncompressed text. One deliberate change can produce several
reference-checker messages; all recorded messages are retained.
Archive-level diagnostic locations use the sample's relative filename instead
of the temporary measurement directory. Internal EPUB entry paths and their
line and column numbers are retained.

To inspect an input through the Epublys website, enable Deep scan and leave
Auto-fix off. That run returns the input's diagnostic report. To request a repair,
run the file again with Auto-fix on. If a repair is available, that second run
downloads an EPUB instead of showing the input report and uses another operation
from the daily allowance. The manifest's engine recordings use Deep scan and
Auto-fix on to record both the original structural verdict and available repairs;
the returned verdict describes the input, not a guarantee about the repair.

Download the complete archive, or individual EPUBs plus manifest.json and
SHA256SUMS.txt. On systems with sha256sum, run `sha256sum -c SHA256SUMS.txt` from the
extracted directory. The complete ZIP contains checksums for its contents;
the separately served checksum file also includes the complete ZIP itself.
The complete ZIP includes unpacked source/ as well as the separate source ZIP.

Run independent reference checks with the official EPUBCheck 5.4.0 distribution:

    java -jar /path/to/epubcheck.jar baseline.epub --failonwarnings
    java -jar /path/to/epubcheck.jar wrong-mimetype.epub --json report.json

Get the distribution and its dependencies from:
https://github.com/w3c/epubcheck/releases/tag/v5.4.0
Do not copy just the JAR out of its distribution's library directory.
The verified distribution ZIP SHA-256 is recorded in manifest.json.
EPUBCheck and JSZip retain their own licences; they are not bundled in this kit.

## Rebuild the input fixtures and download archives

Extract epub-validation-lab-source-v1.zip into an empty directory, then use
Node.js 22 or later. The separately downloadable build.mjs is for inspection;
running it also requires baseline/, observations.json and recorded-repairs/
from the source ZIP:

    npm install --ignore-scripts
    node build.mjs --out dist
    node build.mjs --out dist --check

JSZip 3.10.2 is the only package dependency. The baseline/ directory contains
all original book sources. build.mjs applies the documented single changes,
uses fixed ZIP metadata and generates hashes, manifest and download archives.
It does not contact any service, read a private book or bundle Epublys tool code.

The source package also contains immutable recorded validation observations and
repair files. The standalone builder reproduces input fixtures and packages
those recordings; it does not impersonate EPUBCheck or recompute Epublys repairs.
To rerun the product measurements, use the exact engine source identified in
the manifest with `{ deepScan: true, autoFix: true }`, normalise only ZIP timestamp
fields as described above, and validate the actual results independently.

A changed baseline, mutation or dependency must be verified again before
updating recordings. Do not edit a recorded result merely to make a check pass.
