Let's first be explicit about exactly what a Gauss code is, since it commonly causes some amount of confusion. In an oriented knot diagram, label all the crossings by unique names (for example, $a,b,c$ and so on). Starting from some point away from a crossing, follow the knot in the direction of the orientation, and record three things when you come to a crossing: the crossing label, the crossing orientation ($+$ or $-$), and the crossing type ($U$ or $O$ for "under" or "over"). Then continue following the knot until you reach the beginning again.
In the following figure, the black strand is the followed strand and the gray strand is the other strand, and I have recorded the four types of crossings that might occur:

The first confusion is that $a^{+O}$ and $a^{-U}$ are sometimes called "positive" or "right-handed" crossings and $a^{-O}$ and $a^{+U}$ are sometimes called "negative" or "left-handed" crossings; notice "positive" and "negative" have nothing to do with the crossing orientation! The second confusion is from not realizing that the following is a theorem that must be proved:
Theorem. Given an unoriented Gauss code (i.e., a Gauss code after deleting the $+$'s and $-$'s) of a prime knot, one can recover the knot type up to mirror image. In fact, there are exactly two ways to adorn the unoriented Gauss code with orientations.
This is why many times (unoriented) Gauss codes are written as $-a$ or $a$ for $a^{U}$ or $a^{O}$, for example in Dowker-Thistlethwaite codes. (This theorem fails for virtual knots and for non-prime knots in general.)
So, to be completely accurate, Reidemeister moves of type I correspond to inserting $x^{\pm O}x^{\mp U}$ or $x^{\pm U}x^{\mp O}$ somewhere in the Gauss code for a fresh label $x$.
Virtually speaking, there is no danger in accidentally doing a forbidden move when performing a Reidemeister II move. The move corresponds to inserting a $x^{\pm O}y^{\mp O}$ in one place and $x^{\mp U}y^{\pm U}$ in another (in the case both strands are going "in the same direction"), or to inserting a $x^{\mp O}y^{\pm O}$ in one place and $y^{\mp U}x^{\pm U}$ in another. The "forbidden move" is called so because diagrammatically it looks like it might be a Reidemeister-III-like move, but it does not correspond to a Reidemeister-like modification of a Gauss code. So: if you're modifying Gauss codes directly, there is no such thing as a forbidden move to avoid.
For classical knots, the Gauss code has plenty of information to recover a way to draw a knot diagram. As you follow the knot, you convert the $x^{\pm O}$ and $x^{\pm U}$ into the fragments from my figure above, and then you connect everything up according to the code, only taking care not to let any strands overlap. The constraint on a Reidemeister II move is that it occurs over a face of the diagram, where a face is one of the regions complementary to the diagram itself (the faces are polygons whose vertices are at the crossings and whose edges are crossing-free strands of the knot).
There is a straightforward algorithm to abstractly work with faces through the Gauss code itself. The edges of a face are given by positions between terms of the Gauss code. Orientations of the edges of a face are given by recording "left" or "right" for the position between the terms of the Gauss code.
Given a position between terms and an orientation, we can read off a face whose edges are given counter-clockwise orientation, so as we follow the boundary of the face our left hand is always touching its interior. I'll just do two examples: if we are at the position just before $a^{+O}$ and the edge orientation is "right", then we advance to the position just after $a^{-U}$ and keep the edge orientation as "right." If we are at the position just after $a^{-U}$ and the edge orientation is "left", then we advance to the position just after $a^{+O}$ and switch to the edge orientation "right." (These rules should make sense if you spend some time working them out yourself!)
The point is, it is completely algorithmic to determine the faces. Then, since a face is a collection of orientations of positions between terms in a Gauss code, Reidemeister II corresponds to inserting the sorts of terms mentioned before at pairs of positions in a face in a way that respects the orientations given by the face. Again, a computer could do this.