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.sh default 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-9 builds FROM
    vespaengine/vespa-build-almalinux-9:latest — Vespa’s own supported build env.

Decision

  1. 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, and uv. flake.lock pins the world.
  2. Docker remains the parity/reference environment (vespa-build-almalinux-9):
    authoritative for “does upstream CI green-flag this”, used when Nix and CI disagree.
  3. 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 to build/compile_commands.json where the
    registered clangd-mcp reads it. Container-generated compile commands are not consumed
    by host clangd (compiler-path mismatch, arch mismatch on Apple Silicon).
  4. 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-shellDocker reference
Setup70-line flake, written oncenone (pull image)
Paritywe own driftexact CI parity
host clangd compile_commandsnative paths, no rewritingcontainer compiler paths mismatch host clangd; arch mismatch on Apple Silicon
daemonnoneDocker Desktop resident
reproducibilityflake.lock, reviewable diffs:latest tag drift (pin digest to fix)
scopeone shell serves vespa/pyvespa/gardenper-project containers
upstreamabilityfirst-mover flake could be PR’d to vespa-enginenothing to upstream

Verification

  • nix develop ... -c bash -c 'cd vespa && ./bootstrap.sh && cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON' must end with build/compile_commands.json on the
    host (test running at time of writing; outcome recorded in ledger).
  • clangd-mcp resolves a symbol in vespa/searchlib/... using the generated database.