Two separate issues here I think - provisioning on demand with roles and the value for the role being sent on every cycle.
For the first one, https://learn.microsoft.com/en-us/azure/active-directory/app-provisioning/provision-on-demand?pivots=app-provisioning#known-limitations - On-demand provisioning of roles isn't supported. <-- Edit: WRONG - See comments below.
For the second one, there isn't as clear of an answer. Generally, if something is being retried every cycle it is either because the request failed and generated an error that is being retried, or because something changed on the user and it is being reevaluated. If in the latter case the user is being reevaluated and there is a mismatch in data between what AAD Provisioning is expecting to be there and what is returned on the GET request to read the current state of that user, that's when you'll see a seemingly redundant request.
If possible, can you share not only the PATCH request but also the current state of the user that is returned in the GET that is done before the PATCH? Most attributes don't matter, the format of the roles attribute and the name.givenName attribute are relevant though. For the name.givenName attribute, as you may not want to provide it - is the value being returned on the GET truly identical to what is sent via PATCH?