Rejects timeouts and every entities whose deadline is shorter than the
selected scheduler can honour.
The floor comes from the scheduler, through
AshWorkflow.Scheduler.precision_floor_ms/1.
AshWorkflow.Scheduler.Oban polls on a cron interval, and cron's finest
granularity is one minute — Oban.Cron zeroes the seconds field and its
scheduler only wakes on minute boundaries — so a deadline shorter than a
minute cannot be honoured there. fire_after: {30, :seconds} compiles happily and
then fires anywhere up to 60 seconds late, an error larger than the deadline
itself. The same is true of an every's interval.
Rather than let the DSL make a promise the scheduler cannot keep, a deadline
under the floor is a compile error unless the entity sets
self_scheduled?: true, which asserts that something other than the
scheduler drives the trigger at the resolution the deadline needs.
AshWorkflow.Scheduler.Precise arms a timer per deadline, so its floor is a
millisecond and a sub-minute deadline needs no flag.
A fire_at timeout is skipped
This check reads the duration an entity declares, fire_after on a timeout or
interval on an every, and a fire_at timeout declares neither. It makes no duration promise:
it says "once this instant has passed", and the polling interval decides how
soon after. There is no promised precision to compare against the floor, so
there is nothing to reject.
Before fire_at existed, the same outcome was reached by writing
fire_after: {1, :seconds} against a field holding the deadline instant. That
sentinel handed this verifier a number that meant nothing, and the verifier
checked it anyway. fire_at says the thing directly, and skipping it is
correct by construction.