Eval commands
Score an uploaded local context or an existing Cassis branch against the project's gold cases, and maintain those cases.
eval run
Runs the project’s eval suite and prints per-case results. Failed cases include generated and gold SQL, row counts, missing concepts, and the judge’s verdict and reasoning when available. With --case, passed cases print the same evidence, so you can check that a context change makes a case pass for the right reason; a run of the whole suite lists passed cases on one line. Row values are available in --json and the app, not in terminal output. Generated SQL can contain literals read from your data, so handle CI logs with the same care as queries. Long evidence is explicitly marked as truncated. By default, the CLI uploads the local context as ephemeral run input; it does not publish or replace the project’s context. Pass --branch to score an existing Cassis branch instead, in which case local files are not uploaded.
# Score the local files and wait for results
cassis eval run --project ...
# Run only specific cases (repeatable)
cassis eval run --project ... --case 019f0000-... --case 019f0001-...
# Run against an existing Cassis branch instead of the local context
cassis eval run --project ... --branch feature-x
# Start the run and return immediately, poll in the web app
cassis eval run --project ... --no-wait
# Run every case 3 times and compare the attempts
cassis eval run --project ... --repeat 3
- Subset
--case <id>(repeatable) runs only the named cases. Use it to prove one freshly added case in seconds instead of rerunning everything. Ids come fromlist-cases.- Run input
- Omit
--branchto upload and score the local context without publishing it.--branch <name>selects an existing Cassis branch and ignores the local tree. An unknown name exits 2 (usage error); use--labelto name a local run after your git branch. - Repeat
--repeat N(2 to 5) runs every case N times on the same context and model, then prints how the attempts compare per case instead of the per-case list: see eval compare. A repeat run measures noise: it opens no issue in Review and is not the run the app shows before publishing. It exits 1 only when a case failed every attempt; a case that flipped is the noise being measured.--jsonadds the comparison undercomparison. Combine it with--caseto measure one case. Needs cassis-cli 3.4.- Run label
- Local runs are labeled with your git branch name on the Evals page, taken from the CI environment or checkout.
--labeloverrides it, and is rejected with--branch, whose runs use the Cassis branch name. - Waiting
--waitor--no-wait,--poll-interval(5 seconds),--timeout(30 minutes). The run keeps going server-side if the CLI stops waiting. Ctrl-C cancels the run and exits 130.- JSON
--jsonprints the final run and its results as one JSON document on stdout; the started/progress lines go to stderr, socassis eval run --json | jqworks (cassis-cli 1.7).- Deep link
- It prints a link to the run’s page in the Evals UI.
--app-urlorCASSIS_APP_URLoverrides the base URL when the web app is not served from the API host.
eval compare
Prints how the attempts of a repeat run compare, case by case: the same comparison eval run --repeat prints when the run ends, and the run’s page in the app shows.
cassis eval compare 019f0000-0000-7000-8000-00000000aaaa --project ...
- Summary
- How many cases passed every attempt, failed every attempt, or flipped, with the flips counted by cause.
- Each case that did not pass every time
- Its attempts that passed, how many distinct SQLs the agent wrote, the cause, and the case id.
- Cause
generation: the agent wrote different SQL from the same context, so the context leaves room for both.judge: the judge ruled differently on the same SQL; check the gold SQL and the question’s wording.both: the two at once.unattributed: the evidence decides neither side.- JSON
--jsonprints the comparison record as the server returns it.- Exit
- 0 once the comparison is printed, including for a run still in progress, which it says. 3 on a transport or API error, including a server too old to compare runs.
eval add-case
Adds an approved question and SQL case to the project’s suite. Before running it, have a domain owner or reviewer validate the SQL and the business assumptions it encodes. Executable SQL alone does not establish correct business meaning.
cassis eval add-case --project ... \
-q "What is the average order value?" \
--gold-sql "SELECT AVG(ORDER_VALUE) FROM STALLORA.FCT_ORDERS WHERE IS_DELIVERED = TRUE"
# Multi-line SQL from a file, which avoids shell quoting issues
cassis eval add-case --project ... \
-q "What was revenue in 2025?" \
--gold-sql-file gold.sql
- The gold SQL is run first
- On an executable data source, Cassis runs your SQL before storing the case, so a case that cannot execute never enters the suite. This catches execution errors, not incorrect business interpretation.
- What it stores
- The question plus the gold SQL. On a warehouse-connected project, both generated and gold queries run and their rows are compared deterministically with fuzzy numeric matching. On a schema-only project, an LLM judge compares their SQL logic.
- Rejections
- Exit 1 on a duplicate question or on gold SQL that does not run. Both print the reason; nothing is added.
- Footprint warning
- Right after adding the case, it warns when the gold SQL reads tables the context lacks, as
list-casesdoes. - Entry check
- Cassis then runs the new case three times on the current context, in the background, and the command says so. A minute or two later,
list-casesflags it if the attempts disagree or none passed. Adding a case is never refused because of the check, and the check never blocks your own runs. - No checkout needed
- It talks to the project, not to your files, so it takes no path and no
--base-path.
eval list-cases
Lists the project’s cases, one id and question per line. The ids are what history and delete-case take.
cassis eval list-cases --project ...
# Resolve the gold SQL against a context branch
cassis eval list-cases --project ... --branch feature-x
# Include the gold SQL and the footprint
cassis eval list-cases --project ... --json
- Footprint
- Each case’s gold SQL is resolved against the unpublished context. A case whose SQL does not fully resolve is flagged, with the reason under its line: a table the context lacks, a bare name matching several context tables, or SQL the dialect cannot parse. Qualify the name or fix the gold SQL to make it resolve cleanly. Projects without a data source show no footprint.
- Entry check
- A case whose entry check found it flaky (the attempts disagree) or failing (none passed) is flagged with how many attempts passed. A flaky case’s verdict is noise until its question or gold SQL is tightened; a failing one points at its gold SQL or at a context gap. A case still being checked says so. Editing a case’s question or gold SQL in the app checks it again.
- Branch
--branch <name>resolves against a context branch instead. An unknown name exits 2.- JSON
--jsonadds each case’s gold SQL, its footprint (state,tables,unresolved,ambiguous,shadowed, anderror), and itsentry_check(state:running,stable,flaky,failing, ornot_checked;passed,total,run_id,checked_at).
eval history
Shows how one case has behaved across runs: the same account as the case’s page in the web app.
cassis eval history 019f0000-0000-7000-8000-000000000000 --project ...
# The same record as JSON
cassis eval history 019f0000-0000-7000-8000-000000000000 --project ... --json
- Health
- A verdict (
passing,failing,noisy, orchanged across configurations), the pass rate, how many configurations disagree with themselves, average plan and execution time, and the judge’s divergence categories and footprint states seen across results. - Results
- Every result grouped by the configuration it ran under (context version or branch, model, Cassis version), newest first, each with its verdict, divergence, footprint state, and timings.
- Reading it
- Verdicts that differ inside one configuration are noise to act on: fix the case or the context until it is stable. A verdict that changes across configurations is the context or the model moving.
- Exit
- 1 when the project has no case with that id.
eval delete-case
Deletes one case by the id list-cases prints. Use it to prune a case that is stale or wrong, for instance gold SQL encoding a definition the context has since changed.
cassis eval delete-case 019f0000-0000-7000-8000-000000000000 --project ...
Exit 1 when the project has no case with that id; nothing is deleted.