Status: LIVE and usable since 2026-09-30. Four synthetic wholesaler portals, built so the order satellite can be
tested against something shaped like a real wholesaler's site. Nothing here is real: invented suppliers, invented
prices, no real data, no credential of any kind, and nothing in production depends on it. The work items and the live
verification record are on
The Test Rig (Build Spec), whose §12
is the evidence. This page is the practical one: what you will see, how to get in, and what the four are for.
If you open https://portal1.veripath.co.uk/ you get a sign-in page. That is not a dead end — the page prints its
own demo account, on purpose, because this is a throwaway test portal and the account exists only so the page can be
opened:

The sign-in page. The username and password are printed under the form; type them in and the portal opens.

The same portal after signing in: the bulk-upload input, and the price list to download. This is the whole page — no
navigation, no basket, no order to place.
Portal 2 and portal 4 ask for nothing at all and open straight up:

Portal 2: a quick-order grid, and one download with a single net price and no discount column anywhere in it.

Portal 4: the prices are on the page and there is deliberately no download control at all — which is the state the
satellite has to cope with when a supplier only issues a printed list.
Portal 3 also asks you to sign in, and once in gives the two-file trap and the churn buttons:

Portal 3: a headerless download, a second control that fires two files at once (not a zip), the churn discount
buttons, and the fixed sentence that names the current discount.
Pictures are produced by veripath-ops/scripts/capture-rig-screenshots.py on the server; re-run it when a portal changes
so these stay honest.
Three parts, and it is worth being exact about which one is which, because the confusion is easy to fall into:
So what are these four for, today? They prove the three things that cannot be proved with our own mocks: that the
satellite refuses a page that is not ours (the impostor, below), that the files a wholesaler issues arrive in the
shapes we expect (a price with a discount, a price alone, a headerless file, a printed list), and that every state
the app has to cope with is reachable (signed out, signed in, no download at all, two files at once, a discount that
moves between pulls).
What they are not for, yet: the satellite does not drive a portal. Making it act on one — fetching a price file
from a signed-in page — is the next build, and that build is where these four stop being a reference and start being a
test. The inbound half is specified on
Supplier Price Downloads.
The one thing waiting on a person is the first real run on a Windows PC: download the package from Stock → Order
satellite, extract it, double-click the launcher, log into the app in the window it opens, open an exported order and
read the report. The steps are on the
C8 guide, which also carries the section on why that
run decides the packaging.
| Portal | Address | Sign-in | What it is there for |
|---|---|---|---|
| 1 — Synthetic Wholesaler | https://portal1.veripath.co.uk/ | yes | a bulk-upload input, and a download whose file states a price and a discount |
| 2 — Synthetic Wholesaler Two | https://portal2.veripath.co.uk/ | no | a quick-order grid, and a download with one net price and nothing about a discount |
| 3 — Synthetic Wholesaler Three | https://portal3.veripath.co.uk/ | yes | a download that is headerless, a second control producing two files at once, and the churn buttons |
| 4 — Synthetic Wholesaler Four | https://portal4.veripath.co.uk/ | no | no download at all; the prices are on the page (three states, below) |
Plain http redirects to https, one certificate covers all four names, and every page carries a synthetic banner and
noindex. Portals 1 and 3 ask you to sign in and both use the one demo account, which is printed on the sign-in page
itself — read it there and type it in. It is a fixture that opens nothing but invented prices, it exists on no other
system, and it is deliberately not copied onto this page: the wiki is readable without signing in.
A fifth page carries a perfect copy of the satellite's signal — contract, status, order, supplier, method, target,
file, all of it — served from an address outside our domain:

Byte for byte the same note the satellite looks for, on a page that is not ours. The satellite must refuse it (it exits
with code 8 and says the origin is not a VeriPath page); a page on a loopback address, which is what the development rig
uses, is read normally, and a file:// copy is refused too.
That page is deliberately a perfect copy: if the refusal were only about the content, this would pass. It is fixed by
hosts-file on the server, so you will not reach it from a browser, and it is checked by the browser verifier.
Run on the server, in the rig's own directory:
docker compose exec -T app python seed.py --portal p4 --state prices-table (prices onno-prices (nothing on screen either), print-only (a print view and a PDF, standing inpython seed.py --portal p3 --discount 0 (or 5, or 10) does the same from the command line.python seed.py --portal all reloads all four; one portal can be reloaded without touching theRun from veripath-ops/scripts on the server; each one reads its expectations out of the running rig and writes nothing
to the product:
| Command | What it proves | Checks |
|---|---|---|
verify-synthetic-rig-live.py |
the isolation, the four portals, the files they emit, the seeds and the churn | 88 |
verify-synthetic-rig-browser-live.py |
the impostor refused (exit 8), the real browser downloads, the two-file control | 22 |
verify-rig-files-into-app-live.py |
the rig's own files at the live app's mapping step, with nothing written | 16 |
capture-rig-screenshots.py |
refreshes the pictures on this page, signing in through the real form | — |
All 88 and all 22 passed again on 2026-09-30 after the sign-in pages were changed to print their own demo account.
The portals' tables now name items the app actually holds (changed 2026-09-30, veripath-ops c226b73): every portal seeds the same eight items at different prices using the app's own item codes, so a file taken from any of them lands on an item instead of matching nothing. All four sets of checks were run again after that change (11 rig-side, 88, 22 and 16), and the app's own matcher was run read-only over P1's and P3's real files — 16 of 16 rows matched. The pictures below were re-captured the same day, which is why they show these codes.
veripath-ops/rig/synthetic-portal-rig/, so the rig can be deleted with one command and rebuilt from that copy.portal1–portal4 on 2026-09-30, when the rig stopped being internal-only; the rig, its own