package provision import ( "fmt" "time" ) // MoveRollbackLossRebind moves a lost target's reference from a declaration // whose claim CAS never landed (its signed loss record conflicted) to a // fresh declaration (ยง7.10, claim Plan 10 J4 B1). Legal only from lost with // exactly oldRef; the phase, Dirty and the rollback id are kept, so the // rollback the first declaration decided stands. The caller proves oldRef // is this move's conflicted declaration and binds newRef in its signed // intent. The same newRef again is a replay; anything else is a conflict. func MoveRollbackLossRebind(g MoveGuard, oldRef, newRef string, now time.Time) func(*Record) error { return func(rec *Record) error { if oldRef == "" || newRef == "" || oldRef == newRef || now.IsZero() { return fmt.Errorf("provision: malformed loss declaration") } rb, err := rollingBack(g, rec) if err != nil { return err } switch { case rb.TargetPhase == RbTargetLost && rb.LossRef == newRef: return nil case rb.TargetPhase == RbTargetLost && rb.LossRef == oldRef: default: return fmt.Errorf("%w: another loss is recorded for this target", ErrMoveConflict) } t := now.UTC() rb.LossRef, rb.LostAt = newRef, &t return nil } }