# Reproducible examples

Two deliberately separate kinds of evidence live here:

1. **Matcher examples:** execute the existing deterministic constraint engine against the checked-in documentation snapshot. They do not run PDF extractors, OCR or model weights.
2. **Synthetic extraction smoke test:** actually runs pdfplumber on one invented ruled-table PDF and a rasterized negative control. It does not test the other four tools, represent real-world accuracy, or change the matcher's evidence labels.

No customer documents, uploads, API keys, paid calls or new accounts are used. The matcher examples need only Node.js; the optional extraction check needs the Python packages listed below.

## Run the matcher examples

From the repository root, with Node.js 22 or later (verified here on 24.19.0):

```sh
# Print concise, reproducible outputs for every case.
node pdf-tool-service/examples/run.mjs --all

# Write one complete audit report, including sources and license caveats.
node pdf-tool-service/examples/run.mjs digital-ruled-python-local-commercial > /tmp/digital-report.json

# Check all expectations, determinism, API-handler parity and artifact hashes.
node --test pdf-tool-service/examples/test.mjs
```

The runner imports `src/matcher.js` and `content/tools.json` directly. It makes no HTTP calls. Its API-parity tests exercise the real Fetch handler in process; they do not prove that any public deployment is reachable.

### Verified cases

All cases use Linux, CPU-only hardware, local processing and ruled tables. All request files are in `requests/`, and all request `max_results: 5` so qualified tools cannot be hidden by a shorter limit.

- **`digital-ruled-python-local-commercial`:** `matched`; Camelot, pdfplumber and Tabula qualify. Docling and PaddleOCR stay in `needs_review` because full selected model-bundle licensing is unresolved
- **`scanned-local-no-code`:** `abstained`; zero candidates and all five tools rejected for one or more constraints. No fallback is invented
- **`scanned-technical-license-required`:** `abstained`; Docling and PaddleOCR remain `needs_review` on `commercial_use`, while the three native-text profiles are rejected for scanned input
- **`scanned-technical-license-not-requested`:** `matched`; Docling and PaddleOCR qualify only after setting `commercial_use: false`. Their commercial-use constraint is explicitly `not_required`, and unresolved model-license records remain in the response

`commercial_use: false` means this screen was not requested. It is not a license grant, a finding of noncommercial eligibility, or evidence that the models can be used commercially. Review the actual selected code/model configuration and its terms before use.

[`expected-summary.json`](expected-summary.json) is the output actually recorded for these cases. It includes report IDs and a SHA-256 hash of the dataset bytes. Tests fail if the current output drifts from that snapshot. Review any changed evidence and behavior before intentionally replacing it; do not automatically update expectations merely to make a test pass. Rankings are editorial workflow fit, not measured accuracy or performance.

**Source versus deployed identities:** these snapshots reproduce the source ZIP's `content/tools.json`, whose reported dataset version falls back to its schema version, `1.0.0`. The site build adds dataset version `2026-10-14.1` to its published dataset. Because report IDs hash the full dataset, the same preferences sent to the deployed API or MCP produce different report IDs from these source snapshots, while the case classifications remain unchanged. Compare IDs only within the same dataset snapshot.

## Run the separate real extraction check

This optional check is intentionally small: a one-page, selectable-text, 4-row x 3-column table with three invented products. ReportLab generates the fixture. PDFium rasterizes it into an image-only copy. pdfplumber then runs its line-based table extraction on both files. A 12/12 exact-cell match on this one simple fixture is **not an accuracy estimate**.

Use an isolated Python environment and install the pinned packages from the standard Python package registry if they are not already available:

```sh
python3 -m venv /tmp/proof-of-use-examples-venv
/tmp/proof-of-use-examples-venv/bin/python -m pip install -r pdf-tool-service/examples/synthetic/requirements.txt
/tmp/proof-of-use-examples-venv/bin/python pdf-tool-service/examples/synthetic/run.py --output-dir /tmp/proof-of-use-extraction
```

The recorded run used packages already installed in the cloud runtime; no installation or arbitrary repository execution was needed. Package versions and the Python/OS environment are recorded in the result. Direct and key transitive packages are pinned, but this is not a full platform-specific lockfile. Installing packages may access the registry; running the script uses only local synthetic files.

If those packages are already installed:

```sh
python3 pdf-tool-service/examples/synthetic/run.py --output-dir /tmp/proof-of-use-extraction
```

The command exits nonzero if the digital table differs from the expected cells or the image-only control unexpectedly yields text/tables. It writes both PDFs, a preview PNG and `results.json` to the specified directory. The control preserves the digital page's visual appearance, including its original caption, but removes its text/vector layer by rasterizing the entire page. It is not a noisy real-world scan.

### Recorded result, 2026-10-14

- **Actual extractor:** pdfplumber 0.11.9, Python 3.12.14, Linux x86_64
- **Digital fixture:** one table, 4 rows x 3 columns, all 12 expected cells matched exactly including the header
- **Image-only negative control:** no text layer and zero extracted tables, the expected result without OCR
- **Repeat:** generated PDF hashes and extraction outputs were identical on a second run in the same environment
- **Visual check:** the digital fixture and image-only PDF were rendered and inspected; no clipping or overlap was observed

Inspectable evidence:

- [Exact expected cells](synthetic/expected-cells.json)
- [Executed result and environment](synthetic/verified-run/results.json)
- [Digital ruled-table PDF](synthetic/verified-run/digital-ruled.pdf)
- [Image-only negative-control PDF](synthetic/verified-run/image-only-negative-control.pdf)
- [Reproduction script](synthetic/run.py) and [package pins](synthetic/requirements.txt)

This smoke test does not measure OCR, runtime, memory use, borderless/merged/multipage tables, robustness, security or legal suitability. Camelot, Tabula, Docling and PaddleOCR were not executed. No comparative tool ranking can be inferred. The matcher's `documentation_reviewed_not_tested` label continues to describe its broad compatibility profiles; this isolated pdfplumber result is separate evidence with a much narrower scope.

## What passed

- 10 runnable-example tests, including all four cases, repeated output identity, HTTP-handler parity, no-match behavior, the model-license gate and recorded fixture hashes
- One real local pdfplumber extraction smoke run, repeated with identical fixture hashes and extracted tables

The Node.js test suite checks the recorded extraction evidence's consistency; it does **not** rerun the Python extractor. Use `synthetic/run.py` to do that.
