Skip to content

List the validation rules

Available in: Python · Node · CLI · Browser

Enumerate the validator's numbered rules — the same catalogue every surface runs — to drive a UI legend, a docs page, or a coverage check without hard-coding rule numbers.

# what this shows: enumerate the validator's numbered rules + report the dictionary edition a file resolves to.
import laterite

# list_rules() returns one rich dict per numbered rule (keys incl. rule/title/severity/fixable/...).
rules = laterite.list_rules()

# dict_for(path) resolves a file to its (version, reason) tuple — e.g. ('4.1.1', 'exact').
ver = laterite.dict_for("examples/sample_site.ags")

print(len(rules))
print(sorted(rules[0])[:6])
print(ver)

assert len(rules) >= 20 and isinstance(rules[0], dict)
assert isinstance(ver, tuple) and ver[0] == "4.1.1"
27
['checks', 'fixable', 'observations', 'rule', 'severity', 'title']
('4.1.1', 'exact')

laterite.list_rules() returns one rich dict per numbered AGS4 rule — 27 of them, covering 1, 2, 2a, 2b, 3 … through 20. Each dict carries the rule number (rule), a human title, a prose checks description, a severity (error, or mixed where the rule flags some findings for information only), a fixable flag (whether .fix() / lat fix can repair it mechanically), and the observations it relates to in the divergence catalogue. It's the programmatic mirror of the rule table the CLI prints — drive a docs page, a UI legend, or a coverage check off it without hard-coding rule numbers.

laterite.dict_for(path) resolves a file to the dictionary edition the validator will judge it against, as a (version, reason) tuple — here ('4.1.1', 'exact') because the file's TRAN_AGS declares 4.1.1 and that edition is bundled. The reason tells you how the pick was made (an exact match, a fallback, …); see Dictionary selection for the resolution order.

Filter the list the same way you'd filter any list of dicts — e.g. just the mechanically-fixable rules:

fixable = [r["rule"] for r in laterite.list_rules() if r["fixable"]]

The severity field is mixed for rules that emit both errors and information-only findings (Rule 1 character-set, Rule 16 ABBR pick-lists, Rule 18 dictionary references); everything else is a hard error.

// what this shows: listRules() enumerates the numbered AGS4 rules; each RuleMeta carries severity + fixable.
import { listRules } from "laterite";
import assert from "node:assert/strict";

const rules = listRules();
console.log(rules.length);
console.log(Object.keys(rules[0]).sort());

// The mechanically-fixable rules, straight off the metadata — no hard-coded numbers.
const fixable = rules.filter((r) => r.fixable).map((r) => r.rule);
console.log("fixable:", fixable.join(", "));

assert.ok(rules.length >= 20);
assert.deepEqual(Object.keys(rules[0]).sort(), [
  "checks",
  "fixable",
  "observations",
  "rule",
  "severity",
  "title",
]);
assert.ok(fixable.includes("1")); // Rule 1 (character set) is mechanically fixable
27
[ 'checks', 'fixable', 'observations', 'rule', 'severity', 'title' ]
fixable: 1, 2a, 4, 6, 7, 8, 11a, 11b

listRules() returns the same 27-entry catalogue as an array of RuleMeta objects — rule / title / checks / severity / fixable / observations, the one-for-one mirror of Python's dicts. It's synchronous and needs no DuckDB peer, so a Node service can render a rule legend or a fixable-only filter (rules.filter(r => r.fixable)) straight off the metadata.

lat rules prints the whole catalogue as a table — no file needed:

lat rules
┌──────┬──────────────────────────────────────────────────┬──────────┬──────┐
│ Rule ┆ Title                                            ┆ Severity ┆ Fix? │
╞══════╪══════════════════════════════════════════════════╪══════════╪══════╡
│ 1    ┆ Character Set                                    ┆ mixed    ┆ yes  │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 2    ┆ Data Groups and Data Rows                        ┆ error    ┆      │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 2a   ┆ Line Termination                                 ┆ error    ┆ yes  │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 2b   ┆ Group Header Structure                           ┆ error    ┆      │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 3    ┆ Data Descriptors                                 ┆ error    ┆      │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 4    ┆ Field Count and GROUP Row Format                 ┆ error    ┆ yes  │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 5    ┆ Quoted Fields                                    ┆ error    ┆      │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 6    ┆ Embedded Carriage Returns                        ┆ error    ┆ yes  │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 7    ┆ Heading Order and Duplicates                     ┆ error    ┆ yes  │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 8    ┆ Typed Values                                     ┆ error    ┆ yes  │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 9    ┆ Dictionary Headings                              ┆ error    ┆      │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 10a  ┆ KEY Field Uniqueness                             ┆ error    ┆      │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 10b  ┆ REQUIRED Field Non-Emptiness                     ┆ error    ┆      │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 10c  ┆ Parent-Child Linkage                             ┆ error    ┆      │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 11a  ┆ Record-Link Delimiter                            ┆ error    ┆ yes  │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 11b  ┆ Record-Link Concatenator                         ┆ error    ┆ yes  │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 11c  ┆ Record-Link Resolution                           ┆ error    ┆      │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 13   ┆ PROJ Group Presence and Row Count                ┆ error    ┆      │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 14   ┆ TRAN Group Presence and Row Count                ┆ error    ┆      │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 15   ┆ Unit Definitions                                 ┆ error    ┆      │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 16   ┆ Abbreviation Definitions                         ┆ mixed    ┆      │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 17   ┆ Data Type Definitions                            ┆ error    ┆      │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 18   ┆ DICT Group for Non-Standard Names                ┆ mixed    ┆      │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 19   ┆ GROUP Name Format                                ┆ error    ┆      │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 19a  ┆ HEADING Name Length and Character Set            ┆ error    ┆      │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 19b  ┆ HEADING Name Structure and Cross-Group Borrowing ┆ error    ┆      │
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 20   ┆ File Attachments                                 ┆ error    ┆      │
└──────┴──────────────────────────────────────────────────┴──────────┴──────┘

The Severity and Fix? columns are exactly the severity / fixable fields the library surfaces expose — mixed marks a rule that also emits information-only findings, and yes marks one fix can repair mechanically.

Open the web app and find the rule catalogue under Tools — the same 27 numbered rules with their titles, severities, and fixable flags, rendered from the wasm build. When a validation run flags a finding, it links back to this explainer so you can read what the rule checks without leaving the page.

Every surface reads the same rule catalogue from the one engine, so the numbers, titles, severities, and fixable flags never drift between a Python legend, a Node UI, the CLI table, and the browser explainer.

See also: CLI reference · Dictionary selection