The booking form validates at the confirm checkpoint, so Registration has no caller and a deferral is reported as final too early
Makes the checkpoint the caller's to name, and gives the booking form the one it is documented to use.
The defect
PolicyCheckpoint::Registration had no caller. The webform booking handler validated through OrderManager::validateOrder(), which is hardcoded to Confirm, so the form's submit was evaluated as though it were the confirmation while the docs said otherwise.
Only isLast() distinguishes the two, and Confirm answers TRUE. That is what makes outcomeFor() log "was not evaluated at the last checkpoint" for every policy it could not ask. At the booking form that is false: the confirmation is still to come and will ask them. An operator reading the log was told a rule had been permanently passed over while it was merely early.
What changes
OrderManagerInterface::violationsAt($order, $checkpoint)— the checkpoint is named by the caller.checkoutViolations()(added in [#3614531]) folds into it.validateOrder()stays as the confirmation-named convenience, since that is what its callers mean and its contract says so.unevaluatedPolicies()takes a checkpoint too: which policies could not be asked is a fact about a moment, not about an order.BookingFormHandlerasks atPolicyCheckpoint::Registration.
The checkpoint used to be implied by which method was called, which is exactly how the form came to ask the wrong question. Making it an argument means a surface cannot silently be treated as another one.
Tests
BookingFormCheckpointTest drives the real handler: a submission carrying a capability handle for a run correlated to an order, with a policy attached that legitimately defers at the form. It asserts the manager reports nothing, and its sibling asserts the confirmation still does report it, so the fix is not "never report anything".
Run against the unfixed handler first, where it failed with exactly the "was not evaluated at the last checkpoint" warning.
No policy shipped with the module declares PolicyFact::FROZEN_TRANSACTION, so reaching a legitimate deferral needed one: yoyaku_policy_test gains NeedsASettledBasket, the shape of a real "book at least two nights" rule.
phpcs (Drupal, DrupalPractice, warnings included), the CI phpstan ruleset and cspell are clean over the whole module. The kernel suite is left to this pipeline rather than run locally.
docs/constraint-policies.md is corrected: Registration is reached from the booking form, Confirm from the two later places, and the enforcement paragraph describes the checkpoint as the caller's to name.
Out of scope
Whether the form should enforce at all, and the Enforce constraints option that governs it.