Skip to main content

Requests for Comments (RFCs)

RFCs are the engineering-owned non-functional specification for architectural decisions, data model changes, security, performance, infrastructure, and process changes. They capture how to build it and why that approach over alternatives — never what to build (that’s a PRD).

What is an RFC?

An RFC is a Markdown/MDX document that proposes a non-functional change and walks through the trade-offs:
  • Summary — 2–3 sentences on what is being proposed
  • Motivation — why this change is needed; link to driving PRD if applicable
  • Detailed design — architecture, data model, API changes, security, performance
  • Alternatives considered — what else was evaluated and why each was rejected
  • Migration strategy — how to get from current state to proposed state
  • Validation plan — how the proposal will be proven correct
  • Open questions and risks
  • Decision — filled in after review
RFCs are the deliberation layer. By the time an RFC is accepted, the engineering team has aligned on the approach and the door is open to implementation.

When to write an RFC

SituationWrite an RFC?
New architectural pattern (e.g., introducing a new data store)✅ Yes
Breaking API change✅ Yes
Schema change with downstream contract impact✅ Yes
New security boundary, auth flow, or tenant isolation pattern✅ Yes
New infrastructure component (e.g., new SaaS dependency)✅ Yes
Process change (e.g., new review workflow, new gate)✅ Yes
Anything requiring cross-team or cross-domain alignment✅ Yes
Functional requirement❌ No — write a PRD
Implementation detail of an already-accepted approach❌ No — write a Cycle doc
Single-file refactor❌ No — just open a PR

RFC numbering

  • Sequential: RFC-001, RFC-002, RFC-003, …
  • Numbers are never reused (even if rejected or superseded)
  • Filenames use a descriptive slug: RFC-003-calendar-api-architecture.mdx

RFC lifecycle

draft  →  review  →  accepted | rejected | superseded
StatusMeaning
draftAuthor is iterating; not yet ready for review
reviewOpen for engineering review on the PR
acceptedApproved by reviewers; the proposed approach is the team’s plan
rejectedReviewers determined this approach is not the right one (rationale in doc)
supersededReplaced by a newer RFC (linked in superseded_by)

How to create an RFC

  1. Copy docs/RFCs/_template.mdx to docs/RFCs/RFC-NNN-slug.mdx
  2. Fill in frontmatter and body
  3. Commit on a branch like rfc-NNN-slug and open a PR for review
  4. Reviewers comment in the PR; iterate; merge once accepted
  5. The accepted RFC may produce an ADR recording the decision (optional but encouraged for architectural decisions)
PMs do not author RFCs. PMs may comment on RFCs that affect product surface (e.g., breaking API changes that affect a feature timeline).

Review process

ReviewerRequired When
Domain CE (Chief Engineer)Always — the squad CE owns architectural alignment within their domain
Cross-domain CERequired when the RFC touches multiple domains
CTORequired for any RFC that changes auth, tenant isolation, billing, or platform-wide patterns
PMRequired for any RFC that affects user-facing surface or feature timeline
A minimum of one CE-level reviewer is required to mark an RFC accepted.

Relationship to ADRs

ADRs (docs/adr/) record the decision and its consequences — short, focused, immutable. RFCs record the deliberation — the alternatives considered, the trade-offs evaluated, the open questions worked through.
  • An accepted RFC may produce an ADR (recommended for architectural decisions)
  • ADRs are not required for every RFC; small RFCs (e.g., adding a new infra component) may not need one
  • RFCs are mutable while in draft/review; ADRs are immutable once accepted

Tips for good RFCs

  • Lead with the recommendation, then defend it — reviewers should know your position in the first paragraph
  • Steelman the alternatives — readers should understand why each rejected option was tempting
  • Quantify wherever possible — “lower latency” is weak; “p95 from 800 ms to 200 ms” is strong
  • Include diagrams — Mermaid renders natively in Mintlify; embed images for anything more complex
  • Be explicit about migration — even greenfield additions affect existing code (imports, conventions, CI)

See also