---
# System prepended metadata

title: Proposed concern policy 2024-12-18
tags: [T-lang, minutes, design-meeting]

---

---
title: "Lang design meeting 2024-12-18: Proposed concern policy"
tags: ["T-lang", "design-meeting", "minutes"]
date: 2024-12-18
url: https://hackmd.io/kyjb30WlTFycps1g90hZfQ
---

# Proposed concern policy 2024-12-18

## Summary

Distinguish *concerns* and *blocks*. A *concern* simply signals that something to discuss in triage; concerns are typically resolved once discussion has occurred.

A *block* stops progress. Blocks cannot be proposed by individuals. They result either from a triage meeting consensus that the problem needs to be addressed or as the result of a design meeting in which a "significant minority" (a quarter of the team, minimum 2) agrees that the issue needs to be addressed. Design meetings to propose a block typically take place when triage meeting discussion was inconclusive and some team member feels sufficiently motivated to propose a block. In that case the member is responsible for authoring the document.

## Design axioms

TODO

## More detailed

I haven't fully thought through how to "automate" this. We should really review the [lang team decision process](https://lang-team.rust-lang.org/decision_process.html) again.

But the general idea would be:

* Raising a **concern** nominates the issue for discussion. The concern is typically removed after discussion occurs except in these cases...
    * *meeting consensus on needing more information* -- in which case we ask the question and discuss again
    * *meeting consensus the concern needs to be addressed* -- in which case we can directly raise a block
    * *someone on the team they want to block* -- in which case we will schedule a meeting, possibly in the next planning meeting cycle.
* Raising a **block** is done after...
    * a triage meeting in which meeting consensus was that the concern needs to be addressed
    * a design meeting in which a significant minority felt the concern needed to be addressed
* Meeting consensus is defined as...
    * nobody in the meeting blocked
    * nobody expected that those absent from the meeting would block
        * if this is false we can revisit the question
* A "significant minority" is >= 1/4 of the team with a minimum of 2 team members
    * advisors count as team members for this purpose
* As a procedural note:
    * any team member should be able to instruct the bot to clear a concern or a block. But the expectation is that blocks that were added according to the process above will not be removed without the consent of the person who raised the block or in other exceptional circumstances (e.g., they leave the team).

## Discussion questions

### Does the basic idea seem reasonable?

nikomatsakis: Let's kick off with the basic idea of having concerns be "this needs to be discussed" and blocks be something that results from a meeting and requires a "significant minority".

TC: I was thinking about the case for enum variant orderings, where scott had concerns, it had a lot to do with lang-api side. Scott had concerns. When Scott did, I did, so I would have seconded a block, we were blocking on the idea that Scott wanted to make a proposal for how to straighten the situation out, get people what they wanted in a way that didn't compromise our flexibility of the language. I kinda see how it fits this model.

Josh: Seems helpful to distinguish between the two main things this proposes:

1) Distinguishing between concerns and blocks.
2) Setting requirements for blocks, and what those requirements should be.

Huge :+1: to (1) here; having distinct terminology here will help communicate more clearly what people are seeking to do, and we should have more tools for tracking both. In particular, having good ways to track concerns, in addition to blocks, means we don't have only "one hammer" (blocks) to use for everything.

Relatedly, it seems helpful to tie this to things like "unresolved questions". e.g. it should be easy to add an unresolved question as part of an RFC acceptance, with the expectation that it get resolved before stabilization.

(2) seems like the point likely to produce the most discussion here.

scottmcm: agree that we've often talked in meetings about whether to raise concerns already, and thus having a more "official" version of that sounds good.  I also like that it lets adding a concern from others in FCP be less of a "big deal".

JT: In the past we've talked about distinguishing 1- vs 2-way doors. It seems to me that "anybody" should be able to "block" an RFC, but it can be resolved with an unresolved question -- will be evaluated before stabilization. Under most circumstances (and once we have some process conversations about not creating a "momentum"/"snowball" effect), I think most blocking concerns should be turned into unresolved questions, unless they have consensus concerns among the team. And then the question becomes what to do with blocking concerns on *stabilizations*, which are a 1-way door. We should have a process where there is a 'standard way' to resolve concerns on 2-way doors, and we should hesitate to have "more strongly blocking" concerns that aren't resolved that way. Only concern I would have would be about 1-way doors and saying we can override a concern even on a 1-way door. That creates a bias towards action that I'm not sure we want, given the stability and longevity of Rust.

Tyler: I think the general idea is sound. I'd like to talk through some examples. I'm wondering exactly what it means to "resolve" a block, how they get resolved, etc. What if one of the people filing it decides it's not longer important, etc? More in the weeds. I do think we should talk about the distinction that Josh is making between 1 and 2 way doors. I think that's the hard thing we have to resolve.

TC: I think it'd be interesting to talk through the axioms. Maybe if we work through them.

### Design axioms

nikomatsakis: I feel like I had some axioms but I didn't write them down. I'm going to take a stab at how I got here.

* Spirit of consensus-- I think we should be striving for "non-blocking consensus" in practice. In other words, I don't really want the daily experience of our design and development to change.
* Sharp designs-- we want the ability to do sharp designs, which I think means that sometimes we are going to have to make hard calls. The current setup gives a lot of power to individuals and can easily lead to a kind of catering to individual predilections, I'd prefer to avoid that.
* More structure-- concerns right now are used for a variety of things and I think it's kind of confusing. I know I personally shy away from them for "minor things" because they do have such a big impact on the process, but then it's unclear if a comment of mine is meant as something I want to talk about or just a passing comment. I'd like to see us having ways to express more things.
* Burden of proof on stop energy -- "bias towards action" --

TC: Some other thoughts about the inherent tensions we face in designing a decision process:

- Supermajority: We want broad consensus on the team for language design changes, as we'd get an incoherent language if we went with 51% for each thing.
- Not design by committee: However, in doing that, we have to avoid the problems of design by committee.  We don't want to water down designs with odd compromises.
- Not design by the most likely to block: We don't want the desire for unanimity or broad consensus to end up with a decision process that biases toward the people most likely to block.

Josh:

(These are notes, not an ordered list of axioms)
- :+1: for "Spirit of consensus" *and* "Sharp designs".
- Sharp designs are really important. We should be able to decide between ambitious coherent proposals without always ending up with some amalgamated soup of the subsets we can get consensus on.
- Want to avoid two different failure modes of "design by committee":
  - Failure mode of watering everything down and mixing everything together, and being unable to have sharp designs.
  - Failure mode of including everything anyone wants, and having it not work together, or not take into account the total weight/complexity of the language. We don't want to be C++.
- Consensus, not voting. We've talked for a long time about how we do consensus and not voting, and I don't think we should lose that.

### "Bias towards action" vs "default to no"

Josh: There's a lot of standard wisdom in the Open Source community about whether the default disposition of something is "accept" or "reject", and that the job of a maintainer includes saying "no" a lot. It seems like this proposed process creates a bias towards "merge". This seems like a way to end up with a very "inclusionist" language / design-by-committee.

scott: I think there's maybe some kind of "activation energy" concept here.  Most things don't get the activation energy and should be dropped early, but once they cross that "everything starts with -100 points" threshold then "find a way to merge" becomes appropriate.

scott: which I guess is that same "separate the problem-worth-solving from the specific-solution" thing again?

NM: (paraphrased) some points

* I tend to think the job of maintainer is not just to say NO but to say YES to the right things. The community says NO a lot, we have to find the good ideas and lift them up.
* I feel like it's not quite 1 vs 2 way door, RFCs are like a 1.5 way door, where there are things that it would be better to settle up front -- if the objection is really fundamental, moving it to an unresolved question just feels like deferring a fight. On the other hand I think giving time to work things out is important. I don't quite know how to articulate the criteria for what makes sense.
    * I think one of our strengths as a community is willingness to change our minds -- either because of new realizations or because we realize an objection was more important than we thought.
    * But at the same time I don't love the whiplash feeling of "everything is up in the air all the time". I would like things settled so we can move on and discuss other things. 

tmandry: partly a question of process, not binary decisions.

JT: classic example was the bikeshed on async/await, we knew all along that syntax question was a problem, we kicked it down the road, and never had a good way of solving it. The thing about unresolved question, this is a pattern I've seen several times, there's a notion of "the time for this concern was X" but it already past. 

JT: You raise a concern at stabilization and people say "the time was RFC"; at the RFC they say move it to an unresolved question. We need to have some clearer guidance/process for which one is the "correct" option.

scottmcm: To try and mix a few things, the 3 phase thing-- I like us pushing harder on the experimentation phase. The experimentation can happen without an RFC being merged. I think there's a missing 1st step -- the job of maintainer is to say no -- that classic 'what is the problem you are trying to solve' kind of thing. Maybe there's a first phase of "we don't think it's a problem that semicolons don't compile in a struct definition".

NM: I think the experiment process bar of "you have to have a lang-team second + be a trusted maintainer" already screens out really bad ideas. We could do a bit better identifying the problems as always but I can't think of experiments that were really out of left field.

TM: I want to +1 what Scott is saying. Defining the problem is a very good time to check that we have alignment on what we are actually solving. An example that comes to mind is the mut RFC (making mut a lint). If there had been a problem statement up front rather than a solution presented that gave people knee jerk reactions, we probably could have iterated on the problem statement and led to a different solution and a different understanding of the problem to begin with. Not saying it would have solved the community backlash problem, maybe, but sometimes defining succintly the problem is the most imporatnt first step. One reason I think project goals are useful, you're doing that up front. 

TM: Josh were you lamenting not having picked a syntax up front? 

Josh: I agree the experiment we did was good, I think it's more, we all more-or-less knew we had disagreements on the syntax, despite that it was never the topic of the day until it came to a head and "we have to do something". Unpleasant for everyone. We can do experiments in parallel with deferred syntax, which we should do, but that question needs to be looked at the entire time, not right at stabilization time.

TC: Similar to Niko, I reject the framing of our job as maintainers being to say "no".  Our job is to protect and grow the language, which sometimes means saying "no", but it also means solving problems for users.  It means building something beautiful -- a language that people will love.

TC: I've been especially pleased by our recent tendency to do more experimentation prior to doing the RFC.  Among other benefits, it's worth avoiding having a bunch of accepted RFCs that go unimplemented for years.  There's a cost to that, similar to the cost in having a lot of long-lived branches outstanding.  The world changes, and an RFC we accepted 3 years ago might not make sense today.

TC: When we're thinking to defer things, it's worth asking why we'll be smarter tomorrow than we are today.  And when we reconsider something that we decided earlier, we should ask why we're actually smarter today than we were yesterday.  It's easy to lose track of the context of all the things that were earlier considered and discussed in detail.

TC: Niko mentioned the legal concept.  It's called stare decisis.  "Let the decision stand."  It's based on the very old and very correct notion that, often, we're not smarter than the many similarly-situated people who earlier considered the same question.

TC: Embrace the idea that we are building a language people LOVE. You can't get there by saying NO all the time. You get there by accepting the right ideas. I've been happy with our recent shift towards experimentation. There's a cost to having RFCs that are accepted and go unimplemented for years. That cost is similar to the cost of having a ton of branches outstanding. You have to ask "how does this interact with X", something we've accepted an RFC for but never figured out how to stabilize. To the point of when we defer, I think we have to ask "what will make us smarter tomorrow" -- and when we relitigate, we should ask "why are we smarter today" (what changed). A lot of times you read an RFC thread and it seems everything was considered and came up at the time. 

NM: I think it seems clear we had consensus on "concern vs block" being a useful distinction 

Josh: yes and about 1-, 1.5, and vs 2-way door being a focal point of the process considerations (though we don't yet know what we want there).

(TM: I agree that should be part of the conversation; not sure yet how it should affect the process)

NM, side note 1: I wonder about things like "unresolved question with a plan to resolution" -- i.e., maybe an RFC ought to be "conditionally approved".

NM, side note 2: we should write up some of the problems we are aiming to solve. 

Josh: "deciding not to decide"

Josh: What is an experiment trying to solve? Is it an experiment to 

### Who can raise concerns?

nikomatsakis: My proposal would be any Rust team member (from any team) can raise a concern, but only lang team + advisors can vote towards a block.

TC: It seems this should have a minimum of one lang member, otherwise we'd probably want a separate process then for overriding such blocks where no lang members support it.

NM: i.e., advisor + a team member can block? sounds like what I actually meant, yes.

### What should count as a "significant minority"? 

nikomatsakis: I think it should be at least 2, but a fixed number seems dumb, so I said 1/4.

tmandry: It isn't clear from the doc how to count advisors in that 1/4.
