The public knowledge site
Messages that members opted in to become a public website that a search engine can read and a visitor can actually use. Server rendered, searchable, and gated by consent on every single query.
Server rendered, so it can be read and indexed
Every published message is already in the HTML that leaves the server. Nothing is fetched by client script before the text exists, so a search engine, a reader mode and a phone on a poor connection all see the same content. The page brings its stylesheet and a handful of small scripts inline, each under a nonce issued per response, and loads no external stylesheet and no framework. The only way third party code reaches a visitor is if that archive's operator deliberately configures an analytics script, which is empty by default and widens that one archive's content security policy, nothing else.
JavaScript is an enhancement, not a requirement. Without it you get the full first page of thirty messages, the search and filter form, and a pager whose rel=prev and rel=next links lead crawlers into the depth of the archive. With it, that pager is replaced by continuous scrolling.
Switch JavaScript off and the archive still works. It simply stops loading the next page by itself.
Search and filters
Search runs in Postgres against a generated tsvector column with a GIN index, using the websearch query syntax. Quoted phrases hold together, a leading minus excludes a term, OR is understood. The index uses the simple configuration, so words match as they were written rather than by stem, which is the honest behaviour for an archive that spans several languages and a lot of names.
Alongside the search box sit a type filter across text, images, video, voice, links and files, and a from and until date. All three controls are per archive settings: an operator who wants a plain chronological page can switch search, type filter or date range off, and the site then renders only the controls that are enabled, and validates every incoming filter value against that same setting.
Live updates, and what they are for
The page polls its own origin roughly every eighteen seconds and sends the exact band of cards the reader currently has loaded. The answer contains message ids and a version hash, never content. If a member has withdrawn consent, or an operator has taken something down, that card disappears from the open page within one tick, without a refresh and without the reader doing anything.
New messages are prepended only when the reader is genuinely at the head of the stream. Somebody who arrived on a deep page or scrolled far back never has the ground move under them. The poll has its own rate limit bucket, separate from the scrolling endpoint, so a burst of scrolling can never throttle the check that removes withdrawn content.
A withdrawal is not a nightly job. The message leaves an open page within about eighteen seconds.
Infinite scroll that cannot resurrect a message
Scrolling down fetches the next forty messages by cursor. The cursor is an exact sort boundary of timestamp and id rather than an offset, so nothing is duplicated or skipped when the underlying set changes while you read.
The document is windowed at two hundred cards. Cards far above the viewport are removed behind a spacer that preserves the scroll height, and scrolling back up fetches them again from the server rather than restoring them from a stash in the browser. That is a deliberate choice with a consent reason: a message recalled while it was off screen must not be able to reappear because the browser still held a copy of it. Automatic loading is capped in bursts, after five chunks a button takes over so an embedded frame cannot pull the whole archive by itself.
Media plays in place
Images in the formats this instance can strip, JPEG, PNG, WebP, GIF, TIFF and AVIF, are published as a re-encoded derivative with EXIF, IPTC and XMP removed, and the original is never served. A strippable image whose stripping failed is withheld rather than published unstripped. A format with no stripper on this instance is recorded as such and served as it arrived, and that is visible to the operator rather than silently treated as clean. Video plays inline with the browser's own controls, preloads metadata only so a page full of clips does not download everything, and is served with HTTP byte ranges, which makes seeking work and is what WebKit requires before it will play inline at all. Voice notes and files are offered as links rather than an inline player. The video download button can be switched off per archive, which also removes the browser's own download control on the player. It is a presentation choice rather than an access control: voice notes and files are still offered as links, and anything the consent gate publishes can still be fetched from its own media URL.
A recognised video link becomes a click to play card. Nothing from the video service loads before somebody clicks: the thumbnail is our own stored copy, a notice names the service that a click will contact, and a plain link offers to open it there instead. Only the click writes the player frame, and only towards the no cookie player origin. The page's frame policy is widened solely on pages that actually contain such a card.
Before a visitor clicks, the archive has contacted no video service on their behalf.
Every message has its own address
A published message has a permalink of its own. That page carries its own canonical link, a title and description drawn from the message itself, and its own preview image when the message is an image. It is listed in the archive's sitemap, up to five thousand items, so a single message is a crawlable destination rather than an anchor on a long page. The permalink returns the same 404 as anything unpublished the moment consent is withdrawn.
Sharing is plain links that we build ourselves, for X, Facebook, Reddit, WhatsApp and Telegram, plus a copy link button that confirms in place. No vendor share widget or SDK is embedded anywhere on the site. Those widgets load third party code and observe every visitor whether or not anyone actually shares, and the preview data we already emit makes a shared link look right without them.
Built to be found
An archive page carries a JSON-LD graph in its head: a WebSite node with a search action, an Organization node, a CollectionPage with an ItemList of postings, and VideoObject nodes for uploaded video as well as for recognised video links. A single message's permalink carries its own posting node instead, scoped to that message. Each archive publishes its own sitemap, a root sitemap index ties every archive together with the marketing site, and an RSS 2.0 feed carries the forty most recent items. A robots file opens the public surfaces, closes the administration paths and points at the sitemap index. A social preview image can be generated automatically at 1200 by 630 from the archive's title and accent colour, and the operator can override any of it, including the canonical base, the posting type and the whole set of structured data toggles.
All of it is built from the same consent gated query as the page itself. There is no separate export path for crawlers. A sitemap entry, a feed item, a structured data node or a preview image cannot reference a message that is not currently published, because none of them can see one.
There is no crawler-only export. Every artifact reads through the same published view as the page.
Light, dark, and inside your own site
An archive renders dark, renders light, or follows the browser setting, whichever the operator chooses, and a visitor can toggle it themselves with the choice remembered locally. There is no flash of the wrong theme, because a small boot script sets the theme attribute before the first paint. Accent, background and text colour can be overridden per archive; an archive that changes nothing uses the house palette in both themes.
The same page can be framed inside an existing website. It posts its own document height to the host so the frame can size itself, re-posts after video metadata settles and after fullscreen changes, and has a fallback that restores its own scrolling if a host is not resizing it, so content is never clipped out of reach in a misconfigured embed.
Reporting, and takedowns that leave a trace
Every card carries a report control. It is an ordinary form and works without JavaScript. Four reasons are offered, illegal content, spam, copyright infringement and other, with an optional note of up to a thousand characters. Reports are rate limited per address, cross site submissions are refused, and the confirmation is byte for byte identical whether or not anything was stored, so the form can never be used to find out which message ids exist.
A report never hides anything. Content stays visible until a person decides, and only an operator's takedown removes it, which writes an audit entry against that message. One exception runs the other way: a report of illegal content also places an evidence hold, so the item cannot be destroyed while it is waiting for review. That hold defers destruction only. It does not change publication, and it does not stop the author hiding their own message, which stays instant.
A report is not a delete button. Only an operator's takedown removes a message, and that goes into the audit log.
Quarantine and hash screening In development
The withholding half of this is built and running. A hash match or an operator escalation removes an item from every public read at the database view level, so the page, the media route, the feed, the sitemap and the structured data all stop seeing it at once, and the files themselves are moved out of the media root entirely, so no route can reach them by path either. Segregation that exists only in a database is not segregation.
The detection half is not connected. No screening provider is configured, the default provider transmits nothing and returns no verdict, so nothing is currently being matched, and the absence of a match must not be read as a statement about any content. When a provider is configured, hash matching finds known material only and never new material. A match preserves and quarantines. It never deletes.
No screening provider is connected. Nothing is currently being matched, and a no-match says nothing about content.