Catalogue management

The platform fact catalogue: what a rule condition is allowed to read

A fact like resident.age means the same thing in every rule — registering one is a platform decision, and checking references first stops you orphaning a live rule.

By The Kav team Published 2 min read

A fact is a named value a rule condition is allowed to read — resident.age, say — and it's catalogue data rather than tenant configuration, because a fact has to mean the same thing everywhere it's read. That's why registering a new one needs rules.catalogue.administer, a distinctly higher bar than rules.ruleset.author, which only lets someone author a rule set against a fact the catalogue already defines.

What you declare when you register one

A name, a value type (whole number, number, boolean, text, date or timestamp), whether it's nullable, and a cost class — Local, Cached or Remote. The cost class isn't cosmetic: CLAUDE.md's rule engine compiles every rule's conditions cheapest-first specifically so a free local check can eliminate a rule before an expensive remote one ever runs, and that ordering only works if every fact honestly declares which class it's actually in.

Marking a fact Remote requires naming the capability it's sourced from. That's the platform being explicit that a remote fact costs a real call to a real system every time a rule evaluates it — not a free lookup with a longer name.

Orphaned facts, and why checking is a deliberate extra click

Nothing on this platform fails if you register a fact and no decision point ever ends up referencing it in its input schema. That's a real, quiet failure mode: a fact sitting in the catalogue that nothing reads is authoring effort with no consumer. Each row carries a "check references" button rather than an always-visible count for every fact at once, because the underlying check the server runs — decisionPointCountReferencingFact — is a substring scan across every decision point, not a free index lookup. You pay that cost only for the fact you're actually curious about, when you're actually curious about it.

Run "check references" before you consider removing a fact that looks unused. A zero-reference result here is your actual evidence that nothing depends on it; guessing from the name alone is exactly how a rule quietly loses an input it needed.

Why this lives under the catalogue, not under rules authoring

The fact catalogue sits at /catalogue/facts, alongside the audit log and licence grants — the same shape as those two screens: platform-scoped, no master record to select, one full-width page. A decision point is tenant-authored and versioned; the facts it's allowed to read from are not, for the same reason a capability's contract isn't tenant-authored either — a shared vocabulary is what lets forty different rule sets, written by forty different registrars, all mean the same thing by resident.age.