Thank you for the list of articles, it will be very helpful in the near future!
This article seems to mention the same problem that I found in SortCurveLoops.
I did another test with SortCurveLoops, and indeed it seems to be working reliably only with planar faces. With curved faces it usually does nothing. Only in one curved face I was able to get 2 out of the 4 loops, but it usually gets none.
In this snapshot you can see two masses. The first one has only planar faces, the second one is a copy of the first one with a void that creates a curved face.
The texts show the first line of each loop with the loop indexes as returned by SortCurveLoops. I like to create texts at 1/3 of each line, so it visually gives an idea of the direction of the loop. Just looking at the texts you immediately understand which loops are clockwise and which ones are counterclockwise.
I have the feeling that SortCurveLoops projects the curves to a plane, then crunches the numbers on the projected curves. If this is the case, then it will never be reliable on curved faces. The correct approach would be to work on the UV coordinates.

Here is the code I used:
var loops = face.GetEdgesAsCurveLoops();
var sortedLoops = ExporterIFCUtils.SortCurveLoops(loops);
for (var i = 0; i < sortedLoops.Count; i++)
{
for (var j = 0; j < sortedLoops[i].Count; j++)
{
CreateTextNote($"[{i}][{j}]", sortedLoops[i][j].First().Evaluate(0.33, true), doc);
}
}
TextNote CreateTextNote(string text, XYZ origin, Document doc)
{
var options = new TextNoteOptions
{
HorizontalAlignment = HorizontalTextAlignment.Center,
VerticalAlignment = VerticalTextAlignment.Middle,
TypeId = doc.GetDefaultElementTypeId(ElementTypeGroup.TextNoteType)
};
return TextNote.Create(doc, doc.ActiveView.Id, origin, text, options);
}