Alpha The shape of the args bound by build. Must
extend JsonValue because rules round-trip through JSON
persistence. Defaults to JsonValue. Use
definePrimitive so TypeScript can infer this from build's
parameter.
Unique, namespaced identifier (e.g. limetech.is-admin).
Subject slots the predicate will read at evaluation time. Used by validate to flag rules that reference slots a caller can't provide.
A named, parameterised check that a Rule can refer to by id.
Each primitive declares which subject slots it needs (
reads) and takes some args. Callingbuild(args)returns the actual check, a function that reads from a RuleScope and returnstrueorfalse. Primitives are registered once at bootstrap; rules reference them by id from then on.Display fields (title, description, icon, a custom args editor) live in ConfigMetadata, passed alongside the primitive when registering it. Same pattern as WebComponentRegistry and CommandBus.
Example
A primitive that reads one slot. The args shape lives on
build's parameter; TypeScript infersTArgsfrom there.Remarks
An id must contain a
.(e.g.limetech.is-admin,pluginx.has-feature) so two unrelated authors can't accidentally claim the same one, and because the same id space is shared with saved rules, the prefix keeps those from colliding too.There is no separate dependency-injection mechanism: the code that registers a primitive already has access to whatever it needs (translator, http, repositories, etc.) and the
buildcallback closes over them.If a slot from
readshas no provider, get returnsundefinedand the predicate should returnfalse. Primitive authors should also fail closed on unexpected args or downstream errors. The fail-closed behavior when a predicate does throw is part of compile's contract. See there for details.See