# Receipt scanner licence gate — 2026-09-30

Selected: **tesseract.js 6.0.1**, **tesseract.js-core 6.0.0**, and **tessdata_fast English**. Gate **PASS** before implementation. Selected projects and traineddata are Apache-2.0, with permissive MIT/BSD-3-Clause bundled dependencies; no conversion or modification.

## Separate code and weights findings

- JS browser runtime and worker: npm tesseract.js 6.0.1 declares `Apache-2.0`; its full LICENSE.md says “Apache License” and “Version 2.0, January 2004”. It depends on tesseract.js-core `^6.0.0`, so the selected pinned 6.0.0 core is mutually compatible. Full licence and bundled dependency notices are retained unmodified.
- Bundled notices: regenerator-runtime, buffer and zlib.js explicitly say “MIT”; ieee754 says “BSD-3-Clause License”. These permissive dependency notices are preserved in the two upstream bundle LICENSE.txt files.
- WASM core: npm tesseract.js-core 6.0.0 declares `Apache-2.0`; its LICENSE says “Apache License” and “Version 2.0, January 2004”.
- Weights: tesseract-ocr/tessdata_fast at 87416418657359cb625c412a48b6e1d6d41c29bd retains LICENSE saying “Apache License” and “Version 2.0, January 2004”. English is the integer LSTM-only traineddata: tessdata_fast does not support the legacy engine. We select OEM.LSTM_ONLY (1) and the LSTM-only core to avoid shipping unused legacy code. The upstream README specifies this build choice.

## Immutable asset inventory

Every upstream asset is unmodified. URLs with #member identify exact npm tarball members. No file exceeds 25 MB, so no fetch_models entry or gitignore is needed. assets.json is our own runtime inventory, not an upstream vendor file.

| Asset | Exact pinned URL | SHA-256 | Bytes | Licence / verdict |
| --- | --- | --- | ---: | --- |
| tesseract.min.js | https://registry.npmjs.org/tesseract.js/-/tesseract.js-6.0.1.tgz#member=package/dist/tesseract.min.js | `10fff78484067759c43028a02a72d76d0b90eb17302bb23b58a9ec5410bc928b` | 62,961 | Apache-2.0 PASS (bundled notices retained) |
| worker.min.js | https://registry.npmjs.org/tesseract.js/-/tesseract.js-6.0.1.tgz#member=package/dist/worker.min.js | `38645599043239c0eb6db08a6504a92dcdc292200535f3e9339cd77c4443b842` | 111,162 | Apache-2.0 PASS (bundled notices retained) |
| tesseract.min.js.LICENSE.txt | https://registry.npmjs.org/tesseract.js/-/tesseract.js-6.0.1.tgz#member=package/dist/tesseract.min.js.LICENSE.txt | `cdf963ced7d25a0f98901a547647b4d6e2dbe0197fd78c87a059a87b0e542fe2` | 149 | MIT PASS |
| worker.min.js.LICENSE.txt | https://registry.npmjs.org/tesseract.js/-/tesseract.js-6.0.1.tgz#member=package/dist/worker.min.js.LICENSE.txt | `45f54171aeaa1d10c0c1a66f374b7bba1f02472b1487fbe892eec04f840002ac` | 466 | MIT / BSD-3-Clause PASS |
| LICENSE-tesseract.js.txt | https://registry.npmjs.org/tesseract.js/-/tesseract.js-6.0.1.tgz#member=package/LICENSE.md | `b40930bbcf80744c86c46a12bc9da056641d722716c378f5659b9e555ef833e1` | 11,357 | Apache-2.0 PASS (bundled notices retained) |
| tesseract-core-simd-lstm.js | https://registry.npmjs.org/tesseract.js-core/-/tesseract.js-core-6.0.0.tgz#member=package/tesseract-core-simd-lstm.js | `be3504705d7111d1d1f3f7f9dff326c26d334031ede36e31c4d3cf883027e982` | 124,752 | Apache-2.0 PASS (bundled notices retained) |
| tesseract-core-simd-lstm.wasm | https://registry.npmjs.org/tesseract.js-core/-/tesseract.js-core-6.0.0.tgz#member=package/tesseract-core-simd-lstm.wasm | `187d76742dfc0d8929f0b49a619f145bb6370730776c7bd0d3e20c6b2098808d` | 2,871,377 | Apache-2.0 PASS (bundled notices retained) |
| tesseract-core-lstm.js | https://registry.npmjs.org/tesseract.js-core/-/tesseract.js-core-6.0.0.tgz#member=package/tesseract-core-lstm.js | `48a3ee8e00924cb8c7f0cc0d099b1318fea120af56b3ee8fb3a70dd2311806c2` | 124,747 | Apache-2.0 PASS (bundled notices retained) |
| tesseract-core-lstm.wasm | https://registry.npmjs.org/tesseract.js-core/-/tesseract.js-core-6.0.0.tgz#member=package/tesseract-core-lstm.wasm | `220e2e87551edccb85519796a170469f8ab2a8055216789e3b8b1ada18b7bc2b` | 2,871,085 | Apache-2.0 PASS (bundled notices retained) |
| LICENSE-tesseract.js-core.txt | https://registry.npmjs.org/tesseract.js-core/-/tesseract.js-core-6.0.0.tgz#member=package/LICENSE | `c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08` | 11,358 | Apache-2.0 PASS (bundled notices retained) |
| eng.traineddata | https://raw.githubusercontent.com/tesseract-ocr/tessdata_fast/87416418657359cb625c412a48b6e1d6d41c29bd/eng.traineddata | `7d4322bd2a7749724879683fc3912cb542f19906c83bcc1a52132556427170b2` | 4,113,088 | Apache-2.0 PASS (bundled notices retained) |
| LICENSE-tessdata_fast.txt | https://raw.githubusercontent.com/tesseract-ocr/tessdata_fast/87416418657359cb625c412a48b6e1d6d41c29bd/LICENSE | `cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30` | 11,358 | Apache-2.0 PASS (bundled notices retained) |

## Runtime finding

The upstream directory loader selects a `.wasm.js` build that embeds base64 WASM. To meet the no-base64 rule, our worker explicitly selects the upstream external-WASM `tesseract-core-simd-lstm.js` companion (or `tesseract-core-lstm.js` when SIMD is unavailable). Only this LSTM variant and its non-SIMD fallback ship, with their .wasm files; neither legacy nor relaxed-SIMD builds ship. The browser bundle is retained as requested; our worker uses the same public load/loadLanguage/initialize/recognize message protocol directly, so no extra nested worker is needed.

workerPath, corePath and langPath options are explicit /vendor/tesseract/ paths. gzip is false; cacheMethod is `none` (Tesseract's off setting). Before inference, the worker verifies every selected runtime byte and English data against SHA-256 and size and caches public assets by hash with Cache API. Verified scripts are imported via blob URLs; the external WASM bytes are supplied through the core's wasmBinary option and language bytes through loadLanguage. No unverified fetch fallback and no cross-origin runtime request. Download progress covers all five selected assets. No OCR assets load before a file is added. Cancel terminates this worker, including active inference/downloads. Cache failures use verified in-memory bytes; corrupt cached data is rejected. No receipts enter Cache API.

Sources: [tesseract.js pinned metadata](https://registry.npmjs.org/tesseract.js/6.0.1), [core pinned metadata](https://registry.npmjs.org/tesseract.js-core/6.0.0), [tessdata_fast README](https://github.com/tesseract-ocr/tessdata_fast/blob/87416418657359cb625c412a48b6e1d6d41c29bd/README.md).
