From ba64c8f5c469b08defad9e2acc8b0ed31c398352 Mon Sep 17 00:00:00 2001 From: Allison Truhlar Date: Tue, 30 Jun 2026 15:20:26 -0400 Subject: [PATCH 1/2] fix(devcontainer): pin pixi install version to match committed lockfile An unpinned (latest) pixi can compute a different workspace hash and reject pixi.lock as not up-to-date. Pin PIXI_VERSION=0.66.0 in the image build. --- .devcontainer/Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index f26dca9d..548d2fb5 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -22,8 +22,10 @@ RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ && apt-get install -y --no-install-recommends nodejs \ && rm -rf /var/lib/apt/lists/* -# Install pixi system-wide -RUN curl -fsSL https://pixi.sh/install.sh | PIXI_HOME=/usr/local bash +# Install pixi system-wide. Pin the version so the container's pixi agrees with +# the committed pixi.lock; an unpinned (latest) pixi can compute a different +# workspace hash and reject the lock as "not up-to-date". +RUN curl -fsSL https://pixi.sh/install.sh | PIXI_VERSION=0.66.0 PIXI_HOME=/usr/local bash # Playwright browser + OS deps, pinned to the project's version, in a shared path # readable by the vscode user. The config defines no projects, so only chromium From 5b79ed459002e04a9d1bef51bd8e3eed83715931 Mon Sep 17 00:00:00 2001 From: Allison Truhlar Date: Tue, 30 Jun 2026 15:20:26 -0400 Subject: [PATCH 2/2] fix(devcontainer): chown .pixi to the resolved vscode user, recursively The ownership guard only checked the top-level .pixi dir and hardcoded 1000:1000, so it missed root-owned contents under a correctly-owned top dir and broke when updateRemoteUserUID remapped vscode's UID. Probe the whole tree (find -quit) and chown to vscode by name instead. --- .devcontainer/entrypoint.sh | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/.devcontainer/entrypoint.sh b/.devcontainer/entrypoint.sh index 0280113b..dc967b53 100755 --- a/.devcontainer/entrypoint.sh +++ b/.devcontainer/entrypoint.sh @@ -10,12 +10,19 @@ READY_FLAG="/run/fg-firewall-ready" rm -f "$READY_FLAG" -# Fix ownership of the mounted .pixi volume if it isn't already the dev user's. -# On rootless Podman (keep-id) it's already 1000:1000 -> no-op. On Docker/Colima -# named volumes are created root-owned, so chown them to vscode. -if [ -d "$WORKSPACE/.pixi" ] && [ "$(stat -c %u "$WORKSPACE/.pixi")" != "1000" ]; then - echo "entrypoint: fixing ownership of $WORKSPACE/.pixi" - chown -R 1000:1000 "$WORKSPACE/.pixi" || true +# Fix ownership of the mounted .pixi volume if ANY file in it isn't the dev +# user's. On rootless Podman (keep-id) it's already correct -> no-op. On +# Docker/Colima named volumes are created root-owned, and a stale volume can have +# root-owned contents under a correctly-owned top dir, so probe the whole tree +# (find -quit stops at the first offender) and chown recursively when needed. +# Resolve the dev user by NAME, not a hardcoded 1000: the devcontainers CLI's +# updateRemoteUserUID may remap vscode's UID to the host user's, and chowning to +# the wrong UID is exactly what leaves pixi with "Permission denied". +DEV_USER="$(id -u vscode)" +if [ -d "$WORKSPACE/.pixi" ] && \ + [ -n "$(find "$WORKSPACE/.pixi" -not -uid "$DEV_USER" -print -quit 2>/dev/null)" ]; then + echo "entrypoint: fixing ownership of $WORKSPACE/.pixi -> vscode ($DEV_USER)" + chown -R vscode:vscode "$WORKSPACE/.pixi" fi # Bring up the egress allowlist firewall before the agent can run. Fail closed: