Rule Configuration
Lint rules are configured in chant.config.ts under the lint key.
Basic Configuration
Section titled “Basic Configuration”export default { lint: { rules: { "EVL001": "error", "COR004": "warning", "COR008": "off", }, },} satisfies ChantConfig;Severity Levels
Section titled “Severity Levels”| Severity | Effect |
|---|---|
"error" | Fails the lint run (non-zero exit code) |
"warning" | Reported but does not fail |
"info" | Informational notice |
"off" | Disables the rule entirely |
Presets
Section titled “Presets”Use extends to inherit rule configurations:
export default { lint: { extends: ["@intentius/chant/lint/presets/strict"], rules: { "COR004": "off", // override preset }, },} satisfies ChantConfig;Presets are resolved recursively. Local rules override inherited ones.
Selecting a lexicon preset (chant #2113)
Section titled “Selecting a lexicon preset (chant #2113)”This is a different, narrower thing from extends above. Core’s extends
bundles (strict, relaxed) set AST rule severities. lint.presets is a
lexicon’s own bundle of which of its post-synth check ids get reported
at all, the way tflint-ruleset-terraform ships recommended (13 of its 20
language rules) and all (all 20). A lexicon that ships presets exposes
them through its plugin’s lintPresets(). See Presets,
lintPresets()
for the lexicon-authoring side.
export default { lexicons: ["terraform"], lint: { presets: { terraform: "recommended" }, },} satisfies ChantConfig;The key is the lexicon’s name (plugin.name, e.g. "terraform", not a
serializer name), and the value is a preset name that lexicon’s
lintPresets() defines. Naming a preset the lexicon doesn’t define, or
omitting the entry
for a lexicon that ships presets at all, falls back to "recommended", the
safe default, matching tflint’s own precedent of shipping a curated subset
rather than everything.
A rule the active preset excludes is not the same as rules: { ID: "off" }.
It never runs the severity-override pass in the first place, so it is
counted separately. chant build reports “N post-synth finding(s) not
reported: excluded by the active lint.presets preset,” distinct from the
lint.rules-suppressed count. An explicit rules entry for that id always
wins over the preset and reports it anyway, the same precedence tflint
documents (rule config over preset over disabled_by_default). So you can
opt one report-only rule back in under recommended without switching the
whole lexicon to all:
export default { lexicons: ["terraform"], lint: { presets: { terraform: "recommended" }, rules: { "TF011": "warning" }, // re-enabled even though it's report-only },} satisfies ChantConfig;A lexicon that ships no lintPresets() at all is unaffected by
lint.presets. Every one of its findings reports regardless, exactly as
before this existed.
File-Specific Overrides
Section titled “File-Specific Overrides”Apply different rule settings to specific file patterns:
export default { lint: { rules: { "COR004": "warning" }, overrides: [ { files: ["src/legacy/**/*.ts"], rules: { "COR004": "off" }, }, ], },} satisfies ChantConfig;Rule Options
Section titled “Rule Options”Some rules accept an options object as the second element of a tuple:
rules: { "COR009": ["warning", { max: 12 }],}Post-Synth Checks and Policies
Section titled “Post-Synth Checks and Policies”rules applies to a post-synth check id (a lexicon’s WAW019, WK8005, …)
and a project policy’s own id (ORG-COST-CENTER) exactly the same way it
applies to COR004 or EVL001 above — same key, same severities, "off"
suppresses it entirely:
export default { lexicons: ["aws"], lint: { rules: { "WAW019": "off" }, // this project's scenario needs an open SSH ingress },} satisfies ChantConfig;This is the whole surface for suppressing a post-synth or policy finding.
Two things that work for COR/EVL/COMP rules do not apply here:
- File-specific
overrides— a post-synth check runs over the whole synthesized output, not one file, so there is no file path to match a glob against. chant-disablesource comments — a post-synth diagnostic’s only locator (entity) names a resource in the synthesized output (a CloudFormation logical id, a Kubernetesmetadata.name), not a source file or line, and several checks never set it at all. There is no reliable anchor to put a directive at, so a project-widerules: { ID: "off" }is the only suppression path.
A suppressed post-synth/policy finding is not silently dropped: chant build
prints a count (N post-synth finding(s) suppressed via lint.rules) so the
suppression stays visible.
The chant audit failure-severity floor (chant #2113)
Section titled “The chant audit failure-severity floor (chant #2113)”rules/severity above decides what a rule reports by default. --fail-on
on chant audit is a separate lever. It decides what makes the exit code
non-zero, the job tflint’s --minimum-failure-severity does. It takes one
of four values.
--fail-on | Exit 1 when… |
|---|---|
none (default) | never (read-only) |
merge-worthy | any merge-worthy finding exists |
warning | any error- or warning-severity finding exists |
error | any error-severity finding exists |
error is the floor a rule can ship under before it is trusted to fail a
pipeline. Land it at severity: "warning" (or configure it to "warning"
via rules above), run --fail-on error in CI, and the new rule is visible
in every report without breaking a single build. Nobody’s pipeline is
pinned to a --fail-on value the new rule would trip. Promote it to
"error" later, in the rule’s own default or via rules: { ID: "error" },
once you’re confident. The exact same --fail-on error pipeline then starts
enforcing it, with no separate opt-in step.
chant audit . --fail-on errorSee the chant audit reference for the full
exit-code table.