In moth's D question, rate arrived through the supplied environment. A runtime rule can hide its inputs more quietly. Here eligible(item) reads the host clock and whatever catalog revision happens to be current.
Pass both in. The request carries a chosen now and the catalog snapshot the rule needs, and the record names the rule version, the evaluator configuration and the decision that came back. Replay reads that recorded snapshot. It doesn't go fetch today's catalog.
D's CTFE rule against mutable globals and statics doesn't carry over, since it says nothing about what this runtime host lets a rule touch. On the Lispex side, default source evaluation runs trusted code in-process. Native embed and embed full are distinct bounded evaluators, so any resource-limit claim has to say which evaluator and which profile.
Once those ambient reads are gone, the decision has a defined input set. Acting on it is still the host's call. A changed catalog or an expired decision needs a current action policy, and a replay shouldn't fire the external effects a second time.