From 0fb2ab7716336e66acd78dda7efbdfc343153a10 Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 10 Sep 2026 00:27:11 +0200 Subject: [PATCH] catalogue: composeName handles the apex label '@' (bare public domain) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An empty label composed nothing, so a module served at the bare domain (a node's own site) had to keep a full name — the one route the label model could not express. The zone-file convention '@' now composes to the public domain itself, no leading dot, so the apex is a label like any other. Test added. Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF --- internal/catalogue/declaration.go | 7 +++++++ internal/catalogue/routing_test.go | 16 ++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/internal/catalogue/declaration.go b/internal/catalogue/declaration.go index 3e812b7..ab5ab85 100644 --- a/internal/catalogue/declaration.go +++ b/internal/catalogue/declaration.go @@ -596,6 +596,13 @@ func composeName(values map[string]any, publicDomain string) { if !ok || strings.TrimSpace(label) == "" { return } + if strings.TrimSpace(label) == "@" { + // The apex: a module served at the bare public domain, no subdomain — the zone-file + // convention `@`. Composes to the domain itself, so a node's own site is a label like any + // other rather than the one route that must still carry a full name. + values["name"] = publicDomain + return + } values["name"] = strings.TrimSpace(label) + "." + publicDomain } diff --git a/internal/catalogue/routing_test.go b/internal/catalogue/routing_test.go index 08e57a1..f2a4fe4 100644 --- a/internal/catalogue/routing_test.go +++ b/internal/catalogue/routing_test.go @@ -48,6 +48,22 @@ func TestALabelComposesWithTheNodesPublicDomain(t *testing.T) { } } +func TestTheApexLabelComposesToTheBareDomain(t *testing.T) { + got, err := Resolve(shelf(proxy(), labelled("board", "@", 4000)), + []string{"board"}, withDomain("example.tld"), World{}) + if err != nil { + t.Fatal(err) + } + given := received(t, mustDeclare(t, got)) + if len(given) != 1 { + t.Fatalf("the proxy was told about %d of 1: %v", len(given), given) + } + // `@` is the zone-file apex: served at the bare public domain, no subdomain, no leading dot. + if given[0].Values["name"] != "example.tld" { + t.Fatalf("the apex label did not compose to the bare domain: %v", given[0].Values) + } +} + func TestOneNodeSettingMovesTheCatalogueBetweenDomains(t *testing.T) { // The ADR's name-agnostic check: the same catalogue resolves against two different public // domains by changing one node setting and nothing else.