Status
PROPOSED (2026-10-28). Operator directive: “let’s build a nix expression for vespa”.
Verification result and decision rationale below.
Context
The garden needs host-native compile_commands.json for the registered clangd-mcp
(workspace override: CLANGD_PATH=/opt/homebrew/opt/llvm/bin/clangd,
COMPILE_COMMANDS_DIR=${workspaceFolder}/build). Direct cmake configuration on macOS
failed twice (GTest missing, then dist/vtag.map missing -> bootstrap.sh required).
Vespa’s own vespa-3rdparty-deps is an RPM/Copr Linux-only distribution.
Constraint scan (2026-10-28):
find_package()audit of the vespa tree: external C++ deps are exactly OpenSSL, RE2,
Protobuf, LLVM (CONFIG), ICU, GTest, FLEX, BISON (+system Threads). Vespa vendors the
rest — the monster-dep scenario does not exist.- Java side: Maven (wrapper pins 3.9.16), JDK 17 (
parent/pom.xml<release>17</release>),
bootstrap.shdefault mode builds only the minimal Java modules CMake needs. - No nix expression for the Vespa engine exists anywhere (nixpkgs ships only
vespa-cli,
a Go tool via buildGoModule; zero .nix files in vespa-engine/vespa). A workspace flake
would be the first. - Docker Desktop is installed;
docker-image-dev/dev/almalinux-9builds FROM
vespaengine/vespa-build-almalinux-9:latest— Vespa’s own supported build env.
Decision
- Author
flake.nix(workspace root, outside the upstream
clone — no pull conflicts): a dev-shell flake pinning cmake/ninja, clang 19 (C++ 23),
the eight external C++ deps, JDK 17 + maven, anduv.flake.lockpins the world. - Docker remains the parity/reference environment (
vespa-build-almalinux-9):
authoritative for “does upstream CI green-flag this”, used when Nix and CI disagree. - compile_commands.json policy: generate on the host inside the Nix shell
(nix develop -c bash -c 'cd vespa && ./bootstrap.sh && cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON'), copy tobuild/compile_commands.jsonwhere the
registered clangd-mcp reads it. Container-generated compile commands are not consumed
by host clangd (compiler-path mismatch, arch mismatch on Apple Silicon). - If the Nix shell reveals Linux-only assumptions in Vespa’s own C++ code, those become
documented upstream findings (contradiction register or upstream issue), not silent
patches — pristine-upstream rule (INV-008 spirit).
Consequences
- Host clangd gains real compile_commands for the C++ tree (the ADR-0003-era gap closes).
- We accept ownership of one flake + lockfile; dep bumps track Vespa releases manually
(nix flake update+ re-run configure), with Docker as the arbiter on drift disputes. - First Nix evaluation downloads nixpkgs; first bootstrap downloads the Maven world —
both cached afterwards. - macOS platform bugs in Vespa C++ code, if any, are out of scope for the flake and get
filed upstream rather than patched locally.
Pros/cons record (operator-requested)
| Nix dev-shell | Docker reference | |
|---|---|---|
| Setup | 70-line flake, written once | none (pull image) |
| Parity | we own drift | exact CI parity |
| host clangd compile_commands | native paths, no rewriting | container compiler paths mismatch host clangd; arch mismatch on Apple Silicon |
| daemon | none | Docker Desktop resident |
| reproducibility | flake.lock, reviewable diffs | :latest tag drift (pin digest to fix) |
| scope | one shell serves vespa/pyvespa/garden | per-project containers |
| upstreamability | first-mover flake could be PR’d to vespa-engine | nothing to upstream |
Verification
nix develop ... -c bash -c 'cd vespa && ./bootstrap.sh && cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON'must end withbuild/compile_commands.jsonon the
host (test running at time of writing; outcome recorded in ledger).- clangd-mcp resolves a symbol in
vespa/searchlib/...using the generated database.