How this site is built
Everything below can be verified from your browser’s developer tools without taking anyone’s word for it.
Architecture
Pages are rendered at the network edge, close to the reader, then written to a cache there. In steady state almost every request is served from that cache and never reaches the database: a cached response has no database in its path, which preserves most of the security profile of a purely static site.
Editorial content lives in version control and is deployed as code. Nothing is stored in a content management system.
The revision history on each doctrine document is authored, not generated. Several of those documents predate this site, so their earliest entries describe work done before the repository existed and cannot be derived from it. Every revision made since the site was rebuilt in August 2026 also appears in the commit log, and the first-publication date shown at the top of each document is calculated from the oldest entry in its own history rather than typed separately, so the two cannot disagree.
What this site does not do
- Sets no cookies, which is why there is no consent banner.
- Loads nothing from a third-party origin. No hosted fonts, no analytics, no embedded widgets, no social software development kits.
- Collects no analytics of any kind.
- Has no accounts to sign up for, no passwords and no sessions. Nothing a visitor can reach asks who they are.
- Uses no CAPTCHA, and never asks a visitor to prove they are human. Challenge scripts are an accessibility barrier and a third-party dependency. Unwanted traffic is filtered at the network edge, and the contact form itself ignores anything that fills in a field only a machine can see, anything submitted faster than a person could type it, and more than five messages an hour from one source. All three are invisible to someone writing an ordinary enquiry.
There are share links at the foot of articles. They are ordinary links, not the usual share widgets: no other company's code runs on this page, the icons are drawn into the page itself, and nothing is counted. Nothing is requested from LinkedIn, X, Threads or WhatsApp unless you click one, and then you are simply visiting that site as you would any other.
One exception, on the server side rather than in your browser: when someone submits the contact form, this site calls an email service so the message is not missed. It is told which kind of enquiry arrived and when, never the sender’s name, address or message, which stay in the database described below. Nothing is called for an ordinary page view.
One private page does now exist, and it is easier to describe than to hide. Contact enquiries have to be read somewhere, so there is a page that displays one. It is reached by an address containing a secret: no username, no password, no session and no cookie, and a wrong address is answered the same way as an address that was never issued. It is not linked from anywhere, is absent from the sitemap and the search index, and is served with instructions not to index or store it. The secret in each address opens one enquiry and nothing else, and stops working three days after that enquiry arrived.
The list of held enquiries, as opposed to a single one, also requires a six-digit code from an authenticator app. That is still not an account: there is no username, nothing is stored about who entered it, and the proof that a correct code was given is a signed value in the address that expires by itself. It is the one place on this site where something is asked of anybody, and the person being asked is its owner.
Security posture
- Content Security Policy
- Denies everything by default. No inline style is permitted, and each script is allowed by the SHA-256 hash of its own source rather than by a per-request token or a blanket permission, so the policy cannot fall out of step with what is served, and pages stay cacheable. A script that is not hashed does not run.
- Transport
- HTTPS only, with HSTS preloading and no mixed content.
- Database access
- Every statement is prepared with bound parameters, and all of them live in a single file so there is one place to audit.
- Object storage
- Private. No public bucket and no public bucket domain.
- Data retention
- Messages sent through the contact form are deleted once they have been dealt with, and in any case automatically after one hundred and eighty days. The only other thing stored is what stops the form being flooded and the contact card being harvested: when a message is sent, or when the QR code on his card is scanned, a one-way fingerprint of the network address is kept briefly so that no one source can do either too many times. It is salted with a secret held on the server, which means it cannot be turned back into an address by anyone, including him; for the card it is reduced to the network rather than the device before it is hashed at all; and both are deleted every night. Nothing else about a visitor is recorded, and there is no log of who read what.
The scripts
There are four, all served from this origin, all small, and each one permitted by the SHA-256 hash of its own source. If you want to check that count rather than take it, the script-src list in this site’s content security policy header carries one hash per script and nothing else.
This section was headed “the two scripts” until August 2026, and before that “the one script”. It had fallen a script behind twice. The heading no longer states a number, because the number is the part that goes stale, and the policy header above is checkable in a way that a sentence is not.
The first varies the reading theme, and remembers one only if you ask it to. Arriving without having asked, you get paper, sepia or high contrast, chosen at random for that visit and stored nowhere. Choose a theme from the control at the foot of any page and it applies for that visit alone; a separate button beside it keeps that choice for next time, and that button is the only thing here that writes anything to your browser. Without this script the site follows your operating system’s light or dark preference, and every page works normally.
The second runs only on the search page. It downloads one static index file from this origin and does the matching in your browser, which means no search term is ever sent here, logged or cached. With JavaScript switched off that page still lists every page on the site as ordinary links, so nothing becomes unreachable.
The third runs only on the contact form, and the fourth only on the share links at the foot of articles, where it copies a link to your clipboard. Both pages work with JavaScript switched off: the form submits normally, and the share links are ordinary links.
All four are permitted by the hash of their own source. That detail matters: an earlier version used a per-request token, which meant cached pages were served with a token that no longer matched, and the script was silently blocked. A mechanism that quietly stops working is worse than one that is simply less clever.
There is deliberately no language model here. The whole site is about twenty-five thousand words, so llms-full.txt hands the complete text to whatever assistant you already use. Generating answers on this side would publish paraphrases under this name that nobody had reviewed, which is the opposite of the point.
Typography
Headings are set in Newsreader, which this site serves itself: one file of about thirty-four kilobytes, from this domain, carrying the two weights the site actually uses. Body text is still set in whichever sans-serif your device already has. No font service is involved either way, so none of them learns that you visited.
Until August 2026 the headings were left to whichever serif your device happened to own. That saved a request, and it also meant the headings on this site appeared in four different typefaces depending on whether you arrived on a Mac, a Windows machine, an Android phone or something else. How a claim is set is part of how it is presented, so it is now the same shape for every reader. The face is published under the SIL Open Font License, and the licence travels with it, at newsreader-license.txt.
The one exception is the name at the top of every page. That is a logotype rather than a typeface, so it is drawn as an outline in the page itself, which is why it holds its shape in all four reading themes and takes its colour from whichever one you have chosen. It is still part of the page rather than a separate download, so it costs no extra request and no other company sees it. Everything else, including the name read aloud by a screen reader, remains ordinary text.