docs: add a deprecation policy to the contributing guide#4051
Open
maxrjones wants to merge 1 commit into
Open
Conversation
Closes zarr-developers#2924. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
d-v-b
reviewed
Jun 12, 2026
Comment on lines
+382
to
+390
| A deprecation cycle has a real cost: every user of the affected API must eventually migrate, and we carry the deprecated code and its warning until removal. Before starting one, weigh the following factors and record your reasoning in the pull request. The goal is to evaluate every proposed deprecation on the same shared scale, so that disagreements are argued in these terms rather than relitigated from first principles each time. | ||
|
|
||
| - **How many users are affected.** Assume that every part of our public API is used by someone, including downstream libraries, and put the burden on the person proposing a removal to show that an API is genuinely niche, rather than on users to show that they depend on it. This asymmetry is deliberate, for two reasons. First, the users of an API are mostly invisible to us: they do not follow our issue tracker, and they typically discover a removal only when their code breaks after upgrading -- too late to have spoken up in advance. Absence of reported usage is therefore not evidence of absence of usage. Second, the cost of guessing wrong is lopsided. If we keep an API that turns out to be unused, we pay a bounded maintenance cost that we, the maintainers, can see and manage. If we remove an API that turns out to be used, we impose an unbounded cost on an unknown number of users, discovered late and eroding trust in the library's stability. When the downside of one error is so much larger than the other, the default should favor the cheaper mistake. "I can't imagine anyone using this" is not evidence that no one does; concrete signals -- code search across downstream projects, documented usage, or download statistics -- are. | ||
| - **The cost of migration to users.** Is there a drop-in replacement? Can the migration be performed mechanically, or does it require users to redesign their code? A change with a clear, easy migration path is much cheaper to justify than one without. | ||
| - **The cost of keeping the API.** What do we pay by not removing it -- maintenance burden, bug surface, duplicated logic, or a worse design that we can't improve while the old API exists? A high carrying cost strengthens the case for removal. | ||
| - **Who benefits.** Distinguish benefit to users from benefit to maintainers. A change that helps only maintainers (for example, deleting code that is inconvenient to keep) is a weak case on its own, because users pay the migration cost and get nothing. A change that *also* gives users something they want is a much stronger case. | ||
| - **Whether the goal can be met without removal.** Often a refactor, an alias, or an additive change achieves the same end without breaking anyone. Prefer those. Removing public API is never free; the deprecation cycle is the price, and it is mandatory. | ||
|
|
||
| If, after weighing these factors, a removal is not clearly worthwhile, prefer to keep the API. Conversely, do not leave the decision to remove an API indefinitely deferred: a vague intention to "eventually" break something is itself a form of technical debt. Either commit to the deprecation and begin the cycle, or decide to keep the API and design around it. |
Contributor
There was a problem hiding this comment.
This reads a bit like an effort to discourage developers from wantonly deprecating code they don't like, without regard for how it impacts users. I don't think we have a lot of that in our codebase, so maybe a more neutral tone would work better here. Even better would be just linking to or copying text from the NumPy deprecation guidelines: https://numpy.org/neps/nep-0023-backwards-compatibility.html#general-principles
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2924.
This PR adds a deprecation policy to the contributing guide, so there's a shared framework all contributors and maintainers can apply rather than re-deriving one for each PR. Making it a public doc also gives users visibility into how we handle breaking changes.
The policy is consistent with our EffVer versioning and covers scope, decision framework, mechanics, minimum period, and exceptions to the policy.
TODO:
docs/user-guide/*.mdchanges/