Perhaps this hack will work for bringing colour directives into a canonical form:
In[66]:= canon[col_?ColorQ] := ColorConvert[col, Head[col]]
In[67]:= canon[Hue[1/3, 3, 5, .5]]
Out[67]= Hue[0.3333333333333333, 1., 1., 0.5]
My opinion is that clipping of out-of-range values should be implemented in a way that it extends to the entire behavior, in particular to the way an expression displays on screen in isolation.
Agreed. And because I would expect different functions to have different implementations for colour handling (though I may be wrong...), I would be very careful with such out-of-range values. Just because they work in one context, they may not work in a different one (and that different one may directly concern functionality rather than harmless formatting).
But then taking this thought one step further:
One might say that the lack of formatting is a good thing. It serves as a warning that the values are out of range. Actually, I think I prefer it this way (for this single reason).