Privacy / security

Order text stays
on your computer.

The installed app and its model run locally. Your catalogue, learned names and exports stay in plain CSV files in the project folder.

The app server binds to 127.0.0.1 only. Ollama runs on the same machine; order text is sent to 127.0.0.1:11434. There are no cloud calls during matching.

The local boundary

What data goes where

Everything below is inside the shop’s computer. Internet is needed to install the software and download the model.

  1. Browser

    You paste an order into the local review page.

    127.0.0.1:5178
  2. App server

    Code reads numbers, matches catalogue text and checks each row.

  3. Ollama, only if needed

    Hard lines go to the local model, which picks a product from the shortlist.

    127.0.0.1:11434
  4. Local files

    Confirmed exports and explicitly remembered names are saved as CSV on disk.

The checked answer returns to the browser for review before export. CSV export is for manual import into billing software.

No reporting service

The app has no telemetry, analytics or crash reporting, and loads no external scripts, fonts or styles. This documentation site also uses local assets only.

Your files, your backup

data/real/, data/app/, data/train/ and results/ are gitignored. Back up the catalogue and data/app/ yourself.

If optional fine-tuning is used later, it is a one-time cloud step and should use synthetic or consented data only.

Optional Sentry tracing exists only in the evaluation tool (npm run eval). It is off unless a SENTRY_DSN is set, and refused for anything outside the synthetic and fixture data. The shop app never loads it, and a test checks that. What tracing sends.

Threat model

What the design protects

AssetThreatMitigation or accepted risk
Customer list, prices, order volumeLeaking to a third partyLocal server and local model; no cloud calls during matching.
Invoice correctnessA wrong row exported to billing16 safety rules, server-side re-check of confirmed rows, and evaluation that measures dangerous rows.
Learned namesA mistaken correction poisons a nameOnly explicitly confirmed rows with Remember ticked can teach names. Known catalogue names cannot be learned. Later entries override earlier ones; the plain CSV can be edited.
Local serverAnother program on the computer calls its APIAccepted risk for a single-user desktop tool. There is no authentication. Do not run untrusted software on the shop computer.
Review pageOrder text injects a scriptEvery order-derived string is HTML-escaped before display.

Read the safety rules →

External test pass

Fixed issues

  • CSV formula injection: exported text beginning with =, +, - or @, including after whitespace, receives an apostrophe. This includes skipped rows; carriage returns are quoted too.
  • Oversized and malformed requests: oversized bodies return HTTP 413 and are drained without retaining excess bytes. Malformed JSON and invalid request shapes return 400.
  • Client disconnects: matching calls are aborted, later lines stop and the matching slot is released. Concurrent request bodies cannot bypass the single-order guard.
  • Unconfirmed learned names: a remembered entry must match an explicitly confirmed row’s product words and SKU. Skipped, automatic, missing and unrelated rows cannot teach names.
  • Export overwrite: filenames include a timestamp and UUID, preserving orders exported within the same second.

Open issue

No local authentication

The local server has no authentication. This is an accepted risk for one shop and one operator on one computer. The server must not be exposed to a network as it is.

This is a challenge project without a formal security process. Report a problem with reproduction steps in a repository issue. Use the synthetic catalogue and do not include real shop data.

Source: SECURITY.md → · Verify the offline setup