The package used to fetch the Agent-Field/furrow release asset and stage it for
go:embed, which is what `make build` does. Those bytes are a stock glibc build
that no Nix phase ever touched, so the copy codeaf writes out to
~/.codeaf/bin/furrow-0.1.0 cannot start here: NixOS answers "Could not start
dynamically linked executable" and names stub-ld. Every furrow verb the package
offers was dead with it.
Staging a rebuilt furrow was not an option. Upstream's fetcher hashes what it
stages against internal/furrowbin/pin.json and refuses anything else, and
patching the downloaded asset changes its hash. So this stages nothing, and
./furrow.nix builds the pinned version from source instead. The wrapped codeaf
passes it through CODEAF_FURROW, which internal/furrow reads before it looks at
the embedded copy, so the go binary carries no furrow at all (63 MB, was 67 MB)
and nothing unpatched is written to the state root.
furrow is Rust, not Go, and rusqlite bundles sqlite, hence the build time. Its
test suite wants a filesystem that supports user.* xattrs; the sandbox /tmp is
tmpfs and answers EOPNOTSUPP, which takes out the fixture of all 54 cli tests at
tests/cli.rs:48 and one lib test with it. The unit tests run, minus that one.
Verified with nix build .#codeaf: `codeaf --version` reports 0.7.1, the wrapper
sets CODEAF_FURROW to the store furrow, that furrow prints `furrow 0.1.0`
against store glibc, and it sits in the codeaf output's references so a gc
cannot pull it out from under the wrapper. Not verified on darwin, no builder.
Refs nix-overlay-bju
CodeAF (Agent-Field/CodeAF) is a Go coding harness that ships one binary.
Pinned to v0.7.1; the flake's nixpkgs already carries go 1.26.7 and go.mod
asks for 1.26.5, so no extra nixpkgs input is needed.
Two things about this build are not obvious from the derivation:
- `make build` runs two host-side steps before compiling: `go generate
./internal/manual` packs the built-in manual into the pages.pack.gz and
chat.pack.gz that the codeaf_packed_manual tag embeds, and
internal/furrowbin/cmd/fetch stages the pinned Agent-Field/furrow release
into internal/furrowbin/cache for go:embed. Both are run in preBuild with
GOOS/GOARCH unset, the way the Makefile does it, so a cross build does not
try to run a target binary on the build machine. buildGoModule runs preBuild
in the vendoring derivation as well, before vendor/ exists and before the
dependencies are in reach, so the two steps are gated on vendor/.
- The furrow step gets its bytes from fetchurl and `-from`, the offline road
upstream documents. The fetcher still checks the sha256 in
internal/furrowbin/pin.json, so the hashes here duplicate a pin that is
already in the source; drop the furrow entirely and codeaf still builds and
falls back to looking for the binary on PATH.
Tests are off: the upstream suite is a make/CI matrix with network and timing
assumptions, not a `go test ./...` that fits buildGoModule.
Verified with nix build .#codeaf, `codeaf --version` reporting 0.7.1 and
`codeaf manual` listing the packed manual pages.
Refs nix-overlay-m5y