Skip to content

feat(rfc): make proposed RFCs discoverable from main via a registry/stub index #2278

Description

@purp

Problem Statement

Proposed RFCs are effectively invisible from main. Four RFCs (0007–0010) currently live only on branches, and there is no reliable way to discover them, learn which numbers are taken, or jump to where they're being written.

Two concrete failures make this worse:

  • No branch-naming convention. RFC 0010 lives on a branch named gateway-hooks; RFC 0009 lives on a branch named rfc-0005-sandbox-egress-middleware. Finding an RFC means knowing the branch out-of-band.
  • Number collisions. The create-rfc skill (step 3) tells the agent to "choose the next available NNNN from the existing rfc/NNNN-* directories." But branch-only RFCs aren't in main's directories, so the agent can't see 0007–0010 and picks a colliding number. That's exactly how RFC 0009 ended up on a branch named RFC0005 — it had to be renumbered after the fact.

The result: rfc/README.md describes a clean lifecycle, but in practice the set of in-flight RFCs is unknowable without spelunking through branches, and numbers are assigned from stale information.

Proposed Design

Make proposed RFCs discoverable from main and make number assignment collision-resistant. Regardless of which representation we choose (see options below), the following changes are shared:

A findable branch-naming convention. Adopt rfc-NNNN-short-title (formed from existing repo usage such as 1492-driver-config-rfc/elezar). The create-rfc skill and rfc/README.md should require it.

Split "create the RFC" from "write the RFC" in create-rfc step 3. The create step:

  1. Determine the next RFC number from an authoritative, main-visible source (not from local directories).
  2. Create/rename the branch to rfc-NNNN-....
  3. Create/rename the RFC directory to match the number.
  4. Record the pointer metadata (number, author GH handle, originating issue, branch name) somewhere visible from main.
  5. Land that pointer on main immediately via a small fast-merge PR — so number assignment is durable and the reference to the branch is authoritative before real writing starts.

Then the write step proceeds (carrying over any drafting already done).

Branch name is an external reference. Because the pointer on main records the branch name, the instructions must state that renaming the branch requires updating that pointer on main. The agent working on the branch is thereby aware of the reference it must keep in sync.

Alternatives Considered

We narrowed to three representations and want feedback on which to adopt. All three share the workflow changes above; they differ in what lives on main to make RFCs discoverable.

Option A — Registry file only

A single hand-maintained rfc/REGISTRY.md table on main: one row per RFC with number, author, originating issue link, deep link into the branch's RFC directory, and PR link. The RFC stub/content lives only on the branch.

  • Pros: One at-a-glance view of all RFCs and their state. main's rfc/ folder stays clean (only merged RFCs appear as folders). Exactly one review PR for the RFC content.
  • Cons: The registry is hand-maintained, so it can drift (the same discipline gap that caused today's mess). Number-collision resistance depends on everyone reading/updating the file.

Option B — Stubs only

The create step drops a stub rfc/NNNN-slug/README.md on main (front matter with author, state, links incl. branch, plus a "🚧 being written on branch <link>" body). No separate registry.

  • Pros: Browsing rfc/ on main self-documents which RFCs exist and their numbers. Strongly collision-resistant — you can't easily reuse a number whose directory already exists. Clicking any stub gives the minimal useful info; you could do without a registry entirely.
  • Cons: No single aggregated view — seeing the state of all RFCs means opening each one. In-flight status transitions (draft→review) don't reach main unless the stub is updated there. main's rfc/ folder mixes merged RFCs with in-flight placeholders.

Option C — Registry generated from stubs (recommended starting point)

Keep the Option B stubs, but generate the aggregate index from them rather than hand-maintaining it. A small script (mise task + pre-commit check, matching how the repo already gates formatting) globs rfc/*/README.md, reads each front matter, and emits the index table (e.g. at the top of rfc/README.md).

  • Pros: Keeps every stub advantage (browsable, collision-resistant, click-for-info) while restoring the at-a-glance view — always accurate, zero hand-maintenance. The "registry" becomes a derived artifact, so there is no second file to keep in sync. Status transitions reach main via a one-line state: bump in the stub (~2 over an RFC's life), which is arguably desirable since main then tracks lifecycle.
  • Cons: Requires building and maintaining a small generator + CI/pre-commit check. main's rfc/ folder still carries in-flight placeholder directories.

Open question for reviewers: Some of these could combine along the lifecycle — e.g. a lightweight pointer while an RFC is blessed/in-flight, and the full folder landing on main at accepted (which is essentially today's step 6). Feedback welcome on whether the representation should change by state.

Agent Investigation

  • rfc/README.md already documents a lifecycle where maintainers assign the RFC number in the originating issue (§2) to prevent cross-branch clashes, and add the needs-rfc label. This issue's proposals should reconcile with (or explicitly revise) that authority model — whether the registry/stubs replace maintainer pre-assignment or merely record it is a decision to make.
  • create-rfc skill step 3 currently reads numbers from local rfc/NNNN-* directories, which is the direct cause of the collisions since branch-only RFCs are invisible there.
  • main currently contains rfc/ directories 0000–0004 and 0006; 0005 and 0007–0010 are not present on main (0005 was vacated by the renumbering; 0007–0010 are branch-only).
  • Repo branch usage suggests an rfc-NNNN-... convention would fit existing patterns (1492-driver-config-rfc/elezar, 2219-tcp-nodelay/purp).

A follow-up branch + PR will implement the chosen approach.

Metadata

Metadata

Assignees

No one assigned

    Labels

    state:triage-neededOpened without agent diagnostics and needs triage

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions