Problem
Every shipping build of Arc sets -tags=duckdb_arrow (Makefile GOFLAGS, Dockerfile, .github/workflows/release-build.yml), so production runs the Arrow code path. But a bare go build ./... / go test ./... from a developer shell — or any tooling that doesn't pass the tag — silently compiles the non-Arrow path instead. The default developer/test experience exercises code that is not what ships.
This is a real foot-gun, not hypothetical. In PR #489 (SHOW-command RBAC gating), the executeQueryArrow handler (internal/api/query_arrow.go, //go:build duckdb_arrow) was missing the SHOW gate that the JSON and MsgPack endpoints had. A default go test ./... could not catch it because the file isn't compiled without the tag — it was found only by an internal review that explicitly built with -tags=duckdb_arrow. The Arrow path can rot undetected.
Note: make test does pass the tag (GOFLAGS=-v -tags=duckdb_arrow), so the Makefile path is correct. The gap is everything that runs go test directly (contributors, IDE test runners, ad-hoc CI steps, review agents).
Preferred fix: drop the build tag entirely
Per the prior decision (2026-05-12), the recommended approach is to remove //go:build duckdb_arrow and make Arrow unconditional, rather than teach every tool to pass the tag. Every production build already requires it; the opt-out path is effectively dead.
Files to change (verified present):
internal/database/duckdb_arrow.go — strip //go:build duckdb_arrow
internal/api/query_arrow.go — strip the tag
internal/api/query_arrow_json.go — strip the tag
internal/api/query_arrow_json_test.go — strip the tag
internal/api/query_msgpack_test.go — strip the tag (also tag-gated)
internal/api/query_arrow_stub.go (//go:build !duckdb_arrow, the no-op executeQueryArrow) — delete
internal/database/ — check for a !duckdb_arrow stub counterpart to duckdb_arrow.go and delete it too
Then -tags=duckdb_arrow in Makefile / Dockerfile / release-build.yml is harmless to leave or can be dropped.
The blocker that deferred this (PR #434, arcx loader) merged on 2026-05-13, so it's unblocked.
Acceptance criteria
Scope / risk
Developer-experience + test-coverage hardening; no functional change to shipped behavior (production already builds with the tag). ~10–15 line diff plus two file deletions. Separate PR, not bundled with feature work, so the build-constraint change has its own git blame.
Problem
Every shipping build of Arc sets
-tags=duckdb_arrow(MakefileGOFLAGS,Dockerfile,.github/workflows/release-build.yml), so production runs the Arrow code path. But a barego build ./.../go test ./...from a developer shell — or any tooling that doesn't pass the tag — silently compiles the non-Arrow path instead. The default developer/test experience exercises code that is not what ships.This is a real foot-gun, not hypothetical. In PR #489 (SHOW-command RBAC gating), the
executeQueryArrowhandler (internal/api/query_arrow.go,//go:build duckdb_arrow) was missing the SHOW gate that the JSON and MsgPack endpoints had. A defaultgo test ./...could not catch it because the file isn't compiled without the tag — it was found only by an internal review that explicitly built with-tags=duckdb_arrow. The Arrow path can rot undetected.Note:
make testdoes pass the tag (GOFLAGS=-v -tags=duckdb_arrow), so the Makefile path is correct. The gap is everything that runsgo testdirectly (contributors, IDE test runners, ad-hoc CI steps, review agents).Preferred fix: drop the build tag entirely
Per the prior decision (2026-05-12), the recommended approach is to remove
//go:build duckdb_arrowand make Arrow unconditional, rather than teach every tool to pass the tag. Every production build already requires it; the opt-out path is effectively dead.Files to change (verified present):
internal/database/duckdb_arrow.go— strip//go:build duckdb_arrowinternal/api/query_arrow.go— strip the taginternal/api/query_arrow_json.go— strip the taginternal/api/query_arrow_json_test.go— strip the taginternal/api/query_msgpack_test.go— strip the tag (also tag-gated)internal/api/query_arrow_stub.go(//go:build !duckdb_arrow, the no-opexecuteQueryArrow) — deleteinternal/database/— check for a!duckdb_arrowstub counterpart toduckdb_arrow.goand delete it tooThen
-tags=duckdb_arrowin Makefile / Dockerfile / release-build.yml is harmless to leave or can be dropped.The blocker that deferred this (PR #434, arcx loader) merged on 2026-05-13, so it's unblocked.
Acceptance criteria
go build ./cmd/... ./internal/...andgo test ./...from a clean checkout compile and run the Arrow path with no tag required.//go:build duckdb_arrow///go:build !duckdb_arrowpairs remain in the tree (grep -rn duckdb_arrow --include='*.go'returns nothing in build constraints).go vet ./...clean; existing Arrow + MsgPack tests run by default.executeQueryArrowafter deleting the stub (no duplicate-symbol build error).Scope / risk
Developer-experience + test-coverage hardening; no functional change to shipped behavior (production already builds with the tag). ~10–15 line diff plus two file deletions. Separate PR, not bundled with feature work, so the build-constraint change has its own git blame.