Skip to content

How to propose a cross-cutting change (RFC)

Produce and progress a researched RFC for a cross-cutting, prior-decision, or consensus-requiring change.

Use this when: A change’s direction is still unresolved and more than one owner has to agree, or you want a proposal circulated — plus the reserved categories below, which take this route even with one owner. Prerequisites: governance-extras pack installed. A docs/rfc/ directory and web search are needed only after the artifact checkpoint selects an RFC — see Prerequisites below. Result: The cheapest adequate route. When an RFC is warranted, a scaffolded, research-backed draft at docs/rfc/NNNN-<title>.md, ready to circulate as Open.

You have a change in mind whose direction is not settled, and more than one person has to agree before it can be built — the kind of change where “open a PR and see what happens” is the wrong shape. Note what does not put you here: a change being large, spanning packages, visible to users, or touching a governed document. Those affect how carefully it is reviewed, not which artifact it needs. This guide starts by selecting the artifact. When the result is an RFC, it then walks the new-rfc path: scaffold the file, run the per-subpoint research-and-de-risk phase before any body sentence gets written, draft answer-first, and circulate the proposal after a self-review gate.

For the surrounding system — where RFCs sit relative to ADRs, specs, and the loop that builds features once an RFC is accepted — read the core pack as a system. This guide is task-oriented; it tells you what to type and what to expect back.

Use the new-rfc skill to propose a change to the release approval policy.

The two skills look adjacent but solve different problems. Get this right before you invoke either, or you’ll write the wrong artifact twice.

QuestionRFCADR
TenseForward-looking (“should we change X?”)Backward-facing (“we chose X over Y”)
LifecycleDraftOpenFinal Comment PeriodAccepted | Rejected | Withdrawn (optional Experimental while a trial runs)ProposedAccepted → (Deprecated | Superseded by ADR-NNNN)
Body after acceptanceFrozen at acceptance (status field can change later, body cannot); stays as historical record; produces follow-on ADRs, specs, or CONVENTIONS editsFrozen at acceptance (status field can change later, body cannot)
Reject pathRejected is a normal terminal state — the discussion was the pointA pre-acceptance ADR that doesn’t earn Accepted just isn’t committed; there’s no Rejected state
TriggerThe direction is unresolved and more than one owner must agreeThe decision is made (or is being formally proposed) and has a concrete tradeoff

Quick rule: RFCs propose; ADRs record. If the discussion hasn’t happened yet, you want an RFC. If the discussion is done and you’re writing it down so the next maintainer can reconstruct it, you want an ADR. Both are covered by the lifecycle table in docs/CONVENTIONS.md § Document lifecycle.

If you’re recording a decision that’s already settled, see how to record a decision (ADR) instead.

  • A working docs/rfc/ directory. The skill creates one if it’s missing, but the home for the file matters — the lifecycle rules in docs/CONVENTIONS.md only apply to RFCs at this path.
  • Web search available in your agent harness (Claude Code’s WebSearch, or the equivalent elsewhere). The external prior-art sweep degrades gracefully without it — the skill says so explicitly rather than fabricating citations — but you lose half the research phase’s value.

Bring the upstream material that shaped the proposal: a shaped intent from docs/product/intents/, a decision brief, a research survey or brief, or an architecture concept or reference architecture. Cite that artifact in the RFC; the citation is what makes the later decision traceable.

Before invoking, check that the change clears one of these bars, lifted from docs/CONVENTIONS.md § RFC:

  • The direction is unresolved and more than one owner has to agree.
  • Someone explicitly asks for a proposal to be circulated.
  • It is one of the reserved categories, which take this route even with a single owner: the charter’s mission, scope, or foundational principles; who may approve work, or the governance model; a security trust model (as distinct from a security implementation); withdrawing or breaking a stable published compatibility promise.

Some facts feel decisive and are not. Package or file count, visibility to users, top-level location, a prior ADR, and the pathname of a governed document raise how carefully a change is reviewed — none of them, on its own, calls for a proposal.

If no bar fires, push back on yourself and pick the artifact that fits: a settled durable architectural choice is an ADR (a superseding ADR when it replaces one); a bounded feature whose direction is settled is a spec; routine and behaviour-preserving work, and implementing a decision already accepted, is a PR; and a reversible, time-bounded trial with stated exit criteria just gets normal review.

Working in a repository with no RFC process at all? Reserved and contested decisions still need an explicit recorded decision from the owners before implementation, using whatever mechanism that repository already has. No file, pack, or configuration is required — and if the repository declares a stricter rule of its own, that rule wins.

Step 1 — Choose the artifact before starting an RFC

Section titled “Step 1 — Choose the artifact before starting an RFC”

Ask new-rfc to decide the route before it resolves an RFC number, chooses a target, creates a directory or index, or drafts text. For example:

use new-rfc to decide what artifact this change needs: we need to change
the retention policy, but the direction is already agreed

The skill first checks whether the direction is unresolved and consequential, whether more than one owner must agree, and whether an existing RFC or decision already answers the question. A cheaper route ends the interaction with no RFC effect:

  • Skip when no proposal is needed.
  • Reuse, amend, or reference an adequate RFC or decision that already resolves the question.
  • Use an ADR for a settled durable choice, a spec for a settled bounded feature, a PR for routine work, or an issue for tracked work.
  • Use architecture design for a remaining technical choice.
  • Use a reversible, time-bounded trial with exit criteria when that is sufficient.

Only an unresolved consequential direction that needs agreement, or an explicit request to circulate an RFC, continues to RFC authoring. Reserved governance, trust-model, and stable-compatibility changes also take that route. The skill reports the selected route once, then stops; it does not create an RFC merely to record the route.

Step 2 — Invoke new-rfc for a warranted RFC

Section titled “Step 2 — Invoke new-rfc for a warranted RFC”

Two worked invocations from genuinely different RFC shapes:

use the new-rfc skill to propose a new commit-message convention
requiring spec citations in every feature PR

(a new convention — adds a rule that doesn’t exist yet; the research phase will look hard for prior conventions the rule would clash with.)

use the new-rfc skill to amend the work-loop iteration cap from 5
to 7 based on six months of stasis-detection data

(Differs from above: an amendment to an existing convention — the research phase already has the target sitting in docs/CONVENTIONS.md, so the proposal hinges on whether the precedent’s reasoning still holds today, not on prior-art existence.)

Natural phrasings (propose a change to …, let's get input on …, draft an RFC for …) match the skill’s description and often trigger it. The explicit form is the reliable one.

Step 3 — Shape the proposal (the skill offers, doesn’t force)

Section titled “Step 3 — Shape the proposal (the skill offers, doesn’t force)”

Before any research, the skill gets the frame straight — and how hard it leans depends on how well-formed your ask already is:

  • A sharp ask (a clear change, a named surface, an evident motivation) — the skill infers the frame and moves straight to research. You won’t be made to fill in a questionnaire you’ve already answered.
  • A vague ask (“we should probably do something about X”) — the skill asks a small set of framing questions (what outcome, what’s in and out of scope, what’s the bet) and reflects back a short proposal frame for you to confirm, so research effort doesn’t get spent on the wrong target.

The skill also picks the RFC’s Decision weight here — light, standard, or heavy — by reading work-loop’s risk triggers: a reversal of a frozen ADR/RFC, a governance/charter/security boundary, or a one-way door makes it heavy; a reversible, narrow change makes it light; everything else is standard (the default). The weight now changes what the RFC is actually obliged to do, not just how long it is (see Step 6). It’s an offer, not a gate: a half-formed ask is normal input, not something to be rejected.

Step 4 — Watch the research + de-risk phase

Section titled “Step 4 — Watch the research + de-risk phase”

After the artifact checkpoint selects an RFC, the skill resolves where it will live (the repository root and docs/rfc/, or a non-default location your conventions declare) and then stops before creating the file or writing any body sentence. This is the load-bearing move: a complex RFC is a tree, not one blob, so the skill researches each subpoint, models its options out, and de-risks its own riskiest assumption — rather than handing you a pile of un-researched questions to rescue.

You’ll see a RESEARCH FINDINGS: block in chat (not in the RFC file — the body is gated) with these sections:

  1. Decisions / subpoints. The proposal broken into the decisions it asks for, each self-contained enough to decide from the block alone — you shouldn’t have to open a file. Each states the question in plain language and lists its options — collectively exhaustive (MECE) along a stated axis and grounded in prior art, not a round number someone invented — with, per option, its real trade-off (what it buys vs. costs) and the concrete consequence of accepting it, then a recommendation, an owner, and a decide-by. This is where to push: if a subpoint shows “3 options” with no axis or sources, the space wasn’t modelled; if the options are bare names with no trade-offs, the handoff is too terse to decide from — send it back.
  2. Prior art (in repo). Grep hits across docs/CHARTER.md, docs/CONVENTIONS.md, docs/adr/, docs/rfc/, docs/specs/, and docs/architecture/, each with a file path. They often reveal the proposal touches something you didn’t know was decided.
  3. Prior art (external). Web-search results on how comparable projects or processes handled this shape of problem (Rust RFCs, PEPs, IETF BCPs). Each a markdown link. Empty here is a finding — say so — not an omission.
  4. De-risk. The one assumption that, if false, sinks the proposal, and the result of a small spike against it (or why none was needed).

Read the recommendations carefully. For each:

  • Accept — the recommendation folds into the body when drafting resumes.
  • Reject without an alternative — the question stays in the body’s Open questions section, with a recommended default + owner + decide-by.
  • Revise — give the skill the alternative; it will re-thread that one finding into the body.

Once you sign off, the skill previews the target — the identifier (RFC-NNNN), the status (Draft), the target path, and the index path — then, on your go-ahead, creates the file and drafts the body, leading with the decision, then cascading detail:

  • Reviewer brief. A fixed first-screen orientation grid above “The ask” (Decision · Recommended outcome · Change if accepted · Affected surface · Stakes · Review focus · Not in scope). It orients the reviewer; “The ask” argues the decision — the skill keeps them de-duplicated rather than restating the BLUF twice. (This in-body brief is distinct from the chat-only REVIEW READINESS summary in Step 5.)
  • The ask. Answer-first: the recommendation (BLUF) + an SCQA framing (Situation → Complication → Question) + the decisions you’re being asked to make rendered as a table — one row per decision, each with a recommended option, a decide-by, and a reviewer action column naming what you must do (confirm X, rule on Y). A reviewer should know what they’re approving from the first screen.
  • Problem & goals. Diagnosis before solution, plus Non-goals — the could-have-been-goals deliberately dropped (not “won’t crash”).
  • Proposal. The concrete shape of the change, detailed under each decision.
  • Options considered. Mandatory and MECE along a stated axis, each option grounded in prior art and including “do nothing.” The skill pushes back if the enumeration is a round number with no exhaustiveness argument.
  • Risks & what would make this wrong. A pre-mortem (assume it shipped and failed), falsifiable key assumptions, and drawbacks. The skill pushes back on “no drawbacks.”
  • Evidence & prior art. The spike result and the prior-art citations from the research phase. Empty-with-explanation is valid; empty-with-no- explanation is not, and every citation is fetched and confirmed.
  • Open questions. Each carries a recommended default + owner + decide-by.
  • Experiment / validation (optional). Present only if the proposal needs an experiment — hypothesis, what’s measured, success/failure criteria — with the results linked out to a spike note, not pasted into the RFC. Once circulating, while the trial runs the RFC sits in Experimental (see Step 6).

The file lands at docs/rfc/NNNN-<kebab-title>.md with status Draft, the Decision weight set, and an Approver named in the frontmatter.

Once the file and the RFC index are written, the skill hands back a short completion receipt: the identifier (RFC-NNNN), the file path, the index path, the current status (Draft, or Open once you circulate), the files changed, the owner (the named Approver), and the next step — circulate for review (→ Open), then Approver sign-off (→ Accepted).

Before the RFC moves to Open, the skill runs a self-review gate so you aren’t the one catching obvious misses. Each check is run, not asserted. What the gate obliges depends on the Decision weight: a light RFC gets the completeness checklist and one adversarial pass, not an iterative one, and no automatic fresh-reader readability review; standard adds the full argument, proportionate research, decision-by-decision backing, and adversarial review re-run until clean; heavy adds applicable reversal, compatibility or trust-model analysis, a security review when a security boundary or trust model is involved, and validation planning where the uncertainty is empirical. Two checks apply at every weight, scoped to whatever the proposal actually claims: citation integrity and verify-before-you-assert. The checks:

  • Citation-integrity. Every reference is fetched and confirmed to actually contain the claim it’s cited for — a link that merely loads isn’t enough. Citations are challenged the same way (by fetching), never by eyeballing whether an identifier “looks real.”
  • Verify-before-you-assert. Self-claims the RFC makes about itself (counts, “lighter”, “readable”) are checked against the artifact.
  • Per-subpoint backing + completeness. Each decision is backed; the Approver is named; every decision has a recommendation; do-nothing is present; open questions are ≤3 and owned.
  • A different-lens review. A fresh-context adversarial-reviewer pass (and security-reviewer if the RFC touches a security boundary), re-run until clean — because a same-session self-check rationalises its own draft.
  • A fresh-reader readability reviewconditional, not automatic. It runs only when the proposal coins vocabulary of its own, leans on cross-references to sibling proposals a reader may not have read, or is written for adopters or contributors who did not take part in drafting it. When it runs, a generic subagent gets only the RFC text — denied the project docs, CLAUDE.md/AGENTS.md, and sibling RFCs — and lists every term, acronym, or back-reference it can’t resolve; the skill glosses each before handoff. It is a separate instrument from the adversarial pass, which loads project conventions by design, and it degrades to a noted skip if the harness offers no subagent.

What you get back at handoff is a short, reviewer-friendly readiness summary — the skill’s REVIEW READINESS checklist (decision clear, citations checked, adversarial pass clean, fresh-reader review, and the rest) — not a compliance dump, and the heavy proof (citation-fetch detail, the adversarial-review transcript) stays linked, not pasted into the RFC. The summary is a chat handoff, never a section in the RFC itself. (The skill owns the exact item list, so this guide doesn’t re-enumerate it.)

The lifecycle is Draft → Open → Final Comment Period → Accepted | Rejected | Withdrawn. You move the status manually as the discussion progresses:

  • Draft — still working on it; not yet circulated.
  • Open — ready for reviewers. Update the frontmatter and push.
  • Final Comment Period — discussion is winding down; last call for objections.
  • Experimental (optional) — the proposal includes an Experiment / validation section and the trial is running; the RFC sits here, results pending in a linked spike note, until they land and it moves to a terminal status. Use only when an experiment is genuinely in flight.
  • Accepted | Rejected | Withdrawn — terminal. Fill in Date closed:. The RFC freezes here (see CONVENTIONS.md § Document lifecycle) — status field can change later (e.g. a future RFC supersedes it), the body cannot.

The skill also updates docs/rfc/README.md so the new file shows up in the index.

An accepted RFC is rarely the last artifact. It points at concrete follow-on work, which lives in docs/specs/<feature>/, docs/adr/, or docs/CONVENTIONS.md:

The RFC’s job is done once the follow-on artifacts exist. It stays as history.

A published RFC can still need a correction later — a spec finds a gap, a later RFC reframes a decision. You record it inside the RFC (never by editing the frozen body), under an ## Errata section for a Frozen RFC or ## Amendments for an in-flight one, following the new-rfc skill’s Recording corrections (Errata / Amendments) convention — append-only, with an optional two-layer current-state-over-audit-trail structure once corrections accumulate. The skill is the canonical home for the rules; this guide just points at it.

  • A bug fix, performance improvement, or refactor that preserves behavior. Just open a PR. RFCs are for proposing change to shared shape, not for fixing what’s already agreed.
  • A new feature that fits cleanly within one package and changes no interface. Write a spec, not an RFC — see how to plan and execute non-trivial work.
  • A decision that’s already settled. That’s an ADR — see how to record a decision (ADR). The new-rfc skill explicitly refuses to scaffold an RFC for an already-decided thing.
  • Single-feature internals. The contract for one feature lives in docs/specs/<feature>/spec.md, not in an RFC.

You have either the cheaper adequate route or a research-backed RFC at docs/rfc/NNNN-<title>.md, ready to circulate as Open. After acceptance, turn its concrete decisions into ADRs, specs, or convention changes.