Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 33 additions & 111 deletions .claude/skills/rfc/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,139 +1,61 @@
---
name: rfc
description: Write an RFC document based on user-provided notes and context. Use when the user wants to create, draft, or write an RFC.
argument-hint: [topic or brief description]
context: fork
description: Write, revise, or review an RFC in docs/rfcs/ — interview the author, draft the sections, check the shape. Use for "write an RFC", "draft an RFC", "turn these notes into an RFC", "review this RFC", a bare RFC number, or edits under docs/rfcs/. Not for design docs in docs/design/, PRDs, or issue drafts.
argument-hint: [topic, notes path, or RFC number]
allowed-tools: Read, Grep, Glob, Bash(deno run --allow-read=. -c ${CLAUDE_PROJECT_DIR}/.claude/skills/rfc/deno.json ${CLAUDE_PROJECT_DIR}/.claude/skills/rfc/scripts/check-rfc.ts *), Bash(deno test --allow-read=. -c ${CLAUDE_PROJECT_DIR}/.claude/skills/rfc/deno.json ${CLAUDE_PROJECT_DIR}/.claude/skills/rfc/scripts/check-rfc.test.ts *)
---

# RFC Writer
# RFC

You are an RFC writer. Your job is to produce a high-quality, precise, and complete RFC document based on the user's notes and context. The RFC must follow the Polkadot Fellows RFC template structure (see [template.md](template.md)).
RFCs live in this repo at `docs/rfcs/NNNN-kebab-title.md`, are listed in `docs/rfcs/_index.md`, and follow `docs/rfcs/0001-template.md`. Read the template and a nearby RFC of similar size before drafting — `0008-statement-store.md` for a compact interface change, `0026-supported-chains.md` for a new method with a rationale-heavy Motivation.

## Process
`$ARGUMENTS` is the topic, a path to notes, or the number of an existing RFC to revise.

### Phase 1: Gather Context
This skill covers writing the document. Getting it merged, its status, and its rollout are not its business.

The user will provide some combination of:
- Notes describing what the RFC should cover
- An existing spec or RFC that this new RFC aims to adjust
- A PRD or design document
- Verbal explanation of the problem and proposed solution
- Code references or technical context
## Workflow

**Your first action is to read and deeply understand everything the user provides.**
1. **Read every input before asking anything** — the user's notes, the design doc or PRD, the RFC being amended, the tracking issue, and the code the change lands in. An RFC that contradicts the code it changes dies on the first review pass.

If the user passes arguments (`$ARGUMENTS`), treat them as the initial topic/notes.
2. **Interview until nothing is hand-wavy.** Numbered batches of 5–8 questions, grouped by area, as many rounds as it takes; question bank in `references/interview-questions.md`. Skip what the notes already answer, quote the note you are asking about, and name any contradiction you found instead of quietly picking a side. Do not start drafting while a mechanism is still "somehow" — vague design is what reviewers reject, and it always traces to a question nobody asked.

### Phase 2: Clarifying Questions
3. **Allocate the number**: highest in `docs/rfcs/_index.md` plus one. Gaps stay unused; they belong to RFCs in sibling repos.

**This is the most critical phase. You MUST ask clarifying questions before writing the RFC.**
4. **Draft into the repo shape.** Per-section contract, and the rule for leaving a section out rather than padding it, in `references/section-contract.md`. Uppercase MUST/SHOULD/MAY carry RFC 2119 meanings and belong only in `## Detailed Design`: `references/normative-language.md`.

Do NOT proceed to writing until you are confident that every aspect of the RFC will be concrete and specific — nothing should remain vague, ambiguous, or hand-wavy.
5. **Add the `_index.md` row** in the same change: number, linked title, status, author, PR cell (`—` when there is no PR yet). An RFC missing from the index is invisible to everyone who looks for it.

Ask questions in focused, numbered batches (5-8 questions max per round). Group them logically. Continue asking rounds of questions until you have full clarity.
6. **Gate, then self-review.** Run the checker below, fix what it names, then walk `references/review-rubric.md`.

Areas you must have clarity on before writing:
7. **Revise by patch.** Once the draft exists, edit the sections a comment touches. Never regenerate the file — RFC text is negotiated line by line, and a rewrite silently drops wording that was already settled.

1. **Problem & Motivation**: What exact problem does this solve? Who is affected? What's the impact of not solving it? Are there concrete examples or incidents that motivate this?

2. **Proposed Solution**: What specifically is being proposed? What are the exact mechanics? How does it work step-by-step? What are the key design decisions and why were they made?

3. **Scope & Boundaries**: What is explicitly in scope? What is explicitly out of scope? Are there related problems this intentionally does NOT address?

4. **Stakeholders**: Who are the primary stakeholders? Has this been discussed with anyone? What feedback has been received?

5. **Trade-offs & Alternatives**: What alternative approaches were considered? Why were they rejected? What are the known drawbacks of the chosen approach?

6. **Technical Details**: Are there specific interfaces, data structures, algorithms, or protocols involved? What are the exact parameters, thresholds, or configurations?

7. **Compatibility & Migration**: Does this break anything existing? How do existing users/systems migrate? Is backwards compatibility maintained?

8. **Edge Cases**: What happens in failure scenarios? What are the boundary conditions? Are there race conditions or ordering concerns?

9. **Testing & Verification**: How can correctness be verified? What testing approach is appropriate?

10. **Unresolved Questions**: Are there aspects the author is genuinely unsure about and wants community input on?

**Rules for clarifying questions:**
- Be specific — don't ask "can you tell me more?" Ask "what happens when X occurs during Y?"
- Reference the user's notes when asking — show you've read and understood them
- If the user's notes already answer a question clearly, don't re-ask it
- If something seems implied but isn't explicit, ask to confirm your understanding
- Flag any contradictions or gaps you notice in the provided materials
- When the user provides an existing spec/RFC as context, ask how the new proposal interacts with or modifies it

### Phase 3: Write the RFC

Once you have sufficient clarity, write the complete RFC following this structure:
## Gate

```bash
deno run --allow-read=. -c ${CLAUDE_PROJECT_DIR}/.claude/skills/rfc/deno.json ${CLAUDE_PROJECT_DIR}/.claude/skills/rfc/scripts/check-rfc.ts docs/rfcs/0027-your-rfc.md
```
# RFC: [Descriptive Title]

| | |
| --------------- | ---------------------------------------- |
| **Start Date** | [Today's date] |
| **Description** | [One clear sentence] |
| **Authors** | Valentin Sergeev |

## Summary
[One concise paragraph — the elevator pitch]

## Motivation
[Problem statement + requirements. Be specific with examples.]

## Stakeholders
[Who cares about this and why. Prior socialization.]

## Explanation
[The meat of the RFC. Detailed, precise, implementer-friendly.
Address corner cases. Justify decisions. Show the reasoning.]

## Drawbacks
[Honest assessment of downsides]
Checks filename, frontmatter (`title`, `owner`), H1 number against filename, required sections, headings with nothing under them, surviving template text, `TODO`/`TBD` markers, RFC 2119 keywords in descriptive sections, and the `_index.md` row. `ERROR` blocks handing the draft back; a `WARN` needs a reason, not a fix.

## Testing, Security, and Privacy
[How to test. Security implications. Privacy considerations.]
Passing paths checks one RFC. Passing none audits all 16 — that run reports existing corpus drift, which is not yours to fix unless asked.

## Performance, Ergonomics, and Compatibility
The checks are pinned by fixtures — `deno test --allow-read=. -c ${CLAUDE_PROJECT_DIR}/.claude/skills/rfc/deno.json ${CLAUDE_PROJECT_DIR}/.claude/skills/rfc/scripts/check-rfc.test.ts` proves each one fires on a broken fixture and stays silent on two valid RFCs written in deliberately different styles. Change a check, extend the matrix in the same commit.

### Performance
[Impact analysis]
## Traps

### Ergonomics
[UX/DX impact]

### Compatibility
[Breaking changes, migration path]

## Prior Art and References
[What exists already. What informed this design.]

## Unresolved Questions
[Genuine open questions for discussion]

## Future Directions and Related Material
[What this enables next]
```
**Attribution.** `owner` is the RFC's author — the person whose proposal this is. Take it from the user, or from `git config user.name` when they say it is theirs, and ask when neither is certain. Never carry a name over from the template or a neighbouring RFC: a wrong-but-plausible owner reads fine to everyone except the person it names.

**Writing quality standards:**
- Every claim must be specific and substantiated — no vague language like "improved performance" without explaining how and by how much
- Use precise technical language appropriate to the domain
- Include concrete examples where they aid understanding
- The Explanation section should be detailed enough that an implementer could build from it
- Drawbacks should be genuine, not strawmen — if there are real costs, state them honestly
- Unresolved Questions should reflect actual uncertainty, not false modesty
**Two shapes in one directory.** The repo shape is `Summary / Motivation / Detailed Design / Drawbacks / Alternatives / Unresolved Questions`. Four files in `docs/rfcs/` instead carry `## Explanation`, `## Stakeholders`, and `## Prior Art and References`, copied from the Polkadot Fellowship's template by an earlier version of this skill. Follow the repo template; the gate errors on a missing `## Detailed Design`.

### Phase 4: Review & Iterate
**Facts you cannot source.** A wire id, error variant, type name, threshold, or chain name that you did not read out of the code or hear from the author does not go in the draft. Ask, or put it under `## Unresolved Questions`. Everything an RFC asserts, an implementer will build.

After presenting the draft:
- Ask the user to review
- Be ready to revise specific sections based on feedback
- If revisions reveal new ambiguities, ask follow-up questions before rewriting
**Length is not thoroughness.** The corpus runs 2 KB to 37 KB and the short ones are not the weak ones — `0021-payment-topup-coins.md` adds one enum variant in 2 KB and says everything it needs to. Match the document to the change.

## Important Guidelines
## References

- **Never fabricate technical details.** If you don't know something, ask.
- **Never fill sections with generic placeholder text.** Every section must have real, specific content or be explicitly marked as needing input.
- **Sections can be omitted entirely** if they don't apply. For smaller or narrowly-scoped changes, skip sections like Testing/Security/Privacy, Performance/Ergonomics/Compatibility, or Future Directions rather than filling them with boilerplate. The core sections (Summary, Motivation, Explanation) are always required; everything else is included only when it adds real value. If additional sections are needed beyond the template, add them.
- **Match the technical depth to the audience.** These RFCs are read by protocol engineers and fellowship members — write accordingly.
- **Keep the tone professional and precise**, but not dry. Good RFCs are readable.
| Decision | File |
| --- | --- |
| What must I ask before drafting? | `references/interview-questions.md` |
| What goes in each section, and which ones do I leave out? | `references/section-contract.md` |
| MUST, must, or should? | `references/normative-language.md` |
| Is the draft ready to hand back? | `references/review-rubric.md` |
12 changes: 12 additions & 0 deletions .claude/skills/rfc/deno.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"lint": { "rules": { "include": ["no-sync-fn-in-async-fn"] } },
"fmt": { "lineWidth": 110 },
"imports": {
"@std/assert": "jsr:@std/assert@^1.0.19",
"@std/cli": "jsr:@std/cli@^1.0.32",
"@std/fmt": "jsr:@std/fmt@^1.0.10",
"@std/front-matter": "jsr:@std/front-matter@^1.0.9",
"@std/fs": "jsr:@std/fs@^1.0.24",
"@std/path": "jsr:@std/path@^1.1.6"
}
}
80 changes: 80 additions & 0 deletions .claude/skills/rfc/deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions .claude/skills/rfc/references/interview-questions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# What to ask before drafting

Open with the questions whose answers the draft cannot be written without, and stop asking once the notes have answered them. Batches of 5–8, numbered, grouped by area. Quote the note you are asking about, so the user can see what you already understood.

Two rules make the difference between an interview and an interrogation:

- **Ask about mechanism, never about mood.** "What happens when the host holds no key for that product?" is answerable. "Can you tell me more about the design?" makes the user do your job.
- **Confirm what you inferred.** Anything you deduced but the notes never said becomes a question with your inference in it: "I read this as the host resolving the alias, not the product — correct?"

## Areas

**Problem.** What breaks today, for whom, and how often? Is there an incident, a bug, a tracking issue, or a product that hit it? What is the cost of not doing this? A Motivation section with no concrete failure reads as a preference.

**Mechanism.** Step through the change end to end. Who calls what, with which arguments, in which order? What does the host do that it did not do before? Where does state live, and who owns it? What is the exact type of every new field?

**Surface.** Which trait, method, request id, error variant, SCALE type, or config key changes? Names and shapes, not paraphrases — every repo RFC of consequence carries the literal signature (`0022-account-derivations.md` has 16 fenced blocks, `0017-coinage-payment.md` 12).

**Boundaries.** What is deliberately not in scope? Which adjacent problem does this refuse to solve, and why? When scope is contested, this becomes a `## Non-goals` section rather than a sentence buried in Motivation.

**Rejected designs.** What else was considered, and what killed each one? An Alternatives section that lists only strawmen tells a reviewer the design space was never explored. The strongest rejected option is the one worth writing down.

**Failure and edges.** What happens on a malformed request, a missing key, a concurrent call, a host that does not implement the new method, a version skew between product and host? Which errors are new and what does a product do with each?

**Compatibility.** Does this break an existing wire format, method, or type? Which versions interoperate? What does a host or product have to do to migrate, and can old and new coexist during the rollout?

**Verification.** How does an implementer prove they got it right? Which existing test surface covers it, and what has to be added? For anything cryptographic or consensus-adjacent, what is the oracle — a reference implementation, a round-trip, a known-answer vector?

**Security and privacy.** What can a hostile product or host do with this that it could not before? What new data crosses the trust boundary, and who can see it?

**Prior work.** Which RFC does this amend, supersede, or depend on? Which RFC number, so the draft can link it? Has it been discussed anywhere — an issue, a PR thread, a call? Who has already pushed back, and on what?

**Genuinely open.** What is the author actually unsure about? These become `## Unresolved Questions`. False modesty ("perhaps the naming could be improved") wastes a reviewer's attention; a real fork in the design earns it.

## When to stop

Stop when you can write the Detailed Design without the word "somehow", every new name has a type, and every failure path has a defined outcome. If a question stays unanswered because the user genuinely does not know yet, that is not a blocker — it is an Unresolved Question, and it goes in the draft as one.
Loading