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.yamlframework integration:exd lint . -
CI gate. A green
exd lintis the precondition forexd manifest push. The server runs the same pipeline on receipt and rejects unlinted uploads with422. -
PR review aid. Reviewers run
exd lint --format json . | jqto 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/marketingexd 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 / flag | Required | Notes |
|---|---|---|
<path-or-uri> (positional) | yes | Local directory or remote URI. Schemes: file://, git+file://, git+https://, git+ssh://, https:// / http:// (tarball), exd-server://. |
--format human|json | no, default human | See conventions § JSON output. |
--http-backend curl|in-process | no | Only 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
| Code | Condition |
|---|---|
0 | No E-code diagnostics. Warnings may be present. |
1 | One or more E-code diagnostics. |
2 | Bad arguments; URI fetch failure; unreadable target. |
Diagnostic vocabulary
The full set of diagnostics lives in reference/manifest/11-diagnostics.md. E001–E039 are allocated; W001–W016 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.