Appendix: Backwards Compatible Bug Fixes
The last point of Semantic Versioning 2.0.0 has caused much debate around what constitutes a breaking change. There's no way to strictly define breaking without reducing it to uselessness. Instead, the following tests are applied to determining if a bug fix is backwards compatible. If either of the following holds, fixing the bug is backwards incompatible:
- A reasonable user would not notice the unintended behavior; even if it is not covered by, or is directly opposite to, the documented behavior. It would be impractical for them to personally investigate or debug discrepancies of this magnitude for all third-party code they consume.
- Fixing the unintended behavior would break a user's reasonable workaround for the initial unintended behavior.
When either criteria is met, the existing behavior is the expected behavior until it can be changed in a major version.
Example: Clamped PRNG
Consider a pseudorandom number generator (PRNG) defined to produce numbers on the range
By accident, its implementation will only generate values in the range
If a user builds a maze generator around this function, it is reasonable for them to tune parts of their generation against the observed output of the PRNG, so as to produce mazes of a consistent but not identical complexity or aesthetic.
The first condition is met because a reasonable user cannot reasonably be expected to rigorously verify the output characteristics of all potential PRNGs that they considered using.
A multi-lingual profanity detection library takes a list of words to detect, and exposes a function that returns True if some input string contains any word on the word list. The library supports all unicode characters using the utf8 encoding. However, a bug in the constructor causes all words on the filter list to be converted to ascii, silently ignoring errors.
Because the input will not match the incorrectly converted word list, a reasonable developer creates a workaround that performs the same ascii re-encoding on the input string before passing it to the detection function, so that it will correctly match the input against the incorrectly encoded word list.
The second condition is met because a fix in the constructor such that it no longer re-encodes the word list could break a reasonable workaround to the initial bug. While a more robust workaround exists, the burden is not on the user to create a comprehensive workaround that simultaneously supports the existing bug and any possible fix.
|||There may exist a non-breaking fix for this specific example. For simplicity, assume this is the only practical fix.|
Exceptions can be made, but are not mandatory, for backwards incompatible security fixes. This is at the project's discretion, and will be different for almost every case.