retire

Finalize a drained edge: promote edge to Lifecycle.RETIRED (design §5.3). null unless edge is currently Lifecycle.CLOSING and fully drained (EdgeSummary.outstanding == 0, i.e. every delegated unit has been returned or spent). This is the drain gate: a retire is refused while entitlement is still outstanding across the edge. Once retired, nothing crosses again and its history stays queryable via edge forever.

The patch carries a drain witness — the edge's observed issued/returned/ leafSpent/rollupSpent counter slots at their absolute values (max-safe, same house idiom as the feasibility mutators' witness). Retirement is causally after the drain, but that causality crosses writer streams; without the witness a laggard holding {delegate, close, retire} but not the draining release/spend patch would compute outstanding != 0 against RETIRED and false-fire LedgerConflict.ClosureViolation on honest single-hop delivery. The witness ships the drained counters alongside RETIRED so the retired-and-drained state travels as one.