Let's define "compatible releases" #404
Replies: 5 comments 15 replies
-
First of all, while I do think there's precedent to show it's possible to do compatible releases forever (Examples: HTML, ECMAScript, most programming languages), I don't think the path we're on excludes us from having another incompatible release at some point in the future. We can continue to make compatible releases until we decide we can't anymore and then release a new version and continue with compatible releases of the new version. However, I would hope that would happen very infrequently (on the order of a decade or more). On the topic of deprecation,
That's not how I understand deprecation. Deprecation doesn't mean that it may or may not be implemented, it means that it may be removed in a future release. It's still required for an implementer to implement a deprecated feature, even if it doesn't have users that depend on it yet. So, I don't agree that we should expect to see support for deprecated features wane over time even if we don't remove them. |
Beta Was this translation helpful? Give feedback.
-
However we define things, these are the outcomes I want to see. Deprecation should be very rare. We should be very careful about what we add to the spec with compatibility guarantees. (How we "carefully" introduce features is off-topic for this discussion, but we need to get back to that discussion at some point.) That includes potentially not including in the first release features that might not be entirely stable yet (or including them as explicitly unstable) (Examples: dynamic references, vocabularies). Removal of a deprecated feature, while technically allowed, should effectively never happen. It would have to either be so harmful that the harm is worse than the possibility of breaking schemas, or we know it's not being used (which is nearly impossible to know). |
Beta Was this translation helpful? Give feedback.
-
Copying your table here for convenience:
I think the primary objection is with the two that I've marked with a *. If a schema results a definite pass/fail for validation and the next version of the spec means that schema can't give that same result, then that is an incompatibility. For the others that involve an indeterminate result, this is essentially either the spec hasn't completely defined something ("the behavior is undefined") or an implementation just doesn't support it. The remedies for these, respectively, are the spec defining that behavior or the implementation supporting it, both of which result in a definite result. I believe these are compatible changes. There is also the case where the spec leaves a behavior to the implementation to define (perhaps because it's only something that can be defined in the context of the host language), and the implementation then provides a definite result that may differ from implementations in other languages. This is a gray area; I'm not sure what to do here. |
Beta Was this translation helpful? Give feedback.
-
I agree with this. The consequence of keeping these features in the spec is the same bloat and barrier to entry that implementors have complained about before. If a feature has been marked deprecated for a sufficient time (which we can determine at some point), I have no problem with removing it from the spec. This does mean that technically it's an incompatibility, but I think users and implementors will have had sufficient time to update. And if we provide tooling to update (e.g. alterschema), then that relieves the burden. I'd also be happy with adding a provision for implementors to allow enabling "legacy" support if they wish to continue supporting these features. However, it would mean that we can't re-use keywords, even if they've been deprecated and removed. |
Beta Was this translation helpful? Give feedback.
-
I think we're at least mostly in agreement about where to go with this, so if everyone agrees with the following, I'll close the discussion and consider this settled. Compatible Releases: A specification release is compatible with previous releases if it defines the same true/false result as all previous releases. The release may introduce behavior that results in a true/false result where previous releases produced an indeterminate result, but must not introduce behavior that results in an indeterminate result when previous releases defines a definite true/false result. Here's a truth table representing compatible releases.
Exceptions to compatibility: The only incompatible change to stable features we will allow is removal of the feature and only after an appropriate deprecation period. If a keyword needs to change, it must be deprecated and replaced with a new version. Maintaining compatibility is a high priority and removals will only be considered in extreme situations such as the feature creating a significant security vulnerability. Deprecation: Deprecated features may be removed in a future release, but are required for implementers to support until they are removed. Schema authors are discouraged from used deprecated features in preparation for when they will no longer be reliably supported. Removal: Implementers are discouraged from supporting removed features including removing support for the feature if they have already implemented it. However, it's expected that this transition could take time. Schema authors may find that the feature still works in some implementations, but can't rely on that support continuing or that their schemas will work in other implementations. The name of a removed keyword must not be reused for another keyword at any point in the future. (I expect that we can put off determining the remaining details about how the deprecation/removal process will work until it's needed.) |
Beta Was this translation helpful? Give feedback.
-
People didn't like my definition of "compatible releases", so let's try again.
To briefly summarize that definition, releases are compatible if they produce the same true/false result for any given schema. However, this excludes cases where a true/false result is indeterminable. An example of an indeterminate result is if the schema uses a keyword that an implementation doesn't support. This could be because the keyword was added in a future release that the implementation doesn't support yet or because the keyword was removed at some point and the implementation doesn't support it.
However, it seems people would prefer a stricter definition where a true/false result can't become an indeterminate result in a future release, but also allow us to make incompatible changes in some cases.
For reference, what ECMAScript does is that they technically allow removal of features, but in practice it almost never happens. A feature would have to be significantly harmful or it would have to somehow be known that it's never used.
Part of this task will be to define what it means to deprecate a feature in JSON Schema and under what circumstances (if any) we would consider removal.
Beta Was this translation helpful? Give feedback.
All reactions