Apologies for the sort of vague question. I'll do my best to explain the problem I had/have and explain the solution that I found.
So my custom transform node has added offset attributes that affect the matrix and have output attributes that add the offset to the standard transform attribute.
Problem 1:
When I make a connection to the parent plug of offsetTranslate everything works as intended. The validateAndSet method gets called for offsetTranslate and the normalTransform visually updates in the viewport. 
When I connect to a child plug it calls the compute method for the parent plug (which is bizarre). I was never able to figure out why this happens, but the solution to problem 2 solved this issue as well, so if you're running into this same problem read on.

Problem 2:

When you have outputs being computed using the inputs into the normalTransform node, when those inputs update validateAndSetValue does not get called. So what you need to do is when you get the input data out of the dataBlock to compute the output plug you need to also pass that data to the MPxTransformationMatrix, here's an example:
//outputTranslateX
if (plug == aOutputTranslateX)
{
double offsetTranslateX_val = block.inputValue(aOffsetTranslateX, &status).asDouble();
double translateX_val = block.inputValue(translateX, &status).asDouble();
block.outputValue(aOutputTranslateX, &status).setDouble(offsetTranslateX_val + translateX_val);
block.setClean(plug);
ltm->setOffsetTranslateX(offsetTranslateX_val);
}
ltm is a pointer to the MPxTransformationMatrix
We can use this same method of passing data to the MPxTransformationMatrix during compute to handle those unexplained compute calls for input plugs.
//aOffsetTranslate
if (plug == aOffsetTranslate)
{
if (ltm)
{
ltm->setOffsetTranslateX(plug.child(0).asDouble());
ltm->setOffsetTranslateY(plug.child(1).asDouble());
ltm->setOffsetTranslateZ(plug.child(2).asDouble());
}
else
{
MGlobal::displayError("Failed to get normal transform matrix");
}
block.setClean(plug);
return MS::kSuccess;
}
So now my node is working the way it needs to, so I'll mark this as a solution but if anyone has a deeper insight into why those comput input plug calls were happening. That would be great.