From c2eb46d53fac3bb068c8c29aeb426660d593e574 Mon Sep 17 00:00:00 2001 From: vindard <17693119+vindard@users.noreply.github.com> Date: Tue, 26 May 2026 23:01:32 -0400 Subject: [PATCH 1/5] chore: replace docker-compose with nix process-compose for dev deps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Align with lana-bank's docker-free dev tooling: contributors no longer need Docker (or podman) installed. start-deps now runs Postgres directly via process-compose-flake, with data stored under .nix-deps/. Drops docker-compose.yml and nix/podman-runner.nix. CI surfaces (.github workflows + Concourse pipeline) are unchanged — both already invoke nix run .#nextest, whose internals now use the process-compose path. Refs GaloyMoney/volcano-wip#772. --- CLAUDE.md | 2 +- Makefile | 31 ++++---- docker-compose.yml | 15 ---- flake.lock | 16 ++++ flake.nix | 174 +++++++++++++++++++++++++++++++++++++----- nix/podman-runner.nix | 95 ----------------------- 6 files changed, 187 insertions(+), 146 deletions(-) delete mode 100644 docker-compose.yml delete mode 100644 nix/podman-runner.nix diff --git a/CLAUDE.md b/CLAUDE.md index 33811397..a46b99ba 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -5,7 +5,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Build and Development Commands ### Database Setup -- `make start-deps` - Start PostgreSQL in Docker +- `make start-deps` - Start PostgreSQL via nix process-compose (no Docker required) - `make setup-db` - Run database migrations - `make reset-deps` - Clean, start, and setup database diff --git a/Makefile b/Makefile index 630194c4..7464ad1c 100644 --- a/Makefile +++ b/Makefile @@ -1,22 +1,23 @@ -clean-deps: - docker compose down +NIX_DEPS_DIR := .nix-deps + +.PHONY: start-deps clean-deps setup-db reset-deps sqlx-prepare check-code test-in-ci test-book test-chapter serve-book start-deps: - @command -v docker >/dev/null 2>&1 && docker compose up -d || echo "Docker not found, skipping start-deps" + @mkdir -p $(NIX_DEPS_DIR) + nix run .#nix-deps-base -- up -D + nix run .#nix-deps-base -- project is-ready --wait + +clean-deps: + -nix run .#nix-deps-base -- down + chmod -R u+w $(NIX_DEPS_DIR) 2>/dev/null || true + rm -rf $(NIX_DEPS_DIR) setup-db: - @echo "Waiting for PostgreSQL and running migrations..." - @for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30; do \ - cargo sqlx migrate run 2>/dev/null && echo "Migrations complete" && exit 0; \ - echo "Attempt $$i: Database not ready, waiting..."; \ - sleep 1; \ - done; \ - echo "Database failed to become ready after 30 attempts"; \ - cargo sqlx migrate run - -reset-deps: clean-deps start-deps setup-db - -test-in-ci: start-deps setup-db + nix run .#setup-db-dev + +reset-deps: clean-deps start-deps + +test-in-ci: start-deps rm -rf $${CARGO_TARGET_DIR:-./target}/mdbook-test $(MAKE) test-book cargo nextest run --workspace --verbose diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 391b73c4..00000000 --- a/docker-compose.yml +++ /dev/null @@ -1,15 +0,0 @@ -version: "3" -services: - postgres: - image: postgres:16.4 - ports: - - "5432:5432" - environment: - - POSTGRES_USER=user - - POSTGRES_PASSWORD=password - - POSTGRES_DB=pg - healthcheck: - test: [ "CMD-SHELL", "pg_isready" ] - interval: 5s - timeout: 5s - retries: 5 diff --git a/flake.lock b/flake.lock index c97dd3e3..e72b3d78 100644 --- a/flake.lock +++ b/flake.lock @@ -65,12 +65,28 @@ "type": "github" } }, + "process-compose-flake": { + "locked": { + "lastModified": 1767863885, + "narHash": "sha256-XXekPAxzbv1DmHFo3Elmj/vDnvWc1V0jdDUvM0/Wf7k=", + "owner": "Platonic-Systems", + "repo": "process-compose-flake", + "rev": "99bea96cf269cfd235833ebdf645b567069fd398", + "type": "github" + }, + "original": { + "owner": "Platonic-Systems", + "repo": "process-compose-flake", + "type": "github" + } + }, "root": { "inputs": { "advisory-db": "advisory-db", "crane": "crane", "flake-utils": "flake-utils", "nixpkgs": "nixpkgs", + "process-compose-flake": "process-compose-flake", "rust-overlay": "rust-overlay" } }, diff --git a/flake.nix b/flake.nix index 61fce191..cba11563 100644 --- a/flake.nix +++ b/flake.nix @@ -15,6 +15,7 @@ flake = false; }; crane.url = "github:ipetkov/crane"; + process-compose-flake.url = "github:Platonic-Systems/process-compose-flake"; }; outputs = { self, @@ -23,6 +24,7 @@ rust-overlay, advisory-db, crane, + process-compose-flake, }: flake-utils.lib.eachDefaultSystem (system: let @@ -66,29 +68,157 @@ mdbook bacon postgresql - docker-compose - ytt - podman - podman-compose + process-compose curl ]; + + pgPort = 5432; + pgUser = "user"; + pgPassword = "password"; + pgDatabase = "pg"; + devEnvVars = rec { - PGDATABASE = "pg"; - PGUSER = "user"; - PGPASSWORD = "password"; + PGDATABASE = pgDatabase; + PGUSER = pgUser; + PGPASSWORD = pgPassword; PGHOST = "127.0.0.1"; - DATABASE_URL = "postgres://${PGUSER}:${PGPASSWORD}@${PGHOST}:5432/pg?sslmode=disable"; + PGPORT = toString pgPort; + DATABASE_URL = "postgres://${pgUser}:${pgPassword}@127.0.0.1:${toString pgPort}/${pgDatabase}?sslmode=disable"; PG_CON = "${DATABASE_URL}"; }; - podman-runner = pkgs.callPackage ./nix/podman-runner.nix {}; + # ── Postgres start helper ────────────────────────────────────────── + pg-start = pkgs.writeShellApplication { + name = "pg-start"; + runtimeInputs = [pkgs.postgresql pkgs.coreutils]; + text = '' + NAME="$1" PORT="$2" PGUSER="$3" DB="$4" + PGDATA="$PWD/.nix-deps/$NAME" + + mkdir -p "$PWD/.nix-deps" + + if [ ! -f "$PGDATA/PG_VERSION" ]; then + echo "[$NAME] Initializing data directory at $PGDATA..." + mkdir -p "$PGDATA" + initdb -D "$PGDATA" --username="$PGUSER" --auth=trust --no-locale -E UTF8 + { + echo "port = $PORT" + echo "unix_socket_directories = '/tmp'" + echo "listen_addresses = '127.0.0.1'" + } >> "$PGDATA/postgresql.conf" + fi + + if [ -f "$PGDATA/postmaster.pid" ]; then + pg_ctl -D "$PGDATA" stop -m immediate 2>/dev/null || rm -f "$PGDATA/postmaster.pid" + fi + + postgres -D "$PGDATA" -p "$PORT" -k /tmp & + PG_PID=$! + trap 'kill $PG_PID 2>/dev/null; wait $PG_PID 2>/dev/null' EXIT + + while ! pg_isready -p "$PORT" -U "$PGUSER" -h 127.0.0.1 -q 2>/dev/null; do + sleep 0.1 + done + + if [ "$DB" != "$PGUSER" ]; then + createdb -p "$PORT" -U "$PGUSER" -h 127.0.0.1 "$DB" 2>/dev/null || { + if psql -p "$PORT" -U "$PGUSER" -h 127.0.0.1 -lqt | cut -d \| -f 1 | grep -qw "$DB"; then + echo "[$NAME] Database '$DB' already exists" + else + echo "[$NAME] ERROR: Failed to create database '$DB'" >&2 + exit 1 + fi + } + fi + + echo "[$NAME] Ready on port $PORT (database: $DB)" + wait $PG_PID + ''; + }; + + setupDbDev = pkgs.writeShellApplication { + name = "setup-db-dev"; + runtimeInputs = [pkgs.sqlx-cli]; + text = '' + export DATABASE_URL="${devEnvVars.DATABASE_URL}" + exec sqlx migrate run + ''; + }; + + # ── process-compose: core-pg + setup-db ──────────────────────────── + pcLib = import process-compose-flake.lib {inherit pkgs;}; + + mkPg = { + name, + port, + user, + db, + }: { + command = "${ + pkgs.writeShellApplication { + name = "start-${name}"; + runtimeInputs = [pg-start]; + text = '' + exec pg-start ${name} ${toString port} ${user} ${db} + ''; + } + }/bin/start-${name}"; + readiness_probe = { + exec.command = "${ + pkgs.writeShellApplication { + name = "ready-${name}"; + runtimeInputs = [pkgs.postgresql]; + text = '' + exec psql -p ${toString port} -U ${user} -h 127.0.0.1 -d ${db} -c 'SELECT 1' -t -q + ''; + } + }/bin/ready-${name}"; + initial_delay_seconds = 1; + period_seconds = 1; + failure_threshold = 60; + }; + shutdown = { + signal = 2; + timeout_seconds = 10; + }; + }; + + baseProcesses = { + core-pg = mkPg { + name = "core-pg"; + port = pgPort; + user = pgUser; + db = pgDatabase; + }; + setup-db = { + command = "${setupDbDev}/bin/setup-db-dev"; + depends_on.core-pg.condition = "process_healthy"; + availability.exit_on_end = false; + shutdown = { + signal = 2; + timeout_seconds = 10; + }; + }; + }; + nix-deps-base = pcLib.makeProcessCompose { + name = "nix-deps-base"; + modules = [ + { + settings = { + log_level = "info"; + log_location = ".nix-deps/process-compose.log"; + processes = baseProcesses; + }; + } + ]; + }; + + # ── CI test runner ──────────────────────────────────────────────── nextest-runner = pkgs.writeShellScriptBin "nextest-runner" '' set -e export PATH="${pkgs.lib.makeBinPath [ - podman-runner.podman-compose-runner - pkgs.wait4x pkgs.sqlx-cli pkgs.cargo-nextest pkgs.coreutils @@ -104,22 +234,19 @@ export PGUSER="${devEnvVars.PGUSER}" export PGPASSWORD="${devEnvVars.PGPASSWORD}" export PGHOST="${devEnvVars.PGHOST}" + export PGPORT="${devEnvVars.PGPORT}" cleanup() { echo "Stopping deps..." - ${podman-runner.podman-compose-runner}/bin/podman-compose-runner down || true + ${nix-deps-base}/bin/nix-deps-base down 2>/dev/null || true } - trap cleanup EXIT - echo "Starting PostgreSQL..." - ${podman-runner.podman-compose-runner}/bin/podman-compose-runner up -d + mkdir -p .nix-deps - echo "Waiting for PostgreSQL to be ready..." - ${pkgs.wait4x}/bin/wait4x postgresql "$DATABASE_URL" --timeout 120s - - echo "Running database migrations..." - ${pkgs.sqlx-cli}/bin/sqlx migrate run + echo "Starting PostgreSQL via process-compose..." + ${nix-deps-base}/bin/nix-deps-base up -D + ${nix-deps-base}/bin/nix-deps-base project is-ready --wait echo "Running mdbook tests..." rm -rf ''${CARGO_TARGET_DIR:-./target}/mdbook-test @@ -141,6 +268,13 @@ with pkgs; { packages = { nextest = nextest-runner; + setup-db-dev = setupDbDev; + inherit nix-deps-base; + }; + + apps.setup-db-dev = flake-utils.lib.mkApp { + drv = setupDbDev; + name = "setup-db-dev"; }; checks = { diff --git a/nix/podman-runner.nix b/nix/podman-runner.nix deleted file mode 100644 index 146c5314..00000000 --- a/nix/podman-runner.nix +++ /dev/null @@ -1,95 +0,0 @@ -{pkgs}: let - podman-compose-runner = pkgs.stdenv.mkDerivation { - pname = "podman-compose-runner"; - version = "0.1.0"; - - dontUnpack = true; - - buildInputs = with pkgs; [ - makeWrapper - ]; - - installPhase = '' - mkdir -p $out/bin - - cat > $out/bin/podman-compose-runner << 'EOF' - #!/usr/bin/env bash - set -e - - if [[ "$OSTYPE" == "darwin"* ]]; then - if podman machine list --format json | jq -e '.[] | select(.Name == "podman-machine-default")' >/dev/null 2>&1; then - if ! podman machine list --format json | jq -e '.[] | select(.Name == "podman-machine-default" and .Running == true)' >/dev/null 2>&1; then - echo "Starting podman machine..." - podman machine start - fi - else - echo "No podman machine found. Creating and starting podman-machine-default..." - podman machine init - podman machine start - fi - - mkdir -p ~/.config/containers - echo 'unqualified-search-registries = ["docker.io"]' > ~/.config/containers/registries.conf - echo '{"default":[{"type":"insecureAcceptAnything"}]}' > ~/.config/containers/policy.json - else - echo "Using podman on Linux..." - - export XDG_RUNTIME_DIR="''${XDG_RUNTIME_DIR:-/tmp/podman-runtime-$(id -u)}" - mkdir -p "$XDG_RUNTIME_DIR" - - mkdir -p /var/tmp - mkdir -p /tmp - export TMPDIR=/tmp - - mkdir -p ~/.config/containers - echo 'unqualified-search-registries = ["docker.io"]' > ~/.config/containers/registries.conf - echo '{"default":[{"type":"insecureAcceptAnything"}]}' > ~/.config/containers/policy.json - - echo "Checking podman installation..." - if ! podman version >/dev/null 2>&1; then - echo "ERROR: podman version failed. Output:" - podman version 2>&1 || true - fi - - echo "Getting podman info..." - podman info 2>&1 || true - - if podman ps >/dev/null 2>&1; then - echo "Podman is working correctly" - else - echo "WARNING: podman ps test failed, but continuing anyway..." - fi - fi - - exec podman-compose "$@" - EOF - - chmod +x $out/bin/podman-compose-runner - - wrapProgram $out/bin/podman-compose-runner \ - --prefix PATH : ${pkgs.lib.makeBinPath ( - [ - pkgs.podman - pkgs.podman-compose - pkgs.coreutils - pkgs.bash - pkgs.jq - ] - ++ pkgs.lib.optionals pkgs.stdenv.isLinux [ - pkgs.fuse-overlayfs - pkgs.iptables - pkgs.netavark - pkgs.aardvark-dns - ] - )} - ''; - - meta = with pkgs.lib; { - description = "Podman-compose runner that auto-manages podman machine on macOS"; - license = licenses.mit; - platforms = platforms.all; - }; - }; -in { - inherit podman-compose-runner; -} From 14a35549eedcd1ed487e4e6f2d3f6ba9d82656de Mon Sep 17 00:00:00 2001 From: Lakshyyaa Date: Mon, 1 Jun 2026 15:46:16 +0530 Subject: [PATCH 2/5] fix(ci): drop privileges for Postgres under process-compose --- ci/pipeline.yml | 1 - flake.nix | 40 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/ci/pipeline.yml b/ci/pipeline.yml index 757e64be..2e7cac87 100644 --- a/ci/pipeline.yml +++ b/ci/pipeline.yml @@ -53,7 +53,6 @@ jobs: - { get: pipeline-tasks } - task: tests attempts: 2 - privileged: true config: platform: linux image_resource: #@ nix_task_image_config() diff --git a/flake.nix b/flake.nix index cba11563..57bd28b2 100644 --- a/flake.nix +++ b/flake.nix @@ -70,6 +70,7 @@ postgresql process-compose curl + ytt ]; pgPort = 5432; @@ -90,29 +91,51 @@ # ── Postgres start helper ────────────────────────────────────────── pg-start = pkgs.writeShellApplication { name = "pg-start"; - runtimeInputs = [pkgs.postgresql pkgs.coreutils]; + runtimeInputs = + [pkgs.postgresql pkgs.coreutils] + ++ pkgs.lib.optionals pkgs.stdenv.isLinux [pkgs.util-linux]; text = '' NAME="$1" PORT="$2" PGUSER="$3" DB="$4" PGDATA="$PWD/.nix-deps/$NAME" + # PostgreSQL refuses to run as root. When running as root (e.g. CI), + # drop privileges to _pgdev (UID 70) via setpriv. + PG_UID=70 + PG_GID=70 + IS_ROOT=false + if [ "$(id -u)" = "0" ]; then + IS_ROOT=true + fi + + run_pg() { + if [ "$IS_ROOT" = "true" ]; then + setpriv --reuid=$PG_UID --regid=$PG_GID --clear-groups -- "$@" + else + "$@" + fi + } + mkdir -p "$PWD/.nix-deps" if [ ! -f "$PGDATA/PG_VERSION" ]; then echo "[$NAME] Initializing data directory at $PGDATA..." mkdir -p "$PGDATA" - initdb -D "$PGDATA" --username="$PGUSER" --auth=trust --no-locale -E UTF8 + if [ "$IS_ROOT" = "true" ]; then chown -R $PG_UID:$PG_GID "$PGDATA"; fi + run_pg initdb -D "$PGDATA" --username="$PGUSER" --auth=trust --no-locale -E UTF8 { echo "port = $PORT" echo "unix_socket_directories = '/tmp'" echo "listen_addresses = '127.0.0.1'" } >> "$PGDATA/postgresql.conf" + else + if [ "$IS_ROOT" = "true" ]; then chown -R $PG_UID:$PG_GID "$PGDATA"; fi fi if [ -f "$PGDATA/postmaster.pid" ]; then - pg_ctl -D "$PGDATA" stop -m immediate 2>/dev/null || rm -f "$PGDATA/postmaster.pid" + run_pg pg_ctl -D "$PGDATA" stop -m immediate 2>/dev/null || rm -f "$PGDATA/postmaster.pid" fi - postgres -D "$PGDATA" -p "$PORT" -k /tmp & + run_pg postgres -D "$PGDATA" -p "$PORT" -k /tmp & PG_PID=$! trap 'kill $PG_PID 2>/dev/null; wait $PG_PID 2>/dev/null' EXIT @@ -244,6 +267,15 @@ mkdir -p .nix-deps + # Create _pgdev user (UID 70) for pg-start's setpriv drop when running as root. + # Done once here to avoid /etc/passwd races if multiple PGs ever start in parallel. + if [ "$(id -u)" = "0" ]; then + if ! getent passwd 70 >/dev/null 2>&1; then + echo "_pgdev:x:70:70::/tmp:/bin/false" >> /etc/passwd + echo "_pgdev:x:70:" >> /etc/group + fi + fi + echo "Starting PostgreSQL via process-compose..." ${nix-deps-base}/bin/nix-deps-base up -D ${nix-deps-base}/bin/nix-deps-base project is-ready --wait From 52148b474049923fd0e3de3fd79ffb8cb11ec624 Mon Sep 17 00:00:00 2001 From: Lakshyyaa Date: Mon, 1 Jun 2026 16:18:57 +0530 Subject: [PATCH 3/5] fix(ci): set XDG_CONFIG_HOME and bound process-compose readiness wait process-compose reads/writes under XDG_CONFIG_HOME; the stripped CI image has no /root/.config and the daemon exits silently. Default it to $PWD/.nix-deps/config. Replace `is-ready --wait` (no timeout) with a 60-iteration polling loop and dump `process list` on timeout so a stuck service fails CI in 5 minutes with diagnostics instead of hanging 30 minutes silently. Refs lana-bank PR #5289 and bounded-polling commit d8d5528989. Co-Authored-By: Claude Opus 4.7 (1M context) --- flake.nix | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 57bd28b2..61d25d1c 100644 --- a/flake.nix +++ b/flake.nix @@ -267,6 +267,11 @@ mkdir -p .nix-deps + # process-compose reads/writes config under XDG_CONFIG_HOME; the + # stripped CI image has no /root/.config. Point it at a writable dir. + export XDG_CONFIG_HOME="''${XDG_CONFIG_HOME:-$PWD/.nix-deps/config}" + mkdir -p "$XDG_CONFIG_HOME" + # Create _pgdev user (UID 70) for pg-start's setpriv drop when running as root. # Done once here to avoid /etc/passwd races if multiple PGs ever start in parallel. if [ "$(id -u)" = "0" ]; then @@ -278,7 +283,20 @@ echo "Starting PostgreSQL via process-compose..." ${nix-deps-base}/bin/nix-deps-base up -D - ${nix-deps-base}/bin/nix-deps-base project is-ready --wait + + # Bounded readiness wait. `is-ready --wait` has no timeout and hangs on failure + for i in $(seq 1 60); do + if ${nix-deps-base}/bin/nix-deps-base project is-ready 2>/dev/null; then + echo "Services ready after ''${i}x5s" + break + fi + if [ "$i" = "60" ]; then + echo "ERROR: services not ready after 5 minutes" >&2 + ${nix-deps-base}/bin/nix-deps-base process list || true + exit 1 + fi + sleep 5 + done echo "Running mdbook tests..." rm -rf ''${CARGO_TARGET_DIR:-./target}/mdbook-test From 02cf6f416caa36f1f49f8219530a91f95318969c Mon Sep 17 00:00:00 2001 From: Lakshyyaa Date: Mon, 1 Jun 2026 17:57:06 +0530 Subject: [PATCH 4/5] fix(ci): run migrations synchronously, not as compose one-shot `project is-ready` reports the project ready once processes are running, not when one-shot processes complete. With setup-db as a compose process, is-ready returned while `sqlx migrate run` was still in flight, so tests could start mid-migration. Remove setup-db from process-compose and run the migration synchronously after the readiness gate (Makefile start-deps + nextest-runner). Shell sequencing now guarantees migrations finish before tests start, and a failed migration surfaces as a non-zero exit. Co-Authored-By: Claude Opus 4.8 (1M context) --- Makefile | 1 + flake.nix | 17 +++++++---------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 7464ad1c..c8c2704d 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ start-deps: @mkdir -p $(NIX_DEPS_DIR) nix run .#nix-deps-base -- up -D nix run .#nix-deps-base -- project is-ready --wait + nix run .#setup-db-dev clean-deps: -nix run .#nix-deps-base -- down diff --git a/flake.nix b/flake.nix index 61d25d1c..b186c289 100644 --- a/flake.nix +++ b/flake.nix @@ -168,7 +168,7 @@ ''; }; - # ── process-compose: core-pg + setup-db ──────────────────────────── + # ── process-compose: core-pg ─────────────────────────────────────── pcLib = import process-compose-flake.lib {inherit pkgs;}; mkPg = { @@ -206,6 +206,9 @@ }; }; + # Only long-running services live in process-compose. Migrations are run + # synchronously by callers (Makefile start-deps / nextest-runner) after + # core-pg is healthy, so tests never start mid-migration. baseProcesses = { core-pg = mkPg { name = "core-pg"; @@ -213,15 +216,6 @@ user = pgUser; db = pgDatabase; }; - setup-db = { - command = "${setupDbDev}/bin/setup-db-dev"; - depends_on.core-pg.condition = "process_healthy"; - availability.exit_on_end = false; - shutdown = { - signal = 2; - timeout_seconds = 10; - }; - }; }; nix-deps-base = pcLib.makeProcessCompose { @@ -298,6 +292,9 @@ sleep 5 done + echo "Running database migrations..." + ${setupDbDev}/bin/setup-db-dev + echo "Running mdbook tests..." rm -rf ''${CARGO_TARGET_DIR:-./target}/mdbook-test cargo build --profile mdbook-test --features mdbook-test --lib From 8f7f27f90ba2b796f42a8f7962123a1dc7938546 Mon Sep 17 00:00:00 2001 From: Lakshyyaa Date: Mon, 1 Jun 2026 18:00:10 +0530 Subject: [PATCH 5/5] chore: gitignore .nix-deps/ dev deps dir .nix-deps/ holds the process-compose Postgres data dir, logs, and config. It was untracked but not ignored, so `git add .` could accidentally commit the entire PG cluster. Co-Authored-By: Claude Opus 4.8 (1M context) --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index bac5d4cb..45ae93be 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,9 @@ target/ .direnv/ +# nix process-compose dev deps (Postgres data dir, logs, config) +.nix-deps/ + - .env .bacon-locations