Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

consensus decision making #113

Merged
merged 10 commits into from
Nov 3, 2021
3 changes: 3 additions & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
- [Stabilized](./initiatives/process/stages/stabilized.md)
- [Inactive](./initiatives/process/stages/inactive.md)
- [FAQ](./initiatives/faq.md)
- [Decision process and principles](./decision_process.md)
- [Decision process examples](./decision_process/examples.md)
- [Decision process reference](./decision_process/reference.md)
- [Lang team "how to" guide](./how_to.md)
- [Nominate an issue](./how_to/nominate.md)
- [Propose an initiative](./how_to/propose.md)
Expand Down
53 changes: 53 additions & 0 deletions src/decision_process.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
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.
297 changes: 297 additions & 0 deletions src/decision_process/examples.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
# 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 by the time that he and Barbara
joshtriplett marked this conversation as resolved.
Show resolved Hide resolved
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.
Loading