CLI Reference
Edit on GitHubSubcommands, flags, and exit codes for the spec-to-rest binary
Last updated:
The spec-to-rest binary is built from
modules/cli
and runs locally via sbt "cli/run …" or as a GraalVM native image. Every
subcommand exits with a numeric code; CI consumers should branch on these.
Subcommands
| Command | Purpose |
|---|---|
check | Parse, type-check, and lint a spec; no codegen. |
verify | Run the Z3 + Alloy verification engine on a spec. |
compile | Emit a project from a spec. Runs verify as a gate by default. |
diff | Show which files would change if compile ran against an existing output directory. |
test | Invoke the emitted conformance suite against a running service. |
inspect | Print the IR or Dafny prompt material for one operation (debugging). |
synth try / synth verify / synth verify-all | LLM-driven Dafny body synthesis (Phase 6). |
Global flags
These flags are accepted by every subcommand:
--verbose/-v— show stage timings and per-check breakdowns on stderr.--quiet/-q— suppress everything except errors.--color/--no-color— force ANSI color on or off. Default is auto: color is enabled when stderr is a TTY andNO_COLORis not set.CLICOLOR_FORCE=1forces color even when piped.
compile flags
sbt "cli/run compile [flags] <spec-file>"--framework <id>/-f— framework (defaultfastapi). Known: fastapi, chi, express.--db <id>— database dialect (defaultpostgres):postgres,sqlite,mysql. The accepted set depends on the chosen framework.--lang <id>— language (python,go,ts). Always accepted and validated against the framework's supported languages; only required when the framework supports more than one language (otherwise inferred). Passing a language the framework does not support (e.g.--lang go --framework fastapi) is a hard error, not a silent fallback.
Any unsupported (language, framework, database) combination is rejected
with a typed error that lists what the chosen framework actually supports —
the resolver never warns-and-falls-back to a default target.
--out <dir>/-o— output directory (required).--dry-run— run the full pipeline (parse, verify, build, in-memory emit) but do not write anything. Prints a manifest ofcreate/update/unchanged/preserveactions per file. Exits 0 even when the plan is empty.--ignore-verify— skip the verification gate. Emits unverified code with a warning. Use only for spec exploration.--with-tests— also emit the behavioral + stateful + structural test suite (tests/directory) and the conformance runner. Supported for all nine targets (python-fastapi-*,ts-express-*,go-chi-*× postgres / sqlite / mysql); the suite is emitted in each target's native language (pytest + Hypothesis + Schemathesis / Vitest + fast-check /go test+ rapid). See Test Generation.--strict-strategies— fail compile when--with-testswould emit incomplete property strategies. See Test Generation.--with-synthesis— splice verified Dafny bodies (translated to the target language) into the emitted project. Requiressynth verifyto have populated the cache. See LLM Integration.--allow-skeletons— fall back to unverified skeleton bodies (fromsynth verify --fallback) when the verified cache misses. Generated handlers halt at runtime with a DafnyHaltExceptionwhen invoked.--synthesis-partial— use verified bodies where cached; for anLLM_SYNTHESISop with no verified body, emit a fail-loud stub (skipped by testgen) instead of failing the build.--synthesis-model <name>— model to look up in the cache (defaultclaude-sonnet-4-6).--synthesis-temperature <num>— temperature to look up in the cache (default1.0).--synthesis-cache-dir <path>— override the cache root.--dafny-bin <path>— path to the Dafny binary (defaults to$DAFNY_BINorPATH).--dafny-translate-timeout <sec>— wall-clock timeout fordafny translate(default 60s).
--dry-run example
$ sbt "cli/run compile --framework fastapi --db postgres --ignore-verify \
--dry-run --out /tmp/svc fixtures/spec/url_shortener.spec"
create .gitignore
create Dockerfile
create Makefile
create alembic/env.py
create app/main.py
create app/routers/url_mappings.py
...
✔ dry-run: 26 files planned for /tmp/svc (create=26 update=0 unchanged=0 preserve=0)diff flags
sbt "cli/run diff --framework <id> --db <id> --out <dir> <spec-file>"--framework/--db/--lang— same target axes ascompile.--out <dir>/-o— directory to compare against (required).--ignore-verify— compare regardless of whether the spec verifies.--with-tests— include the test files in the comparison.
diff exits 0 when the directory is in sync with what compile would
produce, 1 when there is drift. The output lists only files that would be
created or updated; unchanged and user-preserved files are summarised at the
bottom.
test flags
sbt "cli/run test --out <generated-dir> [--profile thorough] [--server-url ...]"--out <dir>/-o— directory containing the previously emitted project (required). Must containtests/run_conformance.py(the Python runner;ts-express-*/go-chi-*suites are run natively — see below).--profile <name>— conformance profile:smoke(fast),thorough(default),exhaustive(multi-minute).--server-url <url>— base URL for the service under test (defaulthttp://localhost:8000). The service must be running withENABLE_TEST_ADMIN=1so the runner can hit/__test_admin__/resetbetween phases.--python-bin <path>— interpreter to use (defaultpython3).
test is a thin wrapper around python tests/run_conformance.py <profile> —
the runner itself is part of the
generated test suite. It drives the Python
runner only, so it applies to python-fastapi-* targets emitted with
--with-tests. ts-express-* and go-chi-* now emit fully native
conformance suites, but with native runners — run those directly:
ts-express-*:node tests/run_conformance.mjs <profile>(ornpm test), service booted withENABLE_TEST_ADMIN=1.go-chi-*:bash tests/run_conformance.sh <profile>(orgo test -tags conformance ./tests/...), against a server built with-tags conformanceandENABLE_TEST_ADMIN=1.
Invoking spec-to-rest test against a ts/go project exits 2 (no
tests/run_conformance.py); a unified multi-runner wrapper is a tracked
follow-up.
verify flags
See Verification Pipeline for the full reference. The most useful flags for CI:
--timeout <ms>— per-check Z3/Alloy timeout (default 30000).--parallel <n>— number of concurrent checks (0for serial; default is the host's available processors).--json/--json-out <path>— emit a machine-readable report to stdout or a file (suppresses text output). The--dump-*flags print the translation and exit before the solver runs.--explain— extract Z3 unsat cores and surface contributing spec spans on failures.--dump-smt/--dump-alloy— write the translated SMT-LIB or Alloy source and exit without running the solvers.
check flags
check is the cheapest stage: parse → IR → lint. It does not invoke Z3 or
Alloy. Use it as a fast pre-commit gate.
sbt "cli/run check fixtures/spec/url_shortener.spec"inspect flags
inspect dumps internal compiler state for debugging.
--format <fmt>—summary(default),json(full IR + synthesis tally),ir(raw IRtoString),dafny(Dafny module skeleton),dafny-prompt(LLM prompt material per LLM_SYNTHESIS operation).--operation <name>— filterdafny-promptto a single operation.
Exit codes
| Code | Meaning | Where it comes from |
|---|---|---|
0 | Success. | All commands. |
1 | Spec violation: parse error, type error, lint error, verification failure, or diff drift. | check, verify, compile, diff. |
2 | Generation / translator error: dafny translate failure, missing run_conformance.py, infra failure during test, translator coverage gap. | compile, test, verify. |
3 | Backend or test failure: Z3/Alloy backend crash, conformance test failure (pytest non-zero). | verify, test. |
4 | Trust limitation: a check completed but used a soundness-limited approximation. | verify. |
CI consumers can treat 0 as pass, 1 as user error to surface verbatim,
2–3 as infrastructure problems requiring a retry or operator
intervention, and 4 as a soft warning.
Environment variables
| Variable | Effect |
|---|---|
NO_COLOR (any non-empty value) | Disable ANSI color in --color=auto mode. Honors no-color.org. |
CLICOLOR_FORCE | Force color even when stderr is not a TTY. |
DAFNY_BIN | Default path for the Dafny binary used by compile --with-synthesis and synth verify. |
ANTHROPIC_API_KEY / OPENAI_API_KEY | Required by synth try / synth verify for LLM calls. |
SPEC_TEST_BASE_URL, SPEC_TEST_PROFILE | Set by test when launching run_conformance.py; can also be exported manually if invoking the runner directly. |
Install
Native binary, Docker image, GitHub Action, or from source
Roadmap
Project-level phase ledger, the per-program milestone history (Cats Effect 3 migration, translator soundness, test generation, synthesis), the per-pipeline capability inventory, the live follow-up backlog, and the wontfix decisions of record.