ADR 0033 - Distribution homes to cheshirecube; GitHub deferred

  • Status: Accepted (2026-08-17)
  • Date: 2026-08-17
  • Tracking: #421 (serves #420)

Context

ADR 0032 split two roles. cheshirecube (git.cheshirecube.cloud/sixfold-space/madtea) was the canonical source home. GitHub (github.com/sixfold-space) was the public distribution edge: release binaries, the curl installer, the self-updater download base, the Homebrew tap, the Scoop bucket, the plugin marketplace, and the go-get source. The import path was the vanity domain madtea.lol. PR #382 built that GitHub edge into .goreleaser.yaml, scripts/release.sh, and the self-updater.

The split showed strain at once. Our Forgejo repos are SHA-256. GitHub is SHA-1 only, so it cannot host the canonical repository. ADR 0032’s amendment (2026-08-16) replaced the push mirror with a one-way SHA-1 synced copy (git fast-export | git fast-import), a cheshirecube CI job on each push and tag, and a runbook (docs/contributing/github-source-sync.md). That is a standing maintenance cost: a sync job, unsigned mirror commits, and a second publish token.

Two forces now favour collapsing the edge back onto cheshirecube.

  1. One client (ADR 0017). madtea targets one standard Gitea API v1 behind one gitea.Client, with no per-platform branching. A GitHub distribution edge grows GitHub-specific plumbing (the GoReleaser GitHub provider, a GITHUB_TOKEN, and a sync job) around an otherwise pure Gitea client.
  2. Reach does not require GitHub to host the artifacts. Corporate networks allowlist github.com more reliably than a new self-hosted host. But go install madtea.lol/cmd/madtea@latest resolves through proxy.golang.org, which fetches the source server-side. The user’s machine contacts only the Go proxy for that channel.

The forge is IP-whitelist-gated today, not yet fully public. So proxy.golang.org cannot reach it yet. That is a temporary state. A temporary install note handles it. It is not a reason to keep GitHub in the design.

Decision

Distribution homes to git.cheshirecube.cloud/sixfold-space/madtea. GitHub is fully deferred. madtea stays a single Gitea/Forgejo API client (ADR 0017).

  • Distribution home. Releases, the curl installer base, the self-updater download base, the Homebrew tap, the Scoop bucket, and the Claude Code plugin marketplace all live under cheshirecube (sixfold-space). GoReleaser publishes through its Gitea provider (gitea_urls plus a Gitea/Forgejo token), not the GitHub provider.
  • Import identity is unchanged. The module path stays the vanity domain madtea.lol. The go-import meta tag on madtea.lol points Go straight at https://git.cheshirecube.cloud/sixfold-space/madtea.git. The meta tag is served by the separate madtea-site deploy, not by this repository.
  • go install madtea.lol/cmd/madtea@latest resolves directly from cheshirecube. proxy.golang.org fetches the vanity meta and clones cheshirecube server-side.
  • Temporary GOPRIVATE requirement. While the forge is IP-whitelist-gated, proxy.golang.org cannot reach it. A direct go install then needs GOPRIVATE=madtea.lol, so Go fetches from the user’s own whitelisted network instead of the proxy. This requirement is temporary. It is removed when the forge is fully public. It is a documented install note, not a permanent part of the design.
  • No GitHub REST path. ADR 0017 is preserved. madtea never grows an api.github.com client. The rejected option (a) stays rejected.
  • The self-updater trust model is unchanged (ADR 0012). Only its fetch target moves from GitHub to cheshirecube. Releases stay GPG-signed. madtea update still verifies checksums.txt.asc against the key embedded in the running binary. The embedded verify-key fingerprint is unchanged and is never a flag or a manifest value.

Supersession

This ADR reverses ADR 0032’s distribution edge decision. It preserves the rest of ADR 0032.

Preserved from ADR 0032:

  • Canonical source home = cheshirecube. Distribution now joins it.
  • Import identity = the vanity domain madtea.lol, decoupled from the forge. This decoupling is exactly what lets distribution rehome with zero import churn.

Reversed by this ADR:

  • GitHub is no longer the distribution edge. Every channel a user’s machine fetches directly (releases, the installer, the self-updater, the tap, the bucket, the marketplace, and the go-get source) now resolves from cheshirecube, not github.com.
  • The SHA-1 GitHub synced copy leaves the release path. ADR 0032’s amendment and docs/contributing/github-source-sync.md are parked, not run. That doc is re-labelled a parked fallback: a SHA-1 GitHub mirror to reconsider only if a vanilla go install fails once the forge is fully public. #386 (the sync work) stays open, not closed.

ADR 0032’s Status line points forward to this ADR. The bodies of both are preserved, per the ADR immutability convention.

Consequences

  • One forge, one client. All distribution plumbing speaks the Gitea API. There is no GoReleaser GitHub provider, no GITHUB_TOKEN, and no fast-export sync job in the release path. This restores the ADR 0017 single-client shape end to end.
  • Reach is narrower until full-public. A corporate proxy that allowlists github.com but not cheshirecube cannot reach a direct download while the forge is whitelist-gated. The go install path then needs GOPRIVATE=madtea.lol. This is accepted as a temporary launch-window cost. The GitHub fallback (#386) is parked, not deleted, in case reach forces its return after full-public.
  • A future rehome is a config edit. Portable identity is centralized (the project-identity.env manifest plus internal/meta). Moving forges again changes values in one place, not through a code sweep.
  • The next release tag carries the madtea.lol module path from cheshirecube. The current latest tag (v0.18.3) still declares the old module path and is unaffected. Earlier tags keep their old path, because Go reads the module path from go.mod at the requested tag.

Alternatives considered

  • (a) Grow a GitHub REST / api.github.com client path. Rejected. It breaks ADR 0017’s single-standard-Gitea-client rule and adds the per-platform branching the architecture avoids.
  • (b) Keep ADR 0032’s GitHub distribution edge with the SHA-1 synced copy. Rejected. It carries a standing maintenance cost (a sync job, unsigned mirror commits, a second token, and a runbook) for a reach benefit that a temporary GOPRIVATE note covers during the whitelist window. The copy is parked as a fallback (#386), not run.
  • (c) Home distribution and the self-updater to cheshirecube. CHOSEN. It keeps madtea a single Gitea client, removes the GitHub plumbing, and pays only a temporary GOPRIVATE cost while the forge is whitelist-gated.

Relates to ADR 0032 (supersedes its distribution-edge decision; its source-home and vanity-path decisions are preserved), ADR 0010 (release-and-install model unchanged; the artifact host moves to cheshirecube), ADR 0012 (self-updater trust model unchanged; the fetch target moves to cheshirecube), ADR 0017 (single standard Gitea client preserved; no GitHub REST path), and ADR 0025 (origin-first forge resolution, still resolving from the checkout’s own origin).

Canonical source: docs/adr/0033-cheshirecube-distribution-home.md in the madtea repo.