+A syntax linter sees tokens and can say a key is misspelt. A configuration language with constraints in the type can say a port is out of range. Neither can say that two fields of one resource contradict each other, and neither can say that a resource in one file makes a resource in another file incoherent. They lack the values of every file in the build before anything is emitted. The fold does. A rule that runs over folded values is a pure function of its input, deterministic and free of I/O, which is what lets it run in an editor, and it sees the same data in the editor that it sees in CI, because the data is a function of the source. Two phases follow from this: rules over the declared values before serialization, and rules over the emitted artifact after. chant's lexicons carry the first kind and its post-synth checks the second; a governance tool built on the same evaluator carries both without naming them, in its config loader and in its plan guardrails. The contract those rules run under is `rules.md` (spec `1.4`). It names the input a check sees and when it runs, what a check may do and what a finding carries, and who supplies it. Fixtures for it wait on a harness hook (typescript-as-data#101).
0 commit comments