Proposal: New Spec Development Lifecycle Model #234
Replies: 13 comments 80 replies
-
I know this is a massive paradigm shift for us, but I think it's worth the effort to get us to something like this. I think the proposal will: (1) provide a stable version of JSON Schema without hindering our ability to evolve the spec, (2) eliminate the burden of implementers having to support multiple versions, (3) allow us to get clarifications and bug fixes out to people when they happen, (4) allow us to iterate on new/unstable features more quickly while also putting less burden on implementers and getting features to a stable state sooner. Other than process changes and changes already identified, we would need to determine which features are not stable, but JSON Schema wouldn't be practically usable without them. We would have to get any such features to a stable place before we could do our first release with the new process. Based on recent discussion, I think Ideally, it would be great to have our first release under this model out for the Jan 1, 2023 release. That's only four months away, so that might be a tough goal to hit. If we aren't ready for Jan 1, 2023, I think we should just get it out ASAP and not wait for Jan 1, 2024 for the first release. |
Beta Was this translation helpful? Give feedback.
-
If we move to this model, I'm going to fork my implementation and remove all the baggage from previous (and future!) releases. It should be fairly trivial to provide a compatibility mode for draft-06, draft-07, and 2020-12 with minimal bloat to the implementation. By compatibility mode, I mean that any schema written for draft-07 should evaluate correctly, but certain edge cases wouldn't necessarily pass the test suite. For example, |
Beta Was this translation helpful? Give feedback.
-
Stage 1
Do we have a plan for coordinating this since they are different repos? It also sounds like we're requiring implementations to have some support for pre-release features. I've looked at doing this in my implementation in the past, and it comes with some complications that I won't get into now. Suffice it to say that doing so is hard. Stage 2
Do we have a mechanism for identifying usages of features? I know I can't get any kind of metrics out of my library. Forward compatibility
Should the consumer have the right to disable Stage X features, even if a schema contains them? OtherAre we going to retroactively apply this to pre-existing releases? How does this affect |
Beta Was this translation helpful? Give feedback.
-
cc: @Julian I would like to propose the following structure for the test suite:
Given that features progress through the stages, it makes sense to copy the latest year folder in its entirety for the next year (as we already do between drafts) and move tests around accordingly. This would allow implementors to retroactively test compliance. ("When was I last compliant?") I'm not sure how this fits in with the current effort of reorganizing the folders into the |
Beta Was this translation helpful? Give feedback.
-
@jdesrosiers It's great to see a comprehensive proposal! I have not had time to catch up to this beyond a quick skim, so it will be a while before I have substantive comments. But I do want to note:
Given that not everyone reading these discussions has the full context across all of the repos involved, especially those not under the JSON Schema Org, would you be willing to change this to note that the media type registration is continuing with the IETF? I think it's important that folks be aware of that ongoing connection when reading these proposals. |
Beta Was this translation helpful? Give feedback.
-
It turns out that the OpenTelemetry specification uses a process of mixed stable and unstable components similar to this proposal. https://opentelemetry.io/docs/reference/specification/versioning-and-stability/ |
Beta Was this translation helpful? Give feedback.
-
I'm still working on digesting the whole proposal and responding to it holistically, but for this:
I think it would make more sense to say something like (changes in bold italics):
|
Beta Was this translation helpful? Give feedback.
-
I've been rethinking part of this proposal. Currently the forward-compatibility rules say that if you declare a dialect, you can use unknown keywords as annotations and unstable keywords are enabled. If you don't declare a dialect, these features are disabled. Although this works, it complicates things for implementations and is an awkward rule for users to remember. So, here's what I was thinking instead. Unknown keywords are never allowed and unstable keywords are off by default and must be enabled by configuration provided by the implementation. This is easier for implementers, still preserves forward compatibility by default, and is a much easier concept for users to understand. Of course the downside is that users are forced to use the vocabulary system if they want to use unknown keywords, but that should be fine if we have easy to follow documentation on how to do that. This simplification enables another big benefit. It means that you would only declare a dialect ( Note that the must-be-off-by-default rule only applies to unstable keywords, not necessarily any unstable feature. For example, the output format would initially be unstable, but it doesn't make sense for it to ever be off. It could also make sense to automatically turn on an unstable keyword in some cases. For example, dynamic references would be initially unstable, but they are required to validate the schema against the meta-schema. In this case it would make sense for implementations to turn on dynamic references temporarily for this step and reset it when that step is over. If no one objects, I'll update the proposal in a few days. |
Beta Was this translation helpful? Give feedback.
-
Broadly, I love this concept. On reflection, I'd want to see a few alterations based on recent discussions. In our 2022-09-26 Open Community Working Meeting, you conceeded (or agreed, doesn't really matter) that having a snapshot in the similar way that TC39 does with ECMAScript, has valid use cases. Currently, the proposal as it stands suggests that all features, regardless of stage, will live in the spec document. It will be an activity to the reader to consider each feature or keyword and determine if a feature is stable or not by reading the associated stage tag. The spec document will be "live" in as much as things can be updated and people should always look at the latest version. The discussion regarding snapshots got me thinking. We aren't going to want snapshots containing proposals at specific stages. You only want the snapshots to contain the current stable features, or it sort of defeats the point of not having to determine which parts of the spec doc you can and cannot use / rely on. I went back and read over how TC39 (ECMAScript) works in this regard, and then it hit me. The significant difference in what you're proposing here vs how TC39 function is where the proposals live. I'm very much of the opinion that the proposals should NOT live in the spec document. Our consensus regarding snapshots of the spec aiding people wanting to know what they can use with a specific "editions" of the spec, supports this direction. Having proposals in snapshots feels like a really bad idea. If you wanted to counter by saying the living spec doc could still have proposals, you're creating some unnesecary additional gymnastics for creating the snapshot. Beyond automation, you'd have to make sure section references were correct, and the new stable parts of the spec didn't refrence proposals. My suggestion is to follow the approach of TC39, and rather than proposals going into the spec document, they live outside the spec document until they are propoted to the appropriate stage which guarantees them entry into the spec. If we accept the notion of yearly snapshots, there's no reason promotion of features to "stable" couldn't happen on a more regular basis (quaterly? TC39 do 6x a year). In summary: This is a really great start. I'd like to see it looking closer to TC39, which I think is justified if I'm on the same page in that we found consensus regarding the need for snapshots (or "editions") to be published. As a note, which I think I've mentioned before (but not here), TC39 consider their spec "a living standard" with snapshots. Staged proposals have been used in production and replaced with stable versions when reached, so their approach on this seems to work fine. |
Beta Was this translation helpful? Give feedback.
-
A few scattered comments in case any are helpful -- I'll admit I have not read the long thread, just the original post, and that broadly the below is (somewhat as usual) my thoughts which are welcome to be ignored if others disagree:
Each of these to me really could (have) been treated individually without changing all at once in my opinion -- but I see in skimming some other posts that others may have found the opposite helpful, that since this is comprehensive, it's easier to agree on. Different strokes for different folks I suppose. I guess this too isn't a concern -- what's done is done here and it's good work, but if it turns out any of those are more contentious than others perhaps a way to proceed would be to reduce scope. The above is very much a brain dump as I scan the post, so I'll (well, apologize for not being more ordered or timely with the feedback) but also stress again that I like this train of thought (and general proposal) quite a lot personally! |
Beta Was this translation helpful? Give feedback.
-
@jdesrosiers Can you create an issue for capturing a list of the issues related to this discussion (the SpDLC) please? It would be worth also including a summary of what we have so far, but not much detail. As a locked issue, and asking for no comments, to be used as a tracking location for the sub-discussions. I think we all feel this direction makes sense, but now we're moving, as @Julian pointed out, there are a number of discussions/topics which could do with their own space in the form of an Issue to discuss, and so we can easily see the summary of discussions so far (by editing the first post in the Issue as required). |
Beta Was this translation helpful? Give feedback.
-
Since STAGE-1 and STAGE-2 keywords are not available by default, is their inclusion handled through additional dialects or is there expected to be some other mechanism? Specifically, I am asking from the perspective of a schema author using STAGE-1 and/or STAGE-2 keywords and wants to ensure they are available before the schema is processed. How do they do that? For STAGE-2 in particular, we expect these to be widely used and stable enough to be relied upon in an open system. |
Beta Was this translation helpful? Give feedback.
-
[sorry for the delay- after the reactions in yesterday's call I scrapped everything I'd written and started over with a new approach] Goal for this feedbackThe goal of this feedback thread is to ensure that the SDLC's stability guarantees are applied to the correct things in order for us to have the healthy vocabulary ecosystem necessary to follow our plan of asking people to create extension keywords prior to attempting to get them into the JSON Schema specification. It hinges on the idea that we have three audiences:
As far as schema authors/consumers are concerned, only keywords and a few other things (e.g. output, turning AssumptionsFor several years now, we have told people that keywords should be developed first as extensions. The SDLC would formalize this approach by placing implementation requirements on keywords prior to accepting them to STAGE-1 status within the specification. This is a very good thing, and one reason I generally support the direction of the SDLC. My assumption is that we will continue this, and also that many useful and widely supported keywords will never be added to the spec. We will expect them to be broadly and interoperably usable anyway. This keyword design funnel will work well if most keyword proposals can be implemented in most implementations, which will only happen if:
Or in other words: The right thing must be easy, and the easy thing must be right. Keyword support needs to be consistent, at least within well-understood areas at a conceptual level, across implementations so as to minimize friction when trying out reasonable new keywords. Of course, there will always be keywords stretching the boundaries — we are not trying to prevent that. We just want it to be clear to everyone when a boundary is being pushed so that we can consider the impact to the ecosystem properly. Desired SDLC-level OutcomeAs I understand it, the SDLC stability process is currently defined in terms of keywords, the standard dialect, and observable non-keyword features. This thread proposes adding capabilities, as demonstrated in the examples posted as replied to this comment, as an additional target for that process. This thread is not about enumerating the capabilities or defining the requirements and stability levels currently involved. It is not even necessary to completely enumerate/define them for the next release. I assume that we can figure out the right granularity and level over time. This feedback is about illustrating what capabilities might look like, and making the case that they are a valid interface for two of our three audiences and therefore the SDLC ought to apply to them. This would be a significant change to our thinking, and would need to be integrated into our process to ensure appropriate levels of attention. Examples of benefitsIn responses to this comment, I will go through several detailed examples to highlight benefits. As a TL;DR, here are the highlights:
In conclusionThat last point from the examples about sending a new capability through the STAGE-1, STAGE-2, etc. process is extremely important. I am convinced that one of the worst things about how we introduced It's not that we needed to ratify implementation details, it's that we didn't think through the implications for things like parallel evaluation, runtime state management, etc. Some of you likely did, but there was no process in place to force my attention towards those concerns. I don't recall giving them much thought, TBH. If we had had to put the child-to-parent and parent-to-child runtime dependency relationship capabilities through a STAGE-0, STAGE-1, STAGE-2 process, we would have gotten far more feedback on the impact of those changes (see examples in comment replies for definitions of these capabilities). We would have empowred the community to give clear feedback on both the observable behavior of the keywords and the expected underlying changes prior to any of them becoming baked-in. This could even have included feedback no whether the underlying capabilites ought to be available to non-standard keywords. Instead, here we are three years after their publication and only now debating whether these should be limited to standard or builtin keywords or available more broadly. To me, the fact that the SDLC, if extended to capabilites, would have flushed these concerns out up front, is alone enough for me to endorse the new process. But I only see this benefit happening reliably in a way that will be robust to any of us leaving the project over time if capabilities are part of the process alongside of keywords, the standard dialect, and end-user-observable non-keyword features. |
Beta Was this translation helpful? Give feedback.
-
At this point we seem to have near unanimous agreement that we want to remove IETF from our process (at least for now). This gives us the opportunity to make changes to our process. The following is a proposal for a Specification Development Lifecycle (SDLC) process that I think will be a good fit for JSON Schema. This process is inspired by the TC39 Process used by ECMAScript (blog) with additional inspiration from the trunk-based development paradigm.
Spec documents would remain in essentially the same format they are now, but would be converted from XML to Github flavored markdown and be hosted on the json-schema.org website. This will be a "stable" spec but will include features that are flagged as unstable. In this case, "stable" means no backward/forward incompatible changes. The spec will evolve by modification rather than producing a new spec every release. This is a reasonable approach only because we will be committing to strict compatibility requirements for stable features and clearly flagging unstable features and flagging stable features with the release they reached stability.
Feature Status Flags
Every feature in the spec has a release status. It's either stable, stage-1, stage-2, or deprecated. Flags are used to show the status a feature is in. If a feature doesn't have a flag, it's considered stable. If it has a year flag (such as
2023
) it means the feature reached stability with the 2023 release. The other flags indicate a feature that is not yet stable or is deprecated.STAGE-0
- Consensus has been reached that a keyword is worth pursuing as a standard dialect keyword. A champion is identified with the responsibility of ticking the boxes forSTAGE-1
eligibility.STAGE-1
- This feature is new and may change or be removed all together. Implementers are encouraged to implement these features, but are not expected to maintain support for previous versions when they change. Users who choose to use these features should be comfortable being on the cutting edge and with everything that comes with it.STAGE-2
- This feature is in the last stages of becoming stable. We don't expect any changes, but backward incompatible changes are still possible. At this point, users can be reasonably sure that the feature won't change, but can't expect all implementations to support the feature.{YEAR}
- This feature is stable as of the year specified. Stable features can not be changed or removed, but may be deprecated.DEPRECATED-{YEAR}
- This feature was deprecated as of the year specified. Implementations should still support this feature, but new schemas should not use them. They are retained for backwards compatibility only. Implementations may choose to drop support for deprecated features, but if they do, they must raise an error if they encounter a schema with a deprecated keyword. They must also clearly document that they don't support JSON Schema releases before the keyword was deprecated.Release Process
Effective Jan 1 each year, we would update feature status flags to promote features to stable or STAGE-2. Implementations that express support for the 2023 release must support all features that are stable as of the 2023 release including previous releases. A blog post should be published describing the status changes for the release. A snapshot of the spec will be taken of the stable parts of the spec and made available.
Development Process
Bug fixes, clarifications, and other non-functional spec updates can be merged at any time even for stable features. Changes to STAGE-1 and STAGE-2 features can also be merged at any time. A change-log blog post should be prepared quarterly to give visibility to any changes that were merged in the last quarter.
STAGE-0 Criteria
STAGE-0 features are not added to the spec. They will be maintained through some other channel.
STAGE-1 Criteria
STAGE-1 features can be added at any time as long as it meets all criteria for STAGE-1.
STAGE-2 Criteria
A STAGE-1 feature can only be promoted to STAGE-2 on Jan 1. Generally a feature should stay in STAGE-2 for one year, but may stay longer if we don't see it used enough in the wild.
Stable Criteria
A STAGE-2 feature can only be promoted to stable on Jan 1. Once stable, the status can not be changed back to an unstable status, but may at some point be changed to DEPRECATED.
Backward Compatibility
We would commit to no backward incompatible changes on stable features. Most of the spec is pretty stable. It's mostly new concepts like the vocabulary system, annotations, output format, and dynamic references that are likely to change. Those features and anything else we think might not be stable can be flagged as STAGE-1 or STAGE-2 to start with.
Forward Compatibility
We would commit to not adding/modifying features that could be problematic for forward compatibility.
Forward compatibility can be an issue for unknown and unstable keywords, so if they are supported, they would need to be disabled by default. Users can opt-in to enabling these features with the understanding that they will lose forward compatibility guarantees.
If an implementation encounters a dialect it doesn't support, it should raise an error. If no dialect identifier is provided, the standard validation dialect should be used.
If an implementation encounters a keyword it doesn't support, it must raise an error.
Meta-Schemas
Because there is only one version of the spec, there would be only be one set of meta-schemas. We wouldn't publish a new set for each release, just update the existing ones as necessary. There would be one URI (to be determined later) we would use as the
$id
for the current standard dialect meta-schema. Because of backward and forward compatibility rules, all schemas written for a previous release or for a future release should work with whatever version of the meta-schema an implementation might be using.Vocabulary System
The core vocabulary would no longer be an indicator of the version of JSON Schema because there is only one version and that version is always assumed. The vocabulary system would initially be considered unstable so any other changes we might want to make in this area can be decided later, even after the initial release under this model.
External Standardization
If we get to a point where there's nothing left in STAGE-1 or STAGE-2 and we don't foresee any major changes coming up, we can consider standardization with a recognized standards body such as IETF or W3C.
Media Type Registration
Although IETF wouldn't be part of the main spec development, we still want to register our media types with IANA and we would do that through IETF. The media type registration would follow the IETF process, not this one. That means that it should be stable and we should not expect frequent updates like with the main spec. Our new process gives us a stable spec that the media type registration can link to, but must also be compatible with the older "draft" releases. It would be best to get this done as soon as possible because the media types are already being used in the wild.
EDIT 09/06 - Added media type registration and clarified that we would not be issuing new documents for each release the way we do now.
EDIT 09/09 - Added "Stable Criteria" section. Moved section on dialect to support to the forward compatibility section and fixed an error that seemed to imply that vocabularies aren't a thing.
EDIT 09/22 - Update forward compatibility rules to make unknown and unstable keywords disabled by default. Rewrote "$schema" section and added "Meta-schemas" section based on what was made possible by forward compatibility changes.
EDIT 09/25 - Remove assuming the standard validation dialect by default. Reworded some things about dialects in attempt to address misunderstandings that have come up.
EDIT 09/28 - Add designation of a champion to STAGE-1. Remove suggested URI for current standard dialect meta-schema.
EDIT 10/12 - Add STAGE-0. Mention snapshots.
Beta Was this translation helpful? Give feedback.
All reactions