fix: harden cloud agent bootstrap\n\nStart Nix during bootstrap, gate tracker mutations on a valid bd pin, and fail when required Nix setup fails.\n\nPosted-by: ChatGPT (GPT-5.6 Sol)

This commit is contained in:
Ed Langley
2026-09-25 18:54:09 -07:00
parent 114bdd11e0
commit 58cc47c480
+91 -26
View File
@@ -36,22 +36,74 @@ cd "$ROOT" || exit 0
log() { printf '[agent-bootstrap] %s\n' "$*"; }
nix_status=0
ensure_nix_daemon() {
command -v nix >/dev/null 2>&1 || return 1
# Single-user Nix does not need a daemon; multi-user/cloud installs do.
# If the store already answers, leave the environment alone.
if command -v nix-store >/dev/null 2>&1 && nix-store --ping >/dev/null 2>&1; then
return 0
fi
if ! command -v nix-daemon >/dev/null 2>&1; then
log "ERROR: Nix is installed, but the store is unavailable and nix-daemon is not on PATH"
return 1
fi
log "starting nix-daemon for bootstrap…"
nix-daemon >/tmp/nix-daemon.log 2>&1 &
# The daemon is started asynchronously; wait briefly for its socket before
# invoking the seed/build steps that depend on it.
for _ in {1..50}; do
if command -v nix-store >/dev/null 2>&1 && nix-store --ping >/dev/null 2>&1; then
return 0
fi
sleep 0.1
done
log "ERROR: nix-daemon did not become ready; see /tmp/nix-daemon.log"
return 1
}
# Start the daemon during cloud-agent installation, before any required Nix
# operation. This is harmless for single-user Nix because nix-store --ping
# succeeds without starting a daemon.
if [ "$SKIP_NIX_SEED" -eq 0 ] || [ "$SKIP_CARGO_WARM" -eq 0 ]; then
if ! ensure_nix_daemon; then
nix_status=1
fi
fi
# ── 0. Seed nix flake inputs (required for cloud environments) ─────────────
# GitHub tarball endpoints are blocked in cloud containers. This seeds the
# flake inputs over git so `nix develop` can build the dev shell.
if [ "$SKIP_NIX_SEED" -eq 0 ] && command -v nix >/dev/null 2>&1; then
# Set SSL cert for proxy environments
if [ -z "${NIX_SSL_CERT_FILE:-}" ] && [ -r /root/.ccr/ca-bundle.crt ]; then
export NIX_SSL_CERT_FILE=/root/.ccr/ca-bundle.crt
fi
if [ -f "$ROOT/scripts/nix-seed-flake-inputs.sh" ]; then
log "seeding nix flake inputs (GitHub tarballs blocked in cloud)…"
if "$ROOT/scripts/nix-seed-flake-inputs.sh" >/tmp/nix-seed.log 2>&1; then
log "flake inputs seeded"
if [ "$SKIP_NIX_SEED" -eq 0 ]; then
if [ "$nix_status" -ne 0 ]; then
log "ERROR: cannot seed flake inputs because Nix is unavailable"
elif ! command -v nix >/dev/null 2>&1; then
log "ERROR: nix not available; required flake input seeding cannot run"
nix_status=1
else
# Set SSL cert for proxy environments
if [ -z "${NIX_SSL_CERT_FILE:-}" ] && [ -r /root/.ccr/ca-bundle.crt ]; then
export NIX_SSL_CERT_FILE=/root/.ccr/ca-bundle.crt
fi
if [ ! -f "$ROOT/scripts/nix-seed-flake-inputs.sh" ]; then
log "ERROR: required scripts/nix-seed-flake-inputs.sh is missing"
nix_status=1
else
log "WARNING: nix-seed-flake-inputs.sh failed; see /tmp/nix-seed.log"
log " 'nix develop' may fail. Check network/proxy settings."
log "seeding nix flake inputs (GitHub tarballs blocked in cloud)…"
if "$ROOT/scripts/nix-seed-flake-inputs.sh" >/tmp/nix-seed.log 2>&1; then
log "flake inputs seeded"
else
log "ERROR: nix-seed-flake-inputs.sh failed; see /tmp/nix-seed.log"
log " 'nix develop' is not validated for this session."
nix_status=1
fi
fi
fi
fi
@@ -173,14 +225,18 @@ if [ -n "${AGENT_ENV_FILE:-${CLAUDE_ENV_FILE:-}}" ]; then
echo 'export PATH="$PATH:/root/go/bin:$HOME/go/bin"' >> "$env_file"
fi
command -v bd >/dev/null 2>&1 && bd metrics off >/dev/null 2>&1
if [ "$pin_status" -eq 0 ]; then
assert_bd_pin || pin_status=2
fi
# Do not run any tracker/config mutation through a bd binary whose version does
# not match the repository pin.
if [ "$pin_status" -eq 0 ] && command -v bd >/dev/null 2>&1; then
bd metrics off >/dev/null 2>&1 || true
fi
# ── 3. Sync the issue tracker from the Dolt remote ─────────────────────────
if command -v bd >/dev/null 2>&1; then
if [ "$pin_status" -eq 0 ] && command -v bd >/dev/null 2>&1; then
DB_NAME="$(jq -r '.dolt_database // "improvise"' .beads/metadata.json 2>/dev/null || echo improvise)"
ORIGIN="$(git remote get-url origin 2>/dev/null || true)"
case "$ORIGIN" in
@@ -224,18 +280,23 @@ fi
# ── 4. Warm the build inside nix develop (optional) ────────────────────────
# Uses nix develop to ensure the correct toolchain (rust from flake, wasm target, etc.)
if [ "$SKIP_CARGO_WARM" -eq 0 ] && command -v nix >/dev/null 2>&1; then
log "warming cargo build inside nix develop…"
NIX_FLAGS=(--extra-experimental-features 'nix-command flakes')
if nix "${NIX_FLAGS[@]}" develop --command cargo build --workspace --tests >/tmp/cargo-warm.log 2>&1; then
log "workspace built (nix develop toolchain)"
if [ "$SKIP_CARGO_WARM" -eq 0 ]; then
if [ "$nix_status" -ne 0 ]; then
log "ERROR: skipping required cargo warm because Nix bootstrap already failed"
elif ! command -v nix >/dev/null 2>&1; then
log "ERROR: nix not available; required cargo warm cannot run"
nix_status=1
else
log "WARNING: cargo build failed; see /tmp/cargo-warm.log"
log " This may indicate nix-seed failed or flake inputs are missing."
log "warming cargo build inside nix develop…"
NIX_FLAGS=(--extra-experimental-features 'nix-command flakes')
if nix "${NIX_FLAGS[@]}" develop --command cargo build --workspace --tests >/tmp/cargo-warm.log 2>&1; then
log "workspace built (nix develop toolchain)"
else
log "ERROR: cargo build failed; see /tmp/cargo-warm.log"
log " Required nix develop validation failed."
nix_status=1
fi
fi
elif [ "$SKIP_CARGO_WARM" -eq 0 ]; then
log "WARNING: nix not available; skipping cargo warm"
log " Install nix or use a container with nix for this repo."
fi
# ── 5. Environment notes ───────────────────────────────────────────────────
@@ -252,4 +313,8 @@ cat <<'NOTES'
• Run commands inside `nix develop` or prefix with `nix develop --command`.
NOTES
exit "$pin_status"
exit_status="$nix_status"
if [ "$pin_status" -ne 0 ]; then
exit_status="$pin_status"
fi
exit "$exit_status"