Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

add new documentation guidelines #14115

Merged
merged 21 commits into from
May 26, 2023
Merged
Show file tree
Hide file tree
Changes from 3 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
26 changes: 16 additions & 10 deletions docs/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,17 @@
/client/sysinfo/ @koute
/client/tracing/ @koute

# Documentation audit
/primitives/runtime @paritytech/DevRel/docs-audit
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
/primitives/arithmetic @paritytech/DevRel/docs-audit
# /primitives/core (to be added later)
# /primitives/io (to be added later)

# FRAME
/frame/ @paritytech/frame-coders
/frame/nfts/ @jsidorenko
/frame/ @paritytech/frame-coders @paritytech/DevRel/docs-audit
/frame/nfts/ @jsidorenko @paritytech/DevRel/docs-audit
/frame/state-trie-migration/ @paritytech/frame-coders @cheme
/frame/uniques/ @jsidorenko
/frame/uniques/ @jsidorenko @paritytech/DevRel/docs-audit

# GRANDPA, BABE, consensus stuff
/client/consensus/babe/ @andresilva
Expand All @@ -57,12 +63,12 @@
/primitives/merkle-mountain-range/ @acatangiu

# Contracts
/frame/contracts/ @athei
/frame/contracts/ @athei @paritytech/DevRel/docs-audit

# NPoS and election
/frame/election-provider-multi-phase/ @paritytech/staking-core
/frame/election-provider-support/ @paritytech/staking-core
/frame/elections-phragmen/ @paritytech/staking-core
/frame/nomination-pools/ @paritytech/staking-core
/frame/staking/ @paritytech/staking-core
/primitives/npos-elections/ @paritytech/staking-core
/frame/election-provider-multi-phase/ @paritytech/staking-core @paritytech/DevRel/docs-audit
/frame/election-provider-support/ @paritytech/staking-core @paritytech/DevRel/docs-audit
/frame/elections-phragmen/ @paritytech/staking-core @paritytech/DevRel/docs-audit
/frame/nomination-pools/ @paritytech/staking-core @paritytech/DevRel/docs-audit
/frame/staking/ @paritytech/staking-core @paritytech/DevRel/docs-audit
/primitives/npos-elections/ @paritytech/staking-core @paritytech/DevRel/docs-audit
1 change: 1 addition & 0 deletions docs/CONTRIBUTING.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ There are a few basic ground-rules for contributors (including the maintainer(s)
. **All modifications** must be made in a **pull-request** to solicit feedback from other contributors.
. A pull-request *must not be merged until CI* has finished successfully.
. Contributors should adhere to the link:STYLE_GUIDE.md[house coding style].
. Contributors should adhere to the link:DOCUMENTATION_GUIDELINES.md[house documenting style], when applicable.


== Merge Process
Expand Down
227 changes: 227 additions & 0 deletions docs/DOCUMENTATION_GUIDELINES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
# Substrate Documentation Guidelines

This document is only focused on documenting parts of substrate that relates to its external API. The list of such crates can be found in [CODEOWNERS](./CODEOWNERS). Search for the crates that are auto-assigned to a team called `docs-audit`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could have some docs labels similar to needs-audit like needs-docs and the CI puts them automatically.
Not sure how much that gets us, but would make it easier for people to see that they need to update it.

Copy link
Contributor

@sacha-l sacha-l May 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I support this idea fwiw, yes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would defer this decision to be made as a part of paritytech/labels#29 by @the-right-joyce and @juangirini. As far as I know, the agreed that using labels for things like audit was not the right choice as it is not a permanent label (eg 'needs audit' -> 'audited').

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It depends on how you want to see it. needs-docs could very well be a permanent label, if it means that the PR is worth documenting instead of whether it was already documented or not then it is a permanent label. Similarly we could think of needs-audit.
In that context needs-docs might need a better naming, but I see it useful too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find the label be a redundant side effect of the auto-review rule, isn't that the case? we already will assign this team to review automatically. I think this is semantically the same as the label.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, good point. Though the auto-review rule will only ask the @paritytech/docs-audit team for a review. Should we add a rule to require at least one approval from them on top of the approvals we already need?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eventually, yes, but let's first see if the docs-audit team has enough bandwidth for this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we got rid off the audit labels, for the security audits we will use Github projects in future. The process still needs to be documented, but as a preparation I already have here the project set up: https://github.com/orgs/paritytech/projects/103
I'm syncing with Regina from SRLabs regarding that.

When it comes to the docs update, I'd also say this should be part of the review process. The same way we're changing the release process and want reviewers to add/adapt the changelog if needed, I think it should also be in their responsibility to think if the PR is important for docs as well and respectively add @paritytech/docs-audit as reviewers and the docs team are the ones who decide if the docs should be updated or not - does that make sense?


These are crates that are often used by external developers and deserve a better documents. Consequently, most of this revolves around FRAME-development.
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

- [Substrate Documentation Guidelines](#substrate-documentation-guidelines)
- [General/Non-Pallet Crates](#generalnon-pallet-crates)
- [What to Document?](#what-to-document)
- [Rust Docs vs. Code Comments](#rust-docs-vs-code-comments)
- [How to Document?](#how-to-document)
- [TLDR](#tldr)
- [Other Guidelines](#other-guidelines)
- [Document Through Code](#document-through-code)
- [Formatting Matters](#formatting-matters)
- [Pallet Crates](#pallet-crates)
- [Top Level Pallet Docs (`lib.rs`)](#top-level-pallet-docs-librs)
- [Dispatchable](#dispatchable)
- [Storage Items](#storage-items)


## General/Non-Pallet Crates

First, consider the case for all such crates, except for those that are pallets.

### What to Document?

The first question is, what should you document? Use the following filter:

1. Within the set of crates above,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this line, it's unnecessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kinda disagree 🙈 I think it is good to remind people that this only applies to certain crates. Instead, I will make it a bit cleared. Let me know what you think.

2. Any `pub` item within them needs to be documented. If it is not `pub`, it won't show up in the rust-docs, and won't matter.
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
* Within `pub` items, sometimes they are only `pub` in order to be used by another internal crate, and you can foresee that this will not be used by anyone else other than you. These need **not** be documented thoroughly, and are left to your discretion to identify.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Within `pub` items, sometimes they are only `pub` in order to be used by another internal crate, and you can foresee that this will not be used by anyone else other than you. These need **not** be documented thoroughly, and are left to your discretion to identify.
* There are some `pub` items that are only `pub` in order to be accessible for another internal crate. These should still be documented although you do not need to be as thorough as you are with the `pub` items that are for external developer use.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we ask to add a comment like "//no-doc" to establish that the author intentionally didn't add the docs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hummusonrails I am a bit hesitant about your suggestions that seem paraphrasing to me. Do you have strong opinions that the original text is wrong or poorly worded, or are you adding optional suggestions? I accepted most, but might close some. Please let me know if you prefer otherwise.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kianenigma In this one, I attempted to make it more neutral and formal, whereas your version was more informal and personal in tone. I'm of the opinion that documentation should lean more into the former. That's why I made that suggestion. Hope that helps clarify!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One common convention is to expose such items via a #[doc(hidden)] public module called __private from the crate root. In fact this is used in at least 5 popular crates I can think of, including the entire syn/quote ecosystem. Maybe worth suggesting a convention here?

* Reminder: `trait` items are public by definition, if the trait is public.
3. Of course, all of these crates should have a reasonable module documentation (`//!`).
kianenigma marked this conversation as resolved.
Show resolved Hide resolved


#### Rust Docs vs. Code Comments

Note that anything starting with `///` is external rust-doc, and anything starting with `//` is just for you to see. Don't mix the two!
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

```rust
/// Computes the square root of the input, returning `Ok(_)` if successful.
///
/// # Errors
/// ...
///
/// # Complexity
/// ...
///
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
// Details about the complexity, how you implemented this, and some quirks that
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
// are NOT relevant to the external interface, so it starts with '//'.
// This can also be moved inside the function.
pub fn sqrt(x: u32) -> Result<u32, ()> {
todo!();
}

```

### How to Document?

There are a few very good sources that you can look into:

- https://doc.rust-lang.org/rustdoc/how-to-write-documentation.html
- https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/documentation.html
- https://blog.guillaume-gomez.fr/articles/2020-03-12+Guide+on+how+to+write+documentation+for+a+Rust+crate


As mentioned [here](https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/documentation.html#writing-documentation-comments) and [here](https://blog.guillaume-gomez.fr/articles/2020-03-12+Guide+on+how+to+write+documentation+for+a+Rust+crate), always start with a **single sentence** demonstrating what is being documented. If there is more to say, add it *after a newline*.
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

About [special sections](https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/documentation.html#special-sections), we will most likely not need to think about panic and safety in any runtime related code. Our code is never `unsafe`, and will (almost) never panic.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
About [special sections](https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/documentation.html#special-sections), we will most likely not need to think about panic and safety in any runtime related code. Our code is never `unsafe`, and will (almost) never panic.
About [special sections](https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/documentation.html#special-sections), we will most likely not need to think about panic and safety in any runtime related code. Our code is never `unsafe`, and will (almost) never panic. If you see a panic in the code that is a reason to raise a question to the developer who introduced it rather than work to document it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you elaborate more what you are suggesting? in general, you might see things like expect() in the code but that is acceptable. Did you take that into account?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying to make explicit that a code documenter should flag a panic and seek clarification before documenting as this in the "How to document" section. Very open to alternative ways to do so!


Use `# Example`s as much as possible. These are great ways to further demonstrate what your APIs are doing, and add free test coverage. As a cherry on top, any code in rust-docs is treated as an "integration tests", not unit tests, which tests your crate in a different way than unit tests. So, it is both a win for "more documentation" and a win for "more test coverage".
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

You can also consider having am `# Error` section, but consider that optional. Of course, this only applies if there is a `Result` being returned, and IFF the `Error` variants are overly complicated.
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

Strive to include correct links to other items in your written docs as much as possible. In other words, avoid \`some_func\` and instead use \[\`some_fund\`\]. Read more about how to correctly use links in your rust-docs [here](https://doc.rust-lang.org/rustdoc/write-documentation/linking-to-items-by-name.html#valid-links) and [here](https://rust-lang.github.io/rfcs/1946-intra-rustdoc-links.html#additions-to-the-documentation-syntax).
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

> While you are linking, you might become conscious of the fact that you are in need of linking to (too many) foreign items in order to explain your API. This is leaning more towards API-Design rather than documentation, but it is a warning that the subject API might be slightly wrong. For example, most "glue" traits[^1] in `frame/support` should be designed, and documented without making hard assumptions about a particular pallets that implement them.
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

### TLDR

0. Have the goal of enforcing `#![deny(missing_docs)]` mentally, even if it is not enforced by the compiler 🙈.
1. Start with a single, clear and concise sentence. Follow up with more context, after a newline, if needed.
2. Use examples as much as reasonably possible.
3. Use links as much as possible.
4. Think about context. If you are in need of explaining a lot of foreign topics in documenting a trait that should not explicitly depend on them, you have likely not designed it properly.
kianenigma marked this conversation as resolved.
Show resolved Hide resolved


### Other Guidelines

The above 5 guidelines must always be respected in docs, as long as reasonable possible.
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

The following are a set of notes that may not necessarily hold at all circumstances. Consider them as opinionated guidelines that you may or may not abide by.
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
kianenigma marked this conversation as resolved.
Show resolved Hide resolved


#### Document Through Code

You can certainly do parts of your documentation through your well-organized, properly-named code. That's all true, but:
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

* This is hard to scale at a project the size of Polkadot/Substrate. Moreover, things like examples, errors and panics cannot be documented via just code.
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

* Your written documents should *complement* the code, not *repeat* it. Put bluntly, if you end up writing this, you are likely doing it wrong:
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

```rust
/// Sends request and handles the response.
trait SendRequestAndHandleResponse {

}
```

Because the document is adding no extra information and you are better of without it.
kianenigma marked this conversation as resolved.
Show resolved Hide resolved


#### Formatting Matters

The way you format your documents (newlines, heading and so on) do matter! Consider the below examples:
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

```rust
/// This function works with input u32 x and multiples it by two. If
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
/// we optimize the other variant of it, we would be able to achieve more
/// efficiency but I have to think about it. Probably can panic if the input
/// overflows u32.
fn multiply_by_2(x: u32) -> u32 { .. }
```

```rust
/// Multiplies an input of type [`u32`] by two.
///
/// # Panics
///
/// Panics if the input overflows.
///
/// # Complexity
///
/// Is implemented using some algorithm that yields complexity of O(1).
// More efficiency can be achieved if we improve this via such and such.
fn multiply_by_2(x: u32) -> u32 { .. }
```

They are both roughly conveying the same set of facts, but one is substantially kinder on the eye. Especially for traits and type that you can foresee will be seen/used a lot, try and write the better version!
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

Similarly, make sure your comments are wrapped at 100 characters line-width (as defined by our [`rustfmt.toml`](../rustfmt.toml)), no **more and no less**! The more is fixed by `rustfmt` and our CI, but if you (some some unknown reason) wrap your lines at 59 characters, it will pass the CI, and it will not look good 🫣.
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

[^1]: Those that help two pallets talk to each other.

## Pallet Crates

Everything above is related to non-pallet details. They might be relevant in both crates that are pallets, and non-pallet crates.
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

The following is relevant to how to document parts of a crate that is a pallet.

### Top Level Pallet Docs (`lib.rs`)

for the top-level pallet docs, consider the following template:
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

```
//! # <Pallet Name>
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
//!
//! <single-liner about the pallet>.
//!
//! ## High-Level/End-User Details
//!
//! <a few paragraphs, focus on what external folks should know about the pallet>
//!
//! <The audience here is potentially non-coders who just want to know what this pallet does, not how it does it>
//!
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
//! ### Example
//!
//! <Your pallet must have a few tests that cover important user journeys. Use https://crates.io/crates/docify to reuse your these as examples>.
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
//!
//! ## Code Details
//!
//! <inside [`pallet`] module, a template is auto-generated that leads the reader to the relevant items. This is just a reminder to navigate to that page. Don't repeat things like "See Config trait for ..." that are generated inside [`pallet`] in here>
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
//!
//! See [`pallet`] module.
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
//!
//! <The audience of this is those who want to know how this pallet works, to the extent of being able to build something on top of it, like a DApp or another pallet>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
//! <The audience of this is those who want to know how this pallet works, to the extent of being able to build something on top of it, like a DApp or another pallet>
//! <Readers of this section are developers who want to know how this pallet works, to the extent of being able to build another pallet that uses this pallet, or to build a DApp on top of it>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you expect authors to write 1-2 sentences addressing this? I saw in the fast-unstake pallet you just left it at:

See pallet module for more information.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point, let me re-asses.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated. I think in 99% of the time this section can be copy-pasted. We could even consider auto-generating it, but given that we want it to come after ## Overview, it might be hard to do.

//!
//! ## Low Level / Implementation Details
//!
//! <The format of this section is up to you, but we suggest the Design-oriented approach that follows>
//!
//! <The audience of this would be your future self, and those who want to deeply understand the pallet to optimize it further and such>
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
//!
//! ### Design Goals (optional)
//!
//! <Describe your goals with with the pallet design.>
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
//!
//! ### Design (optional)
//!
//! <Describe how you reach those goals. This should namely describe how your storage is laid out.>
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
//!
//! ### Terminology (optional)
sacha-l marked this conversation as resolved.
Show resolved Hide resolved
//!
//! <Optionally, contain any custom terminology here. You can link to it if you want to use the terminology further up>
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
```

### Dispatchable

For each dispatchable (`fn` item inside `pallet::call`), consider the following template:
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

```
/// <One liner explaining what this does>
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
///
/// ## Dispatch Origin
///
/// The dispatch origin of this call must be <details>
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
///
/// ## Details
///
/// <All other details. Focus on what errors could occur within this dispatch>
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
///
/// ## Errors (optional)
///
/// <If an extensive list of errors can be returned, list them individually instead of mentioning them in the section above>
///
/// ## Events (optional)
///
/// <Events are akin to the "return type" of dispatchables, optionally mention them>
pub fn name(origin: OriginFor<T>, ...) -> DispatchResult {}
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
```

### Storage Items

1. If a map-like type is being used, always note the choice of your hashers as private code docs (`// Hasher X chosen because ...`). Recall that this is not relevant information to external people, so it must be documented as `//`.
2. Consider explaining why a storage type is always bounded.
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
3. Consider explaining the crypto-economics of how a deposit is being taken in return of the storage being used.
5 changes: 2 additions & 3 deletions docs/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@ Before you submit, please check that:
- [ ] Github project assignment
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
- [ ] **Related Issues:** You mentioned a related issue if this PR is related to it, e.g. `Fixes #228` or `Related #1337`.
- [ ] **2 Reviewers:** You asked at least two reviewers to review. If you aren't sure, start with GH suggestions.
- [ ] **Style Guide:** Your PR adheres to [the style guide](https://github.com/paritytech/substrate/blob/master/docs/STYLE_GUIDE.md)
- [ ] **Style Guide:** Your PR adheres to [the style guide](https://github.com/paritytech/substrate/blob/master/docs/STYLE_GUIDE.md).
- In particular, mind the maximal line length of 100 (120 in exceptional circumstances).
- There is no commented code checked in unless necessary.
- Any panickers in the runtime have a proof or were removed.
- [ ] **Runtime Version:** You bumped the runtime version if there are breaking changes in the **runtime**.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this no longer needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not relevant anymore, contributors don't bump this. only the release team manages it. @coderobe can you confirm?

- [ ] **Docs:** You updated any rustdocs which may need to change.
- [ ] **Docs:** You updated any rustdocs which may need to change, as described [here](https://github.com/paritytech/substrate/blob/master/docs/DOCUMENTATION_GUIDELINES.md).
- [ ] **Polkadot Companion:** Has the PR altered the external API or interfaces used by Polkadot?
- [ ] If so, do you have the corresponding Polkadot PR ready?
- [ ] Optionally: Do you have a corresponding Cumulus PR?
Expand Down