What is a team?
— 2023-11-08

update (2023-11-08): I've swapped the usage of "horizontal" and "vertical" in this post based on feedback.

This is going to be an ultra-short post to share an idea I've been mulling over in my head for a while. Yesterday I raised the question again about WG Async getting checkboxes for approval on decisions. For the past five or so years we've had a version of the async working group driving the design of async Rust. With the past three years being a lot more organized, with a steady roster, leadership, and mandate. WG Async getting the ability to set checkboxes for approval would mostly just be a formalization of the existing role we play in the project.

However, in order to give checkboxes to the Async WG there is a question about the way it should integrate into the project. Historically we've distinguished between: top-level "teams", and domain-specific "working groups". Teams are formal, first-class entities with voting rights. While working-groups are not. This current structure still exists in the project, and so in order for WG Async to get checkboxes we'd need to become a "team". And with that there is also a question about whether we should be a sub-team (like T-Types) or a top-level team.

Top-level teams get a seat on the council. Sub-teams are only represented on the council by their parent teams. In the case of T-Types the parent teams are "Lang" and "Compiler". In the case of WG Async the parent teams should be at least "Lang" and "Libs-API"; but arguably also "Compiler" since we tend to implement the features we've designed.

And this is where I think the current model runs into trouble. Ideally we'd think of the organization hierarchy as a tree: there are teams and there are sub-teams. But because sub-teams can have multiple parents, our tree is really a DAG. And that becomes pretty complex to reason about. So instead I want to propose an alternate model to our organizational DAG: I think we might be better off reasoning in terms of vertical and horizontal teams.

Categorizing teams like this doesn't directly help answer questions about who should have a seat on the council, nor things like membership. Those are questions of policy, and I'm intentionally keeping that out of scope for this post. But I hope it can help us explain why teams like "Async" feel different from teams like "Compiler".

Specifically I also believe that horizontal teams can help fill the gaps left between verticals. The Types Team exists because we identified that it's not enough to think about the language, or the compiler - but there is a need to also consider how the two interact. Similarly: WG Async doesn't just consider the async language, library, or compiler aspects. It needs to consider how the language features will be implemented, and how that in turn will affect libraries.

I don't know what we want to name these groups. In my opinion both vertical and horizontal teams should be teams in their own right; with neither being "more real" than the other. But as I've said: if we were to adopt that we'd need to reason about a bunch more things, because the current project structure attaches certain things to "top-level" teams right now.

There is also a final question about the difference between "teams" and "initiatives". The way I'm reasoning about those is as follows:

From my perspective the purpose of an initiative is to organize specific sets of work under a team, without requiring the people doing that work are members of that team. For example, neither Oli nor I are members of the Lang team, but the Effect Generics are a language-level effort. The Effects Initiative allows us to do this work under the purview of the Lang Team without either of us being on the Lang Team.

And that's about it. I think if we're going to be talking about teams and sub-teams, I think it's clearer to reason about teams in terms of "vertical concerns" (fixed domains like "compiler", "language", "stdlib") and "horizontal concerns" (cross-cutting domains like: "the type system", "async support", "moderation").