From becf3043e3f858c2b8f6f313dd8ff2a0cb3877c9 Mon Sep 17 00:00:00 2001 From: Admin <1+admin@noreply.git.dcntrlized.org> Date: Sun, 16 Aug 2026 17:18:16 +0100 Subject: [PATCH] fix(registry): dev never falls back to the public registry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BaseURL() in dev mode used to silently fall back to https://git.dcntrlized.org when DCNTRLIZED_GITEA_URL was unset — a dev Maestro could resolve installs and infra from the wrong (and cred-less) registry. Dev now uses the debug registry exclusively; an unset URL returns '' so registry ops fail loudly. Locked with a BaseURL seam test. --- src/lib/registry/registry.go | 8 ++++++-- src/lib/registry/registry_test.go | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/lib/registry/registry.go b/src/lib/registry/registry.go index ccde62e..d040a91 100644 --- a/src/lib/registry/registry.go +++ b/src/lib/registry/registry.go @@ -42,13 +42,17 @@ import ( ) // BaseURL returns the Gitea instance base URL (scheme://host[:port]). -// Production defaults to git.dcntrlized.org; dev mode (DCNTRLIZED_DEV=true) -// overrides it with DCNTRLIZED_GITEA_URL when set. +// Production defaults to git.dcntrlized.org. Dev mode (DCNTRLIZED_DEV=true) +// uses DCNTRLIZED_GITEA_URL (the debug registry) exclusively and never falls +// back to the public one; when the dev URL is unset it returns "" so callers +// fail loudly instead of silently talking to the wrong registry. func BaseURL() string { if env.IsDev() { if u := strings.TrimRight(env.GiteaURL(), "/"); u != "" { return u } + logger.Warn("registry: DCNTRLIZED_DEV=true but DCNTRLIZED_GITEA_URL is unset — refusing to fall back to the public registry") + return "" } return "https://git.dcntrlized.org" } diff --git a/src/lib/registry/registry_test.go b/src/lib/registry/registry_test.go index cc7b14a..3b98cf1 100644 --- a/src/lib/registry/registry_test.go +++ b/src/lib/registry/registry_test.go @@ -50,3 +50,24 @@ func TestItemByNameLive(t *testing.T) { t.Logf("resolved %s -> image=%s url=%s version=%s", name, item.Image, item.URL, item.Version) } } + +// TestBaseURLNeverFallsBackToPublicInDev locks the dev registry seam: with +// DCNTRLIZED_DEV=true Maestro must talk to the debug registry +// (DCNTRLIZED_GITEA_URL) only — an unset dev URL yields "" (loud failure), +// never the public git.dcntrlized.org. +func TestBaseURLNeverFallsBackToPublicInDev(t *testing.T) { + t.Setenv("DCNTRLIZED_DEV", "true") + t.Setenv("DCNTRLIZED_GITEA_URL", "http://192.168.122.183:3000") + if got := BaseURL(); got != "http://192.168.122.183:3000" { + t.Fatalf("dev with DCNTRLIZED_GITEA_URL: got %q", got) + } + t.Setenv("DCNTRLIZED_GITEA_URL", "") + if got := BaseURL(); got != "" { + t.Fatalf("dev without DCNTRLIZED_GITEA_URL must not fall back to public, got %q", got) + } + t.Setenv("DCNTRLIZED_DEV", "") + t.Setenv("DCNTRLIZED_GITEA_URL", "http://192.168.122.183:3000") + if got := BaseURL(); got != "https://git.dcntrlized.org" { + t.Fatalf("production must use the public registry, got %q", got) + } +}