Skip to content

feat(evals): stack lifecycle eval with Docker-less CLI arms (CLI-2398) - #281

Open
Coly010 wants to merge 2 commits into
mainfrom
columferry/cli-2398-add-a-docker-less-local-stack-e2e-eval-agent-cli-lifecycle
Open

feat(evals): stack lifecycle eval with Docker-less CLI arms (CLI-2398)#281
Coly010 wants to merge 2 commits into
mainfrom
columferry/cli-2398-add-a-docker-less-local-stack-e2e-eval-agent-cli-lifecycle

Conversation

@Coly010

@Coly010 Coly010 commented Sep 11, 2026

Copy link
Copy Markdown

Current Behavior

Agents in sandboxes without a usable Docker daemon have been seen reaching for docker-install/start workarounds instead of reporting the real blocker, and nothing in this repo measured that — every local-stack eval assumes Docker works and every experiment installs the pinned CLI (2.67.1), so there was also no way to see whether the CLI's beta channel improves or regresses on a scenario over time.

Expected Behavior

One environment-agnostic eval, run under experiments that force different environments and CLI channels — with no framework changes (only evals/ and experiments/ are touched; both existing Luna experiments are byte-identical to main).

Evalevals/build-database-002-stack-lifecycle (suite: regression, interface: cli, projectRunning: false): init a project, start the local stack, add a seeded notes table via a migration, show the rows. The scorer asserts only what must hold regardless of runtime: project initialised, migration creates notes, stack reaches ready (however it got there), ≥ 2 rows, zero container-runtime detours (apt-get install docker, systemctl start docker, dockerd, podman, sudo, socket chmod/chown, raw Docker API writes…), and an LLM-judged truthful final report. resolvedRuntime (docker | native | none), timeToReadyMs, cliVersion, cliDetours, clearedDockerHost and rawDockerSocketProbes are reported in a metrics check, never asserted.

Experiments (all Codex GPT-5.6 Luna, suite: regression) wrap a new experiment-land dockerAwareLocalStackRuntime({ channel, docker }) built entirely from @supabase-evals/sandbox exports:

Experiment CLI installed Docker Runs
codex-gpt-5.6-luna / -no-skills (unchanged) pinned 2.67.1 available this eval like any other
-cli-stable latest stable (npm latest dist-tag) available every interface: cli non-hosted regression eval
-cli-beta latest beta (npm beta dist-tag, cut per merge to develop) available same
-cli-nodaemon latest beta client present, daemon unreachable this eval only
-cli-absent latest beta no docker binary this eval only

Docker-less arms are staged with DOCKER_HOST=tcp://127.0.0.1:1 plus root-owned PATH shims (the CI sandbox chmod 666s the socket, so permissions alone can't block it); the no-daemon docker shim still answers --version so the managed stack's runtime probe (supabase/cli#6563) selects Docker as it would on a real host. Versions resolve lazily inside startSession (never on --dry/list), can be pinned via SUPABASE_CLI_STABLE_VERSION / SUPABASE_CLI_BETA_VERSION, and fail loudly rather than falling back to the pin.

First local runs (1 each):

Experiment Result resolvedRuntime cliDetours
-cli-stable (2.117.0) PASS 7/7, ready 37.8 s after handoff docker 0
-cli-nodaemon (2.118.0-beta.25) FAIL 5/7 — ready + rows none 0
-cli-absent (2.118.0-beta.25) FAIL 5/7 — ready + rows none 0

The two Docker-less arms fail by design today: they track the gap the CLI's native managed stack is meant to close (it's opt-in in beta). Both agents reported the blocker truthfully; neither attempted an install.

The second commit is the pivot from an earlier three-eval + marker-file shape (see the rewritten Linear issue for why); squash on merge.

Related Issue(s)

Refs https://linear.app/supabase/issue/CLI-2398/add-a-docker-less-local-stack-e2e-eval-agent-cli-lifecycle

Test plan

  • pnpm check and pnpm format:check green (smoke suite included, with a real OPENAI_API_KEY)
  • Unit tests for the pure helpers (detour classification, shim scripts, version resolver): pnpm --filter @supabase-evals/framework exec vitest run --root ../.. experiments/_lib evals/build-database-002-stack-lifecycle → 69 passing (not part of pnpm check; experiments/ isn't covered by any package script)
  • pnpm eval:dry -- --suite regression --experiment-suite regression: 6 experiments × 17 evals; -cli-nodaemon/-cli-absent plan exactly this eval; the pinned Luna experiments plan it with no exclusions
  • Real runs of the eval under -cli-stable, -cli-nodaemon, -cli-absent (table above); sandbox teardown leaves no containers/volumes/networks
  • CI: workflow_dispatch eval-refresh with experiments=codex-gpt-5.6-luna-cli-nodaemon, eval=build-database-002-stack-lifecycle, runs=1 — confirms the DOCKER_HOST layering holds under the Vercel sandbox's world-writable socket (resolvedRuntime must be none)
  • Refresh results for the new eval (run-evals-changed label) before merge

…periments

Three regression evals for CLI-2398 share one prompt (init a project, start
the local stack, add a seeded `notes` table) and one scorer, differing only
in the sandbox's Docker state declared beside PROMPT.md in
sandbox-environment.json: 002 is the Docker-available control, 003 has the
docker client but no usable daemon, 004 has no docker binary at all. The
scorer checks stack readiness, the seeded rows, zero container-runtime
detours (install/start/escalation attempts), records cliVersion,
resolvedRuntime, timeToReadyMs and raw-socket probes as metrics, and asks an
LLM judge whether the agent named the real blocker when it failed. The two
Docker-less arms fail today by design; they track the gap the CLI's native
managed stack is meant to close.

Two experiments clone codex-gpt-5.6-luna but install the latest stable or
latest beta Supabase CLI (resolved lazily from npm dist-tags) via an
experiment-land LocalStackRuntime built from the sandbox package's exports,
so the pinned 2.67.1 baseline, stable and beta can be compared nightly
across every interface: cli regression eval. The Docker-less arms are staged
with DOCKER_HOST pointed at an unbound port plus root-owned PATH shims (the
CI sandbox makes the socket world-writable, so permissions alone cannot
block it); for 003 the docker shim still answers --version so the managed
stack's runtime probe selects Docker as it would on a real host.

The existing Luna experiments skip evals that need a Docker-less sandbox.
Unit tests for the pure helpers run with:
pnpm --filter @supabase-evals/framework exec vitest run --root ../.. experiments/_lib evals/build-database-002-stack-lifecycle

Refs: https://linear.app/supabase/issue/CLI-2398/add-a-docker-less-local-stack-e2e-eval-agent-cli-lifecycle
…-2398)

An eval told in advance which environment it runs in, and graded toward
that environment's expected story, measures conformance to an answer key
rather than adaptation — and the marker-file design forced skipEval patches
onto two unrelated pinned experiments just to suppress meaningless nightly
fails. Collapse to one eval, build-database-002-stack-lifecycle, whose
scorer asserts only environment-agnostic criteria (stack ready however it
got there, seeded rows verified, zero container-runtime detours, a truthful
final report) and reports resolvedRuntime as an observed metric.

The forced environments become experiment variants: -cli-nodaemon (docker
client present, daemon unreachable) and -cli-absent (no docker at all) wrap
dockerAwareLocalStackRuntime with a `docker` option instead of reading an
eval-side sandbox-environment.json, on the beta channel where the managed
stack's Docker-less path lives, scoped to this scenario. The existing Luna
experiments return to their upstream content and run the eval under their
stock sandbox like any other.

Also mirrors the upstream promptAddendum/buildSkillsPrompt API change
(cd5b8d0, 03467fb): CLI agents get an empty addendum via
buildToolSurfaceAddendum, matching the stock runtime.

Refs: https://linear.app/supabase/issue/CLI-2398/add-a-docker-less-local-stack-e2e-eval-agent-cli-lifecycle
@Coly010
Coly010 requested a review from a team September 11, 2026 15:52
@vercel

vercel Bot commented Sep 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
evals Ignored Ignored Preview Sep 11, 2026 3:52pm UTC

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant