Skip to main content

exd lint

Validate a flag namespace against the manifest spec. Reports every diagnostic (E-codes and W-codes) the linter can raise.

Synopsis

exd lint <path-or-uri>
[--format human|json]
[--http-backend curl|in-process]

Description

Loads the flag namespace at <path-or-uri>, runs the full lint pipeline (parse → typed-model construction → cross-file passes), and reports every diagnostic. Errors exit 1; warnings print but exit 0.

exd lint is the only producer of typed model values in the system — the SDK's Namespace::from_dir, the WASM bridge's lintFiles, and exd-server's push endpoint all funnel through the same pipeline. If exd lint says the manifest is valid, every downstream consumer agrees.

Use cases

  • Pre-commit hook. Block commits that introduce lint errors. Pair with the .pre-commit-hooks.yaml framework integration:

    exd lint .
  • CI gate. A green exd lint is the precondition for exd manifest push. The server runs the same pipeline on receipt and rejects unlinted uploads with 422.

  • PR review aid. Reviewers run exd lint --format json . | jq to see structured diagnostics — useful for spotting drift across renamed segments or retired flags.

  • Inspect a remote flag namespace. Lint a server-hosted manifest without pulling it first:

    exd lint exd-server://flags.acme.com/marketing
    exd lint https://raw.githubusercontent.com/acme/flags/main/marketing.tar.gz
  • Agent authoring. An agent generating TOML can lint after each edit to validate the flag namespace before proposing a diff.

Arguments and flags

Argument / flagRequiredNotes
<path-or-uri> (positional)yesLocal directory or remote URI. Schemes: file://, git+file://, git+https://, git+ssh://, https:// / http:// (tarball), exd-server://.
--format human|jsonno, default humanSee conventions § JSON output.
--http-backend curl|in-processnoOnly relevant for remote URIs.

Examples

Clean manifest

$ exd lint .
namespace 'marketing': 3 flags, 5 segments — OK

Errors and warnings

$ exd lint .
error[E037] flag 'onboarding-banner' env block '_' is missing 'variant'
at flags/onboarding-banner.toml
warning[W014] flag 'legacy-toggle' marked retired but evaluation traffic in last 7d
at flags/legacy-toggle.toml

1 error, 1 warning

Exit code is 1 because at least one E-code fired. Warnings alone exit 0.

JSON output

$ exd lint . --format json
{
"query": "lint",
"query_version": "1",
"schema_version": "1",
"exd_version": "0.4.0",
"inputs": { "target": "." },
"result": {
"namespace": "marketing",
"flags": 3,
"segments": 5,
"diagnostics": [
{
"code": "E037",
"severity": "error",
"file": "flags/onboarding-banner.toml",
"message": "env block '_' is missing 'variant'"
},
{
"code": "W014",
"severity": "warning",
"file": "flags/legacy-toggle.toml",
"message": "marked retired but evaluation traffic in last 7d"
}
]
},
"diagnostics": [],
"provenance": { "source": ["."], "engine": "static", "record_count": 0, "time_range": {} }
}

result.diagnostics is the lint output; the envelope-level diagnostics is empty for exd lint (lint diagnostics live in result, not in the top-level diagnostics channel that telemetry commands use).

Exit codes

CodeCondition
0No E-code diagnostics. Warnings may be present.
1One or more E-code diagnostics.
2Bad arguments; URI fetch failure; unreadable target.

Diagnostic vocabulary

The full set of diagnostics lives in reference/manifest/11-diagnostics.md. E001E039 are allocated; W001W016 are allocated. New diagnostics use E040+ / W017+.

See also

  • exd schema — what context shape the manifest's predicates require.
  • exd explain — static description of a flag (consumes the same typed model lint produces).
  • Manifest reference — every field, predicate operator, and diagnostic an E-code can flag.
  • Conventions--http-backend, JSON envelope, exit-code policy.