AlphaThe 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.
Union of context keys the predicate is allowed
to read. Inferred from reads by definePrimitive. Defaults
to every key in ContextMap.
AlphaidUnique, namespaced identifier (e.g. limetech.is-admin).
AlphareadsContext keys the predicate will read at evaluation time. Used by validate to flag rules that reference keys a caller can't provide, and by the type system to narrow ContextScope.get to just those keys.
AlphaBind args to a predicate. compile
calls this once per ref leaf in the rule tree.
The args from the ref leaf.
A function that reads from a ContextScope and
returns true or false.
A named, parameterised check that a Rule can refer to by id.
Each primitive declares which context keys it reads (
reads) and takes some args. Callingbuild(args)returns the actual check, a function that reads from a ContextScope 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 context key. The args shape lives on
build's parameter; TypeScript infersTArgsfrom there, andTReadsfrom thereadstuple.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 context key from
readshas no provider, ContextScope.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.readsis areadonlytuple, so the predicate'sscope.getparameter is restricted to keys declared here. The trade-off is that callers should not mutate the array after construction; the registry implementation already treats it as read-only.See