It’s a bug in your code.
A transform’s properties up, down and such return the corresponding local axis in world space representation.
Example:
Suppose an object is rotated 90 degrees around the y-axis (clock-wise), i.e. it looks into the x-direction (object’s local forward direction is aligned with x-axis).
A call to transform.forward does now return (1, 0, 0)
Let’s start to rotate it:
Rotate the object around its own forward in Space.World => it’s actually going to rotate around the world space’s x-axis, transform.forward (local z-axis) stays aligned with the world space’s x-axis, hence it’ll continue to return (1, 0, 0) and you’ll see no weird rotations… but it looks as if it rotated locally.
Rotate the object around its own forward in Space.Local => it’s going to look very strange.
The reason is, that it takes the transform’s forward (local z-axis), which is (1, 0, 0) in world space again. But this value is going to be used in local space now, that is, the object rotates around its local x-axis, which is the z-axis in world space - and this does only apply to the first frame.
Due to that rotation, the next time you call transform.forward, it’ll now return the object’s local forward again, but it’s no longer (1, 0, 0). Again, this will locally be the z-axis, but in world space it’s going to be something like (x, 0, z).
*Edit
Of course I missed an important part: a possible solution 
Try to pass Vector3.up, down and so on directly, do not use the transform.forward, because they’re not going to stay the same in world space (remember, they always return the direction in world space).