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

RFC process proposal #1

Merged
merged 13 commits into from
Dec 11, 2020
124 changes: 124 additions & 0 deletions accepted/rfc-process.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# RFC process for the Bytecode Alliance

# Summary

As the Bytecode Alliance (BA) grows, we need more formalized ways of communicating about and reaching consensus on major changes to core projects. This document proposes to adapt ideas from Rust’s [RFC](https://github.com/rust-lang/rfcs/) and [MCP](https://forge.rust-lang.org/compiler/mcp.html) processes to the Bytecode Alliance context.

# Motivation

There are two primary motivations for creating an RFC process for the Bytecode Alliance:

* **Coordination with stakeholders**. Core BA projects have a growing set of stakeholders using and contributing to foundational projects, often from varied organizations or teams. An RFC process makes it easier to communicate _possible major changes_ that stakeholders may care about, and gives them a chance to weigh in.

* **Coordination within a project**. As the BA grows, we hope and expect that projects will be actively developed by multiple organizations, rather than just by a “home” organization. While day-to-day activity can be handled through issues, pull requests, and regular meetings, having a dedicated RFC venue makes it easier to separate out discussions with far-ranging consequences that all project developers may have an interest in.

# Proposal

The design of this RFC process draws ideas from Rust’s [Request for Comment](https://github.com/rust-lang/rfcs/) (RFC) and [Major Change Proposal](https://forge.rust-lang.org/compiler/mcp.html) (MCP) processes, adapting to the BA and trying to keep things lightweight.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it expected for this process to deviate from Rust's one? In case of if either process changes, the statements "like Rust's" or "similarly to the one in Rust" might become incorrect. Is it possible to point this proposal to specific version of Rust's RFC process?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point that those processes might change, and that these references might become stale as a result. I think that that's fine though, since over time it'll also become less important to be able to anchor expectations to related processes in other communities. But we could certainly include more stable links here; would you be up for looking them up, @yurydelendik?


## Stakeholders

Each core BA project has a formal set of **stakeholders**. These are individuals, organized into groups by project and/or member organization. Stakeholders are not necessarily members of the BA. Formally, stakeholder review is required for RFCs to be accepted, and stakeholders can likewise block the process from proceeding.

The process for determining core BA projects and their stakeholder set will ultimately be defined by the Technical Steering Committee, once it is in place. Until then, the current BA Steering Committee will be responsible for creating a provisional stakeholder arrangement, as well as deciding whether to accept this RFC.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we expect the stakeholder set to be completely unbounded in number? If so, can we say that explicitly? If not, how do we handle that?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what you have in mind about "unbounded in number" here. I don't foresee a hard limit on the stakeholder count, but rather a policy around stakeholders that naturally results in a reasonable upper bound in practice. For example, a likely criterion for formal stakeholdership is being a major contributor to the project itself, a number which is likely to be self-limiting for other reasons.

All that said, I'm also wary of trying to specify too much about the stakeholder determination in this RFC, preferring to treat it as a modular detail ultimately owned by the TSC.


## Structure and workflow

### Creating and discussing an RFC

* We have a dedicated bytecodealliance/rfcs repo that houses _all_ RFCs for core BA projects, much like Rust’s rfcs repo that is shared between all Rust teams.
* The rfcs repo will be structured similarly to the one in Rust:
* A template markdown file laying out the format of RFCs, like [Rust’s](https://github.com/rust-lang/rfcs/blob/master/0000-template.md) but simplified.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest that our process should take inspiration from the current direction of Rust processes, and start with a more MCP-like template (focused on the problem statement and not just the proposal). There may also be value in adopting the processes for assigning a liaison, and having the option of designating a project group to shepherd complex proposals.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, it seems like a point of confusion here is that there are multiple notions of "MCP" in flight in the Rust community. There's the existing one for the Compiler team, which doesn't even have a problem statement section, and the one in the works for the language team.

I think what'd be helpful here is to get more concrete: is there something about the template, or some other part of the process, that is underemphasizing writing about the motivation?

Note also that there's an explicit separate template for early-stage ("draft") RFCs that pretty closely resembles the proposed Rust Lang Team MCP template.

re: liaisons and project groups, my feeling is that we are probably too early on in the BA for those ideas to apply well. (In particular, the total group of people writing or consuming RFCs is likely to be quite small at the outset, compared to where Rust was even back at the 1.0 days). I suspect that we'll want to evolve the RFC process over time as the unique needs of the BA become more clear.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that establishing processes for liaisons and project groups would be premature at this point. I could easily see a need for either or both in the future, but by then we should have a well-functioning TSC which can drive establishing those parts of a process.

* A subdirectory holding the text of all accepted RFCs, like [Rust’s](https://github.com/rust-lang/rfcs/tree/master/text).
* New RFCs are submitted via pull request, and both technical and process discussion happens via the comment thread.
* The RFC is tagged with **project labels**, corresponding to the BA project(s) it targets. This tagging informs tooling about the relevant stakeholder set.

### Making a decision: merge or close

* When discussion has stabilized around the main points of contention, any stakeholder can make a **motion to finalize**, using a special comment syntax understood by tooling. This motion comes with a disposition: merge or close.
aturon marked this conversation as resolved.
Show resolved Hide resolved
* N.B.: an RFC may be closed for reasons of timing or other project management concerns. The project team should make clear under what conditions, if any, a similar RFC would be reconsidered.
* In response to the motion to finalize, a bot will post a special comment with a **stakeholder checklist**.
* This list includes the GitHub handle for each individual stakeholder, organized into stakeholder groups.
* The individual who filed the motion to finalize is automatically checked off.
aturon marked this conversation as resolved.
Show resolved Hide resolved
* Once _any_ stakeholder from a _different_ group has signed off, the RFC will move into a 10 calendar day **final comment period** (FCP), long enough to ensure that other stakeholders have at least a full business week to respond.
* During FCP, any stakeholder can raise an **objection** using a syntax understood by the bot. Doing so aborts FCP and labels the RFC as `blocked-by-stakeholder` until the objection is formally resolved (again using a special comment syntax).
* Finally, the RFC is automatically merged/close if either:
* The FCP elapses without any objections.
* A stakeholder from _each_ group has signed off, short-cutting the waiting period.

## What goes into an RFC?

In general, an RFC is a single markdown file with a number of required sections. Many RFCs should begin as _drafts_, to encourage early discussion about the approach and only a sketch of a proposal. Full RFCs contain a fleshed-out proposal and more discussion around rationale and alternatives.

Template files for both draft and full RFCs will be available in the repository root.

### Draft RFCs

It is encouraged to use the RFC process to discuss ideas early in the design phase, before a _full_ proposal is ready. Such RFCs should be marked as [a draft PR](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests#draft-pull-requests), and contain a markdown file with the following sections:

* **Motivation**. What problem are you ultimately hoping to solve?
* **Proposal sketch**. At least a short sketch of a possible approach. Beginning discussion without _any_ proposal tends to be unproductive.
* **Open questions**. This section is especially important for draft RFCs: it’s where you highlight the key issues you are hoping that discussion will address.
aturon marked this conversation as resolved.
Show resolved Hide resolved

RFCs cannot be merged in draft form. Before any motion to merge, the draft should be revised to include all required RFC sections, and the PR should be changed to a standard GitHub PR.

### Full RFCs

Full RFCs are markdown files containing the following sections (which will be laid out in a template file):

* **Summary**. A ~one paragraph overview of the RFC.
* **Motivation**. What problem does the RFC solve?
* **Proposal**. The meat of the RFC.
* **Rationale and alternatives**. A discussion of tradeoffs: why was the proposal chosen, rather than alternatives?
tschneidereit marked this conversation as resolved.
Show resolved Hide resolved
* **Open questions**. Often an RFC is initially created with a broad proposal but some gaps that need community input to fill in.

## What requires an RFC?

When should you open an RFC, rather than just writing code and opening a traditional PR?

* When the work involves changes that will significantly affect stakeholders or project contributors. Each project may provide more specific guidance. Examples include:
* Major architectural changes
* Major new features
* Simple changes that have significant downstream impact
* Changes that could affect guarantees or level of support, e.g. removing or adding support for a target platform
* Changes that could affect mission alignment, e.g. by changing properties of the security model
* When the work is substantial and you want to get early feedback on your approach.

## Tooling

The proposal above assumes the presence of tooling to manage the GitHub workflow around RFCs. The intent is to use Rust's [rfcbot](https://github.com/rust-lang/rfcbot-rs). It will need some modifications to support the proposed workflow; these can hopefully land upstream so we can share the tool with the Rust community, but otherwise the BA will maintain its own fork.

## Approval of this RFC and future process-related RFCs

This RFC, and any future RFCs targeting similar process-related questions, will go before the Bytecode Alliance Steering Committee (eventually replaced by the Technical Steering Committee, once that group has been formed).

# Rationale and alternatives

## Stakeholder and FCP approach

This proposal tries to strike a good balance between being able to move quickly, and making sure stakeholder consent is represented.

The core thinking is that getting active signoff from at least one person from a different stakeholder group, together with the original motion to finalize, is sufficient evidence that an RFC has received external vetting. The additional 10 day period gives all stakeholders the opportunity to review the proposal; if there are any concerns, or even just a desire to take more time to review, any stakeholder can file an objection. And on the other hand, proposals can move even more quickly with signoff from each group.

In total, this setup allows proposals to move more quickly than either Rust’s RFC or MCP processes, due to the less stringent review requirements and ability to end FCP with enough signoff. At the same time, the default FCP waiting period and objection facility should provide stakeholders with enough notice and tools to slow things down when needed.

## Organizations vs individuals

Motion through the FCP process is gated at the stakeholder group level, but the actual check-off process is tied to individuals. There are reasons for both:

* **Gated by group**. The goal of the signoff process is to provide a “stakeholder consent” check before finalizing an RFC. We view a signoff from _any_ member of an organization or project as a fair representation of that organization or projects’s interests, and expect individuals to act accordingly.
* **Individual sign-off**. Despite being gated by groups, we call out individuals by GitHub handle for review. Doing so helps avoid diffusion of responsibility: if we instead merely had a checkbox per organization, it could easily create a situation where no particular individual felt “on duty” to review. In addition, tracking which individual approved the review provides an important process record in case that individual fails to represent their group's interests.

## Comparison to Rust’s RFC and MCP processes

The Rust RFC process has successfully governed the development of the language from before 1.0, and covers an enormous range of subprojects, including the language design, tooling, the compiler, documentation, and even the Rust web site. It is a proven model and variations of the process have been adopted by several other large projects. Its workflow is simple and fits entirely within GitHub, which is already the central point of coordination within the BA. And given the central role of Rust within the BA, it’s a model that members are likely to already be familiar with.

That said, a major difference in design is the notion of **stakeholders** and how they impact the decision-making process. Here we borrow some thinking from Rust’s lightweight MCP process, allowing a decision to go forward after getting buy-in from just one stakeholder within a different group -- but still requiring a waiting period to do so. A further innovation is that getting sign off from within _all_ groups immediately concludes FCP. That was not possible in the Rust community, where the set of stakeholders is unbounded.

A common complaint about the Rust RFC process is that it is, in some ways, a victim of its own success: RFC comment threads can quickly become overwhelming. While this may eventually become an issue for the BA as well, we have some additional recourse in this proposal: we have a clear stakeholder model which will allow us to prioritize concerns from stakeholders, and take action when individuals who are not formal stakeholders overwhelm comment threads.

We could instead follow Rust’s MCP model and use Zulip streams for RFC discussion. However, that introduces a more complex workflow (spanning multiple systems) and leaves a less permanent and less accessible record of discussion.

# Open questions

* As written, an individual stakeholder can block acceptance of an RFC indefinitely. In the Rust community, such an arrangement has sometimes caused problems, leading to a secondary process that kicks in after a waiting period, and requires an _additional_ stakeholder to approve continued blocking. Should we consider building in such a mechanism now, or add it to the process only if it becomes necessary later?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's discuss this on Monday, but my take is that we should see how things work for now, and apply remedies if and when we see symptoms of something going wrong.