Tiles
A tile is a reusable, parameterized bundle of static resources — a theme, a landing page, a documentation layout — published as a lol.dids.sites.tile record. Anyone may author one, and anyone may bind one to their own domain. A tile author never needs to own a domain, and never touches the sites that use their work.
Binding by CID
When a site binds a tile, the site record pins that tile's exact version by content hash. This is the property everything else rests on.
- Publishing a new version of a tile changes nothing about any site already bound to an older one.
- A site owner is shown that a newer version exists, and upgrades by editing their own record.
- Deleting a tile removes it from the directory but does not break bound sites: they hold it by hash, and the service keeps the bytes.
A tile author cannot change your live site, and cannot take it away.
Publishing a tile
A tile record carries a manifest of resources — the same path-keyed shape a site's inline manifest uses — a name, an optional description and icon, and a list of declared parameters. Its key is a TID, so an identity may publish many.
To publish a new version, write to the same key. The version history is indexed, and a site can pin any indexed version, not only the newest.
Tiles are admitted from identities that have claimed a domain — registered one, whatever its verification state — or that the operator has allowlisted. An operator may tighten that to verified domains only. Validation is the authority: it answers TileAuthorNotPermitted for an identity the policy excludes, so you find out before you write rather than after. Eligibility applies going forward — a tile published before you became eligible is not indexed retroactively, and publishing a new version of it is what gets it in.
Parameters
A tile declares what it takes: name, type, whether it is required, a description, and any constraints. The types are the AT Protocol primitives — string, integer, boolean, blob, array — plus a record reference by NSID.
There are no defaults. An optional parameter a site owner leaves empty is simply omitted, and your description is the only place you can say what the tile does in that case. Write it as if it will be read, because it will: it is the help text on the form.
A constraint that the type does not permit makes the tile invalid. maxLength on an integer is an error, not a no-op.
What a tile can read at runtime
A tile is static files; nothing of yours runs on the server. What it gets instead is a set of files the origin serves alongside it, generated from the bound record:
/_bard/params.json— the parameters the site owner supplied, exactly as they were canonicalized into the record. The service never reshapes a value./_bard/params/…— typed paths for individual parameters, so a blob parameter can be referenced directly from markup without reading and decoding the JSON./_bard/site.json— what the site is: the domain, the record it serves, the tile and version bound.
Read those with fetch from your own origin. They are same-origin, so the fixed Content-Security-Policy permits it.
What a tile cannot do
The policy on every served site forbids third-party scripts, and there is no request-time code execution anywhere in the system. A tile cannot call home, load an analytics bundle, pull a font from a CDN, or vary its output per visitor. Everything it renders comes from the bytes you published and the parameters the site owner bound.
Incomplete tiles
If the service cannot fetch one of the blobs your record names, the tile is marked incomplete and is not bindable. The remedy is to re-upload the missing file and publish a new version — nobody else can fix it, because the blobs live in your repository.