Issue #3615627: Let a payment step end its own lapsed window, instead of making every workflow draw a release step

Adds a payment_lapsed timeout action so a payment step can end its own lapsed window, and the release a consumer brackets the round-trip with happens on the payment's own event instead of a step drawn on an outgoing edge.

The step's backstop deadline is the one road that announces nothing, so a consumer's release never runs from it. This action makes the payment lapse for real, through the same expire() the reaper calls, so the existing bracket closes the way it always does.

It will not claim that no money moved: a payment the provider has already seen is left alone and the token left parked, for the next reaper run to ask about. What it ends are the two cases nothing else will - a payment that never reached a provider, and a step whose payer never asked to pay, which would otherwise park for ever because an instance- or node-anchored duration is a one-shot the sweep does not re-arm.

Also declares the two outcomes PaymentWorkflowBridge announces (paid, expired) as constants on the payment interaction and uses them in the bridge, so the vocabulary has one source. They are deliberately NOT added to signalOutcomes(), which is the allowlist for visitor-initiated resumes - declaring paid there would let a crafted request mark a step paid.

The example workflow gains the backstop to demonstrate it; its expired flow already existed.

Includes PaymentLapsedTimeoutTest (three cases), docs in docs/timers.md, and the French translation.

Merge request reports

Loading
Loading