Config File
chant uses a chant.config.ts file at the project root for configuration.
Minimal Config
Section titled “Minimal Config”export default { lexicons: ["aws"],};Full Config
Section titled “Full Config”export default { lexicons: ["aws"],
lint: { extends: ["@intentius/chant/lint/presets/strict"],
rules: { "EVL001": "error", "COR002": "warning", "COR009": "off", },
overrides: [ { files: ["src/legacy/**/*.ts"], rules: { "EVL001": "warning", "COR005": "off", }, }, ],
plugins: ["./lint-rules/org-standards.ts"], },};Fields
Section titled “Fields”lexicons
Section titled “lexicons”An array of lexicon names the project uses.
ownership
Section titled “ownership”Opt-in cloud-side ownership marking. When stack is set, the serializer stamps a chant ownership marker carrying this stack (and optional env) identity onto every supported resource at synthesis time:
ownership: { stack: "billing", // stamped onto every resource (enables marking) env: "prod", // optional environment identity // enabled: false, // set to disable without removing the block}env can also reference a declared build-time parameter, so the marker takes the value the build was invoked with rather than a value fixed when the config loaded:
ownership: { stack: "billing", env: { param: "env" } },buildParams: { env: { type: "string", default: "dev", env: "BILLING_ENV" },},With that, chant build --param env=prod stamps env=prod into the marker and binds params.env to "prod" for source in the same resolution. A reference to a parameter the config does not declare, or one with no value for the build, is a build error. A literal env next to an env parameter that resolved to something else gets a warning naming both values.
The marker is the record that later lets delete be precise without an authoritative state file — ownership lives on the cloud resource, not in a file chant has to host or lock. It is stamped into each target’s native metadata channel:
| Channel | Targets | Keys |
|---|---|---|
| Labels | Kubernetes, GCP (Config Connector) | app.kubernetes.io/managed-by=chant, chant.intentius.io/stack, chant.intentius.io/env |
| Tags | AWS | chant:managed-by=chant, chant:stack, chant:env |
| Tags | Azure | chant-managed-by=chant, chant-stack, chant-env |
The marker carries stack identity, not just managed=true, so one stack never mistakes another’s resources for its own. Ownership means “carries chant’s marker”, not “carries only chant’s marker” — co-stamping with other tools (ArgoCD, Terraform) is fine, and explicit per-resource tags/labels win on key collisions. Walk-away cost stays zero: these are standard tags/labels, nothing proprietary.
environments
Section titled “environments”An optional array of environment names the project deploys to. An environment is just a named identity chant threads through the operational layer — there is no per-environment config block to maintain.
environments: ["local", "staging", "prod"],--env <name> selects one and defaults to local when omitted. The selected environment is what chant lifecycle diffs against, the environment organizational policy evaluates against during chant build, and the key the component release ledger records each deploy under — as in chant run --components <name> --env <env> and chant components status <env>. The env stamped into the ownership marker is a separate setting, ownership.env, which can reference a build parameter so the two stay one value.
An entry containing * is a glob pattern, declaring an unbounded family of environments at once — per-PR previews, per-suite test copies:
environments: ["staging", "prod", "pr-*"],--env pr-42 (and, with a param-bound ownership.env, --param env=pr-42) is then legal; any name no entry covers is still rejected. Matching is literal first, then by pattern; * matches any run of characters and is the whole pattern syntax — no ?, no character classes, no regex. A pattern entry can carry an endpoint like any other entry, and a literal entry always wins over a pattern for the same name.
An entry can also carry the endpoint that environment’s --live reads should target, instead of a bare name:
environments: [ "prod", { name: "floci", endpoint: "http://localhost:4566" },],This is for a local emulator (Floci, mudflaps) or any non-default endpoint: without it, --live --env floci shells out to each lexicon’s CLI honoring whatever the ambient shell happens to export (AWS_ENDPOINT_URL for AWS, FLY_FLAPS_BASE_URL for Fly) — and if that var isn’t set, the read silently targets real AWS/Fly instead of the emulator, returning an empty (but not erroring) result. Declaring the endpoint makes --env floci self-sufficient: chant injects it into the right ambient var for the read, unless that var is already set in the shell — an ambient value always wins, so nothing changes for a project that already exports it. If a --live describe still comes back with zero resources for an environment that has declared entities, chant warns rather than reporting a quiet “nothing here.”
lint.extends
Section titled “lint.extends”An array of preset configuration paths to inherit from:
extends: ["@intentius/chant/lint/presets/strict"]lint.rules
Section titled “lint.rules”A map of rule ID to severity or [severity, options] tuple:
rules: { "EVL001": "error", "COR009": ["warning", { max: 12 }],}lint.overrides
Section titled “lint.overrides”File-specific rule overrides using glob patterns:
overrides: [ { files: ["src/legacy/**/*.ts"], rules: { "EVL001": "warning" }, },]lint.plugins
Section titled “lint.plugins”An array of plugin paths to load custom lint rules:
plugins: ["./lint-rules/org-standards.ts"]Config Resolution
Section titled “Config Resolution”- Load
chant.config.tsfrom the project root - Resolve and merge all
extendspresets (in order) - Apply local
ruleson top - Load
plugins - At lint time, apply
overridesto matching files