From 106d4fd3ac0cc8fcc2d7f308d216712500d17429 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 25 Sep 2026 19:20:34 +0000 Subject: [PATCH] feat: make nix develop the default toolchain path User ruling: agents must work inside nix develop (or direnv) for this repo. Bare system cargo that fails edition2024 is a misconfigured session. Changes: 1. scripts/agent-bootstrap.sh: - Added section 0: seed nix flake inputs automatically - Cargo warm now runs inside 'nix develop --command' - Added --skip-nix-seed flag for environments that don't need it - Updated environment notes to emphasize nix-first 2. .cursor/environment.json: - Removed --skip-cargo-warm (full nix-backed warm now default) 3. AGENTS.md: - Added 'Toolchain' row to multi-stack table (nix develop required) - Added 'Toolchain Requirement' subsection with usage examples - Updated local agents guidance to use 'direnv allow' 4. context/cloud-agents.md: - Bootstrap now lists nix-seed as step 1 - 'What does not work' table updated: bare system cargo now listed as failing; nix develop works after bootstrap - Updated nix section to reflect automatic seeding Previous soft gap: nix-seed was a manual footnote; now it runs in bootstrap. Co-authored-by: Ed Langley --- .cursor/environment.json | 2 +- AGENTS.md | 22 +++++++++++-- context/cloud-agents.md | 31 ++++++++++-------- scripts/agent-bootstrap.sh | 67 ++++++++++++++++++++++++++++---------- 4 files changed, 88 insertions(+), 34 deletions(-) diff --git a/.cursor/environment.json b/.cursor/environment.json index ad4d8ea5..8f01ff31 100644 --- a/.cursor/environment.json +++ b/.cursor/environment.json @@ -1,5 +1,5 @@ { "name": "Improvise", - "install": "./scripts/agent-bootstrap.sh --skip-cargo-warm", + "install": "./scripts/agent-bootstrap.sh", "start": "nix-daemon &" } diff --git a/AGENTS.md b/AGENTS.md index f47132cc..453143f3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -34,18 +34,34 @@ potentially others. All stacks share the same operational setup: | Component | Location | Notes | |---|---|---| +| Toolchain | `nix develop` / `direnv` | **Required.** Rust from flake, wasm target, beads pin, trealla | | Skills | `.agents/skills/` | Canonical source; `.claude/skills/` and `.cursor/skills/` symlink here | -| Session bootstrap | `scripts/agent-bootstrap.sh` | Stack-agnostic; installs bd, syncs tracker, warms cargo | +| Session bootstrap | `scripts/agent-bootstrap.sh` | Seeds nix inputs, installs bd, syncs tracker, warms cargo | | Knowledge base | `scripts/kb` | **All stacks use this**, not Prolog MCP | | Issue tracker | `bd` CLI | Synced from Dolt remote at session start | +### Toolchain Requirement + +**Agents must work inside `nix develop` (or direnv) for this repo.** Bare system cargo that +fails `edition2024` or missing wasm target is a misconfigured session. The bootstrap seeds +nix flake inputs automatically (GitHub tarballs are blocked in cloud), so `nix develop` +should work after install completes. + +Run commands inside the dev shell: +```bash +nix develop --command cargo test +nix develop --command cargo build --workspace +``` + +Or enter an interactive shell: `nix develop` + **Claude Code**: `.claude/hooks/session-start.sh` calls the bootstrap automatically. **Cursor cloud**: `.cursor/environment.json` runs the bootstrap via `install`. Skills are discovered from `.cursor/skills/` (symlinks to `.agents/skills/`). -**Local agents**: Run `scripts/agent-bootstrap.sh` manually, or use `direnv` / `nix develop` -for the full dev shell which includes `bd` from the flake pin. +**Local agents**: Run `scripts/agent-bootstrap.sh` manually, or use `direnv allow` for +automatic dev shell activation. See `context/cloud-agents.md` for environment-specific notes (nix, network, etc.). diff --git a/context/cloud-agents.md b/context/cloud-agents.md index 7ab55bda..f88b35fb 100644 --- a/context/cloud-agents.md +++ b/context/cloud-agents.md @@ -7,10 +7,14 @@ Cursor cloud agents, and similar setups. Local checkouts are unaffected. All agent stacks use the same bootstrap script: `scripts/agent-bootstrap.sh`. It: -1. Verifies the `bd` version matches the flake.nix pin -2. Installs `bd` if missing -3. Syncs the Dolt issue tracker from the git remote -4. Optionally warms the cargo build +1. **Seeds nix flake inputs** (GitHub tarballs are blocked; seeds over git instead) +2. Verifies the `bd` version matches the flake.nix pin +3. Installs `bd` if missing +4. Syncs the Dolt issue tracker from the git remote +5. Warms the cargo build **inside `nix develop`** + +**After bootstrap, `nix develop` works.** This is the required toolchain — bare system +cargo that fails `edition2024` or missing wasm target is a misconfigured session. **Claude Code**: `.claude/hooks/session-start.sh` calls the bootstrap automatically when `CLAUDE_CODE_REMOTE=true`. @@ -75,7 +79,8 @@ same if you need to re-sync by hand; never run it in the working tree. | Thing | Status | Use instead | |---|---|---| -| `nix develop` **unseeded** | Fails: flake inputs are GitHub **tarballs**, which are not served here | Run `scripts/nix-seed-flake-inputs.sh` first — see below. Or just use the preinstalled `cargo`/`rustc`, the same stable toolchain the flake pins | +| `nix develop` **without bootstrap** | Fails: flake inputs are GitHub **tarballs**, which are blocked | Bootstrap seeds inputs automatically; if it failed, run `scripts/nix-seed-flake-inputs.sh` manually | +| Bare system cargo | Fails: `edition2024`, missing wasm target | **Always use `nix develop`** — this is the required toolchain | | `bd dolt push` | Fails: 403 outbound | Nothing; bead status changes stay local. Say so rather than implying the tracker was updated | | `git+ssh://` Dolt remote in `config.yaml` | No ssh client in the container | `git+https://`, which the hook passes explicitly | | `git push`, GitHub API | **Work normally** | — | @@ -85,13 +90,13 @@ starting by hand). Reads of public GitHub repos over the git protocol work — it is specifically the `/archive/*.tar.gz` and `codeload` endpoints that are refused. -### Making `nix develop` work +### How nix develop works after bootstrap -`scripts/nix-seed-flake-inputs.sh` makes the devShell work **without touching -`flake.nix` or `flake.lock`**. Verified end to end: `rustc 1.98.1`, `cargo`, -`crate2nix` in the shell, `git status` clean. +The bootstrap runs `scripts/nix-seed-flake-inputs.sh` automatically, which seeds +the flake inputs over git **without touching `flake.nix` or `flake.lock`**. +After bootstrap, `nix develop` should work. If it fails, check `/tmp/nix-seed.log`. -Why it is needed, and why the obvious fixes are not available: +Why the seeding is needed: - Nix's `github:` fetcher wants a tarball. GitHub traffic **bypasses the environment's domain allowlist entirely** and goes through a proxy that @@ -120,9 +125,9 @@ around it — a mismatch fails loudly. Do not instead rewrite the lock's nodes to `git` type: carrying the old `narHash` onto a different fetcher is exactly the claim the lock exists to make. -It is not in the session-start hook because it is expensive (minutes, plus -several GB of store once the devShell builds) and most work does not need the -devShell. Run it when you do. +The bootstrap runs this automatically. It takes a few minutes and several GB of +store once the devShell builds. If bootstrap reported a seed failure, check +`/tmp/nix-seed.log` and re-run `scripts/nix-seed-flake-inputs.sh` manually. Two alternatives if per-container seeding is unattractive: push the inputs to a binary cache with `nix flake archive` and point sessions at it with diff --git a/scripts/agent-bootstrap.sh b/scripts/agent-bootstrap.sh index 196e28b3..7f2e328c 100755 --- a/scripts/agent-bootstrap.sh +++ b/scripts/agent-bootstrap.sh @@ -3,24 +3,30 @@ # # This script prepares any coding agent (Claude Code, Cursor, etc.) to work # on this repo. It handles: -# 1. bd (beads) installation and pin verification -# 2. Issue tracker sync from the Dolt remote -# 3. Optional cargo workspace warming +# 1. Nix flake input seeding (so `nix develop` works in cloud environments) +# 2. bd (beads) installation and pin verification +# 3. Issue tracker sync from the Dolt remote +# 4. Optional cargo workspace warming (inside nix develop) # # Usage: -# scripts/agent-bootstrap.sh [--skip-cargo-warm] +# scripts/agent-bootstrap.sh [--skip-cargo-warm] [--skip-nix-seed] # # The script is idempotent and safe to re-run. Nothing here writes to tracked # files, stages anything, or creates a commit. # +# IMPORTANT: This repo requires `nix develop` (or direnv) for builds/tests. +# Bare system cargo that fails edition2024 is a misconfigured session. +# # See also: `.claude/hooks/session-start.sh` (Claude Code wrapper), # `.cursor/environment.json` (Cursor cloud config) set -uo pipefail SKIP_CARGO_WARM=0 +SKIP_NIX_SEED=0 while [[ $# -gt 0 ]]; do case "$1" in --skip-cargo-warm) SKIP_CARGO_WARM=1; shift ;; + --skip-nix-seed) SKIP_NIX_SEED=1; shift ;; *) shift ;; esac done @@ -30,7 +36,27 @@ cd "$ROOT" || exit 0 log() { printf '[agent-bootstrap] %s\n' "$*"; } -# ── 0. The bd on PATH must be the bd flake.nix pins ──────────────────────── +# ── 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" + else + log "WARNING: nix-seed-flake-inputs.sh failed; see /tmp/nix-seed.log" + log " 'nix develop' may fail. Check network/proxy settings." + fi + fi +fi + +# ── 1. The bd on PATH must be the bd flake.nix pins ──────────────────────── beads_pin() { sed -n 's|.*beads\.url[[:space:]]*=[[:space:]]*"github:[^/]*/[^/]*/v\{0,1\}\([^"]*\)".*|\1|p' \ flake.nix 2>/dev/null | head -1 @@ -123,7 +149,7 @@ install_tracker() { return 1 } -# ── 1. bd on PATH ────────────────────────────────────────────────────────── +# ── 2. bd on PATH ────────────────────────────────────────────────────────── export PATH="$PATH:/root/go/bin:$HOME/go/bin" BD_INSTALLER_REF=f45b249ce6b40ba62aecc03949e6371e8f7c79d8 # tag v1.3.0 @@ -153,7 +179,7 @@ if [ "$pin_status" -eq 0 ]; then assert_bd_pin || pin_status=2 fi -# ── 2. Sync the issue tracker from the Dolt remote ───────────────────────── +# ── 3. Sync the issue tracker from the Dolt remote ───────────────────────── if 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)" @@ -196,27 +222,34 @@ if command -v bd >/dev/null 2>&1; then fi fi -# ── 3. Warm the build (optional) ─────────────────────────────────────────── -if [ "$SKIP_CARGO_WARM" -eq 0 ] && command -v cargo >/dev/null 2>&1; then - log "warming cargo build…" - if cargo build --workspace --tests >/tmp/cargo-warm.log 2>&1; then - log "workspace built" +# ── 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)" else log "WARNING: cargo build failed; see /tmp/cargo-warm.log" + log " This may indicate nix-seed failed or flake inputs are missing." 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 -# ── 4. Environment notes ─────────────────────────────────────────────────── +# ── 5. Environment notes ─────────────────────────────────────────────────── cat <<'NOTES' [agent-bootstrap] Environment notes (see context/cloud-agents.md): - • Use the preinstalled cargo toolchain for ordinary work. `nix develop` - also works, but only after scripts/nix-seed-flake-inputs.sh — GitHub - tarballs are not served here, so the locked inputs are seeded over git. + • This repo REQUIRES `nix develop` (or direnv) for builds and tests. + Bare system cargo that fails edition2024 is a misconfigured session. + • The bootstrap seeded flake inputs over git (GitHub tarballs are blocked + in cloud). If nix develop still fails, check /tmp/nix-seed.log. • `bd dolt push` is blocked outbound (403). Bead status changes stay local. • Never run a bare `bd init` in this repo: it rewrites AGENTS.md, CLAUDE.md and .claude/settings.json, and commits. Use --skip-agents --skip-hooks. - • `bd dolt push ` ignores its argument and pushes to origin. • Use `scripts/kb` for knowledge base operations, not Prolog MCP. + • Run commands inside `nix develop` or prefix with `nix develop --command`. NOTES exit "$pin_status"