Egress and --offline
ProofPack runs inside your environment and reads your table there. The table
below lists every channel by which anything can leave when our code runs it
(the support mailbox is the one route on it your own people operate), and the
field list beside each channel is generated at build time from the engine’s
own schema/egress_schema.json — vendored into this site, hashed against a
provenance record, compared against the engine repository in CI. The rows are
read by the same loader the trust page reads; the site’s
build test parses this page’s table and holds every row to the manifest, the
schema and the trust page’s rows.
The egress table
Section titled “The egress table”| Channel | When | Fields (exhaustive) | Limits and suppression | Exists today? |
|---|---|---|---|---|
| Demo — upload | never | — | No endpoint exists that accepts uploads. To be verified by the visible network counter and by a CI network-capture test (Playwright HAR). | Not built yet The in-browser demo is a later lane-S day. Nothing on this site accepts an upload today because no upload route exists in the repository at all. |
| Demo — event | on run completion, unless opted out |
| No headers, no numbers, no file names. `source` is one of `sample` or `upload`. | Not built yet No analytics of any kind is wired up on this site yet — not even Cloudflare Web Analytics. |
| Runner — licence check | never (removed before launch) | — | There is no licence server. A licence file is an Ed25519-signed document that verifies offline against the public key published on the trust page (/trust#licence-key), so the runner never phones home to check it. | Removed D2 §5.1 listed a licence-check call. D1 §6 and §7 removed it: at launch the runner makes at most one outbound call, and it is not this one. The row is kept so the removal is on the record rather than silently absent. |
| Runner — telemetry | run end; skipped entirely with `--offline` or `egress.telemetry: false` |
Generated from | The manifest hash only — no column names, no counts below bucket level, no metric values, no row-level field, no free-text declaration field. `row_count_bucket` is one of `<1k`, `1k-10k`, `10k-100k`, `>100k`; `halt_code` is a typed code or null. | Not built yet The runner's telemetry module is a lane-E day that has not run yet. The field list beside this row is generated from the schema the engine will validate the payload against, not typed by hand. |
| Runner — narrative (optional, online, off by default) | deferred past v1.0 — no code path exists | — | If it is ever built: column headers passing the whitelist regex, and a claims JSON of aggregates only, validated against the `proofpack-aggregates/1` branch of the egress schema, which the trust page publishes verbatim (/trust#egress). Cells with n<10, events<5 or non-events<5 suppressed before egress; sites and devices pseudonymised (Site A, Site B…) and mapped back locally; no free text, no dates, no row-level fields. The aggregate rules are already in the schema and already CI-tested, so the rule exists before the feature. | Deferred There is no LLM anywhere in the pack pipeline at launch. Nothing in ProofPack v1.0 sends anything to a language model. |
| Support — support@ | only when a person at your company emails us |
| We never ask for test-set data, model outputs or patient data in a support ticket. If a support answerer is ever built, it will be tested against a corpus of tickets containing pasted data to prove it makes no model call on them, before it is switched on — no such module or corpus exists today. If you send us data anyway it is in our mailbox, which is the one egress route on this table that your own people control rather than our code. | Yes Our company email is hosted on Google Workspace today, which is why Google is on the sub-processor list (/trust#sub-processors and /legal/sub-processors). The `support@` alias itself has not been created yet, so mail to us reaches the founder’s mailbox. The tested support answerer is a lane-A day that has not run yet. |
| Site — buying ProofPack | when you start a checkout or ask for a quote |
| Held by Stripe (payments, tax, invoicing) and in our own database; quote PDFs are stored in a private bucket and served through our own route. The IP address and user-agent are recorded only as the audit record for a quote acceptance, which the acceptance page itself states before you submit it. No test-set data, no model output and no patient data reaches any of it, because none of it is ever asked for. | Yes Built and tested against a Stripe mock. No live Stripe, database or email account exists yet, so nothing has actually been stored anywhere. |
At launch the runner makes at most one outbound call: the telemetry POST. It
carries a licence id, a run id, the engine version, the platform, the
manifest hash, the duration, a coarse row-count bucket and the HALT code if
one fired — no column names, no counts below bucket level, no metric values,
no row-level field, no free-text declaration field. Its module is not in
engine 0.1.0.dev1, and the row above says so.
--offline
Section titled “--offline”--offline opens zero sockets. No licence check (a licence is an
Ed25519-signed file verified locally against the public key published on
the trust page), no telemetry, no narrative call. doctor, map,
run and compare all accept it, before or after the subcommand.
The claim is tested as: the engine’s whole test suite run with the network
namespace removed (unshare -rn, fixture F19), and a continuous-integration
job that runs the reference image under network capture on every release and
publishes the capture summary on the trust page. Neither exists yet; both are
listed as pending on the validation page, and until they
are green the sentence “zero sockets” is a design commitment we have written
down, not a measurement we have taken.
egress.telemetry: false in criteria.yaml switches the telemetry call off
for every run without the flag.
Suppression before anything is serialised
Section titled “Suppression before anything is serialised”The engine’s defaults are min_n = 10,
min_events = 5,
min_nonevents = 5, read here from the
schema; the egress.suppression block in criteria.yaml may raise them and
the schema refuses a lower value. Suppression applies to egress only: a
suppressed cell is still reported in your local pack, annotated with the tier
it fell into.
These attribute levels are pseudonymised (Site A, Device A, Level A)
before egress, with the map back written only to your machine:
site device protocol attr_*
Only canonical column names matching ^[a-z][a-z0-9_]{0,31}$
could ever be serialised, and only by the deferred narrative channel; an
original header never is.
These are never serialised at all, in any channel:
original headersrow-level valuesjustificationdescriptionsourceraw dates
The demo
Section titled “The demo”The browser demo, when it ships, parses and analyses an uploaded file inside your browser tab under Pyodide. There is no upload endpoint. The trust page carries the browser-only statement verbatim and, once the demo exists, a screenshot of what your browser’s developer tools should show.
Data-use agreements
Section titled “Data-use agreements”Before a first run on real data, check two things against the agreements that govern your test set:
- Derived aggregates. A ProofPack pack is a document of aggregates — counts, rates, intervals, curves — computed from the table. Confirm that your data-use agreement permits derived aggregates to be created and filed; a pack contains no row.
- Telemetry. The one outbound call carries no data about the table
beyond a row-count bucket, but it is an outbound call from the environment
the data sits in. If the agreement, or your information-security policy,
does not permit it, run with
--offlineor setegress.telemetry: false. Nothing in the pack changes.
ProofPack does not need, and never asks for, a business associate agreement, because no protected health information reaches Global Phoenix Solutions Ltd by any channel our code operates. The one route on the table that your own people control is the support mailbox, and support asks you never to put data in it. The pricing FAQ says the same.
The schema itself
Section titled “The schema itself”The trust page publishes egress_schema.json byte for byte, with the commit of
the engine repository it was vendored from. Read it there: a summary of a
schema is not a schema.