Skip to main content

CLI conventions

Conventions shared across every exd subcommand. Each command page links back here rather than restating these.


Common flags

Every read-side exd subcommand (lint, eval, explain, fixtures, schema) and exd manifest * accept the following flags. Telemetry has its own common-flag set documented in exd/telemetry/.

FlagDefaultNotes
--manifest <path-or-uri>. (cwd)Path or URI to the flag-namespace directory. Scheme support: file://, git+file://, git+https://, git+ssh://, https:// / http:// tarballs, exd-server://. Lint errors in the manifest exit with code 1; lint warnings print to stderr and processing continues.
--http-backend curl|in-processenv-resolved (see below)Selects the HTTP transport for --manifest URIs, exd manifest *, and any server interaction. No effect on local paths.
--format human|jsonhumanAll read-side commands accept these two. exd fixtures additionally accepts rust and typescript. exd schema additionally accepts jsonschema, rust, and typescript.

exd manifest * additionally requires server coordinates:

FlagDefaultNotes
--server <url>$EXD_SERVER_URLHTTPS URL of an exd-server. Required for manifest push, manifest pull, and manifest versions.
--token <secret>$EXD_API_TOKENBearer token. Required scope is per-subcommand (namespace-write for push, namespace-read for pull and versions).

Environment variables

VariableRead byDefaultMeaning
EXD_SERVER_URLevery server-touching exd subcommandunsetEquivalent to --server.
EXD_API_TOKENevery server-touching exd subcommandunsetEquivalent to --token. Avoid leaking via shell history; prefer a per-CI secret.
EXD_HTTP_BACKENDevery HTTP-touching surfacein-process (when compiled with the default http-in-process feature)One of curl or in-process. curl shells out — useful in restricted environments. in-process uses reqwest.
EXD_DB_PATHexd-server, exd-server-admin./exd.sqliteSQLite database path.
EXD_LISTENexd-server127.0.0.1:8080Listen address (host:port).
EXD_GIT_ROOTexd-server./exd-data/git (sibling of EXD_DB_PATH)Directory containing one bare git repo per flag namespace: ${EXD_GIT_ROOT}/<tenant>/<slug>.git.
EXD_GIT_HOOK_BINARYexd-serversibling of the exd-server executablePath to the exd-server-git-hook pre-receive binary.

Variables read only by tests, internal hooks, or the git-hook binary are not listed here.


--ctx k=v parsing

Used by exd eval and (optionally) exd explain to construct an evaluation context.

  • Each occurrence of --ctx takes one key=value pair. Repeatable.
  • Split on the first =. Empty key, missing =, or unparseable input → exit 2 (error: --ctx '<raw>' is not in key=value form).
  • Duplicate keys across --ctx occurrences → exit 2.
  • Value coercion is deterministic — no heuristics:
    1. true / false → boolean.
    2. ^-?\d+$ parseable as i64 → integer.
    3. ^-?\d+\.\d+$ parseable as f64 → float.
    4. Otherwise → string.
  • Multi-valued attributes (StrList) are not reachable through --ctx. They are a runtime-only shape; the CLI cannot construct one.
  • Explicit-type overrides (--ctx-int, --ctx-bool, --ctx-str) are deferred. If the sniff rules disambiguate incorrectly for a real flag, use exd explain --ctx … --format json and inspect inputs.ctx.<key> to verify what was parsed.

Examples

--ctx user.id=u-1932 # string (after the integer-sniff fails on the `u-` prefix)
--ctx user.tier=pro # string
--ctx user.age=42 # integer
--ctx user.weight=68.5 # float
--ctx user.beta=true # boolean
--ctx country=US --ctx region=NA # two flat keys
--ctx user.country=US # dotted name; treated as a single flat key

Exit codes

Stable across lint, eval, explain, fixtures, schema, and manifest *.

CodeCondition
0Success. Includes fixtures runs that emit TBD synthesis-failed rows — those are known limitations, not tool errors.
1Domain failure: manifest lint errors, unknown flag, unknown environment in typed-env mode, runtime eval error with no fallback, version conflict on manifest push.
2Invocation error: malformed --ctx, missing required argument, unknown flag-level flag, manifest URI fetch failure.

exd telemetry * has its own exit-code table; see the telemetry index.


JSON output: provenance envelope

--format json always emits a single object with this shape (defined in crates/exd-client/src/telemetry/provenance.rs):

{
"query": "<command name>", // "eval" | "explain" | "fixtures" | "schema" | "telemetry.<query>"
"query_version": "1", // bumps when the result shape changes
"schema_version": "1", // bumps when the envelope itself changes
"exd_version": "<crate-version>",
"inputs": { /* parsed CLI args */ },
"result": { /* command-specific; see per-command pages */ },
"diagnostics": [ /* lint warnings + T-codes */ ],
"provenance": { /* see telemetry/07-provenance */ }
}

diagnostics carries warnings from the manifest load step plus any T-code diagnostics emitted by telemetry queries. The same signal that the human format prints to stderr is structured here for scripted consumers.

provenance.source is [manifest_uri] for read-side commands, the list of telemetry sources for telemetry commands. provenance.engine is "static" for static-only inspection (no context), "static+ctx" for context-bound explain, "static+synth" for fixtures, and an engine name ("inmemory", "duckdb", …) for telemetry commands. provenance.record_count is 0 for read-side; the consumed record count for telemetry.


Manifest fingerprint

A short hash, used by exd fixtures and exd schema to detect drift between generated test data and the current manifest:

fingerprint = sha256( canonical_toml(flag) || canonical_toml(seg₁) || … || canonical_toml(segₙ) )[..6]

Rendered as <namespace-slug>@<6-hex> in human and code-generation output (e.g. marketing@a1b2c3) and as a structured field in JSON output. Stable across whitespace and key-order changes — canonicalization walks the parsed AST.

For flag-namespace-wide invocations (exd schema without a <flag> argument), the hash covers every flag and every segment in declared order.


Discovering subcommand-level flags

Each command page in this reference enumerates its full flag set. The CLI also self-documents:

exd --help
exd <subcommand> --help
exd telemetry <subcommand> --help
exd-server-admin --help
exd-server-admin <subcommand> --help

The structured equivalent for the telemetry surface is exd telemetry capabilities --format json, which emits every command, parameter, and diagnostic the binary can raise.