pub struct GuardedUtilityPolicy { /* private fields */ }Expand description
A composite policy: ordered guards, then weighted utility over the options the guards left, then an optional bounded random tie-break.
Guards run in order. The first Select or Defer ends the decision at the
guard stage; Exclude removes an option and records the guard and reason.
The remaining available options are scored. When random_tie_break is set
and at least two options score within near_equivalence_margin of the best
score, the policy returns DecisionOutcome::PendingRandom naming only
those candidates (uniform weight 1, canonical option order). A declared
boundary system resolves it with the existing ResolveDecisionRandomly
directive, passing this pending decision as the resolution’s tie-break so
the draw evidence covers only the candidates. Otherwise the best score wins
and equal scores fall back to the lowest option ID.
The identity reuses DecisionPolicyKind::Utility; its
semantic_hash commits to the guard policy identity, the ordered guard
IDs, utility weights, margin, and tie-break flag, so a controller binding
rejects a reconfigured policy that keeps the same ID and version. Guard
behavior is application code outside the hash: change a guard’s ID or the
guard policy version when its behavior changes. A controller must also opt
in with DecisionControllerBinding::with_random_tie_break before a pending
tie-break can be evaluated or resolved.
In canwu-sim, a random resolution fails its boundary before any draw is
committed when the ticket’s person decision maker (DecisionMakerUnavailable)
or its controller’s authority person (IssuerUnavailable) is unavailable in
the availability committed before that boundary. Any availability change
made in the same boundary does not fail it: the draw is committed and the
end-of-boundary sweep cancels the ticket instead. Tie-break systems should
skip tickets whose decision maker or controller authority person is
unavailable, read through SimulationView::person_availability with
StateKey::core_person_availability() declared as a read.