Extended core for the custom services of a self-hosted SourceHut instance (compare, spec, dolt, cover, bench, ...). Everything these services share that is ours — not upstream's — lives here, so the sr-ht-core fork can stay a clean mirror of upstream core-go, and so the services stop carrying drifting copies of the same code.
chrome — the shared page chrome: service-switcher nav built from the
shared config.ini (chrome.BuildNav), per-request chrome.Page with
login/logout/profile URLs against meta.sr.ht's unified login, embedded
srht-nav / srht-env-banner template partials (circle brand + red service
label + switcher + login box), and the generic template helpers (dict,
shortsha).grants — the grant vocabulary of tokens.sr.ht (SPEC ch. 3):
<service>:<action> members split on ASCII whitespace, * for every action
of every service, the reserved id:<n> member a registered token carries,
and the subset rule an exchange narrows by. Shared because the daemon that
mints and every service that validates have to read one grammar — two
parsers that disagree about what counts as a permission is a hole on the
security path, not a cosmetic divergence.svc := chrome.NewService(conf, "compare.sr.ht")
svc.StyleHref = cssHref // after discovering the hashed stylesheet
t := chrome.MustAttach(template.New("layout").Funcs(chrome.Funcs()))
// ... parse the service's own templates into t ...
page := svc.Page(r, "Page title", username) // username "" = anonymous
In the layout:
{{template "srht-env-banner" .}}
<nav class="container navbar navbar-light navbar-expand-sm">
{{template "srht-nav" .}}
</nav>
The template dot must expose the chrome.Page fields — either a Page
itself, or a service view struct that embeds one (promoted fields resolve in
templates).
The chrome bakes in the instance-wide decisions instead of parameterizing
them: the switcher renders only for authenticated viewers; paste, pages and
hub never appear in it; the brand is always circle + site name + red service
label and links to the service's own root; the profile link prefers hub's
~username page when hub is configured. Service-specific nav entries go
through Service.ExtraNav; per-page width through Page.ContainerClass.