This project is never going to be complete, but to release at all we need to figure out some versioning scheme.
My proposal is this: Release using the date as the software version number, and have a system of stability promises. A promise has a unique name and version, starting from 1. The promise can be increased to add new functionality or features, but it can never be reduced to remove functionality or change behavior. In the case we ever need to break or remove functionality, we create a new promise and start from version 1 again. To retain backwards compatibility we keep the old promise for a specific amount of time.
Compared to standard versioning like semantic versioning or just major.minor.patch this is a little strange, but it tries to work around the reality that most software can only have one version installed at a time in any given system. So when backwards compatibility is broken suddenly you can't use software that requires guarantees or behavior from the older software. By versioning promises instead of software, promises can be provided by third-party software like compatibility layers or other implementations entirely.
Maybe this is overly complicated, it might just be better to version interfaces separately from the software itself and then support those interfaces.