223. A deployment carries the site built at its own commit, and the hosted server serves it at /docs
Kontext
The owner asked, on 2026-10-22, that the hosted server at prismatic-majordomus.gigalixirapp.com
serve the same site GitHub Pages serves at majordomus.dev, with links that work where it is
served. ADR 0219 decision 3 builds what a provider receives from three things only, all read at
one commit: the object's build.inputs, the provider's generated files and the executable.
A built site is none of those. The site is an output of the canonical pipeline, not a tracked
input, so the slug could not carry it.
Most of the remaining machinery already existed:
deployment/v1declares an optionalbuild.site, which is validated as a relative path and read by nothing.scripts/site-build --servebuilds the same Zola source with the base/docsintotarget/web/docs. Beside the pages it writes asurface.jsonnaming the mount and the commit it was built from (built_from).web::discoverfinds that directory, and the surface registry serves it at/docswithout shadowing/api,/ui,/cockpitor/mcp.scripts/site-basepath-checkalready proves that the source carries no origin-absolute link, so one build serves under any host.
Rozhodnutí
- A slug carries a fourth thing when the object declares it. When
build.siteis set, the tree a provider receives also holds the site the canonical pipeline built at the same commit, placed at the declared path. This amends ADR 0219 decision 3; its other two decisions stand. - The site comes from the slug's own commit, or not at all. The site's
surface.jsonmust name a commit (built_from) that is a prefix of the slug's commit. A site built from any other commit is refused, and so is a site with no commit, so a slug stays a function of one commit. A site that holds a link or anything but files and directories is refused too. - The object is what declares it.
deploy slug --site <dir>names where the build left the site. The flag is required exactly when the object declaresbuild.site, and refused when it does not. The record the slug carries (SOURCE.json) names how many site files it holds and a digest over them. - The hosted server serves the site at
/docs. That is the mount the site build already targets and the surface registry already reserves./stays the native home, which lists every surface,/docsincluded. Moving the site itself to/is a separate decision, because it would displace the native home. - The site is rebuilt at deploy time, not copied from Pages. The Pages build uses the base
https://majordomus.dev, and Zola renders absolute links. Rewriting them would be a second build path. The provider workflow runsscripts/site-build --serveat the commit it deploys.
Důsledky
- A deployment that declares
build.sitecannot be assembled without its site. The failure names the build to run, so a deployment never ships without its documentation and without an error. - The hosted server answers the same site as Pages at
/docs, built from the same source at the commit it runs. Its links are relative to/docsand hold on any host. - The slug grows by the size of the built site. I0921 measures the size of the deployment.
Zamítnuté alternativy
- Copying the gh-pages tree into the slug. It carries
https://majordomus.devin every absolute link, and it is built at whatever commit Pages last published, not at the slug's commit. - Mounting the site at
/now. It would shadow the native home and every surface's index, and it needs its own decision about what/is for on a server that is also a mesh hub. - A new site field outside
build.build.sitealready exists indeployment/v1. A second field would be two declarations of one fact.