Giter VIP home page Giter VIP logo

team's Introduction

Rust teams structure

This repository contains the structure of the Rust teams. The repository is automatically synchronized with:

Service Synchronized every
@bors In real time Integration source
Crater and @craterbot In real time Integration source
Perf and @rust-timer In real time Integration source
@rfcbot 5 minutes Integration source
GitHub teams membership Shortly after merge Integration source
GitHub repositories Shortly after merge Integration source
Mailing lists and aliases (@rust-lang.org, @crates.io) Shortly after merge Integration source
Zulip user group membership Shortly after merge Integration source
Governance section on the website 2 minutes Integration source
crates.io admin access 1 hour Integration source

If you need to add or remove a person from a team, send a PR to this repository. After it's merged, their account will be added/removed from all the supported services.

Documentation

Using the CLI tool

It's possible to interact with this repository through its CLI tool.

Verifying the integrity of the repository

This repository contains some sanity checks to avoid having stale or broken data. You can run the checks locally with the check command:

cargo run check

Note that some of these checks will be skipped due to missing API tokens.

Adding a person to the repository

It's possible to fetch the public information present in a GitHub profile and store it in a person's TOML file:

cargo run add-person <github-username>

You can also add additional information, such as someone's Discord or Zulip ID by adding additional fields to their .toml file.

To determine someone's Zulip ID, find them in the list of people on the right-hand side in Zulip, click the "three dots" menu, and copy the 'User ID' into the toml file:

zulip-id = <user id>

Querying information out of the repository

There are a few CLI commands that allow you to get some information generated from the data in the repository.

You can get a list of all the people in a team:

cargo run dump-team all

You can get a list of all the email addresses subscribed to a list:

cargo run dump-list [email protected]

You can get a list of all the users with a permission:

cargo run dump-permission perf

You can generate www.rust-lang.org's locales/en-US/tools.ftl file by running

cargo run dump-website

The website will automatically load new teams added here, however they cannot be translated unless tools.ftl is also updated.

You can also print a list of users with individual access to repositories

# Group the accesses by repository
cargo run dump-individual-access --group-mode repo

# Group the accesses by contributor
cargo run dump-individual-access --group-mode person

Building the static API

You can build locally the content of https://team-api.infra.rust-lang.org/v1/ by running the command:

cargo run static-api output-dir/

The content will be placed in output-dir/.

Encrypting email addresses

If an email address in a list needs to be confidential it's possible to encrypt it. Encrypted email addresses look like this:

encrypted+3eeedb8887004d9a8266e9df1b82a2d52dcce82c4fa1d277c5f14e261e8155acc8a66344edc972fa58b678dc2bcad2e8f7c201a1eede9c16639fe07df8bac5aa1097b2ad9699a700edb32ef192eaa74bf7af0a@rust-lang.invalid

The production key is accessible to select Infrastructure Team members, so if you need to add an encrypted email address you'll need to reach out to that team. The key is stored in the following parameter on AWS SSM Parameter Store:

/prod/sync-team/email-encryption-key

The cargo run encrypt-email and cargo run decrypt-email interactive CLI commands are available for infra team members to interact with encrypted emails. The rust_team_data (with the email-encryption feature enabled) also provides a module to programmatically encrypt and decrypt.

team's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

team's Issues

alumni are added to the all mailing list

As @pietroalbini discovered in #356, apparently working group alumni are added to the all mailing list. In general, I don't think alumni should be on the mailing list, but it seems especially inconsistent to have folks being added to the mailing list only when they become alumni and not before!

Specify optional additional resources (homepage, blog, <your idea here>)

Currently we only support specifying a repo which is not ideal to lure in people who're vaguely interested in learning more a team/WG but not necessarily want to wade through the amount and level of details a repo typically provides.

Some teams/WG have dedicated homepages to feature their work and others also frequently blog about it so it would be nice to being able to provide links to that work, too.

Missing people from alumni

I think there're definitely more people from the early days of Rust who should be listed in alumni page. Actually I don't know them well, but maybe people like Graydon Hoare should be in the list.

Track Discord username/ID

We'll eventually want to setup some form of bots, like highfive's review pings, on Discord. It would be great to start populating that data now -- or at least support doing so.

I'm willing to take on the fieldwork of trying to track these down and making a pull request; I would rather not do the implementation work though to avoid stepping on any toes (I presume there's some churn currently).

Resolve individual repository access.

Part of RFC 2872 specifies that individuals should not be given permissions to repositories. We have a few individuals currently with access that we should resolve. They currently are:

  • areweasyncyet.rs:
    • upsuper
    • Recommend: Create a team, figure out relationship with web-presence.
  • backtrace-rs:
    • alexcrichton
    • Recommend: Remove Alex, he's been uninvolved for a few years.
  • cargo-bisect-rustc:
    • ehuss
    • Recommend: Create a team, subteam of compiler (@ehuss assigned).
  • cc-rs
    • NobodyXu
    • Recommend: Create a team, subteam of libs.
  • flate2-rs
    • alexcrichton
    • brson
    • Recommend: Remove Alex (specified he has handed off) and brson (hasn't been involved).
  • google-summer-of-code
    • Kobzol
    • jackh726
    • Recommend: Create a team? Working-group? Where to slot it?
  • log
    • Thomasdezeeuw
    • Recommend: Create a team, subteam of libs.
  • mdbook
    • Dylan-DPC
    • Recommend: Create a team, subteam of devtools (@ehuss assigned).
  • pkg-config-rs
    • sdroege
    • Recommend: Create a team, subteam of libs.
  • project-deref-patterns
    • traviscross
    • Recommend: Switch to lang-ops.
  • rustc_codegen_cranelift
    • bjorn3
    • Recommend: Create a team, subteam of compiler.
  • socket2
    • chansuke
    • sfackler
    • Thomasdezeeuw
    • carllerche
    • Darksonn
    • Recommend: Create a team, subteam of libs.

`Polonius` team: fix path specified under "relevant repositories" section for the borrow check crate in the main Rust repo

On the Polonius Working Group Web Page, under the Relevant Repositories bullet in the How can I get involved? section, it specifies the rust-lang/rust repository, but specifically the path src/librustc_mir/borrow_check. In the current state of the rust-lang/rust repository, that path no longer exists. It was moved to compiler/rustc_borrowck as of tag 1.57.0 (September 6th, 2021 for a specific date) in the repository and still stands here to the present day. This change should be made so any newcomers that aren't particularly familiar with the rust-lang/rust repository are not misled by the now error in the writing.

How to add observers?

I have the status of observer to core, which is a stepping stone to membership, but not full membership.

I'd like the info to be presented in the interest of transparency, but also don't want to claim full.

Add liaisons key to teams

As part of the project group RFC we introduced the role of "liaison", and this issue is to track adding the role to the team repository in the form of a liaisons = ["..."] key in a team's definition file.

Finer-grained GitHub permissions synced with teams

In GitHub, I just created a crates.io triage team that only has access to the crates.io repo and only has triage permissions to it. When this repo supports syncing everything with GitHub teams, it'd be nice to have a way of specifying more finer-grained permissions for a team.

RFE: Indicate the representation of Leadership Council members

For this page: https://www.rust-lang.org/governance/teams/leadership-council

The folks on the council are each there to represent a particular top-level team, but there's no indication of that in the member list. Even having broad context, some of them are active in multiple areas of the project, so their particular connection for the council is not obvious. But I think we should make it clear even to visitors that have no such context.

Teams without members

For the lack of better modelling, there's currently some teams with just one members. For example, in the compiler team: Compiler Performance, LLVM, MIR Optimizations, Traits.

https://www.rust-lang.org/governance/teams/compiler

These have fluctuating membership, but (optionally?) a contact point and a repository attached.

It's useful to model them differently, to also display them differently (maybe more condensed) on the website. "Responsibilities" or "Subjects" sounds like a good first iteration, but I'm sure there's something better.

Relevant website issue: rust-lang/www.rust-lang.org#670

Enable branch protection for rust-lang/rfcs repo

Every time when I finish a review an RFC, I nearly click the merge button.

RFCs are the essential part of public discussions of Rust features. We probably want to prevent it from accidental merges to reduce confusions.

image

Email Bounce List

Currently if a mailing list address is deleted or archived as part of a team, any future emails sent those addresses will be lost. It would be nice if we had functionality to handle that.

Possible Solutions

  • Provide a generic email on bounce informing the sender that the list is no longer active, and find another means of contact.
  • Redirect the message to another mailing list.

Related PRs

Sync with GitHub teams

Being able to ensure the teams on rust-lang are in sync with this data would be awesome.

Add remaining Zulip user groups

The following are the remaining Zulip user groups that are not yet synced between the team repo and the Zulip instance.

Please review the user groups and send pull requests adding them to the team repo (see below for instructions).

Once these are added, the Zulip user groups will be completely managed by the team repo.

  • 'WG-rls2.0' @matklad
  • 'WG-llvm' @nagisa
  • 'WG-traits' @jackh726 (this group is inactive and only not yet archived due to limitations in the team repo)
  • 'project-custom-linter' (this has never been used publicly - perhaps it's inactive?)
  • 'WG-polonius' @lqd
  • 'WG-rustc-dev-guide' @spastorino #843
  • 'WG-const-eval' #834
  • 'WG-pipelining' (this was last used publicly in Jan 2020 - perhaps it's inactive?)
  • 'WG-mir-opt' @oli-obk #839
  • 'mods'
  • 'WG-governance' (I believe this working group is inactive)
  • 'WG-unsafe-code-guidelines' @RalfJung #838
  • 'WG-ffi-unwind' @BatmanAoD #845
  • 'WG-polymorphization' @davidtwco #846
  • 'WG-self-profile' @wesleywiser
  • 'WG-async' #832
  • 'WG-async-sprint-planning' #832
  • 'WG-rfc-2229' (this working group is probably inactive)
  • 'WG-diagnostics' @estebank
  • 'WG-prioritization/alerts' #836
  • 'project-const-generics' @lcnr
  • 'T-compiler/WG-meta' (this group seems to be inactive) #857
  • 'WG-profile-guided-optimization' (this has never been used publicly - perhaps it's inactive?)
  • 'WG-nll' (this group is likely inactive) #856
  • 'wg-incr-comp' @pnkfelix
  • 'T-community/l10n' (this work is still active in general but not very much on Zulip)
  • 'foundation'

Instructions

To add a working group follow the documentation here. More than likely this will simply involve adding the following lines to your team's toml config:

[[zulip-groups]]
name = "T-awesome-zulip-team" # Make sure to change this! 

If you need to add or remove people from the baseline of team membership, you can use the extra-people and excluded-people fields.

If someone you've added does not have a zulip-id field in their personal configuration file, you will need to add it. You can find some instructions on where to find their zulip-id here

As an example, you can see how the compiler team's configuration is set here.

Make team descriptions consistent

Currently, each (some?) teams have descriptions. These appear at https://www.rust-lang.org/governance. However, there is little consistency in how they are formatted. Some start with capital letters and some don't; some have periods and some don't.

It would be great if each description was formatted the same way and with the same tense and "voice" (active, passive, etc.).

This is somewhat of a duplicate of rust-lang/www.rust-lang.org#560, but I figured it would be good to have an issue in this repository.

Consider disabling clippy in CI

Currrently our CI is broken due to a bump in the stable compiler, resulting from a new Clippy lint being added. While the same can happen from just rustc, rustc adds new lints very rarely when they affect normal, 'good' code; the same is not true of clippy.

Given that we likely want the CI in this repository to always pass (so that we can e.g. land PRs without worrying about fixing CI), it's not clear to me that having clippy is worthwhile. Alternatively, we could consider pinning the stable compiler used for the clippy build, but that has other disadvantages.

More informative team descriptions

Many teams on @rust-lang have a description (the extra text shown when I type @rust-lang/) that just says "managed by the team repository". That's not very useful when I want to figure out which is the right team to ping. Would be better to instead show a brief description of what the team is doing. :)

Zulip ID?

I just noticed by pure coincidence that a person's toml file can also contain a Zulip ID. The README doesn't mention this.

How do I find out my Zulip ID? I think that might be useful to add. Maybe one day someone writes a nice tool to map between Zulip and GH usernames and I'd certainly like that tool to work for my accounts. :D

Update Rust Team Information

Introduction

Hello everyone, The governance working group has been looking to formalise some of the current structure of Rust Programming Language organisation that we have found to be currently unclear and under or undocumented. One example of this is that some of the team's current membership is out of date with rust-lang/team. So we're asking that team leads (or relevant members) update their roster and to synchronise their team permissions with GitHub. This will reduce some of current overhead in managing our infrastructure.

How To Update Team Information.

  1. Clone the rust-lang/team repository.
  2. Visit your team's information available in the teams/ directory.
    • Refer to the TOML schema for how to configure the file.
  3. Check that all of the names in members matches what you expect. Add any recent/missing team members, and remove any inactive members.
    • When adding members, also ensure that they are also present in the people/ directory.
    • The command cargo run add-person <github-username> inside the team repo will load publicly available information.
    • If the member is not available, please contact them directly, asking them to add their information to rust-lang/team.
  4. Make sure your team contains something like the following code snippet. Importantly that you have the rust-lang org in your org. This will synchronise your team information here with the team information on GitHub. Your team may already have this and if so no action is required.
[github]
orgs = ["rust-lang", "rust-lang-nursery"]
  1. Run cargo run check inside the team repo to ensure the changes you made are valid.

Potential Questions

How do I decide whether a person should be added or removed from my team?

The Goverance Working Group's purpose is to provide guidance, not decisions. It is up to each team's discretion to decide their roster and what qualifies for membership.

How important is it to update this?

Having you and your team's information up to date and synchronised with GitHub will help reduce some overhead in adminstrating Rust's infrastructure, and will help in the future lay groundwork for proposals for formalising Rust's access policy.

How can I see the difference between GitHub's team membership and rust-lang/team?

With your new changes to the team repository you can check the difference between the team repo and the GitHub teams. To do that, clone the rust-central-section repository, set the GITHUB_TOKEN environment variable to a valid GitHub personal access token (you need to be a member of the rust-lang and rust-lang-nursery orgs) and run this command:

cargo run --bin sync-github -- --team-repo <path-to-your-team-repo>

The tool will output the differences between GitHub and the team repo, if present.

Hey, I know what changes I want to make, but I don't have the time to make a PR, is there any way to send a list?

Yes! You can email your desired changes to [email protected], and I or another member of the working group will make a PR with those changes.

Tracking For Confirmation Of Updated Information

Team Archival

Not all teams or working groups are permanent efforts, we should have the ability to reflect that in the team repo.

Potential Solutions

  • archived folder in teams/ containing the team files.

Team API v2 wishlist

Things we should improve if we create a second version of the Team API:

  • Remove GitHub usernames from the permissions, keeping only the GitHub IDs (authorizing by username is insecure)
  • Replace _ with - in the permission names and paths

Update on the recent issue?

khionu closed the discussion, so that's fine, but people are wondering. Have there been
any news pertaining to the issues?

Working Group mailing list

Currently all at rust-lang.org doesn't include working group members, this makes announcing information to the working groups hard.

Solutions

  • Add working groups to all
  • Create a new mailing list that is all working groups.

Script to backfill team alumni

I put this together for due diligence in #1123. It looks at the history of https://github.com/rust-lang/team and https://github.com/rust-lang/prev.rust-lang.org to find former team members who are not listed as alumni in the teams they were members of.

The output looks like this:

Kimundi ["libs-api"]
alexcrichton ["core", "devtools", "infra", "libs-api", "release", "rustup", "wg-security-response", "wg-wasm"]
aturon ["cargo", "core", "infra", "lang", "libs-api", "wg-wasm"]
brson ["community", "core", "devtools", "infra", "libs-api", "style"]
huonw ["core", "lang", "libs-api"]
// [dependencies]
// anyhow = "1"
// chrono = "0.4"
// git2 = "0.18"
// serde = { version = "1", features = ["derive"] }
// serde_yaml = "0.9"
// toml = "0.8"

use anyhow::{Context, Result};
use chrono::{DateTime, NaiveDate};
use git2::{Commit, Object, ObjectType, Repository};
use serde::Deserialize;
use std::borrow::Cow;
use std::collections::{BTreeMap as Map, BTreeSet as Set};
use std::path::Path;
use std::str;

const TEAM_REPO: &str = "/path/to/rust-lang/team";

const OLD_WEBSITE_REPO: &str = "/path/to/rust-lang/prev.rust-lang.org";

#[derive(Deserialize, Debug)]
struct Toml {
    name: String,
    people: TomlTeam,
}

#[derive(Deserialize, Debug)]
struct TomlTeam {
    members: Vec<String>,
    #[serde(default)]
    alumni: Vec<String>,
}

#[derive(Deserialize, Debug)]
struct Yaml {
    #[serde(default)]
    teams: Vec<YamlTeam>,
}

#[derive(Deserialize, Debug)]
struct YamlTeam {
    name: String,
    members: Vec<String>,
}

fn main() -> Result<()> {
    // person -> set of teams
    let mut historical_membership = Map::<String, Set<String>>::new();
    let mut present_membership = historical_membership.clone();

    let team_repo = Repository::open(TEAM_REPO)?;
    let master_object = team_repo.revparse_single("origin/master")?;
    for_each_commit(&master_object, |commit| {
        let tree = commit.tree()?;
        let Some(teams_dir) = tree.get_name("teams") else {
            return Ok(());
        };
        let object = teams_dir.to_object(&team_repo)?;
        let mut nested_trees = vec![(String::new(), object.into_tree().unwrap())];
        let timestamp = DateTime::from_timestamp(commit.committer().when().seconds(), 0)
            .unwrap()
            .date_naive();
        while let Some((prefix, nested_tree)) = nested_trees.pop() {
            for entry in &nested_tree {
                let object = entry.to_object(&team_repo)?;
                match entry.kind() {
                    Some(ObjectType::Blob) => {}
                    Some(ObjectType::Tree) => {
                        assert_eq!(prefix, "");
                        let nested_prefix = entry.name().unwrap().to_owned();
                        nested_trees.push((nested_prefix, object.into_tree().unwrap()));
                        continue;
                    }
                    _ => unreachable!(),
                }
                let blob = object.into_blob().unwrap();
                let content = str::from_utf8(blob.content())?;
                let de: Toml = toml::from_str(content)
                    .with_context(|| format!("failed to parse {}", entry.name().unwrap()))?;
                let team_name = if prefix.is_empty() {
                    Cow::Borrowed(&de.name)
                } else {
                    Cow::Owned(format!("{}/{}", prefix, de.name))
                };
                let Some(team_name) = normalize_team(&team_name, timestamp) else {
                    continue;
                };
                for member in de.people.members.into_iter().chain(de.people.alumni) {
                    historical_membership
                        .entry(member)
                        .or_insert_with(Set::new)
                        .insert(team_name.to_owned());
                }
            }
        }
        if commit.id() == master_object.id() {
            present_membership = historical_membership.clone();
        }
        Ok(())
    })?;

    let old_website_repo = Repository::open(OLD_WEBSITE_REPO)?;
    let master_object = old_website_repo.revparse_single("origin/master")?;
    for_each_commit(&master_object, |commit| {
        let de: Yaml = if let Some(yaml) = read_path(&old_website_repo, commit, "_data/team.yml")? {
            serde_yaml::from_slice(&yaml)
        } else if let Some(content) = read_path(&old_website_repo, commit, "en-US/team.md")? {
            let content = str::from_utf8(&content)?;
            let (yaml, _markdown) = content.split_once("\n---").unwrap();
            serde_yaml::from_str(yaml)
        } else if let Some(content) = read_path(&old_website_repo, commit, "team.md")? {
            let content = str::from_utf8(&content)?;
            let (yaml, _markdown) = content.split_once("\n---").unwrap();
            serde_yaml::from_str(yaml)
        } else {
            return Ok(());
        }?;
        let timestamp = DateTime::from_timestamp(commit.committer().when().seconds(), 0)
            .unwrap()
            .date_naive();
        for team in de.teams {
            let Some(team_name) = normalize_team(&team.name, timestamp) else {
                continue;
            };
            for member in team.members {
                historical_membership
                    .entry(member)
                    .or_insert_with(Set::new)
                    .insert(team_name.to_owned());
            }
        }
        Ok(())
    })?;

    for (member, historical_teams) in &historical_membership {
        let uncredited = if let Some(present_teams) = present_membership.get(member) {
            historical_teams
                .difference(present_teams)
                .filter(|team| !eclipsed(team, present_teams))
                .collect()
        } else {
            Vec::from_iter(historical_teams)
        };
        if !uncredited.is_empty() {
            println!("{} {:?}", member, uncredited);
        }
    }

    Ok(())
}

fn normalize_team(name: &str, when: NaiveDate) -> Option<&str> {
    match name.strip_suffix(" team").unwrap_or(name) {
        "Cargo" => Some("cargo"),
        "Community" => Some("community"),
        "Compiler" => Some("compiler"),
        "Core" => Some("core"),
        "Crates.io" => Some("crates-io"),
        "Dev tools peers" => Some("archive/devtools-peers"),
        "Dev tools" | "Tools" => Some("devtools"),
        "Documentation peers" | "docs-peers" => Some("archive/docs-peers"),
        "Documentation" | "docs" => Some("archive/docs"),
        "IDEs and editors" | "ides" => Some("archive/ides"),
        "Infrastructure" | "Tooling and infrastructure" => Some("infra"),
        "Language team shepherds" => Some("archive/lang-shepherds"),
        "Language" | "Language design" => Some("lang"),
        "Library team shepherds" => Some("libs-contributors"),
        "Library" => Some("libs-api"),
        "Moderation" => Some("mods"),
        "Release" => Some("release"),
        "Rust team alumni" | "alumni" => None,
        "Rustdoc" => Some("rustdoc"),
        "Style" => Some("style"),
        "aarch64" => Some("arm"),
        "cloud-compute" => None,
        "core-observers" => Some("archive/core-observers"),
        "docsrs-ops" => Some("docs-rs"),
        "ecosystem" => Some("archive/ecosystem"),
        "infra-admins" => Some("archive/infra-admins"),
        "interim-leadership-chat" => Some("archive/interim-leadership-chat"),
        "lang-shepherds" => Some("archive/lang-shepherds"),
        "leads" | "wg-leads" => None,
        "libc" => Some("crate-maintainers"),
        "library-reviewers" => Some("libs-contributors"),
        "libs" if when < NaiveDate::from_ymd_opt(2021, 6, 13).unwrap() => Some("libs-api"),
        "mods-discord" => Some("archive/mods-discord"),
        "production" => Some("archive/production"),
        "project-foundation" => Some("archive/project-foundation"),
        "reference" => Some("archive/reference"),
        "rust-analyzer-contributors" | "wg-rls-2-triage" => Some("rust-analyzer"),
        "rust-by-example" => Some("wg-rust-by-example"),
        "security" | "wg-security" => Some("wg-security-response"),
        "test-tools" => Some("testing-devex"),
        "wg-async-await" | "wg-async-foundations" => Some("wg-async"),
        "wg-clippy" => Some("clippy"),
        "wg-codegen" => Some("archive/wg-codegen"),
        "wg-governance" => Some("archive/wg-governance"),
        "wg-learning" => Some("archive/wg-learning"),
        "wg-localization" => Some("community-localization"),
        "wg-meta" => Some("archive/wg-meta"),
        "wg-net" => Some("archive/wg-net"),
        "wg-net-async" => Some("wg-async"),
        "wg-net-embedded" => Some("wg-embedded"),
        "wg-net-web" => Some("archive/wg-net-web"),
        "wg-nll" | "wg-compiler-nll" => Some("archive/wg-nll"),
        "wg-parselib" => Some("archive/wg-parselib"),
        "wg-rls-2" | "wg-rls-2.0" => Some("rust-analyzer"),
        "wg-rustfix" => Some("archive/wg-rustfix"),
        "wg-rustfmt" => Some("rustfmt"),
        "wg-rustup" => Some("rustup"),
        "wg-traits" => Some("types"),
        "wg-unsafe-code-guidelines" => Some("opsem"),
        _ => Some(name),
    }
}

fn eclipsed(team: &str, present_teams: &Set<String>) -> bool {
    match team {
        "compiler-contributors" => present_teams.contains("compiler"),
        "libs-contributors" => present_teams.contains("libs") || present_teams.contains("libs-api"),
        _ => false,
    }
}

fn for_each_commit(head: &Object, mut f: impl FnMut(&Commit) -> Result<()>) -> Result<()> {
    let mut commit = Cow::Borrowed(head.as_commit().unwrap());
    loop {
        if let Err(err) = f(&commit) {
            eprintln!("at commit {}: {:#}", commit.id(), err);
        }
        if commit.parent_count() == 0 {
            return Ok(());
        }
        commit = Cow::Owned(commit.parent(0)?);
    }
}

fn read_path(
    repo: &Repository,
    commit: &Commit,
    path: impl AsRef<Path>,
) -> Result<Option<Vec<u8>>> {
    let tree = commit.tree()?;
    let Ok(tree_entry) = tree.get_path(path.as_ref()) else {
        return Ok(None);
    };
    let object = tree_entry.to_object(repo)?;
    let blob = object.into_blob().unwrap();
    Ok(Some(blob.content().to_owned()))
}

I would like to join the moderation team (for a while)

I've spent the last two days talking to a lot of people involved with the RustConf Keynote Fiasco, so I could make a public informed statement / summary about it.

However, in doing so, I've realized that in addition to the information I can responsibly make public, there's a whole side to this that shouldn't be made public at this time, but I would still like to help with.

As a result, I've decided to apply for a position on the moderation team.

Why add anyone to the moderation team?

In short: burn-out, conflicts of interest re: the recent situation, and following this piece of advice from #671:

  • we suggest that the future Mod Team take special care to keep the team of a healthy size and diversity, to the extent possible. It is a thankless task, and we did not do our best to recruit new members.

Why add me specifically?

I would rather it be someone else, and in fact, I encourage anyone who would be willing to serve on the moderation team for at least a little bit to step forward. I would also encourage people to encourage people who they know might do a decent job at it.

I've been active in the Rust space since 2019, mostly through my writings and videos as a content creator / educator. This has allowed me to meet with folks from various teams of the Rust project, Rust foundation, and RustConf. I maintain friendly relationships with a lot of them.

However, I have never been a member of any team, I am not beholden to any team's specific agenda. My ties with the 3 Rust orgs so far have been:

  • Received $5K from the foundation in 2023 for content creation
  • Was briefly asked by the project whether I wanted to join a team sometime in 2021/2022 (I didn't)
  • I was on the RustConf program committee in 2022

What's my plan?

I would like my time on the moderation team (if it my application is accepted) to last only as long as it needs to. I would like to focus on several areas:

  • Helping to finish resolving the "RustConf Keynote Fiasco" internally as peacefully as possible (I unfortunately cannot give any more details publicly at this time)
  • Leadership Council: Facilitating in whatever ways I can the arrival of the Leadership Council, which heralds the death of the core team (and the leadership chat, implicitly)
  • Recruitment: Helping to grow and diversify the moderation team to better distribute the burden
  • Professional training & support: Working with the foundation to provide/require professional training for people serving on the moderation team so that they're better equipped to deal with complex moderation issues, as well as mental health support, and access to third-party mediators
  • Specialization: Seriously considering the idea of renaming and/or splitting the moderation team between "moderation" issues (GitHub, Discourse, external CoC violations) and "internal support/mediation" issues (interpersonal conflict, crisis of consensus/quorum, formal processes not being followed, etc.)
  • Transparency: Helping the Rust project as a whole achieve better transparency and regain public trust. This doesn't include all past issues, but it should be an important goal moving forward.
  • Thinking about the power held by subreddit moderators (disclosure: I was added to /r/rust's moderators on May 28), and whether there needs to be coordination between both teams. I only learned a few days ago that the "moderation team" and the "/r/rust mods" were two separate groups (that overlapped at various points)

I have not checked ahead of time with anyone regarding these: these are just on my mind.

Will I have time to do this?

I'm setting aside time to do it. I'm not currently employed (I live off of sponsorship money through Patreon & GitHub Sponsors + severance from my last job), but I do normally try to make technical contributions (see my work on rust-analyzer proc-macro compatibility for example) to Rust, or educational contributions to Rust.

I most likely won't have time to do these initially, or as much, or perhaps at all for a while. That's okay with me.

Why is this a github issue? Surely this is not how you apply to the mod team?

Well!

I've been asking around and nobody can tell me what the procedure is for applying to the moderation team.

This page says:

Its members are chosen directly by the core team, and should be community members who have demonstrated the highest standard of discourse and maturity.

Except the core team is about to be dismantled by virtue of the leadership council being established. In the interim, it seems it would fall to the "(interim) leadership chat" to step in? The problem is, I have the feeling that document is fairly outdated.

The Moderation team page says nothing about applying. There is an "E-mail" button, and I was given discord handles, but it felt wise for there to be a public trace for my application, so that a larger number of people can be aware of it (and potentially be inspired to apply in turn).

I have no idea who will be ultimately responsible for ๐Ÿ‘ -ing or ๐Ÿ‘Ž -ing this, but, well, here we are. I am willing to discuss my application more in private or in public, with anyone who reaches out.

(cc @khionu and @technetos)

Document how to add new members to teams

I did this manually, by inspecting the list of teams in the root teams directory.

The README.md suggests using cargo run add-person <username>, but does not explain if / how you can do a similar process for adding members to teams.

Discourse Integration

Discourse has the notion of groups which can be given different privacy and permissions to different forums, it would be nice if we could sync our discourse forums to have groups that match the teams in the team repository. The implementation should be a straightforward addition as discourse's API is relatively simple. The most amount of work would probably be getting everyone to add their discourse usernames to the team repo.

Add link to the CLI working group's GitHub repository

Currently, the page for the CLI working group does not link to a coordination repository for that working group:
https://www.rust-lang.org/governance/wgs/cli

There is a GitHub organization @rust-cli that claims to be the CLI working group and has this repository:
https://github.com/rust-cli/team

That seems to be the repository to which the working group's page on RLO should link, unless @rust-cli is fake and somehow impersonating the working group (despite appearing to have the real working group's participants).

Linking to the repository can help users trust that @rust-cli is not fake, without needing to compare the participants.

(Edited to add: I am not in a position to verify that @rust-cli is the real working group; "appearing to have the real working group's participants" reflected only a casual inspection by an outsider to the Rust team.)

Review of the data

Hey @rust-lang/core!

I should have imported all the team structure and related mailing lists, but you should review everything is correct for your teams. You should look for both mailing list memberships and team memberships (me and Ashley still need to discuss how to handle website data).

In the README there is the schema of the data and the commands you can use to inspect/verify it.

  • all
  • alumni
  • cargo
  • community-content
  • community-events
  • community-rustbridge
  • community-survey
  • community
  • compiler
  • core
  • crates-io
  • devtools
  • docs
  • ecosystem
  • ides
  • infra
  • lang-shepherds
  • lang
  • leads (automatically generated from team leads)
  • libs
  • mods
  • production
  • reference
  • release
  • rustdoc
  • security
  • style
  • twir
  • wg-bindgen
  • wg-clippy
  • wg-codegen
  • wg-compiler-nll
  • wg-debugging
  • wg-embedded
  • wg-grammar
  • wg-leads (automatically generated from wg leads)
  • wg-net
  • wg-rustfmt
  • wg-traits
  • wg-unsafe-code-guidelines
  • wg-wasm

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.