الدستور
The RocMail Constitution
Version 1.3.0 · ratified 9 August 2026, last amended 14 November 2026 · versioned with the source code
Correspondence is where people are most themselves — contracts and love letters, diagnoses and dissent. The industry default treats that intimacy as inventory. This constitution exists so that RocMail can never quietly become what it was built to refuse: every article below binds the service, its operator, and every future version of its code. These are not aspirations. Each article names the mechanism that enforces it, and the software tests itself against this document.
Where the code and this constitution disagree, the code is the defect.
The inversion is deliberate. Everywhere else in our repository the rule runs the other way — where the documents and the code disagree, the code is authoritative and the document is the bug, because those files describe what the system does. This document does not describe. It governs: code that contradicts an article is a defect whatever it shipped as, however long it has been live, and however convenient it has become.
Why a constitution
Every service publishes values. Almost none can be held to them, because a promise without a mechanism is a mood — it lasts exactly as long as the goodwill, funding and ownership of the people who wrote it.
So every article below names the mechanism that keeps it true whether or not we remain trustworthy. Those names are not decoration: a test in our codebase reads this document, extracts every mechanism, and fails the build if one disappears.
That is the whole design: make the values load-bearing, so betrayal requires vandalism rather than a quiet policy update. Where this constitution and a product decision disagree, the constitution wins and the decision is the bug.
I.The Seal
The mailbox is the user’s, not ours
- I.1Mail content shall be readable by its owner alone. The service shall never possess, generate, or accept a key capable of opening stored mail. We cannot read the mail we store — not “do not”, cannot. Bodies, subjects, senders, recipients, previews, attachment bytes and filenames, drafts, contacts and the search index are sealed to a vault identity whose secret half exists only inside your unlocked browser.
- I.2The ingest worker holds a public key only: it can seal mail to you and can never open it.
- I.3The historical server mail key was destroyed on 7 August 2026 after every stored message was re-sealed. Old database snapshots are unreadable because the key that opened them no longer exists anywhere. It will never be recreated.
- I.4If sealing cannot happen, delivery is refused so the sending server retries. We never silently store a readable copy of mail you believe is encrypted.
Enforced bySealing at ingest (Mashrabiya: ML-KEM-768 + X25519), a delivery path that refuses rather than falls back to plaintext, a test that scans the raw database files for plaintext, and no server key path left that could open mail.
II.No Watchers
No advertising, no tracking, no data economy
- II.1No advertising, ever. Advertising is funded by attention and paid for with profiling; a mail product that shows ads is reading something to target them.
- II.2No analytics, no trackers, no fingerprinting — in the app or on the public pages. No third-party script, font, CDN, or beacon may be loaded by any page we serve.
- II.3No cookies for anonymous visitors. Signed-in users receive exactly two: a session cookie and its CSRF twin.
- II.4We do not sell, share, rent, or “anonymise and aggregate” user data. There is no lawful-basis paragraph that makes this acceptable later.
- II.5Incoming mail’s tracking pixels are neutered by default — remote content loads only when the reader asks for it, per message.
Enforced byA Content-Security-Policy with no third-party origins (the analytics beacon was removed in v27), self-hosted fonts with no preconnects, tracker stripping at ingest, and tests that scan the served pages for off-host resources.
III.Custody Without Sight
Power over accounts, never over correspondence
- III.1An operator exists and is necessary at scale. The operator’s power is account management: invite, suspend, unsuspend, delete, and the instance’s own settings. Never read.
- III.2This is structural, not procedural: the operator’s commands meet the same ciphertext as a stranger’s. There is no privileged read path to abuse, forget to protect, or be compelled to use.
- III.3The owner cannot read mail either. No role in this system, including the one that owns the server, can open a user’s mailbox.
- III.4No account holds the operator’s power. It is exercised only from the server’s own console, by whoever holds root on the machine — who could do all of it anyway. The web app has no administration page and no admin route: no session, cookie or password, the owner’s included, can suspend an account, mint a voucher, open registration or choose an address on a shared domain. A phished password, a stolen session or a hole in the web client reaches one mailbox and nothing more. The owner’s account is a mailbox like any other.
- III.5Every operator action is audit-logged as the console’s, with no account and no address attached.
Enforced byEvery operator power in one module that only the server’s console imports; no administrative route at all (a test fails if one appears, or if web code calls one of the operator’s writes); suspension enforced where sessions are resolved; and a rehearsal on a real server that drives the console end to end and checks that the old admin routes answer 404 to the owner too.
IV.Full Disclosure
Honesty about limits
- IV.1We publish what we do not defend against: an unlocked device, script injection while the vault is open, traffic analysis, a malicious client update we ship ourselves, and a seized machine.
- IV.2We state the metadata the server keeps — timestamps, folder and read flags, attachment counts, the forwarding addresses of names, rule conditions, message-ids — on the public site, not in a footnote.
- IV.3Where the documents and the code disagree, the code is authoritative and the document is the bug. We fix the document.
- IV.4We do not claim a property we cannot demonstrate. Marketing language that outruns the mechanism is a defect, reportable like any other.
Enforced byA published threat model, the same limits on the security page, and the metadata table printed on the landing page itself.
V.Plain Speech
Clarity is part of the product
- V.1Text you receive must be readable: never raw encoding, never mangled leftovers of our own pipeline. Every surface — list preview, reader, quote, export, search row — shows the same repaired truth.
- V.2System verdicts must be explained in sentences, not protocol acronyms. A signal you cannot interpret is decoration.
- V.3Repairs must be conservative: honest text passes through byte-identical. We would rather show one message imperfectly than corrupt a thousand.
- V.4Errors say what happened and what it means. Silence is not a UX state.
Enforced byRepair applied at every read path, a plain-language explanation of every SPF, DKIM and DMARC verdict, and tests that honest text passes unchanged and that the list row, the reader and the verdict sentences agree.
VI.No Back Door, at Any Price
No back door, and the price we pay for it
- VI.1No recovery escrow, operator override, or intercept capability shall be built, bought, or accepted — not for convenience, not for growth, not under pressure. There is no password recovery for the vault and no “contact support” path that ends in someone else holding your key.
- VI.2The honest cost shall be stated wherever it applies — signup, vault creation, the security page, the terms: a user who loses both the vault passphrase and the recovery phrase has lost their mail, mathematically, and no support request changes mathematics.
- VI.3A service that offers both recovery and privacy is describing a key it keeps. We will not become that by convenience.
- VI.4Account deletion destroys the vault wraps, which makes the user’s mail permanently unreadable in the live database and in every copy taken from it afterwards — stronger than deleting rows, and irreversible by design. A backup taken before the deletion still holds the old wraps until it ages out, and the old passphrase or recovery phrase would open it; [the privacy policy](/privacy#backups) states how long backups are kept. When the last of them is gone, so is the last key.
Enforced byA reset path that destroys rather than resets and says so in those words (“DELETE MY MAIL PERMANENTLY”), the vault gate, and account deletion that removes the wraps rather than the rows.
VII.Right of Departure
The exit door stays open
- VII.1Leaving must always be possible. Full mailbox export to standard mbox and a sealed (ciphertext) archive ship in the product — not on a roadmap, not behind support. The passwords kept beside the mail leave the same way: as an encrypted backup file that only the passphrase chosen for it opens, or as a plain file in the Bitwarden format that other password managers import.
- VII.2Lock-in built on the cost of leaving is a business model we refuse.
- VII.3The self-hosting seams — provider-neutral inbound, SMTP outbound, the both-engines database schema — are maintained and tested, so this instance can be left behind entirely, including by us.
- VII.4Deletion destroys the keys, not merely the rows. Deleting an account first destroys every wrapping of that mailbox’s key, which is what makes the mail unrecoverable at once in this database and in object storage — and in every page, write-ahead log and replica copied from them afterwards, which deleting rows alone could never reach. Backups taken before the deletion keep the old wraps until they age out (VI.4). There is no escrow, no operator override, no support path that reverses it: once those backups have aged out, the ciphertext exists nowhere with a key.
- VII.5Nothing keeps the name of someone who left. The deletion cascade removes the account’s rows from every table that holds them, and a test sweeps the entire schema — every table, every column — for the departed id, so a table added in future cannot quietly retain a person who asked to be erased.
Enforced byBoth mailbox export formats and both password exports in the product today; a tested provider-neutral mail path so the whole service can move hosts; the key-destroying delete path, with a schema-wide sweep test that fails if any table still holds a deleted account.
VIII.Whom the Service Serves
Who we build for
- VIII.1This service is built to be defensible for journalists, their sources, activists, and anyone whose correspondence can be used against them. When a design decision trades convenience against that person’s safety, safety wins.
- VIII.2Hosting is chosen so the host itself is treated as an adversary for metadata — not merely for content. A privacy-jurisdiction server we control, with a Tor onion service so readers’ network location is nobody’s to log.
- VIII.3We will not add a feature whose value depends on watching users.
Enforced byThe sovereign-hosting runbook (the target architecture and the onion service — held privately until the migration completes), and an onion origin supported as a first-class deployment target.
IX.The Limits of Money
Money, and what it may not buy
- IX.1The service is funded by people paying for it. Not advertisers, not data brokers, not “partners” with an interest in the inbox.
- IX.2No investor, acquirer, or partner may obtain a capability this constitution denies. A change of ownership does not change Article I — and could not, without the destroyed keys that no longer exist.
- IX.3There is no sponsored surface: no feed, no board, no placement, on any page. Nothing appears anywhere because someone paid, and the schema has no table a payment could buy a row in. (A curated news and markets feature once existed and was removed whole in schema v31; this clause outlived it.)
- IX.4Payment must not identify the mailbox. Money buys a voucher; a voucher feeds any account; the join key between the two is never stored. The voucher table has no user column to subpoena, and redemption extends an account in a separate statement that never learns which code paid. Rails are offered in privacy order — cash by mail, Monero, Bitcoin — and any future card rail must buy vouchers through a hosted page, never subscriptions against an account.
- IX.5Non-payment freezes; it never deletes, and it never gates receiving. An expired account keeps receiving, reading, and exporting forever. Deletion is the user’s act alone — immediate, warned, and irreversible.
Enforced byBilling that never consults payment state to receive, read or export (only sending and creating names do), a redemption that records no voucher, a voucher table with no account link, and the rails and the card rule published on the pricing page.
X.Defence Without Surveillance
Abuse controls that do not become surveillance
- X.1We defend the service against spam, brute force and abuse using the thinnest signals that work: rate limits, sending ceilings for young accounts, authentication verdicts, and content scoring that happens in memory at arrival and keeps only its verdict.
- X.2Anti-abuse never becomes a reason to read mail, profile users, or retain more than the mechanism needs.
- X.3Registration is gated, not surveilled — closed, invite-only, or open by the owner’s decision, with invite codes stored hashed so a database leak mints nothing.
Enforced byPer-identity rate limits, a young-account sending ceiling, hashed single-use invite redemption that grants no privilege, and spam verdicts stored without their evidence.
XI.Hard Constraints
Hard constraints
- XI.1No back door, key escrow, or “lawful access” capability will be added. Where compelled by valid legal process, we produce what we hold — account email, routing metadata, ciphertext — and say honestly that content is not ours to give.
- XI.2No content scanning for advertising, model training, or profiling. Ever.
- XI.3No dark patterns: no engagement mechanics, no manufactured urgency, no interfaces designed to make leaving, deleting, or refusing harder than accepting.
- XI.4No silent capability expansion. New powers over user data require a public change to this document, with the reasoning, before the code ships.
Enforced byThese are absolute, not balanced against anything. No mechanism can substitute for keeping them.
XII.The Public Record
Accountability
- XII.1This document lives in the repository with the code, versioned in a public history. Amendments are commits: dated, attributable, reviewable.
- XII.2Mistakes are published, not buried. When we break a promise here — as with the ingest bug that stored message bodies unreadably in August 2026 — the fix, the cause and the test that prevents recurrence are recorded in the commit history and the status ledger.
- XII.3Security reports reach a monitored address and are answered.
- XII.4If this service is ever wound down, users get at least 90 days’ notice and their exports.
Enforced byA test suite that reads this constitution, extracts every mechanism it names, and fails the build if one is removed from the codebase; and the running ledger of what shipped, failures included.
Amendment
An amendment must state what changed, why, and which mechanism now enforces — or no longer enforces — the affected article. An amendment that weakens a protection must say so in those words: no euphemism, no “clarification” framing for a removal.
Articles I, VI and XI are load-bearing. Amending them to grant any party — including us, including a future owner — the ability to read your mail would not be an amendment to this constitution. It would be a different product, and it must be named as one.
The authoritative text lives in the repository as CONSTITUTION.md. See also the security model, ethics, and the privacy policy.