feat(cli): add the cli eval suite and experiment suite plumbing - #327
Conversation
Moves the CLI channel resolver into @supabase-evals/sandbox and lets localStackRuntime's cliVersion accept 'stable'/'beta' in addition to an exact version, resolved against npm's dist-tags at session start. An eval's own cliVersion: frontmatter pin still wins. Forwards the resolved channel pins to Vercel sandbox jobs so a run scores against one version instead of each job re-resolving "latest" independently.
…vals/sandbox
Promote the CLI team's experiment-land dockerAwareLocalStackRuntime into a
first-class localStackRuntime({ docker: 'no-daemon' | 'absent' }) option, so
any experiment can stage a sandbox where the Docker daemon is unreachable or
the docker binary is absent entirely, alongside the mountDockerSocket sandbox
primitive and needsDocker eval frontmatter it depends on.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
- Export FORWARDED_ENV_NAMES from run-vercel-evals.ts and import it in the test instead of a drifted local copy, so a leaked XAI_API_KEY can no longer break agentEnvironment()'s assertions. - Make cliDebUrl's arch param required and check both amd64 and arm64 release assets, since the resolver's host arch can differ from the sandbox container's; delete the now-unused hostDebArch. - Generalise the beta walk-back to every published X.Y.Z-beta.N version older than the unpublished one (not just the same minor), ordered with a numeric compareBetaVersionsDesc comparator instead of a string compare. - Treat a thrown error for one walk-back candidate as "unavailable" and keep probing the rest, instead of aborting the whole walk-back; the initial dist-tag asset check still fails loud. - Import isRecord from @supabase-evals/core/json instead of a local copy that dropped the array guard. - Guard the version cache's rejection cleanup with an identity check so a stale promise can't evict a newer cached one. - Drop cliDebUrl/hostDebArch from the sandbox barrel (no external consumers) and correct local-stack-runtime's doc comment: channel resolution is memoised per process, not per session.
…y/sandbox-docker-availability
… resolution Strips agent-added comment cruft (module docblock essay, CI-run-ID call-out, code-shape narration) back to the invariants and external quirks the code can't express on its own; no behaviour change.
…y/sandbox-docker-availability
Condense multi-paragraph comments in local-stack-runtime.ts down to the non-obvious fact each one exists to preserve, dropping restated code sequences and step-by-step narration.
a2edffd to
1e930b2
Compare
…ls once per run debAssetHeadOk conflated a GitHub 429/5xx with a missing asset (response.ok false for both), which could downgrade a beta release during a GitHub outage and record results under the wrong version. Only a 404 now means "asset not published"; any other non-2xx throws. The beta walk-back loop is updated to match: a 404 still advances to the next candidate, but a thrown error aborts the walk-back and propagates instead of being caught and skipped. Separately, nothing set SUPABASE_CLI_STABLE_VERSION/SUPABASE_CLI_BETA_VERSION, so each sandbox job resolved its own CLI channel version independently, risking two different versions in one fan-out if a release landed mid-run. runPairs now resolves each channel pin once via resolveChannelPins() before runBounded and threads the same pins into every job's .env write.
Union each pair's effective channel (exact eval pins win and need none; otherwise the pair's experiment's localStack.cliChannel) before fan-out, instead of unconditionally resolving both channels. A run with no CLI-channel experiments now does zero npm/GitHub lookups. An experiment that can't be resolved to a config throws instead of silently counting as needing no channel.
…i-version-channels
The controller's channel lookup built experiments/<name>.ts by hand, which stopped matching when experiments moved to experiments/<owner>/*.experiment.ts. Use the shared discovery helper so the path convention lives in one place.
…y/sandbox-docker-availability # Conflicts: # packages/sandbox/src/cli-channel.ts # packages/sandbox/src/local-stack-runtime.ts
Splits the final chunk out of the closed #308: the cli suite/experiment enums, CODEOWNERS scoping, the four forced-environment CLI experiment columns plus their skip predicates, and CI wiring so the eval-refresh and gh-pages-history workflows know about the new suite.
presets.ts landed without the baselineExperiment alias these spread, and typechecking experiments/ now needs the test files excluded.
bdbaafe to
9cba14a
Compare
…pt text, and read the environment marker without trusting the agent's PATH writeRootFile only chmod'd after docker cp, leaving the marker and CLI shims owned by the host UID rather than root. buildToolSurfaceAddendum and buildLocalStackTools also described docker as installed/reachable in the no-daemon and absent states. And the environment marker was only reachable through exec(), whose SANDBOX_PATH has an agent-writable first entry that could shadow cat. Fix writeRootFile to chown+chmod in one checked root command, thread the resolved Docker state into both prompt/tool builders, and add DockerSandbox.readRootFile (docker exec in exec form, no shell) plus LocalStackScoringContext.environmentMarker to read the marker as root without going through resolveSandboxPath or the agent's PATH.
…cker-availability # Conflicts: # README.md # packages/sandbox/src/cli-channel.ts # packages/sandbox/src/local-stack-runtime.ts
The model upgrade renamed the baseline preset and its experiment file, so the cli columns follow it — their names key cli-eval-results.json, and no results exist yet to churn.
Rodriguespn
left a comment
There was a problem hiding this comment.
Thanks for updating this for the GPT-6 changes. Can we make three changes before merging?
- Can we record
environmentMarker().cliVersionin raw and exported results, so each stable/beta run names the exact CLI binary? - Can we remove eager stable/beta resolution from the workflow, pass through only manual overrides, and let
run-vercel-evals.tsresolve channels from the actual pairs? - Can we add a CLI-owned pinned experiment using
codexGpt6LunaandskipUnlessCli, so pinned/stable/beta use the same eligibility rules without changing the shared benchmark/regression experiment?
…r channel resolution to the controller, and give the CLI suite its own pinned column Records environmentMarker().cliVersion (the CLI binary that actually ran) into raw and exported results instead of the near-always-empty frontmatter pin, widening cliVersionSchema to accept prerelease versions so beta runs validate. Strips eager npm resolution from eval-refresh.yml's prepare job so run-vercel-evals.ts's requiredCliChannels narrowing runs as intended, folding the now-pass-through step into "Prepare inputs" and treating a blank env var as unset in resolveChannelPins. Adds a CLI-owned codex-gpt-6-luna-cli-pinned experiment (skipUnlessCli, no localStack override) so pinned/stable/beta share eligibility rules, and reverts the shared benchmark/regression experiment to its original suite.
|
all three done in fab2e19, CI green.
two things i hit on the way that weren't in your list:
|
Final chunk of the closed #308 — the piece @mattrossman asked for: the minimal CLI suite plumbing and CODEOWNERS, standalone, with no CLI experiment internals to review. 15 files, 260 lines, and four of those files are 11–13 lines each.
Everything it depended on is now on
main(#315'sexperiments/<owner>/layout, and #324 + #325's sandbox options), so this is based onmainand the diff is only its own content.What it adds
clias an eval suite and an experiment suite,@supabase/cliownership over/evals/cli/,/experiments/cli/andcli-eval-results.json, and the workflow wiring soeval-refreshandappend-gh-pages-historyknow the suite exists.The substance is five environment columns: one scenario run unchanged across forced CLI environments, so a failure isolates to which environment broke. They're thin now that
experiments/presets.tsexists — the whole of the Docker-less column is:codex-gpt-6-luna-cli-pinnedinterface: clieval that isn't hosted-linked…-cli-stablelatest…-cli-betabeta…-cli-nodaemonneedsDocker: false+projectRunning: false…-cli-absentdockerbinaryneedsDocker: false+projectRunning: falseAll five columns share one
skipEval: skipUnlessCli, so they run the same eval set and stay comparable — which is the whole point of the suite. An earlier revision made the pinned column the shared benchmark experiment with'cli'appended to itssuite; that experiment has noskipEval, so it picked up hosted-linked evals the other four skip. A CLI-owned pinned experiment fixes that and leaves this PR touching nothing outside CLI-owned paths.skipUnlessCli/skipUnlessDockerlessare the only things left over from the oldexperiments/_lib/; they live inexperiments/cli/lib/, which discovery ignores for free since it only matches*.experiment.tsdirectly under an owner directory.Verified, including the parts tests can't reach
format:check,typecheck, and the sandbox, core, framework,test:cli-lib, vercel-runner and web suites all pass.Two things unit tests can't cover, checked directly instead:
experiments/cli/lib/is correctly not treated as an experiment, and the five columns resolve to the intended runtimes and channels (beta,beta,beta,stable, and none for the pinned baseline).cli_stable_version/cli_beta_versiondispatch inputs and otherwise letsrun-vercel-evals.tsderive the channels from the actual pairs. Pre-filling both env vars would have short-circuited that narrowing.Each run's results now record the CLI version the sandbox actually installed, read from the session's environment marker, so a
stablerow names its binary rather than just its channel. That neededcliVersionSchemawidened — it rejected every prerelease, so a beta run's real version could not have been recorded at all.test:cli-libcarries--passWithNoTestsdeliberately:evals/cli/has no scorer tests until #281/#314/#316 land, and without the flag the script's exit code depends on which of its two paths happens to be populated.Note on the column names
These follow the
gpt-6-lunarename from #328. They keycli-eval-results.json, and no results exist yet, so there is nothing to churn — but that also means the names should settle before the suite is first run.Next
#281, #314, #316 and #307 get re-parented onto
mainonce this lands — they currently point at the retained branch of the closed #308. /cc @Rodriguespn @kanadgupta