follow compare.sr.ht's rename to diff.sr.ht The service renamed itself; what reaches this repository is the section name in ecoretest's synthetic config.ini, which every service's switcher test is built from, and the examples in the chrome docs and README that spelled the old section. The fixture's custom services now read bench, cover, diff, dolt, spec, tokens — alphabetical, which is the order BuildNav puts them in.
README: the packages of the third uplift
chrome: carry the service's extra hashed assets bench and cover each grew a pair of UplotCSSHref/UplotJSHref fields beside the embedded Page, compare a BundleHref, and all three wrote the same justification next to it: the hash in the name is a property of the binary rather than of a page, so a page handed its own asset URLs is one that can be written without them and silently render nothing where the chart was. That argument is about the chrome, so the slot belongs to the chrome. A map rather than named fields because ecore has no business knowing that this instance vendors uPlot; the service names its own artefacts and its layout reads them back with index, guarded on emptiness the way StyleHref is.
README: the web-tier packages
chrome: give the brand both halves, and share the login URL and time helpers The brand was upstream's minus its hub link: core.sr.ht points the whole brand at hub when the instance has one and drops the red service label, while this package kept the label and pointed at the service root. Hub is excluded from the switcher, so that left the chrome with no route to hub at all. Split the brand in two — the site name to hub (to the service root on an instance without one), the label to the service root — and neither half has to lose. The label keeps its own <span class="text-danger"> because the theme colours ".navbar-light .navbar-brand a", which outranks .text-danger and would repaint a red <a> white in dark mode. LoginURLFor exports the line Page already computed. A handler that gates a page behind login was building an entire Page to read one field off it. RelTime/AbsTime come up from the services, where the copies had already drifted over what to print for a future instant: "in 3 hours" on one service, "just now" on the next, for the same timestamp.
bearer: the shared working-token validator of SPEC ch. 6
grants: the shared grant vocabulary of tokens.sr.ht
chrome: shared page chrome for the instance's custom services Extract the nav/chrome idiom that compare, spec, dolt and cover each carried as a private copy (and bench was about to fork as a sixth): BuildNav over the shared config.ini with the canonical ordering and paste/pages/hub exclusions, a per-request Page with login/logout/profile URLs against meta's unified login, embedded srht-nav / srht-env-banner partials (circle brand + red service label + switcher + login box), and the generic dict/shortsha template helpers. Policy decisions the copies had drifted on are baked in: switcher only for authenticated viewers, hub excluded in the builder rather than the template, profile link prefers hub's ~username page, environment name uppercased for the banner. Service-specific needs surfaced by the cover survey get seams instead of copies: ExtraNav for extra switcher entries, ContainerClass for full-bleed pages, the config section as an explicit parameter for the active check.