Quaternion orientation = ...; //The quaternion we're rotating
var offset = MathUtil.DegreesToRadians(15);
var up = Vector3.Transform(Vector3.Up, orientation); //Get the up axis
var rotationA = Quaternion.RotationAxis(up, offset); //Create a rotation around that axis
var rotationB = Quaternion.RotationAxis(up, -offset);
var rotatedA = Vector3.Transform(Vector3.ForwardRH, rotationA * orientation); //Combine the rotations and get the resulting forward vector
var rotatedB = Vector3.Transform(Vector3.ForwardRH, rotationB * orientation);
Didn't matter which order I multiplied the quaternions in, they both seemed to give me weird directions.
Rotate a quaternion
What do you exactly mean by "rotating a quaternion"? You usually use a quaternion to rotate a 3D vector (or imaginary quaternion) since unit quaternions do not represent rotations in a 4D real vector space. Moreover, quaternions do not rotate a vector by multiplication: they do it by conjugation (i.e. q*v*q^{-1} ). What Vector3.Transform does in your code? How Vector3.Up and Vector3.ForwardRH are defined? How your quaternion is defined?
Vector3.Transform is probably the conjugate operation, but like I said I'm not good with quaternion terminology. It does what you described conjugation does: it rotates the 3D vector by the quaternion. Vector3.Up is defined as (0, 1, 0) and Vector3.ForwardRH is defined as (0, 0, -1). I'm not sure what you mean by how the quaternion is defined. I wasn't aware they could be defined in more than one way. I'm using SharpDX for the quaternion stuff, you can see how it's defined here: http://sharpdx.org/documentation/api/t-sharpdx-quaternion
If you want to combine rotations, you have to multiply together the two quaternions. If q_1 is the first rotation and q_2 is the second rotation, then q_2*q_1 is the rotation obtained by first rotating using q_1 and then q_2. q_1*q_2 is the rotation obtained by first rotating using q_2 and then q_1. Indeed, q_2*q_1*v*(q_2*q_1)^{-1} = q_2*(q_1*v*q_1^{-1})*q_2^{-1}.
var offset = MathUtil.DegreesToRadians(15);
var rotationA = Quaternion.RotationAxis(Vector3.Up, offset);
var rotatedA = Vector3.Transform(Vector3.ForwardRH, orientation * rotationA);
That should take the forward vector, rotate it by rotationA and then rotate it according to the entity's facing. It seems to point 180 degrees in the wrong direction though.And actually... after a bit more testing, turns out the input "orientation" quaternion was wrong. Problem fixed

Moreover, quaternions do not rotate a vector by multiplication: they do it by conjugation (i.e. q*v*q^{-1} ).Allow me to step in here for a short moment. This has always been unintuitive to me, and though not understanding (other than "because the formulas work out") why it must work that way didn't prevent me from using quaternions (you can likely grow old and never have a real need to know why it works!), it is still interesting.
I've had a mathematician explain (or try to explain) that reason to me not long ago. And while I don't claim that I find quaternions or 4D space much more intuitive now (though funnily, homogeneous coordinates are 4D too, and they're entirely intuitive), it is much clearer to me now why you rotate qvq-1 with ?/2 rather than just qv with ?.
Unit quaternions do not rotate in 3D at all, but they perform two "isoclinic" rotations in 4D (let's pretend you can truly imagine how that looks like, I can't for sure). But the important detail is that 3D space is a plane in 4D (or so the mathematicians tell us, let's trust them!), and one of these rotations is the rotation in the 3D plane that we want, the other is... something else, a rotation in a plane that is orthogonal to the 3D plane. Therefore, if you just rotated using one quaternion which corresponds to ?, then you would get... some transformation, but not a proper rotation in 3D, which you want.
If you multiply on the left, both rotations go in the same sense, if you multiply on the right, they go in the respective opposite sense (so one is clockwise, and the other counter-clockwise), and a quaternion's conjugate corresponds to the same orientation, but rotated the other way around.
So the trick is to build a quaternion that only rotates ?/2 and do one multiplication on the left, and one on the right with the conjugate, which does the second half of the 3D rotation that you want and at the same time "unrotates" the other one that you don't want.
Samoth got me thinking that I am one of those who uses quaternions without actually knowing how it works.
About that, I found this presentation from Jim Van Verth that is simply awesome:
http://www.essentialmath.com/GDC2013/GDC13_quaternions_final.pdf
And then these videos that seem pretty interesting but far more in depth:
Disclaimer: I haven't fully watched them, so I don't know how good they are. I just saw enough to deem they were worth sharing.
“We should forget about small efficiencies, say about 97% of the time; premature optimization is the root of all evil” - Donald E. Knuth, Structured Programming with go to Statements
"First you learn the value of abstraction, then you learn the cost of abstraction, then you're ready to engineer" - Ken Beck, Twitter