ADR-0017: Remove the Go implementation, and publish the documentation through GitLab Pages
Status: accepted · Date: 2026-10-13 · Decision makers: James Hebden
Context and Problem Statement
For two weeks this repository held two implementations of one tool: the Go program it forked from (368 source files under cmd/ and internal/, plus its documentation, Hugo site, integration tests, and CI) and the Rust workspace that replaces it. The project is meant to be public, and the Go side was the wrong thing to show. Its documentation named the wrong binary, its CI exercised the wrong program, and its configuration pointed at GitLab-internal templates and chat channels. The Rust workspace had also ported every Go behaviour it intended to port, and its parity tests were already in crates/.
The documentation needed a public home. The Hugo site that published the Go documentation had been replaced by the mdBook in ADR-0010, and nothing published it.
Decision Drivers
- A public repository should describe the program it contains
- The Go behaviour is the specification the Rust code was ported against, so it has to remain findable
- No scenario coverage should vanish silently
- The pipeline should check what’s in the tree: Rust, the examples, the book, and the dependencies
- Documentation errors should fail a merge request, not a deployment
Considered Options
- Remove the Go source, documentation, tooling, and CI; keep the Rust workspace, the schema, and the examples; pin an upstream commit as the reference; publish the book through a GitLab Pages job
- Keep the Go source in the tree as a parity reference, and remove only its documentation and CI
- Move the Go source to a branch or a second repository
- Keep everything and mark the Go side as legacy
Decision Outcome
Chosen option: “Remove everything Go, pin an upstream commit, publish through GitLab Pages”. The Go source is already in the project’s history and in the upstream repository, which is public; keeping a second copy in the working tree would mean carrying code nothing builds or tests. Upstream commit fa1a2d1e is the last state before the Rust workspace was added, so it’s the reference for every “Ported from” comment and PORT_NOTES.md entry. Options 2 and 4 keep the problem; option 3 adds a place to maintain.
What was removed: cmd/, internal/, main.go, the Go module files and tooling configuration (golangci-lint, goreleaser, mockery, semantic-release), the Dockerfiles, the Hugo site and the docs/ it published, and the GitLab-internal template and review-automation configuration (Copier answers, Renovate presets, Duo instructions, and the shared CI components).
What was kept: the Rust workspace, schema/ (embedded by xianyun-core), examples/ (validated in CI), the Nix flake and VM tests, and the scripts for the documentation.
The content in the removed documentation that still applies to Xianyun was rewritten into the book, and each page was checked against the binary: composition, lifecycle hooks, Linux and Podman setup, troubleshooting and resets, use cases, and the architecture page. The decisions in the old decision log and in the registry-cache design became ADR-0011 through ADR-0016.
The pipeline is in .gitlab-ci.yml. Every job runs inside nix develop, so the toolchain is the one pinned by flake.lock. The docs job builds the whole site (regenerated command reference, mdBook, link check, rustdoc with warnings denied) on merge requests and on the default branch and keeps it as an artifact. The pages job runs on the default branch only and publishes that artifact. That split follows the pattern in GitLab’s hardened-builds project: the site is built and checked before anything is deployed, and the deploy job only moves files into place. A scheduled pipeline runs cargo deny alone, because advisories appear without a code change.
Consequences
Good:
- The repository contains one implementation, and its documentation describes it
- A broken link, a stale command reference, or a rustdoc warning fails the merge request
- Dependency policy is checked:
deny.tomlenforces licenses, advisories, and sources, and records the two accepted advisories with reasons
Bad:
- The Go integration suites are gone. They drove the Go binary against real clusters and covered scenarios with no Rust equivalent yet: dev CA drift, multiple environments from sibling directories, the mirrord reloader (with and without a project file), the registry cache in bring-your-own mode, bundled ingress, and basic bring-up. Deployers can’t run in Xianyun yet (GAP-001), so those suites couldn’t pass against it anyway. Each scenario is recorded in the specification’s backlog and is to be rebuilt as a NixOS VM test. The eighth suite, which validated every example configuration, needs no cluster and was replaced by
scripts/validate-examples.sh. - The pipeline’s end-to-end coverage is thinner than the Go project’s: the unit suite, the example validation, and two NixOS VM tests, one of which needs KVM and runs manually
- Anyone who wants the Go source has to look it up upstream. The pinned commit is linked from the README and
AGENTS.md. - Several
PORT_NOTES.mdfiles still mention Go test names and file paths that are no longer in the tree
Neutral:
- The Hugo site is gone, along with its theme submodule. Pages for GitLab’s published documentation moved to the book.
- Publishing is by GitLab Pages, so the site’s address depends on the project path
Implementation Location
.gitlab-ci.ymlscripts/build-docs.shscripts/validate-examples.shdeny.tomlbook/book.toml
More Information
- Recorded on 2026-10-13, in the same change that removed the Go tree.
- Update 2026-10-14: deployers now work (GAP-001 closed), and five of the seven scenarios were rebuilt as NixOS VM tests (ADR-0019). The two that need edit mode remain.
- Related: ADR-0002, ADR-0010, Building the documentation.