CASCADE Routing audit, KYC extraction Seal 1151f5a1cfaae0c0 · measured, then frozen
Appendix B Security and data handling ← Back to the findings

Your data stays where it belongs. Verify it anytime.

A matte aluminium padlock; its shackle, closed, is the same deep green as the site's accents.

This page names every place the tool touches: the one network call it makes, the two places it writes, the packages it ships, and what an audit cannot promise. Where a claim lives in the source, its path is on this page.

One network call, four guarded sites

A measurement makes exactly one kind of network call: to the local model runtime, on this machine's loopback address by default. The source has four places that send a document, and each one first passes a guard that refuses any host that is not this machine, with the refusal written in plain words.

The guard is not a habit, it is enforced: a structural test walks every source file, finds each send site, and fails the suite if a fifth site appears without the guard. The only way around it is an explicit flag written into the command line, where an auditor can see it.

Verify the guard

Run the test suite. The structural test walks the sources, finds every send site, and fails if one of them has lost its guard.

run it yourself
npm testfails if a send site loses its guard

Where it livessrc/tiers.ts:523 · src/frontiere.test.ts:33

The models are pinned, cached, and 1.3 GB

Inference runs locally, on four sets of model weights, pinned by revision and by SHA‑256 per file, cached on disk and verified before anything is written. Two nuances, because they matter to a bank:

  • on the first run, the weights are fetched once from huggingface.co, 1.3 GB in total, and the tool says so before doing it. If your network policy forbids that, the weights can be exported on one machine and imported on yours;
  • one leak, measured and named rather than hidden: even with every weight cached, the model library still asks huggingface.co for one public metadata file each time the extractors load — an upstream behaviour the pin does not control, carrying nothing of yours. The offline mode is now tested, and because of that same leak it refuses to start with the cause named instead of failing mid‑extraction. Until the library honours the pinned revision, a fully closed network cannot run the encoder tiers — the tool says so out loud rather than pretending.
Verify the weights

The pinned revisions and the per-file hashes live in the source; the refusal to run on altered weights is itself tested.

run it yourself
npm testrefuses to run on absent or altered weights

Where it livessrc/poids.ts:66 · src/poids.test.ts:129

What it takes to run

Four things, and nothing exotic:

  • Node 24 or newer;
  • 1.3 GB of disk for the pinned model weights, fetched once or imported offline;
  • a local Ollama runtime for the generative readers, reached on this machine's loopback address by default;
  • and memory to breathe: the bench runs on modest machines, but below 1 GB of free memory it marks its own durations as non‑transportable rather than publishing figures it cannot stand behind.
Verify the floor

The engine requirement is declared in the manifest; the memory floor is written into every timing record the bench refuses to publish.

run it yourself
node --versionyours, against the declared minimum

Where it livespackage.json:53 · src/tiers.ts:295

What it reads, and the two places it writes

The tool reads only the files you name by flag. It never scans a disk.

It writes to exactly two places: its own records, under its repository root, in a folder that git ignores so nothing measured on your data can travel into a public repository; and one report deposited beside the file you pointed it at, named after that file. The one record that is versioned — the egress observation — has your file paths replaced by a placeholder before it is written, and a journal header records no machine name and no user name.

The dependency surface

One production dependency and two development dependencies; 77 packages in the lockfile, each with a content hash, of which 51 install on a given machine (the rest are per‑platform variants). Their licences are classified by a generator, not by hand: 50 permissive, 1 with obligations, 0 blocking, 0 undetermined, re‑checked on every test run. A CycloneDX software bill of materials ships with the tool.

The repository itself has no install‑time script beyond wiring its own git hooks. Two transitive production packages do carry install scripts; on macOS and Windows they touch nothing beyond the npm registry, and on one platform — linux/x64 — one of them fetches optional GPU providers from a second registry at install time. npm ci --ignore-scripts neutralises both, and loses nothing on the documented CPU path.

Verify the counts

The licence table and the test count are generated, and each carries a checker that fails the suite when the document drifts from the sources.

run it yourself
node src/licences.ts --checkfails when the licence table driftsnode src/readme.ts --checkfails when the test count drifts
Your reviewers can read the code

The licence is PolyForm Noncommercial: source‑available. Anyone may read, study and fork the code with no time limit, and an evaluation grant lets any organisation run it on its own data, internally, for thirty days. One honest limit: it is not an OSI‑approved licence, and some organisations exclude such licences by policy.

What this page cannot promise

The tool also watches itself run, sampling open connections during a measurement, and publishes what it saw. That record carries its own stated limit: sampling can show presence, never absence. The guarantee on this page is the guarded code path and the test that patrols it, not the observation.

And the figures here are guarded the same way as everywhere on this site: 596 tests across 66 files, a sentence generated from the sources and re‑checked on every test run, so it cannot silently rot.

On your records, on your machine. Nothing leaves the network.