From 53997191142f4d69d357b0d2791808e65029e490 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 2 May 2025 13:07:01 -0400 Subject: [PATCH 1/3] decision process --- book.toml | 3 + src/2-way-door.md | 30 +++ src/SUMMARY.md | 6 +- src/consensus.md | 73 ++++++++ src/decision-making.md | 28 +++ src/decision_process.md | 53 ------ src/decision_process/examples.md | 297 ------------------------------ src/decision_process/reference.md | 194 ------------------- 8 files changed, 137 insertions(+), 547 deletions(-) create mode 100644 src/2-way-door.md create mode 100644 src/consensus.md create mode 100644 src/decision-making.md delete mode 100644 src/decision_process.md delete mode 100644 src/decision_process/examples.md delete mode 100644 src/decision_process/reference.md diff --git a/book.toml b/book.toml index f959253..452bf60 100644 --- a/book.toml +++ b/book.toml @@ -40,3 +40,6 @@ command = "mdbook-mermaid" "/initiatives/process/stages.html" = "how_to/propose.html" "/initiatives/process.html" = "how_to/propose.html" "/initiatives/stable.html" = "how_to/propose.html" +"./decision_process.md" = "decision-making.md" +"./decision_process/examples.md" = "decision-making.md" +"./decision_process/reference.md" = "decision-making.md" diff --git a/src/2-way-door.md b/src/2-way-door.md new file mode 100644 index 0000000..44edc18 --- /dev/null +++ b/src/2-way-door.md @@ -0,0 +1,30 @@ +# Reversible decisions + +Reversible decisions do not represent team consensus. +Rather, they indicate that *somebody* on the team is in favor of the idea. +We use them to begin experiments and do other small things. +We never use them for decisions that impact stable code, such as stabilizing a feature. + +## Examples where this process is appropriate + +* Championing a lang-team experiment +* Closing an RFC -- + * Technically reversible (you can always re-open the PR), but particularly when external contributors are involved it's best to discuss this with the team beforehand. It's very confusing for people to have their PR closed and re-opened and can lead to burned bridges. + +## Process + +### Decision maker (lang team member or lang team advisor) + +* Write a comment on the Github issue or PR that + * Explains decision and context + * Labels the issue with `T-lang` (`@rustbot labels +T-lang`) + * Starts a `@rfcbot poll` -- typically the issue should *only* have `T-lang` to avoid excessive pings +* If people raise concerns, particularly Rust team members: + * Remember to **treasure dissent**. Engage with them and make sure you understand it. Note all the concerns raised on the tracking issue as "unresolved questions" or things to explore so they don't get forgotten. + * Concerns don't *block* you from going forward, but they may give you pause, particularly if they are shared by many on the team. + +### Other team members + +* Since this action is reversible, your approval is not required. However, please check your box to indicate you reviewed the issue, it's useful feedback. +* If you disagree with the decision, or think the experiment is a bad idea, say so (constructively)! +* For experiments, ask youself: What are the "weak spots" that the experiment ought to probe? What information can we gather? diff --git a/src/SUMMARY.md b/src/SUMMARY.md index b1b6a9e..53dbe7f 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -8,9 +8,9 @@ - [Propose or extend a new lint?](./how_to/new_lint.md) - [Add an experimental feature gate](./how_to/experiment.md) - [Stabilize a feature](./how_to/stabilize.md) -- [Decision process and principles](./decision_process.md) - - [Decision process examples](./decision_process/examples.md) - - [Decision process reference](./decision_process/reference.md) +- [Decision making](./decision-making.md) + - [Reversible decisions](./2-way-door.md) + - [Consensus decisions](./consensus.md) - [Becoming and being a lang-team member](./membership.md) - [Lang-team leads](./leads.md) - [Chat platform](./chat_platform.md) diff --git a/src/consensus.md b/src/consensus.md new file mode 100644 index 0000000..8b37f0f --- /dev/null +++ b/src/consensus.md @@ -0,0 +1,73 @@ +# Consensus decisions + +Consensus decisions represent the official opinion of the team. They require that a majority of the team is in favor and that nobody has raised a concern that achieved [strong enough support](#threshold-to-resolve-a-concern-without-consent) to block the decision. + +They are used for for decisions that cannot be reversed (e.g., stabilization decisions or decisions that affect language semantics). They are also used for RFC approvals because, while the designs described there can be reversed before stabilization, we do not wish to do so lightly. + +## Definitions + +The decision making process distinguishes the following roles + +* **Lang team**: the [Language Design Team](https://github.com/rust-lang/team/blob/master/teams/lang.toml). +* **Lang team member**: a member of the Lang team. Lang team members are the ones who have to [approve the final decision](#the-process). +* **Advisor**: a member of the [lang team advisors](https://github.com/rust-lang/team/blob/master/teams/lang-advisors.toml). Advisors can propose a decision and can raise [formal concerns](#raising-concerns) but their approval is not required. +* **Decision document**: the RFC, issue text, or other document describing the decision being made. +* **Document author**: The person who authored the decision document. They ultimately decide what changes they wish to make to the text in response to concerns. They often do this in close consultation with a member of the lang team, but that is not required. + +## The process + +Consensus decisions are done using rfcbot. They always begin with a decision document authored by the [document author](#definitions). The document author can be anyone, they do not have to be a member of a Rust team. + +To make a decision, a [lang team member or advisor](#definitions) should issue `@rfcbot fcp merge`. This will create checkboxes. Once [2/3 of the boxes have been checked](#doing-the-math), the decision will enter final-comment-period. During that period the team should review any comments raised — assuming no concerns are raised (see below), the decision is finalized once the FCP has expired. + +*Note:* Before finalizing the decision, the team should engage with **new** points raised on the thread (particularly if they are made by people not able to raise formal concerns). + +## Raising concerns + +[Lang team members or advisors](#definitions) are entitled to raise a **formal concern** during the discussion process. This can be done with `@rfcbot concern concern-name`. The decision cannot be finalized until the concern is resolved, either because the person who raised the concern is satisfied and [resolves](#resolving-a-concern) it themselves, or because the team decides to [challenge it](#challenging-a-concern). + +### Expectations on raising a concern + +The [lang team member or advisor](#definitions) who raises a concern is expected to + +* write a constructive comment explaining the concern; +* make themselves available for discussion in a reasonable fashion; +* be prepared to write a document summarizing their concern for the lang-team if requested. + +### When a concern is raised + +When a concern is raised, the team will review the concern in the triage meeting. Based on that discussion, the [document author](#definitions) can decide whether they wish to make changes to mitigate or resolve the concern. + +## Resolving a concern + +If the person who raised the concern is satisfied, either because of changes made or because they don't wish to continue blocking progress, they should resolve the concern themselves with `@rfcbot resolve`. This is the desired outcome. + +If the concern has still not been resolved, there will typically be a period of deeper discussion. The goal is to [find common ground](./making_decisions.md#design-axioms), either by mitigating it directly or by side-stepping it via a subset of the design that still achieves the major goals. + +### Challenging a concern + +If deeper discussion does not reach a solution, a [lang team member](#definitions) can challenge a concern. This indicates that they feel they understand the concern and do not agree it is a problem. + +Challenging a concern is done by scheduling a meeting in which the lang team reads and discusses a summary of the concern and the subsequent discussion. At the end of this meeting, the concern will either be *sustained* (meaning that progress is still blocked) or *resolved* (meaning that final-comment-period can continue, assuming there aren't other concerns to be resolved). + +Sustaining a concern requires [1/3 of the lang team](#doing-the-math) to agree to sustain; this number includes the person who raised the concern, if they are a member of the lang team and not an advisor. Members can agree to sustain either because they with the concern *or* because they feel more time is needed for discussion. + +*Note:* The document to be read during the meeting will ideally be prepared by both the person raising the concern and the people challenging it so that it fairly represents both points of view. The document should include a + +1. summary of the concern and discussion; +2. coverage of possible mitigations, changes, or subsets that were considered and their pros/cons + + +## Doing the math + +Given a team of N>=4 members, the actual threshold `R` for approving a decision is `R = floor(N * 2 / 3)`. The threshold `S` for sustaining a concern is then `N - R`. So e.g... + +| N | R | S | +| --- | --- | --- | +| 8 | 5 | 3 | +| 7 | 4 | 3 | +| 6 | 4 | 2 | +| 5 | 3 | 2 | +| 4 | 2 | 2 | + +If the team has 3 members or less, all members must agree to all decisions and concerns cannot be challenged. Really y'all need to recruit some new members at that point. \ No newline at end of file diff --git a/src/decision-making.md b/src/decision-making.md new file mode 100644 index 0000000..4508b28 --- /dev/null +++ b/src/decision-making.md @@ -0,0 +1,28 @@ +# Decision making + +This page documents our decision making process. + +## Our goal + +We want the ability to make designs that feel fresh, bold, and innotative. We do not want Rust to feel like it has been "designed by committee", with all the interesting bits smoothed down. + +We also want designs that meet Rust user's needs and live up to Rust's ethos of reliabile, performant, accessible code. + +These two goals can be in tension. The former pushes us to empower individuals. The latter pushes us to validate designs broadly. We use this decision making process to guide us in balancing those tensions. + +## Design axioms + +Our decision making process axioms are rules that we follow to help us achieve our goal. We try to satisfy them all, but if they come into tension, we prefer items that appear first in the list. + +* **No new rationale**. We make decisions only after the rationale have been presented publicly and all relevant stakeholders have had a chance to present counterarguments. In particular, we never make [1-way door decisions](./consensus.md) in sync meetings. Instead, we present meeting consensus and leverage rfcbot. +- **Not afraid to do the right thing**. At the end of the day, we have to do what we feel is *right*. Sometimes this means breaking with the tradition and precedent set by other languages. Sometimes it means taking a socially uncomfortable stance (but always with respect). +- **Find common ground**. It's good to break up designs into small pieces and proceed step by step. But be sure that each piece solves an end-to-end problem on its own. +- **Trust each other**. Lang team members are expected to have demonstrated sharp instincts, humility, and the ability to hear and understand others. Sometimes you have to put your doubts aside and trust the others on the team. +- **Treasure dissent**. When someone raises a concern, we take it as an opportunity to improve the design, not an obstacle to be overcome. We invite people to elaborate and make sure we understand what's motivating them before we decide how to respond. + +## Processes + +We divide decisions into two categories: + +* [Reversible decisions (aka, 2-way door)](./2-way-door.md), used for [starting experiments](./how_to/experiment.md) and other decisions that don't make a promise to our end users. Reversible decisions follow a "champion" rule, which means that just one person on the team has to be in favor for the decision to go through; others on the team present concerns as a way to help make sure the champion is aware of them. +* [Consensus decisions (aka, 1-way door)](./consensus.md), used for [stabilization decisions](./how_to/stabilize.md) and for RFC approvals. Consensus decisions require everyone on the team to sign off. The decision cannot be finalized if there is a blocking concern backed by 2 or more team members. diff --git a/src/decision_process.md b/src/decision_process.md deleted file mode 100644 index 664e3cf..0000000 --- a/src/decision_process.md +++ /dev/null @@ -1,53 +0,0 @@ -This section documents the work-in-progress Rust language team decision -process. This process, and the `rustbot` tooling to support it, does not yet -have a finished implementation. This document serves to explain the intended -process, for the purposes of ongoing implementation. - -## Prioritized principles of Rust team consensus decision-making - -These are in order of priority. They're intended to be general enough that they -could apply to any Rust governance team, not just the language team. - -- **Treasure dissent.** When someone raises a concern, that's a chance to - improve the design, and to discover and explore underlying values. Dissent - should be an amicable, cooperative process. -- **Understand and cooperatively resolve concerns.** We cannot resolve a - concern without first understanding it, including the underlying values - motivating it. We should demonstrate that understanding by documenting the - concern. We should consider the tradeoffs and the impacts on users, through - the Rust design principles. We should seek out and favor satisfying solutions - (those that satisfy everyone's values) over - [satisficing](https://en.wikipedia.org/wiki/Satisficing) solutions (those - that are just good enough for people to accept them as a compromise among - conflicting values, without actually being happy with the outcome). -- **Don't force an irreversible decision.** We should make decisions - reversible whenever we can. When making a necessarily irreversible decision - (e.g. stabilizing a feature), we should pay close attention to dissent, and - hesitate before overriding objections. If possible, we should seek a better - alternative, or seek common ground we can find consensus on, or seek an - intermediate step that addresses the same use case and supports evaluation - for a more informed decision in the future. If none of those are possible, - consider the null alternative; not making a change should always be the - easier path, and the burden of proof to override a concern on an irreversible - decision should be high. -- **Value expertise.** When cooperatively resolving a concern, or when - considering overriding a concern, carefully weigh the advice and - recommendations of experts. This includes team advisors, domain experts, and - the owners or members of relevant initiatives. -- **Recording reasoning helps ensure good, consistent decisions over time.** - Even if we decide not to sustain an objection, we should always record the - objection and the reasons for our decision as a "dissent", as well as any - unresolved questions for evaluation later in the process. The team member who - raised the objection has the perogative to author that dissent and frame the - unresolved questions (within reason). -- **Consensus doesn't mean unanimity.** Consensus means everyone is heard and - understood, and all concerns are addressed (even those not treated as - blocking), and the team finds the outcome reasonable. Consensus does not mean - everyone agrees completely. - -## Consensus decision-making process - -First, see [some examples of the decision-making process in -action](./decision_process/examples.md). Then, read the [decision process -reference](./decision_process/reference.md) for the full process and the -`rustbot` tooling to support it. diff --git a/src/decision_process/examples.md b/src/decision_process/examples.md deleted file mode 100644 index d09bd61..0000000 --- a/src/decision_process/examples.md +++ /dev/null @@ -1,297 +0,0 @@ -# Examples of the decision-making process in action - -## Reversible decision: merging a proposal - -The process is best described by example. Suppose that there is a pending lang -team proposal, and a lang team member would like to serve as the liaison. They -contact the team leads and receive the go-ahead. They can then write: - -> @rustbot merge -> -> I propose to merge this proposal. I think it will be a great addition to -> Rust! - -This indicates that they would like to merge the proposal. At the moment, there -is no decision pending, so rustbot would add a comment that looks like the -following: - -> Hello! @Alan has proposed to merge this. This is a **reversible decision**, -> which means that it will be affirmed once the "final comment period" of 10 -> days have passed, unless a team member places a "hold" on the decision (or -> cancels it). -> -> | Team member | State | -> | --- | --- | -> | @Alan | **merge** | -> | @Barbara | | -> | @Grace | | -> | @Niklaus | | - -As the comment says, the PR is now in "pending decision" state, with Alan -having kicked off the process with a proposal to merge. Alan's status of -**merge** will link to his comment. - -Now, for this particular proposal, Barbara has a concern. She thinks that the -proposal has overlooked an important consideration. She writes a comment: - -> @rustbot hold -> -> Did you consider reversing the polarity? Or the impact on the flux capacitor? - -At this point, rustbot updates the state; Barbara's status of -**hold** will link to her comment: - -> Hello! @Alan has proposed to merge this. This is a **reversible decision**, -> which means that it will be affirmed once the "final comment period" of 10 -> days have passed, unless a team member places a "hold" on the decision (or cancels it). -> -> | Team member | State | -> | --- | --- | -> | @Alan | **merge** | -> | @Barbara | **hold** | -> | @Grace | | -> | @Niklaus | | - -Alan is currently busy at work, though, so by the time that he and Barbara -get a chance to talk, 11 days have passed. (Alan and Barbara receive a ping -from rustbot after a week or so.) Once they get a chance to talk, Alan -fully addresses Barbara's concern, so Barbara posts: - -> @rustbot merge - -The comment is updated: - -> Hello! @Alan has proposed to merge this. This is a **reversible decision**, -> which means that it will be affirmed once the "final comment period" of 10 -> days have passed, unless a team member places a "hold" on the decision (or cancels it). -> -> | Team member | State | -> | --- | --- | -> | @Alan | **merge** | -> | @Barbara | ~~hold~~ **merge** | -> | @Grace | | -> | @Niklaus | | - -Barbara's previous ~~hold~~ status links to her previous comment setting her -status to `hold`, and her current **merge** status links to her more recent -comment setting her status to `merge`. - -At this point, all the statuses are either empty or **merge**, and more than 10 -days have passed since the FCP started. Therefore, it completes immediately. - -## Authoring an RFC (illustration of `rustbot restart`) - -After some time, the proposal is completed and an RFC is proposed. This is a -reversible decision. Alan, as the liaison, proposes to merge the RFC with -`@rustbot merge`, and the decision making process proceeds as above. - -This time, Niklaus has a concern: - -> @rustbot hold -> -> I have not had time to read this yet! Give me a bit of time to write it up. - -After 7 days have passed, rustbot writes to him: - -> @Niklaus, I see you have placed a hold but 7 days have passed. Are you any -> closer to reaching a decision? (cc @Alan) - -This continues for a week or two while Alan and Niklaus play "email tag". In -the interim, Barbara decides she agrees with the RFC, so she uses `@rustbot -merge` as well. The status now looks like this: - -> Hello! @Alan has proposed to merge this PR. This is a **reversible -> decision**, which means that it will be affirmed once the "final comment -> period" of 10 days have passed, unless a team member places a "hold" on the decision (or cancels it). -> decision. -> -> | Team member | State | -> | --- | --- | -> | @Alan | **merge** | -> | @Barbara | **merge** | -> | @Grace | | -> | @Niklaus | **hold** | - -Eventually, Alan and Niklaus find a time to discuss, and Alan agrees that -Niklaus's concerns are valid, so he makes some major edits to the RFC. Given -that the RFC is completely different, he decides to restart the clock and -writes: - -> @rustbot restart - -This strikes through the state of all team members (setting their current -status to blank, while preserving the history) and begins the clock anew. -rustbot also pings the relevant team members: - -> Dear @rust-lang/team, @Alan has restarted the clock! - -The status now looks like this: - -> Hello! @Alan has proposed to merge this. This is a **reversible decision**, -> which means that it will be affirmed once the "final comment period" of 10 -> days have passed, unless a team member places a "hold" on the decision (or cancels it). -> -> | Team member | State | -> | --- | --- | -> | @Alan | **merge** | -> | @Barbara | ~~merge~~ | -> | @Grace | | -> | @Niklaus | ~~hold~~ | - -Barbara can use `@rustbot merge` to re-affirm her **merge** status, and Niklaus -can use `@rustbot merge` to set his own status to **merge** since he agrees -with the resolution of his concern. - -## Authoring an RFC continued (Overriding a concern) - -At this point, Grace has a concern, and explains that concern in detail: - -> @rustbot hold -> -> I've thought about this a lot, and I don't think we should do this. Now that -> I see the syntax used in practice, I feel like if we do this it'll have an -> adverse effect on the ecosystem... - -The status now looks like this: - -> Hello! @Alan has proposed to merge this. This is a **reversible decision**, -> which means that it will be affirmed once the "final comment period" of 10 -> days have passed, unless a team member places a "hold" on the decision (or cancels it). -> -> | Team member | State | -> | --- | --- | -> | @Alan | **merge** | -> | @Barbara | ~~merge~~ **merge** | -> | @Grace | **hold** | -> | @Niklaus | ~~hold~~ **merge** | - -Niklaus reads this message. He feels he understands the concern well, and -agrees that this point hasn't yet been considered: - -> @rustbot hold -> -> I agree. I think we should take more time to evaluate alternative syntaxes. -> What about... - -Over the course of a few subsequent meetings and side conversations, Grace and -other team members discuss the concern further; the initiative owner also -considers the concern, and raises it with others working on the initiative. - -The owner of the initiative updates the RFC to include a discussion of a couple -of alternative syntax proposals. The owner recommends a slightly modified -version of the originally proposed syntax, and outlines criteria that they feel -the syntax should meet in order to support the use case. - -Grace agrees that her concern has been understood, but does not agree with the -proposed syntax. Grace feels the new proposal is an improvement, but her -concern remains. - -Niklaus feels that the team has understood Grace's concern, and furthermore, -that the updated proposal addresses Grace's concern: - -> @rustbot merge -> -> I appreciate the potential impact this may have on the ecosystem. However, I -> feel that as now described in section XYZ of the RFC, the value of A -> outweighs the risk of B, and I think C mitigates the potential risk by... - -(Notice that while Niklaus feels that the team has understood Grace's concern, -he does not speak for the entire team or imply that his summary represents the -entire team. Niklaus is just withdrawing his own support for the concern.) - -At this point, the entire team other than Grace agrees that the proposal should -move forward: - -> Hello! @Alan has proposed to merge this. This is a **reversible decision**, -> which means that it will be affirmed once the "final comment period" of 10 -> days have passed, unless a team member places a "hold" on the decision (or cancels it). -> -> | Team member | State | -> | --- | --- | -> | @Alan | **merge** | -> | @Barbara | ~~merge~~ **merge** | -> | @Grace | **hold** | -> | @Niklaus | ~~hold~~ ~~merge~~ ~~hold~~ **merge**| - -(We'll assume, for this example, that Grace does not manage to convince anyone -else.) - -Grace takes some time, working with the RFC author, to add a dissent, including -a specific unresolved question. - -Grace then writes a comment containing `@rustbot dissent`. (If necessary, or if -Grace would prefer, another team member may issue `@rustbot @grace dissent` on -her behalf.) The status now looks like this: - -> Hello! @Alan has proposed to merge this. This is a **reversible decision**, -> which means that it will be affirmed once the "final comment period" of 10 -> days have passed, unless a team member places a "hold" on the decision (or cancels it). -> -> | Team member | State | -> | --- | --- | -> | @Alan | **merge** | -> | @Barbara | ~~merge~~ **merge** | -> | @Grace | ~~hold~~ **dissent** | -> | @Niklaus | ~~hold~~ ~~merge~~ ~~hold~~ **merge**| - -Since all statuses are now either **merge** or **dissent** rustbot also posts a -comment: - -> The final comment period has resolved, with a decision to **merge**. -> -> Note that this decision has dissents; please ensure these dissents have been -> recorded for subsequent consideration. - -## Stabilizing a feature - -The feature has been implemented and is now eligible for stabilization. Alan -writes a stabilization report and posts it, and then issues the command - -> @rustbot stabilize - -Rustbot recognizes that a "stabilization" decision is irreversible, so the -template is a bit different: - -> Hello! @Alan has proposed to stabilize this. This is a **irreversible -> decision**, which means that it will be affirmed once all members come to a -> consensus and the "final comment period" of 10 days has passed. -> -> | Team member | State | -> | --- | --- | -> | @Alan | stabilize | -> | @Barbara | | -> | @Grace | | -> | @Niklaus | | - -This time, Barbara, Grace, and Niklaus must all explicitly provide a status -before the decision can proceed. One by one, they join the PR. They must -individually set their state using one of the rustbot commands. - -Niklaus reads this and comments with `@rustbot merge`. But then, Niklaus uses -the feature and discovers a crucial flaw. He posts a comment: - -> @rustbot close -> -> After more testing, I believe this is not ready for stabilization. I have -> found that it doesn't work at all like the specification in the case of foo! -> This seems closely related to Grace's concern on the RFC; I think if we -> stabilize at this point we may indeed harm the ecosystem... - -Other team members test as well, and find that Niklaus is right. Alan changes -his status using `@rustbot close`, and Grace (with some relief) sets the same -status. - -Once everyone has changed their status, rustbot posts a comment: - -> The final comment period has resolved, with a decision to **close**. - -(Note: Since `close` is an inherently reversible status (a PR can always be -reopened), rustbot can observe that everyone has set a reversible status, and -will start treating the decision as reversible; this means the final comment -period can end even if Barbara hasn't responded yet.) - -This may not be the end of this feature's consideration, and the concern might -get resolved in many different ways. The initiative owner might need to do some -additional design work on how to solve the original use case and address the -concern; implementers may find a way to address the concern by improving the -implementation; or the team may change their mind. diff --git a/src/decision_process/reference.md b/src/decision_process/reference.md deleted file mode 100644 index 44e2391..0000000 --- a/src/decision_process/reference.md +++ /dev/null @@ -1,194 +0,0 @@ -# Decision-making process, detailed description - -- Entering a "decision period" can be done by having a team member tell rustbot - an initial status (`merge`, `stabilize`, or `close`; or, `reversible` or - `irreversible` with a custom identifier). - - All other team members have no initial status set. - - During a reversible decision period, if later commenters indicate the - decision is irreversible, the decision changes to irreversible. - - During an irreversible decision period, if all commenters change their - status to a reversible status (most commonly `close`), the decision becomes - reversible. - - Bot commands accept `mut`/`mutable`/`rev` as synonyms for `reversible`, and - `immut`/`immutable`/`irrev` as synonyms for `irreversible`. -- Once the "decision period" has begun, a clock of 10 days starts. The clock is - never paused unless an explicit `@rustbot restart` command is given. -- The `restart` command sets the decision period back to its initial state - (members' current statuses are also set back to blank, though the history of - their previous statuses is preserved as with any other status change). -- A decision is reached when the following conditions are met: - - At least 10 days have elapsed since the decision period began (or when it - was last `restart`ed). - - Everyone is set to the same status, or to `abstain`, or to `dissent` (with - at most one `dissent` status), or (for a reversible decision only) blank. -- Member may place a *hold* (raise a concern) at any phase of the process: - proposal, experimentation, testing, stabilization. Ideally, concerns should - be raised as early as possible. - - In general, one of the liaison's jobs is to anticipate concerns that may - arise and reach out proactively to the members of the team. If we find that - team members regularly need to place serious holds for similar reasons, - that may indicate we need to work harder at team calibration. -- "Holding" a decision is simple. If you have a potential concern that you - haven't had a chance to fully articulate yet, you get periodic pings. -- In order to proceed after a concern is raised, whether sustaining the concern - or overriding the concern, the team must understand the concern. This - understanding should be expressed in writing rather than just verbally. - Commonly, the owner of an initiative/proposal may incorporate the concern - into the proposal and address it there (whether via their own words or those - of a team member). - - Ideally, a concern is only considered "understood" if the objector agrees - it has been. If that is not possible, then everyone on the team other than - the objector must unanimously agree that there is no further understanding - to be gained. (In practice, this agreement is determined by whether anyone - on the team is willing to support the objection.) -- If the owner feels that the concern has been adequately addressed, they can - produce a write-up that describes the concern and request a poll of the team - members to see where everyone stands. - - Sustaining an objection requires one team member other than the objector. A - team member should sustain an objection if either they believe the - objection has been understood and they agree that it must be addressed, or - if they believe the objection has not been fully understood (whether they - personally agree with it or not). - - If everyone else agrees that the concern has been understood *and* that the - current design is sufficient, then the concern is *overridden*. - - Team members are encouraged to regularly sustain objections they don't - personally agree with, if they believe the objection has not yet been fully - understood; this is a normal and valuable part of the process. -- Whenever a concern is overridden, team members are encouraged to add a - **dissent** into the document to describe their concern and why they don't - agree with the decision. They (or another team member) should then set their - status to `dissent`. - -# Rustbot commands - -The following commands are accepted by rustbot. (Commands written below omit -the required `@` on rustbot to avoid invoking rustbot when quoting the -documentation.) A number of comments take one or more optional `@member` -arguments, denoted `@member*`; if supplied, the command is issued on behalf of -those member(s), instead of the person writing the command. (The `@` for each -member is required.) It is also permitted to write `@rust-lang/team` to select -all members of the team. rustbot will always link from each member's row in the -table to each comment changing their status. - -- `rustbot @member* reversible ident` or `rustbot @member* mutable ident` - (unambiguous prefixes such as `mut` or `rev` also work) - - If not in a decision period: begin a reversible ("mutable") decision, - proposing the outcome `ident`; all other members are set to a blank status. - - If in a decision period: set yourself to `ident`. (Decisions do not proceed - unless all members have the same status or `abstain`.) -- `rustbot @member* irreversible ident` or `rustbot @member* immutable ident` - (unambiguous prefixes such as `immut` or `irrev` also work) - - If not in a decision period: begin an irreversible ("immutable") decision, - proposing the outcome `ident`; all other members are set to a blank status. - - If in a decision period: set yourself to `ident`. If the decision was - previously considered reversible, change it to irreversible. The decision - now requires full team consensus. (Members may set a status of `abstain` on - the decision if they wish.) -- `rustbot @member* merge` - - Alias for `rustbot @member* reversible merge` - a reversible decision with - the proposed outcome `merge`. -- `rustbot @member* close` - - Alias for `rustbot @member* reversible close` - a reversible decision with - the proposed outcome `close`. -- `rustbot @member* stabilize` - - Alias for `rustbot @member* irreversible stabilize` - an irreversible - decision with the proposed outcome `stabilize`. -- `rustbot @member* abstain` - - If not in a decision period: error - - If in a decision period: set your status to `abstain`. This status does not - block a decision. -- `rustbot @member* hold` - - If not in a decision period: error - - If in a decision period: set your status to `hold` - - Every N days while a hold persists, rustbot will ping all members who - have status `hold` (and potentially other involved team members as well) -- `rustbot @member* dissent` - - Equivalent to `abstain`, except that it sets a status of `dissent`. This - status on one team member does not block a decision. A status of `dissent` - on two or more team members will block a decision. - - Note that `dissent` should not be set when first raising a concern, only - after attempts to resolve the concern have been unsuccessful. -- `rustbot restart` - - If not in a decision period: error - - If in a decision period: set all members other than the one issuing the - command to have a blank status. Preserve the last set status of the person - issuing the `restart`. - - Note: if the last set status of any team members were irreversible, the - decision will continue to be treated as irreversible until all such members - set an explicit status otherwise. -- `rustbot cancel` - - If not in a decision period: error - - If in a decision period: cancel the decision period. - - Note that if a subsequent decision is started in the same issue, rustbot - should link to the previous decision summary table. - -# Frequently asked questions - -## Why can members override other members positions? - -It's quite common to want to check boxes and similar on behalf of all the -people in a meeting. It's also annoying to have to restart a decision process -(e.g. closing and reopening with rfcbot) just to be able to close concerns on -someone else's behalf (e.g. people who have left the team, or people who raised -a concern on behalf of someone else not on the team, or similar). We can trust -each other on the team. If people abuse `rustbot` to disrupt the process, that -isn't a problem to be solved with tooling. - -## Do we want to require "all but N" people to affirm a decision, as `rfcbot` does? - -We opted to require 100% participation on irreversible decisions such as -stabilization, but not on very lightweight reversible decisions such as -starting an initiative. We believe that lang team members can be expected to at -least leave a comment (even if just `rustbot abstain`), but in the limit we -also have the option to set a status on another member's behalf. - -## Why does the timer start when the decision period *starts*, and not when a consensus is reached? - -The current `rfcbot` starts the 10 day FCP timer once a consensus is reached. -However, we have observed that, in practice, the "holdouts" on consensus are -typically the lang team members. Further, this seems to assume a "two-phased" -decision making model where folks outside the team are commenting only after -the lang team has reached a consensus. In practice, both decision-making and -commenting tend to be more fluid, and hence we would prefer not to have a long -delay after we reach consensus. - -## Why not use checkboxes? - -This process recognizes that sometimes, in the flow of conversation, the -decision to merge can transmute into a decision to close, or there may be -multiple potential outcomes. - -The presentation of statuses also makes it easy for `rustbot` to present the -history of status changes, with links to team members' messages. - -## Why is `close` always reversible? - -Because, well, it is! We can always re-open a PR or issue, after all. - -## What about "postpone"? - -Just write it in the comment for a `@rustbot close`. In practice, a "close" -does not preclude reopening later, and a "postpone" does not guarantee -reopening later. - -## Is "Don't force an irreversible decision?" absolute? - -No; it's a strongly held principle, but not an absolute one. Sometimes we may -have to make an irreversible decision, even in the face of dissent. However, we -should be *extraordinarily* careful when doing so, and in particular, we should -consider very carefully whether we could make a reversible decision, or find a -better consensus, or whether the consequences of *not* making the decision -outweigh the consequences of making it. This should be an extremely rare event. - -The previous decision-making process based on `rfcbot` allowed indefinitely -blocking concerns. This new process introduces a means of carefully resolving -such concerns, and a very careful means of proceeding *despite* such concerns -while ensuring those concerns are understood and recorded and considered. - -## What purpose does `restart` serve? - -Sometimes, a proposal has changed enough to warrant re-checking people's -positions, but has not changed enough to warrant closing it and starting the -process over. `restart` clears people's statuses to ensure that they have the -opportunity to re-confirm (or raise a hold or concern) before the decision -proceeds. From 87568db3b183bc1a6590d77a781c3fa2d1d73270 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 2 May 2025 19:17:29 -0400 Subject: [PATCH 2/3] tighten the nnr rule to its essence --- src/decision-making.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/decision-making.md b/src/decision-making.md index 4508b28..32bf1d2 100644 --- a/src/decision-making.md +++ b/src/decision-making.md @@ -14,7 +14,7 @@ These two goals can be in tension. The former pushes us to empower individuals. Our decision making process axioms are rules that we follow to help us achieve our goal. We try to satisfy them all, but if they come into tension, we prefer items that appear first in the list. -* **No new rationale**. We make decisions only after the rationale have been presented publicly and all relevant stakeholders have had a chance to present counterarguments. In particular, we never make [1-way door decisions](./consensus.md) in sync meetings. Instead, we present meeting consensus and leverage rfcbot. +* **No new rationale**. We make decisions only after the rationale have been presented publicly and all relevant stakeholders have had a chance to present counterarguments. - **Not afraid to do the right thing**. At the end of the day, we have to do what we feel is *right*. Sometimes this means breaking with the tradition and precedent set by other languages. Sometimes it means taking a socially uncomfortable stance (but always with respect). - **Find common ground**. It's good to break up designs into small pieces and proceed step by step. But be sure that each piece solves an end-to-end problem on its own. - **Trust each other**. Lang team members are expected to have demonstrated sharp instincts, humility, and the ability to hear and understand others. Sometimes you have to put your doubts aside and trust the others on the team. From f667fe810190fcd30a5c81803a561bd682def849 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 3 May 2025 11:57:18 -0400 Subject: [PATCH 3/3] adjust formula After some discussion with tmandry, I realized that S + R do not have to add up to N. In fact, it seems good to have a bit of a "gap" such that it's easier to sustain a concern than it is to push something forward, allowing for "abstains". --- src/consensus.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/consensus.md b/src/consensus.md index 8b37f0f..6e3380d 100644 --- a/src/consensus.md +++ b/src/consensus.md @@ -50,7 +50,7 @@ If deeper discussion does not reach a solution, a [lang team member](#definition Challenging a concern is done by scheduling a meeting in which the lang team reads and discusses a summary of the concern and the subsequent discussion. At the end of this meeting, the concern will either be *sustained* (meaning that progress is still blocked) or *resolved* (meaning that final-comment-period can continue, assuming there aren't other concerns to be resolved). -Sustaining a concern requires [1/3 of the lang team](#doing-the-math) to agree to sustain; this number includes the person who raised the concern, if they are a member of the lang team and not an advisor. Members can agree to sustain either because they with the concern *or* because they feel more time is needed for discussion. +Sustaining a concern requires [1/4 of the lang team](#doing-the-math) to agree to sustain; this number includes the person who raised the concern, if they are a member of the lang team and not an advisor. Members can agree to sustain either because they with the concern *or* because they feel more time is needed for discussion. *Note:* The document to be read during the meeting will ideally be prepared by both the person raising the concern and the people challenging it so that it fairly represents both points of view. The document should include a @@ -60,14 +60,19 @@ Sustaining a concern requires [1/3 of the lang team](#doing-the-math) to agree t ## Doing the math -Given a team of N>=4 members, the actual threshold `R` for approving a decision is `R = floor(N * 2 / 3)`. The threshold `S` for sustaining a concern is then `N - R`. So e.g... +Given a team of N>=4 members, the actual threshold `R` for approving a decision is `R = round(N * 2 / 3)`. The threshold `S` for sustaining a concern is `floor(N / 4)`. So e.g... | N | R | S | | --- | --- | --- | -| 8 | 5 | 3 | -| 7 | 4 | 3 | +| 20 | 13 | 5 | +| ... | ... | ... | +| 12 | 8 | 3 | +| ... | ... | ... | +| 9 | 6 | 2 | +| 8 | 5 | 2 | +| 7 | 5 | 2 | | 6 | 4 | 2 | | 5 | 3 | 2 | -| 4 | 2 | 2 | +| 4 | 3 | 2 | If the team has 3 members or less, all members must agree to all decisions and concerns cannot be challenged. Really y'all need to recruit some new members at that point. \ No newline at end of file