Skip to content

Lint Rules

llms.txt lists every page for an agent

Rules under the CED prefix. The complete generated table is on All Rules; this page is the reasoning.

The two engines, and why there is only one

Section titled “The two engines, and why there is only one”

Cedar’s own validator runs in-process through @cedar-policy/cedar-wasm, the upstream validator itself. It answers “is this policy well-formed against this schema”.

Everything else is a TypeScript check. There is no cedarGate(), because organizational policy in chant is post-synth checks and a second policy engine would duplicate the lint engine.

permit (principal, action, resource);

Every scope unconstrained, no conditions. Legal Cedar, validates clean, grants everything to everyone. The rule is env-aware:

EnvironmentVerdict
dev / localwarn
stagingwarn
prodfail

Env-aware rather than absolute because an absolute rule gets suppressed the first time it fires during development, and a suppressed rule protects nothing. A permit with any constrained scope position, or any when/unless, is not bare.

A policy naming an entity type or action the schema does not declare fails everywhere, dev included. Two failure modes hide behind it:

  • The typo — App::Documnt. Generated classes make this a compile error before any check runs; it survives only inside when/unless expression strings.
  • The silent no-op — a scope naming an absent entity type parses, and Cedar’s request-envelope resolver answers “success, nothing”. The policy is well-formed, deployable, and can never fire.

Cedar only ever sees policies, while a chant build holds the policies and the infrastructure they govern in one entity graph. So a post-synth check can span both:

  • an entity id in a policy references an actual resource declaration
  • every declared bucket is covered by at least one forbid
  • no schema action lacks any policy

These are ordinary post-synth checks. They need both halves in the same build, which chant already has.

Terminal window
npx chant cedar coverage # schema -> generated artifacts

The MCP tool asks the other half:

cedar:coverage { "path": ".", "format": "text" }

It builds the policy set, hands each policy to Cedar’s own getValidRequestEnvsPolicy alongside the schema, and reports:

FieldMeaning
uncoveredDeclarations no policy can apply to
forbidOnlyDeclarations reachable only from a forbid — nothing grants them
inertPolicies whose request envelope is empty; they can never fire
unresolvedPolicies the resolver rejected outright
parseErrorsWhy the set would not split into policies

Container entity types (the ones that appear in no action’s appliesTo and exist only to be in) show as uncovered even under a bare permit. That is correct: no request can name them.

The post-synth checks encoding all of the above are INTENTIUS/chant#1651. Today the lexicon ships the source-level rule set and the validation plumbing; the checks that span policies and estate land there.

chant