decision

Shipping the method to the browser IS the privacy guarantee

2026-07-20 · SEC-113

The question

The payload washer runs client-side, so its entire rule set — every pattern, the word lists, the policy matrix — is delivered to every visitor. Can the quality of those rules be treated as proprietary?

Constraints

  • The tool is a client component and imports the engine directly, so roughly 1,300 lines of rules ship in the bundle. This is observable by anyone with a browser.
  • There is no authentication anywhere on the production deployment. The middleware short-circuits unless the build is a preview.
  • The zero-network property is the single strongest privacy claim in the product, and it exists precisely BECAUSE the computation happens in the browser.

Alternatives considered

  • Move the rule corpus behind a runtime-fetched pack.

    Rejected — There is nothing to authenticate the fetch against. With no accounts and no auth on production, a pack endpoint is public by construction — the rules would be one request away instead of one bundle away.

  • Ship the corpus encrypted and decrypt it client-side.

    Rejected — Self-defeating: the key has to ship with the code that uses it. This buys obfuscation, not secrecy, and obfuscation that looks like secrecy is worse than neither.

  • Move the wash server-side so the rules never leave the host.

    Rejected — This destroys the strongest privacy claim in the product for exactly the customers most likely to care about it. A payload that must be uploaded to be washed is a payload that was uploaded.

  • Accept the disclosure and treat curation as the moat.

    Chosen.

The decision

Accept it. "Runs entirely in your browser" and "never reveals how" cannot both hold for one tool — shipping the computation to the client IS the privacy guarantee AND IS complete disclosure of the method. The defensible asset is not the rules; it is the judgement about which rules matter, why each one is scoped the way it is, and what the tool refuses to claim.

The two claims are the same fact

This is the part worth keeping. The instinct on discovering that the rules are public is to treat it as a leak to be plugged. It is not a leak — it is the same architectural fact as the privacy property, seen from the other side:

  • Because the wash happens in the browser, the payload never leaves the machine.
  • Because the wash happens in the browser, the rules do.

Every proposal that hides the rules moves the computation somewhere the payload has to follow. There is no arrangement where both properties hold.

Why "refuted as originally scoped" rather than "closed"

The ticket was filed as a security finding: the rule corpus is exposed. That framing is what got refuted — the exposure is not a defect, it is a consequence of the design's best property. What remains open is the commercial question the finding accidentally surfaced, and it is a different question with a different owner.

Recording it as refuted-with-a-residue rather than fixed-or-wontfix is the honest shape, and it is why this record is a decision and not a postmortem: nothing went wrong. A hypothesis was tested and did not survive.

Where this is canonical

docs/backlog/IMONFHIR_MASTER_BACKLOG.mdFiled as refuted-as-originally-scoped and still open as a decision. The register entry is canonical; this record is a dated snapshot.