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,postgres(default),sqlite, ormysql. 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.--no-tests: opt out of test emission. The behavioral + stateful + structural test suite (tests/directory) and the conformance runner are emitted by default for every supported target; pass--no-testswhen only the service skeleton is needed. 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 default test emission would produce incomplete property strategies. No-op when combined with--no-tests. 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 Synthesis Pipeline.--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.--no-tests: exclude test files from drift detection. Matchescompile's default-on behaviour: test files are included by default; pass--no-teststo skip them.
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).testglobstests/run_conformance.*and dispatches to the single file it finds; the file's shebang line declares the interpreter (#!/usr/bin/env python3/node/bash), so the wrapper carries no per-language mapping.--profile <name>: conformance profile, one ofsmoke(fast),thorough(default), orexhaustive(multi-minute). Forwarded to the runner asargv[1]and asSPEC_TEST_PROFILE.--server-url <url>: base URL for the service under test. Optional; if omitted, each runner picks its own per-target default (http://localhost:8000for python-fastapi,http://localhost:8080for ts-express / go-chi). When set, exported asSPEC_TEST_BASE_URL. The service must be running with the sameADMIN_TOKENthat is exported to the runner, so it can authenticate against/admin/resetbetween phases.--runner-bin <path>: override the interpreter read from the runner's shebang.
test is a thin uniform wrapper around the per-target runner that
compile emits, with the same exit-code contract (0 / 1 / 2) and the same
SPEC_TEST_* env-var contract across all three languages. The runner
itself is part of the generated test suite.
For a project compiled with --no-tests, test exits 2 with a hint to
re-compile.
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 and 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. |
Playground
Type a spec, see its IR and Dafny kernel without installing the CLI
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.