A Meta RFC For The Implementation Of RFCs

thumbnail

This is an RFC for implementing RFCs I wrote for work and thought it would be good enough to publish here. It is mostly unchanged except for these things:

  • Links to company documents have been replaced with fun videos.
  • My comments (originally on Notion) providing addition info have been written as footnotes.

The RFC template is also at the end.


Summary

The RFC (Request For Comments) process is intended to provide a clear path for new ideas to enter the organisation. It also allows all team members to collaborate on the design in a consistent and controlled manner.

Motivation

The RFC process is meant to support, or preferably replace, the bigger items in the current issues register that take time to explain and discuss in engineering meetings.

RFCs allow for semi-formal, asynchronous communication that enable team members to put more time and thought into what they're proposing or commenting on instead of being rushed in a meeting that has lasted for over two hours (or is the cause of the meeting taking more than two hours). RFCs also ensure that we have proper documentation (along with conversation about it) surrounding proposed and planned changes, instead of being quickly jotted down in the aforementioned meeting.

Many items in the issues register are also early ideas that could benefit from a structured plan or document to be fleshed out over time.

General reference

An RFC is a document that is created in the Notion RFCs page using the RFC template that introduces new ideas to the organisation. Team members can comment on the document to discuss the idea. When all team members agree that the idea is to be implemented or not, the document is set as Accepted or Inactive.

Technical reference

Larger changes to organisational processes should be submitted as RFCs. Examples of recent items from the issues register that should have been written as RFCs if implemented at the time are:

  • Moving CI/CD to GitHub Actions.
  • Scraper job definitions.
  • Implementing the CQRS architecture pattern.

Examples of changes that do not require an RFC:

  • Rephrasing, reorganising, refactoring, or otherwise ("changing shape does not change meaning").
  • Additions that strictly improve objective, numerical criteria (changes where no tradeoff will need to be made and where the result is objectively better than what it was before in all situations).

What the process is

RFCs are created in the RFC page in Notion by using the RFC Template. RFCs are assigned an ID that is incremented by one from the previous RFC (I don’t think we actually need to do this, but it’s a standard and standards are fun!!)

In progress RFCs don’t have to be drafted in Notion. You could, for instance, use a text editor that supports Vim keybindings (as you should if you want to be a good engineer) and write the draft locally. But if it is on Notion and viewable by others, it should be given the Draft status and no formal discussion should be done on the proposal until writing has been completed. When considered finished by the author, the RFC will be given the status of Active and can be shown to (preferably announced on the engineering Slack channel) and discussed by other team members.

RFCs should also follow standard typography rules and be aesthetically pleasant for other members to read (Notion uses a superset of Markdown, so remember to use code blocks, links, tables, and other typographic elements when applicable). It is required to use correct formatting for a document, although in most cases that means following the template and adding more subheadings when necessary (use the “Heading 2 block” for subheadings).

Comments can be done using Notions' commenting tools (either on the entire page, or on singular text blocks). While active, RFCs are not immutable and are to be considered as “living documents” that can be changed according to the discussion surrounding them (Notion also provides the ability to “resolve” comments when a change has been made).

It is important to remember that the comments to an RFC are as important as the RFC itself, and anyone reading the RFC should also be reading the comments. This specific RFC has some extra contextual information I have written in as comments that are highlighted in yellow on Notion.

Also, please read the entire RFC first before commenting.

If all team members are happy with the RFC and the proposed changes, the status will change from Active to Accepted and work on the proposal can carry out. In comparison, an RFC that is rejected will be given the Inactive status (it sounds nicer than “rejected”). When either accepted or not, the RFC is to be locked in Notion to prevent further edits.

Devil’s advocate

  • RFCs may take some time to write to be able to properly explain all the details of a proposal.[1]
  • Some people do not like writing, or reading. Kids these days… smh.

Rationale and alternatives

The RFC process gives a good balance of formality and agility over current processes, as it discourages un-actionable or vague items, and gives confidence to team members on why processes are being implemented. It is a tried-and-true methodology used by many in the industry and can help team members to communicate effectively and share important knowledge and context.

Other prominent processes used in the industry include Google’s design docs and Architecture Decision Records (ADRs).

I find that design docs are too structured and formal for a fast-paced agile team (Google recommends docs have a length of 6 to 12 pages 😐) and enforce too many specific subsections that may not be applicable in all circumstances. This can lead to the author being confused on which subsections to include. Comparatively, the sections of an RFC are often overarching enough for an author to be able to find something to put in the section, no matter the subject.

ADRs can vary widely in structure depending on the template used, which may help in some cases, but can typically be its own detriment as the process will need to go through much more iteration to conform with the team than RFCs or design docs, both of which have standard historical precedents on what the process should look like.

In general, RFCs have a slightly more informal tone than either, which can help alleviate some peoples’ aversion to writing or reading technical documentation. I believe them to be a good mix between formality and informality that can still convey information in a concise and efficient manner.

Alternatively to all other options, we could maintain current processes for discussing ideas, but possibly start writing things down a bit more.

Prior art

The RFC process started in 1969 on ARPANET and was first written by Steve Crocker. He did so to avoid “sounding presumptuous” when compiling notes from a meeting of graduate students and staff. Other members of the group soon followed suit, writing RFC memos of their own, printing them out, and mailing the documents to one another in the era before email.

The RFC process is now used by a number of open-source projects, including prolific frameworks and languages such as Ember, React, Vue, Swift, and most importantly (for obvious reasons that I won’t get into), Rust, to propose, implement, and plan new features. Some companies, including Artsy and Uber, have also adopted the process for introducing technical, and in Artsy’s case - cultural changes, internally to help scale the planning and decision-making process for a growing team.

In these instances RFCs are especially helpful to culture and community, while some organisations might reach an agreement by decree of engineering leadership, RFCs provide a more egalitarian approach.

A side note on cultural impact

Apart from the obvious technical benefits, I have found that the RFCs (specifically the discussion part) in other communities can be useful when rejecting ideas. A well explained, well argued, and well reasoned RFC will require a similarly well explained, well argued, and well reasoned argument against it, which may soften the blow for an author whose RFC is being shut down. The asynchronous communication helps with this by allowing opponents to put more thought into their constructive criticisms and word them properly.[2]

In the same vein as Steve Crocker trying not to “sound presumptuous”, the name “Request For Comments” sets the tone of the document for the author as a way to say “I’m throwing this idea out there, what do you all think?” This can help with emotionally distancing the author from the proposal and being more open to criticism.[3]

Documenting big decisions more transparently empowers everyone on a team, regardless of skill level or experience, to both observe and participate in the surrounding discussions. And since writing is a friendly medium for distributed teams, the asynchronous nature of RFCs can contribute to a more inclusive culture that welcomes anyone to take part in the conversation.

Open questions

  • Does this RFC template and process work well with the team? What further refinements should be made?

Future possibilities

  • If used a lot, more metadata should be added as Notion properties for easier filtering of the RFCs page.
  • RFCs may be used outside of engineering and could become a part of “general product development”.
  • The RFCs Notion page could be connected to a Slack channel to allow readers to be easily be updated on changes.

[1]: Au fait, not all RFCs will need to be this long (1500+ words), I’m doing this to set a good precedent for future ones.

[2]: There’s much more I want to say about this, but this part RFC is getting too long, so here it is in a comment:

Many engineers like to point out something wrong the moment they see it. I think we are very good at it because we’re basically trained for it. When it comes to code reviews, or design reviews for complicated distributed system protocols, we want to be able to spot flaws as quickly as possible. But there’s a point where it just becomes a habit.

Habits are usually formed with three factors – trigger, behaviour and reward. It's the same thing that drives the “feel sad” → “eat chocolate” → “feel good” cycle. For engineers, the cycle is “see a problem” → “spot flaws” → “feel good”. After this cycle gets reinforced, it leads to a more deeply rooted habit - you must point out something wrong the moment you see it.

Trying to spot flaws in a system is not a bad thing, obviously. However, when we are dealing with people, the knee-jerk reflex of pointing out something is wrong might lead to negative feelings from the other side; and hurt relationships. This is when we should take a pause before pointing out something is wrong. Think about how to deliver the feedback before actually doing it.

It is especially important if you are not familiar with the full context - which is almost never the case. Yes, things can be “wrong” due to lack of knowledge or incompetence. Sometimes. But not always.

I think it is important then to try to be curious and understand why something is the way it is first. Something an RFC process provides in spades and something I don’t think should be underestimated.

[3]: This is also similar to why I’ve called the “negatives” section “devil’s advocate”.

The negatives against RFCs I’ve put in here are genuinely my best effort of trying to find them, but I still found them very weak. So much so, that I’ve considered removing them entirely because I didn’t think they were even worth mentioning.

Instead, I think calling it “devil’s advocate” helped me justify putting them in the document “for the sake of argument” even if I don’t agree with them.

Of course, there is no real issue with calling it the “negatives” or “drawbacks” section instead if that is what you prefer.


Summary

One paragraph explanation of the proposal.

Motivation

Why are we doing this? What use cases does it support? What is the expected outcome?

General reference

Explain the proposal as if it was already used in the organisation, and you were teaching it to another team member for the first time.

That generally means:

  • Introducing new named concepts.
  • Explaining the feature largely in terms of examples.
  • Explaining how members should think about the proposal, and how it should impact the way they work. It should explain the impact as detailed as possible.
  • Giving sample code for basic usage, if applicable.

Technical reference

This is the technical portion of the RFC. Explain the design in sufficient detail that:

  • Its interaction with other features is clear.
  • It is reasonably clear how the feature would be implemented.
  • Corner cases are dissected by example.

The section should return to the examples given in the previous section, and explain more fully how the detailed proposal makes those examples work.

Devil’s advocate

Why should we not do this?

Rationale and alternatives

  • Why is this design the best in the space of possible designs?
  • What other designs have been considered, and what is the rationale for not choosing them?
  • What is the impact of not doing this?

Prior art

Discuss prior examples (positives and negatives) of this proposal being done in other various organisations, projects, etc.

This section is intended to encourage you as an author to think about the lessons from other projects, and to provide readers of your RFC with a fuller picture. If there is no prior art, that is fine as well - your ideas are interesting whether they are brand new or if it is an adaptation from other projects.

History lessons are also encouraged. 🙂

Open questions

You can specifically request comments on certain parts of your proposal here.

Future possibilities

Think about what the natural extension and evolution of your proposal would be, and how it would affect the organisation and project as a whole in a holistic way. This is also a good place to "dump ideas", if they are out of scope for the RFC you are writing but otherwise related.

If you have tried and cannot think of any future possibilities, you may simply state that you cannot think of anything.