From 3dd53425dc3c130601afd9b3a6c03941f2206bbe Mon Sep 17 00:00:00 2001 From: Basilio Bogado <541149+basiliskus@users.noreply.github.com> Date: Tue, 6 Oct 2026 08:41:59 -0700 Subject: [PATCH 1/3] feat(devenv-image): move to nixos-26.05 (devenv 2.1.2), VERSION 2.0.0 Pin NIXPKGS_REV to nixos-26.05 so the image ships devenv 2.x, which first appears there. The devenv major is part of the image contract, so this is a major VERSION bump; 1.x consumers keep the immutable 1.0.0 tag. --- integrations/isolation/images/devenv/Dockerfile | 8 +++++--- integrations/isolation/images/devenv/VERSION | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/integrations/isolation/images/devenv/Dockerfile b/integrations/isolation/images/devenv/Dockerfile index b97349e3..45c2521a 100644 --- a/integrations/isolation/images/devenv/Dockerfile +++ b/integrations/isolation/images/devenv/Dockerfile @@ -5,9 +5,11 @@ ARG BASE_IMAGE=docker/sandbox-templates:shell-docker FROM ${BASE_IMAGE} -# devenv/direnv nixpkgs pin (nixos-25.05). Bump this and VERSION together — -# unpinned `nixpkgs#…` tracks unstable HEAD and drifts per build. -ARG NIXPKGS_REV=ac62194c3917d5f474c1a844b6fd6da2db95077d +# devenv/direnv nixpkgs pin (nixos-26.05 → devenv 2.1.2). Bump this and +# VERSION together — unpinned `nixpkgs#…` tracks unstable HEAD and drifts per +# build. The devenv major is part of the image contract: a major change here +# is a major VERSION bump. +ARG NIXPKGS_REV=0d9e9b832d03ac387417e16ce1febf73b2e631e1 # Checksum pin for the installer script below (release assets are mutable); # bump together with the installer version. diff --git a/integrations/isolation/images/devenv/VERSION b/integrations/isolation/images/devenv/VERSION index 3eefcb9d..227cea21 100644 --- a/integrations/isolation/images/devenv/VERSION +++ b/integrations/isolation/images/devenv/VERSION @@ -1 +1 @@ -1.0.0 +2.0.0 From 7f6ce35bb2c011587f15464878439ffeb436cb35 Mon Sep 17 00:00:00 2001 From: Basilio Bogado <541149+basiliskus@users.noreply.github.com> Date: Tue, 6 Oct 2026 09:59:49 -0700 Subject: [PATCH 2/3] docs(devenv-image): record the devenv major contract and 2.x consumer notes Document that the devenv major is part of the image contract and what a 2.x CLI changes for repos still locked to 1.x modules: the explicit git-hooks input, lock rewrites between majors, .devenv reuse, and the devenv processes down behavior observed in sandboxes. --- .../isolation/images/devenv/README.md | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/integrations/isolation/images/devenv/README.md b/integrations/isolation/images/devenv/README.md index daf0ad68..dcc2e8ff 100644 --- a/integrations/isolation/images/devenv/README.md +++ b/integrations/isolation/images/devenv/README.md @@ -34,6 +34,30 @@ The image contains only the base-agnostic toolchain: Nix (single-user store owned by `agent`), devenv + direnv pinned to a nixpkgs rev, flakes enabled, and the bash wiring that puts the Nix profile and direnv hook in every shell. +The devenv major is part of the image contract: `1.x` tags ship devenv 1.x +(nixos-25.05), `2.x` tags ship devenv 2.x (nixos-26.05). devenv 2.x bundles +its own Nix for evaluation and builds and shares the single-user store with +the installer's Nix on `PATH`; both read and write the same store database. + +## devenv 2.x notes for consuming repos + +A 2.x image runs a repo's `devenv.nix` with the modules pinned by that repo's +`devenv.lock` (the `devenv` input), so a 1.x-locked repo keeps its 1.x module +semantics until someone runs `devenv update`. What the CLI major changes +regardless of the lock: + +- The `git-hooks` input is no longer implicit. A repo using `git-hooks.hooks` + fails with `git-hooks or pre-commit-hooks input required` until it declares + the input in `devenv.yaml`. +- `devenv shell` rewrites `devenv.lock` to drop the implicit `git-hooks`, + `pre-commit-hooks`, and `flake-compat` nodes; a 1.x CLI adds them back at + current HEAD. Teams mixing 1.x CI with 2.x sandboxes see lock churn until + `git-hooks` is declared explicitly, which makes both majors agree. +- `.devenv/` written by either major is reusable by the other (the eval cache + is keyed on the devenv version). +- `devenv up -d` works; `devenv processes down` may time out and SIGKILL the + process group without stopping the service's children. + Everything else is a kit's job: - **Runtime CA trust** — e.g. the `zscaler-ca-certificate` kit; the image pins @@ -53,6 +77,7 @@ docker build --build-arg EXTRA_CA_CERT="$(cat proxy-root-ca.crt)" . ## Versioning [`VERSION`](VERSION) is the published tag, bumped together with any toolchain -change (`NIXPKGS_REV`, installer version, base image); tags are never reused — +change (`NIXPKGS_REV`, installer version, base image), with a major bump when +the devenv major changes; tags are never reused — the workflow refuses to republish an existing version tag. A moving `latest` also exists — pin the version tag in anything durable. From ebe73f2ba76bd2656552cb5be44d63fa168cf76a Mon Sep 17 00:00:00 2001 From: Basilio Bogado <541149+basiliskus@users.noreply.github.com> Date: Wed, 7 Oct 2026 06:13:13 -0700 Subject: [PATCH 3/3] docs(devenv-image): note .devenv persistence, 2.x port allocation, and SecretSpec Record three devenv 2.1.2 behaviors a consuming repo can hit in a sandbox: .devenv/ lives in the workspace (lost on recreate under --clone), built-in services auto-allocate the next free port once a repo uses 2.x modules (strict_ports: true keeps a published port fixed), and SecretSpec is opt-in and prompts only on a terminal. --- integrations/isolation/images/devenv/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/integrations/isolation/images/devenv/README.md b/integrations/isolation/images/devenv/README.md index dcc2e8ff..7a473e74 100644 --- a/integrations/isolation/images/devenv/README.md +++ b/integrations/isolation/images/devenv/README.md @@ -57,6 +57,19 @@ regardless of the lock: is keyed on the devenv version). - `devenv up -d` works; `devenv processes down` may time out and SIGKILL the process group without stopping the service's children. +- `.devenv/` lives in the project root, so in a sandbox it is part of the + workspace and persists with it. Under `--clone` the workspace is inside the + sandbox, and a recreate discards `.devenv/state` along with any service data + it holds (a Postgres database, for example). +- Once a repo moves to 2.x modules, built-in services (Postgres, Redis, and + others) pick the next free port when their base port is taken. Set + `strict_ports: true` in `devenv.yaml` when a kit publishes or another tool + expects a fixed port, so a conflict fails instead of silently moving the + service. +- SecretSpec is opt-in (`secretspec.enable` in `devenv.yaml`, or + `SECRETSPEC_PROVIDER`/`SECRETSPEC_PROFILE`). On missing secrets it prompts + only when stdin is a terminal, which an agent's PTY can be; otherwise it + fails. Everything else is a kit's job: