Framework for composing algorithms
For such a simple use case, I would drop the abc module in favor of NotImplementedError:

class BaseAlgorithm:
    """This is the base on which all other algorithms are to be built."""

    # Unless explicitly stated otherwise, algorithms are in development
    STATUS = Status.in_development

    def encrypt(self, word):
        """Encrypt the word using an internal algorithm."""
        raise NotImplementedError

    def decrypt(self, word):
        """Decrypt the word using an internal algorithm.

        If this is not overloaded, it is assumed that
        encrypting and decrypting are the same operation.
        """
        return self.encrypt(word)


Using such base, only encrypt is explicitly required to be overloaded. I also extracted the status from a method to a class constant as this is the kind of information that does not depend of any state about this class. It also allows to focus on the algorithm first and only change the status when it is ready. Lastly, I also expanded the docstrings a bit so they are more explicit; you may want to explain, in the class docstring, what a user is expected to do when inheriting from BaseAlgorithm.

As for RotateAlg:


you could name it Rotate as the Alg part is already implied from the base BaseAlgorithm class;
you could incorporate the rotate function directly in the rotate method as there shouldn't be much use for a function on their own;
you could handle the rotate_left logic better by using this information directly as a parameter to rotate.


This would become something along the lines of:

class Rotate(BaseAlgorithm):
    """Takes a rotation amount  which it uses to encrypt or decrypt
    all words pass into it"""
    def __init__(self, offset):
        try:
            self.offset = int(offset)
        except ValueError:
            raise ValueError("the offset must be an integer") from None

    def encrypt(self, word):
        """Encrypts by rotating the word"""
        return self.rotate(word, rotate_left=False)

    def decrypt(self, word):
        """Decrypts by rotating the word back"""
        return self.rotate(word, rotate_left=True)

    def rotate(self, word, rotate_left=False):
        """Rotates the word to the chosen direction"""
        offset = -self.offset if rotate_left else self.offset
        offset %= len(word)
        return word[offset:] + word[:offset]


And, unless you specify otherwise with:

class Rotate(BaseAlgorithm):
    STATUS = Status.under_testing
    ...


then Rotate.STATUS will still be Status.in_development.