It looks like you have everything under control now, but just to elaborate, a very common thing to see in shaders is:
float diffuseTerm = saturate( dot( N, L ) );
float specularTerm = pow( saturate(dot( N, H )), power );
I suspect that if all you did to fix the shader was copy:
specular *= saturate( NdotL * 4);
What is actually happening is that in the backfacing case, NdotL is less than 0, and saturate clamps from (0,1), so you are multiplying by zero to knock out the unwanted specular. In the cases of any NdotL greater than .25, you’ll just be multiplying by 1. So most of the time, this bit of code just multiplies by zero or one.
Although that snippet might produce some sort of interesting effect as light falls off. I can’t quite picture it in my head.
Screenshots looked good. Realtime preview is always great. Cheers! and keep up the good work guys.