Go

1. What's in the catalogue

Two published lines, 1.26.7 and 1.27.0; pin with @1.26 or @1.27. (Line 1.26.6 was retired from the catalogue — kapsl --info go prints the lines that are live.) As of catalogue 2026.35.22 (2026-08-25):

ToolCapsRequiresNotes
gonet, rwtoolchain; rw because a build tool produces output, net because modules fetch
gofmtrwthe formatter

Nothing declared-not-published here. No gopls in the catalogue — editor integration is the IDE use case's.

2. The five-minute version

kapsl go version
go version go1.27.0 linux/arm64

linux/arm64 on a macOS host is the whole story in one line: there is no Go toolchain on this machine at all.

Build and run a scratch module (go.mod + main.go):

kapsl go run .
Hello from Go

No flags. A stdlib-only module fetches nothing, so net goes unused; a module with dependencies uses it on the first build.

3. The environment story: what go build produces

Go is a compiled language, so the catalogue's measured ABI pin applies: each image's C-library floor is measured at index-build time, never declared. The more visible consequence for Go is what the output is: kapsl go build produces a Linux executable, because the toolchain ran on Linux. The go-simple example checks the output with file:

hello: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, Go BuildID=…

Go links statically by default, so on a Linux host the built binary runs natively — no kapsl, no sandbox. On a macOS or Windows host it is the wrong kind of binary entirely (zsh: exec format error), and kapsl ./hello keeps the prefix forever. That is usually what you want — you are building the thing you deploy — but it is a deliberate consequence, not an accident.

If you want a host-native binary, cross-compile and say so:

kapsl -E GOOS=darwin -E GOARCH=arm64 go build -o hello-darwin .

That binary then runs on your host directly — outside kapsl, with all of your own privileges, like any other program you built.

4. Tooling

gofmt is published (rw, no network):

kapsl gofmt -l .

No gopls, no staticcheck in the catalogue. The IDE use case covers the editor-side story; gopls running against a mounted workspace is the same pattern as the other language servers.

5. Project patterns

  • go-simple — all three levels of integration, with the full toolchain-vs-built-binary treatment: two subcommand indices in one overlay (go keys on index 2, because serve sits after run .; the ./hello path key keeps the default 0), a path key (./hello) in the project config with its own port and args, the shim level for the toolchain, the cross-compile recipe above, and the --install ./hello error.

The overlay from that example carries both ways of starting the same program:

tools:
  go:
    subcommand_index: 2
    subcommands:
      serve:
        ports: ["8080"]
        args: ["-addr", "0.0.0.0:8080"]

  ./hello:
    capabilities: [rw]
    subcommands:
      serve:
        ports: ["8080"]
        args: ["-addr", "0.0.0.0:8080"]
  SECURITY  .kapslrc declares a project overlay
            ./hello: +rw, port(serve) 8080, args(serve) -addr 0.0.0.0:8080
            go: port(serve@arg2) 8080, args(serve@arg2) -addr 0.0.0.0:8080

port(serve@arg2) versus a bare port(serve) — the @argN suffix appears only when the index isn't the default. A key that matches nothing is silently inert, so that review line is where to look when a port isn't being published.

6. Known limitations

  • The binary can't be shimmed. A shim is a symlink in ~/.local/bin named after a PATH-stable tool name; ./hello means something different from every directory, so there is nothing coherent to install:

    kapsl --install ./hello
    ERROR  --install doesn't apply to a path ('./hello') -- shims are for named tools
  • On non-Linux hosts, the built binary needs the prefix forever. kapsl go build outputs a Linux executable; running it bare fails with an exec format error, and kapsl ./hello stays the invocation. On a Linux host the bare binary runs natively with no sandbox at all — a different trade-off worth being deliberate about.

  • The example transcripts predate line 1.27. go-simple was captured on go1.26.5; the shapes it demonstrates (indices, path keys, ports) are unchanged on the current lines.