The web surfaces #
Four websites sit around this project. They look similar from the outside and they are not interchangeable: each has a different origin, a different thing serving it, and a different reason it may not be merged with the others. An agent asked to "work on the dashboard" or "the site" has to say which one, and the answer changes what language it is written in and which host it runs on.
Written down because the distinction was previously only implicit — spread across ops-dashboard, policy-dashboard and agent-sites — and one of the four was not recorded anywhere.
Surface 1 — the marketing site, did.bot #
A static site. Marketing and launch pages, the prose documentation from
docs/, and the compiled Rust API documentation. Built from site/ and
published to an object store behind a CDN; nothing about it is served by this
project's own binaries, and it holds no state.
It is the only one of the four whose audience is people who have not yet decided anything.
Surface 2 — the policy site, on a separate origin #
A static page with no backend, and it may not be served by the server it governs. The owner signs in against their own personal data server as a public OAuth client and writes policy records with their own key.
The reason is in policy-dashboard and it is worth repeating here, because it is the constraint most likely to be accidentally violated by someone consolidating pages: if the server this policy governs also served this page, a compromised server would serve modified JavaScript, the owner would sign the attacker's policy with their own key, and every downstream check would pass. Hosting it elsewhere removes that path.
Likely a subdomain of did.bot, which satisfies "not served by the governed
server" while staying under a name the project already controls. Note the
cookie-scoping problem in agent-sites before deciding
the exact name: cookies are scoped by domain rather than by origin, so a
sibling host under a shared registrable domain is not the isolation it looks
like.
Surface 3 — the per-server homepage and operations dashboard, served by the PDS #
Served by this project's own binary, out of didbot-serve, about the
server serving it. Live state — agents, sessions, grants, refusals — and it
carries the emergency stop.
This is the one that has to interoperate with Rust. It is not a static site
built elsewhere and copied in: it is served by the running server, reads that
server's own state, and its front end talks to Rust either through the server's
routes or through wasm compiled from this workspace. Anything built for it
belongs in this repository, in didbot-serve and the asset directory beside
it.
Two consequences that catch people out:
- It owns no policy. Everything it can change is operational. Policy is written from surface 2, into the owner's own repository, and only read here.
- It can lie. A compromised server serves this page and also supplies its numbers, so anything security-relevant has to be checkable against the owner's own records instead. ops-dashboard makes saying so a deliverable of the page rather than a footnote.
There is one of these per deployment, not one for the project.
Surface 4 — vibescrobble.com, another repository #
A consumer of what this project publishes, developed separately and not in this tree. It reads data served from personal data servers — this project's among them — over the ordinary public interfaces.
It is named here so that nobody looks for it in this repository, and so that a change to a public interface is understood to have a reader outside this codebase. It gets no special access and no private endpoint; if it needs something, that something is a public capability and belongs in a lexicon.
Which one is being asked for #
| If the work is… | It is surface | It lives in |
|---|---|---|
| Marketing, docs, API reference | 1 | site/, static |
| Editing policy as the owner | 2 | separate origin, static |
| Watching or stopping a running server | 3 | didbot-serve, this repo |
| Reading published records elsewhere | 4 | another repository |
Surfaces 1 and 2 are static and may be built with whatever a static site is best built with. Surface 3 is part of the server and follows this workspace's conventions. Surface 4 is somebody else's build entirely.