diff --git a/assets/gip-0001/gip-process-flowchart.png b/assets/gip-0001/gip-process-flowchart.png index 93095c4..24ddafb 100755 Binary files a/assets/gip-0001/gip-process-flowchart.png and b/assets/gip-0001/gip-process-flowchart.png differ diff --git a/assets/gip-0001/smart-contracts-process-flowchart.png b/assets/gip-0001/smart-contracts-process-flowchart.png new file mode 100644 index 0000000..cd9d04b Binary files /dev/null and b/assets/gip-0001/smart-contracts-process-flowchart.png differ diff --git a/gips/0000-template.md b/gips/0000-template.md index 7d0f421..8cb8e92 100644 --- a/gips/0000-template.md +++ b/gips/0000-template.md @@ -1,12 +1,11 @@ --- -GIP: +GIP: Title: Authors: Created: -Updated: -Stage: +Stage: Discussions-To: -Category: <(Optional) The type of GIP or GRP. This field should be left blank for GRCs. Valid types are "Protocol Logic", "Protocol Interfaces", "Subgraph API", "Process", "Economic Parameters", and "Protocol Charters".> +Category: <(Optional) The type of GIP. This field should be left blank for GRCs. Valid types are "Protocol Logic", "Protocol Interfaces", "Subgraph API", "Process", "Economic Parameters", and "Protocol Charters".> Depends-On: <(Optional) A list of GIPs that this GIP depends on. If some other type of dependency exists, include a reference link here and an explanation in the body of the GIP.> Superseded-By: <(Optional) A GIP that supersedes the current proposal. If this field is specified, the stage of the GIP should be "Withdrawn".> Replaces: <(Optional) A GIP that this proposal is intended to supersede.> @@ -20,7 +19,7 @@ Audits: <(Optional) A list of URLs to audits related to this proposal.> *This is a template GIP proposal showing the layout and formatting described in GIP 0001. Italicized writing are comments and should be removed or replaced. Sections marked optional may also be removed if left empty.* -*All GIPs MUST include a preamble, in RFC 822 format, preceded and followed by three dashes ("—-"). This formatting aids in compatibility with most static site generators.* +*All GIPs MUST include a preamble, in RFC 822 format, preceded and followed by three dashes ("---"). This formatting aids in compatibility with most static site generators.* *Given the heterogeneous types of proposals this template is meant to reflect, most sections below, except "Abstract" and "Motivation," may be treated as optional. The author, however, should exercise good judgment in deviating from the template, as they are reflective of the type of information, when relevant, that editors will look for in reviewing a proposal.* @@ -38,11 +37,11 @@ Audits: <(Optional) A list of URLs to audits related to this proposal.> ## High-Level Description -*(Optional) Describe your specific solution at a high level. Include diagrams, math formulas, pseudocode, and any other artifacts helpful in showing how your proposal works at a conceptual level. This type of information is required for a proposal to reach the "Proposal" stage.* +*(Optional) Describe your specific solution at a high level. Include diagrams, math formulas, pseudocode, and any other artifacts helpful in showing how your proposal works at a conceptual level. ## Detailed Specification -*(Optional) Include specific APIs, semantics, data structures, code snippets, etc. related to this proposal. This type of info is required for a proposal to reach the "Draft" stage.* +*(Optional) Include specific APIs, semantics, data structures, code snippets, etc. related to this proposal. ## Backward Compatibility diff --git a/gips/0001-gip-process.md b/gips/0001-gip-process.md index cc25918..97ffab4 100644 --- a/gips/0001-gip-process.md +++ b/gips/0001-gip-process.md @@ -1,11 +1,11 @@ --- GIP: "0001" Title: Graph Improvement Proposal (GIP) Process -Authors: Brandon Ramirez +Authors: Brandon Ramirez , Pablo Carranza Velez Created: 2021-02-21 -Updated: 2021-04-09 +Updated: 2023-09-28 Stage: Living -Discussions-To: https://forum.thegraph.com/t/gip-0001-and-getting-started-with-gips-grps-grcs-etc/1722/4 +Discussions-To: https://forum.thegraph.com/t/gip-0001-and-getting-started-with-gips-grps-grcs-etc/1722/4, https://forum.thegraph.com/t/gip-0061-improvements-to-the-gip-process/4570 Category: Process --- @@ -35,80 +35,139 @@ The high-level process is captured in the diagram below. ## Before a proposal is written -The author(s) should do the leg work to assess whether their idea is a good one that is likely to be supported by the community. This includes discussing the idea in public formus such as Discourse, Discord and Twitter. +The author(s) should do the leg work to assess whether their idea is a good one that is likely to be supported by the community. This includes discussing the idea in public spaces such as [Discord](https://discord.gg/graphprotocol), [Twitter](https://twitter.com/graphprotocol), and [The Graph forum](https://forum.thegraph.com/). The author should also make sure the proposal is in line with the values and mission of The Graph. This may include reading past blog posts that allude to The Graph's design philosophy as well as talking to existing contributors to The Graph. Talking to active contributors of The Graph's various software repositories is also a good strategy to discern early on whether such an idea has already been considered in the past as well as its technical feasibility. +All this being said, authors are welcome to post an initial draft of a GIP that just includes Abstract and Motivation, and use the forum discussion as a way to refine the proposal to flesh out the specification. + ## Writing a proposal -There are three primary types of documents that are tracked in this repo. These are tracked in separate folders with their own numbering: +There are two primary types of documents that are tracked in this repo. These are tracked in separate folders with their own numbering: - **Graph Improvement Proposals (GIPs).** Describes some improvement to the protocol rules, interfaces, software functionality, protocol charters, protocol parameters, processes, etc. -- **Graph Requests for Proposals (GRPs)** Formalizes a problem or opportunity for the protocol to address without putting forth a specific solution. - **Graph Requests for Comment (GRCs)** Specifies an application-level community standard. For example, this could be a common way of designing subgraphs for specific use cases or to support better composability between applications. Depending on the type of proposal, they will move through the following stages, as indicated by the diagram up above: -1. **Strawperson.** A proposal at this stage describes an idea or problem that the proposal aims to solve but doesn't expand too much on the specifics of a solution. In terms of the document sections outlined below, a proposal at this stage would have a well-defined "Abstract" and "Motivation" and optionally a rough draft of a "High-Level Description.". -2. **Proposal.** Describes how a proposal works at a high level, without getting too in the weeds with specific APIs and technical implementation details. Sections relevant to this stage might include a more well-developed "High-Level Description", "Prior Art," "Dependencies," "Backwards Compatibility", etc. -3. **Draft.** This is a detailed technical specifical of a proposal. It includes specific API changes, implementation details, architecture, etc. Relevant document sections might include "Detailed Specification", "Risks and Security Considerations," "Validation," "Rationale and Alternatives". -4. **Candidate.** A proposal at this stage has a reference implemenetation that has been linked in the document and can be used to validate the idea described in the protocol. -5. **Accepted | Deferred | Withdrawn | Living.** These are resolution stages for a proposal: - 1. "Accepted" indicates that the proposal has been adopted. For GIPs this would typically mean a protocol upgrade initiated by The Graph Council, but for process changes, it could simply represent a rough consensus of the community. - 2. "Deferred" changes have been voted on at least once as protocol upgrades and have been rejected. Deferred proposals may be included in future governance votes. - 3. "Withdrawn" proposals have been withdrawn by the creator either because they have been superseded by another proposal or are no longer relevant for another reason. - 4. "Living" proposals are documents that are never in a finalized state, but rather are actively changing in response to feedback and community input. This proposal is such an example. +1. **Draft.** Day 0 through to Candidate stage +2. **Candidate.** The Author may move their GIP to the candidate stage in Github to indicate to the Council and to the public that they believe enough support has been gathered from the community and sufficient due diligence has been completed for the Council to make a decision for approval. A minimum of 1 week draft on forum for public review is required. +3. **Approved | Deferred | Withdrawn | Implemented | Living.** These are resolution stages for a proposal: + 1. "Approved" Council approval has been obtained for the GIP + 2. "Deferred" The GIP is on hold or otherwise working through remediations to obtain Council approval + 3. "Withdrawn" The submission was withdrawn by the Author or was withdrawn due to Inactivity. If more than 6 months have elapsed with no activity editors may move the status of a GIP to withdrawn. Authors may still contact editors to re-activate their proposal if the Author would still like to proceed with their submission at a later date. + 4. "Implemented" Indicates that a GIP has either been deployed in the case of a code change or is in use today for procedure changes or other non-code based changes. + 5. "Living" proposals are documents that are never in a finalized state, but rather are actively changing in response to feedback and community input. This proposal is such an example. -The above describes the stages that all GIPs may move through. GRPs and GRCs, on the other hand, only advance to the "Draft" stage, as their intent is not to be accepted by governance or community consensus, but act as a document that is well thought-out and can be easily referenced, discussed, and used by the rest of the community. +The above describes the stages that all GIPs may move through. GRCs, on the other hand, always stay on "Draft" stage, as their intent is not to be accepted by governance or community consensus, but act as a document that is well thought-out and can be easily referenced, discussed, and used by the rest of the community. ## While a proposal is being worked on The author should take strides to solicit insights from as many protocol contributors and community members as possible to produce a proposal that best serves the entire protocol. Activities an author may participate in during this time, include, but are not limited to: - Evangelizing their proposal in the forums. -- Present at Protocol Townhalls and other community calls and receive feedback from community. +- Present at Indexer Office Hours, Core Dev Calls, and other community calls and receive feedback from community. - Form working groups with other community members interested in a similar idea. -- Advocate for community polls on the proposal when it is sufficiently mature. - -## After a proposal is worked on. +- Advocate for community polls, Council votes on the proposal when it is sufficiently mature. +- Develop the implementation of the proposal, get security audits (potentially with support from The Graph Foundation), or request participation from Core Devs in the implementation. -Advancing through the stages of the GIP Process does not guarantee inclusion in the protocol. Protocol upgrades are implemented via decentralized governance, while the GIP Process is geared towards surfacing and building legitimacy for valuable protocol upgrades that can be considered in that process. Multiple GIPs may be bundled together into a release and be voted on as a single Graph Governance Proposal (GGP). - -GGPs may also include protocol upgrades that did not go through the GIP Process, such as bugs that were reported as responsible security disclosures, or enhancements that were too minor to justify a full-fledged GIP. +The sections below elaborate more on these activities and the steps to get a GIP accepted after it's published. # Anatomy of a GIP The GIP structure is intended to be flexible enough to describe a variety of categories of proposals. Rather than be overly prescriptive, we encourage authors to choose a document structure that best conveys their ideas. -The only requires parts are the *front matter—*which includes metadata such as the author's name, the date the protocol was created, and the stage the proposal is at—and the "Abstract" and "Motivation" sections of the body of the proposal. +The only required parts are the *front matter—* which includes metadata such as the author's name, the date the protocol was created, and the stage the proposal is at—and the "Abstract" and "Motivation" sections of the body of the proposal. -A template has been added to this repo called "0000-Template.md" which provides additional detail on these sections and should be kept up to date with the latest process as described in this proposal. +A template has been added to this repo called "0000-template.md" which provides additional detail on these sections and should be kept up to date with the latest process as described in this proposal. # Editors -Editors are the maintainers of this repo and the managers of this process. As the name implies, their role is purely editorial, and they should advance proposals to stages on the basis of how well they have been constructed per the guidance in this proposal, rather than based on the likelihood for the proposal to be included in the protocol. +Editors are the maintainers of this repo and the managers of this process. As the name implies, their role is purely editorial, and they should advance proposals to stages on the basis of whether specific criteria have been met, rather than based on the likelihood for the proposal to be included in the protocol. Editors do not play a role in decentralized governance, but rather lend their expertise to help proposals get written that are clear, concise, and advocate effectively for their respective ideas. +The Editors' role is not to act as gatekeepers, so proposals can advance up to being accepted by the Council even in case of Editor inactivity. + The current GIP editors are: -- Ariel Barmat -- Brandon Ramirez -- Jannis Pohlmann +- Michael Macaulay +- Pedro Diogo -Over time, as more community members build deep familiarity with the protocol design and associated software, more editors will be added to this list. +Over time, as more community members build deep familiarity with the protocol design and associated software, more editors can be added to this list. # Submitting a Proposal -The GIPs repository is hosted on [Radicle](https://radicle.xyz/), a crypto-native decentralized alternative to Github. Currently, Radicle does not support an issue or Pull Request workflow, although this is being worked on. +The GIPs repository is [hosted on GitHub](https://github.com/graphprotocol/graph-improvement-proposals). + +Proposals can be submitted by forking the repository and creating a Pull Request to include the proposal in Markdown format, following the GIP-0000 template. + +Discussions around proposals should be directed to the [GIPs and Governance](https://forum.thegraph.com/c/governance-gips/) category of The Graph's forum. + +**To avoid conflicts in GIP numbers, proposals should be posted as a Pull Request on GitHub with a GIP number _before_ being posted to the forum**. + +After creating the Pull Request, post a thread in the GIPs and Governance category with a link to the Pull Request. The post should have the same title as the GIP, and include the Abstract and Motivation sections but linking to GitHub for the full GIP text. (Older GIPs may include the full proposal text in the forum post, but this is now discouraged as it is hard to keep the forum and GitHub versions in sync). + +Editors will merge the PR into the main branch of the repo when it meets acceptance criteria, but the PR being merged is not a prerequisite for the community to discuss the GIP, or even for it to be implemented, accepted by the Council and deployed. + +After opening the Pull Request and posting on the forum, your proposal should be updated to have the URL of the forum thread in the "Discussions To" field of your proposal front matter. In this way, anyone viewing the proposal can find the conversation where a given proposal was discussed. + +## Choosing a GIP number + +Authors may attempt to self-assign the next available GIP number when submitting the Pull Request to the GitHub repo and before posting to the forum. When doing so, they should ensure: +- That the GIP number is not used in an existing GIP in the repo, and +- That the GIP number is not used in an open Pull Request in the repo. + +When creating the Pull Request, the title of the Pull Request should begin with the full GIP number (e.g. "GIP-0000"), to make it easier for other contributors to know that the number is taken. + +In case of conflicts, Editors may change the number for a GIP or ask the authors to change it, both in the repo and the forum post. + +If they prefer, authors may also ask the Editors to assign a number rather than self-assigning. + +# After submitting a proposal + +Publishing a GIP does not guarantee inclusion in the protocol. Protocol upgrades are implemented via decentralized governance, while the GIP Process is geared towards surfacing and building legitimacy for valuable protocol upgrades that can be considered in that process. Multiple GIPs may be bundled together into a release and be voted on as a single Graph Governance Proposal (GGP - more on this [below](#getting-a-proposal-accepted-by-the-council)). + +GGPs may also include protocol upgrades that did not go through the GIP Process, such as bugs that were reported as responsible security disclosures, or enhancements that were too minor to justify a full-fledged GIP. + +Once a GIP is published on the GitHub repo and the forum, some time should be left for the community to discuss. Some more complex or controversial proposals may require more time and discussion, while others that are more straightforward may be accepted more quickly, always at the Council's discretion. + +After publishing, the authors are encouraged to present the GIPs in one or many of the relevant community calls, for instance, Indexer Office Hours that happen weekly on Discord, or the monthly core developer calls. To request a speaking slot in one of these calls, you can use [this form](https://thegraph.typeform.com/to/UIKoy6ys) to get in touch with organizers from core dev teams and The Graph Foundation. + +# Implementing a proposal + +Proposal authors are welcome to begin implementing the changes needed for a proposal at any time before or after submitting the proposal. They do so at their own risk, as there is no guarantee that the community and the Council will move forward with the proposal. + +If the author is unable to do the implementation of a GIP, and would like instead for core developers to implement it, this should be expressed in the GIP or the forum discussion, and the author may use [this form](https://thegraph.typeform.com/to/UIKoy6ys) to request core devs for help implementing a GIP. The author may need to present evidence of community support for the proposal, and core devs' may accept or reject the request at their discretion. + +## Proposals requiring off-chain software changes + +For proposals requiring changes in the behavior of off-chain components (e.g. Graph Node, Indexer Agent, Indexer Service), changes must be made as Pull Requests to the corresponding repositories (generally under the [graphprotocol org on GitHub](https://github.com/graphprotocol)). Authors are encouraged to collaborate with core developers (and if necessary, the Technical Advisory Board), to ensure the changes meet the quality criteria for each repository. These changes generally do not require explicit Council approval, unless the behavior of the components changes in a way that requires changes to the [Feature Matrix](https://github.com/graphprotocol/indexer/blob/main/docs/feature-support-matrix.md) or the [Arbitration Charter](./0009-arbitration-charter.md). In particular, Graph Node versions are approved through a GGP. + +If needed, a GIP could propose adoption of a new repository or package, in which case this should be mentioned in the proposal. + +## Proposals requiring smart contract changes + +For proposals that involve changes to protocol smart contracts, the authors are encouraged to work with core devs and the Technical Advisory Board to define a comprehensive plan to ensure the quality and security of the changes. The precise requirements will vary with the complexity of the changes, but generally, authors can expect the following process: + +- **Pull request QA**: Core devs will review pull requests to the contracts repositories and may leave comments to note issues or improve code quality. Authors are encouraged to address these comments to get the code ready for audit. The protocol contracts keep a high standard of quality, including unit test coverage for most of the code, extensive NatSpec comments, and attempting to follow Solidity best practices as much as possible. +- **Audit**: Most changes will require an audit with a vetted auditor. Previous protocol audits have been performed with OpenZeppelin, Consensys Dilligence, Trust Security and 0xMacro. Audit contests in Code4rena have also been used in the past. Other audit firms may be accepted at the discretion of the Technical Advisory Board and Council. Authors can pay for audits at their own expense and risk, or request an audit slot from the Foundation using [this form](https://thegraph.typeform.com/to/UIKoy6ys). Depending on the complexity, some proposals might require more than one audit. The version of the code that is deployed must match the audited commit; any changes must be re-reviewed by the auditors, with few exceptions (for instance, changing event parameters). +- **Test Plan**: Besides unit tests, contract changes must be tested on a testnet. Often, the process involves testing on a "staging" testnet deployment, before deploying to the official testnet once the Council has given a clear signal that the GIP is close to approval. Authors are welcome to write automated scripts to execute the tests on a testnet, but it is generally accepted to document manual testing steps on a spreadsheet or Notion document (a "Test Plan"), and record the results and transaction hashes. The Test Plan should generally cover the main changes from the proposal and the most relevant edge cases. The authors are welcome to collaborate with core devs and the Technical Advisory Board in drafting this plan, and may request help from core devs in running it. +- **Deployment Plan**: Updates to protocol contracts are generally a multi-step process. To reduce the probability of human error, authors and/or core devs must develop a "Deployment Plan", i.e. a document (generally a spreadsheet or Notion page) specifying the transactions that must be run, and any relevant off-chain actions that must be taken to deploy the GIP. Council transactions that can be batched together must be identified as such. + +The following flowchart illustrates the usual process, though some of the steps could run in parallel, in different order, or be skipped, depending on the GIP and its complexity: + +![Flowchart for the Smart Contracts development process](../assets/gip-0001/smart-contracts-process-flowchart.png) + +# Getting a proposal accepted by the Council -In the meantime, all discussions around proposals should be directed to the [GIPs and Governance](https://forum.thegraph.com/c/governance-gips/) category of The Graph's Discourse forum. Post a thread in there that includes the Radicle ID of your copy of the repo, along with the proposal title, and the branch that the proposal can be found on. +After the author has followed the process described above, the proposal has been discussed in relevant calls, and the changes have met the requirements to be ready for deployment, the proposal can advance to the Candidate stage. At this point, the author can request the Council to discuss the proposal for acceptance by filling in [this form](https://thegraph.typeform.com/to/UIKoy6ys) . The Council may rely on the Technical Advisory Board to filter these requests and validate that changes are really ready for deployment, and may invite the authors to a Council meeting to present the proposal. The Council may also request a community Snapshot vote (at this stage, or any earlier stage in the process) to gauge community consensus before making a decision. -In this way, editors will be able to merge your changes into their repos once the proposals meet the respective acceptance criteria and request changes to you via Discourse. +To accept a proposal, the Council will use a Graph Governance Proposal or GGP. GGPs are executed through a vote on [Snapshot](https://snapshot.org/#/council.graphprotocol.eth) were each Council member can vote, and 6 positive votes mean that a proposal was Accepted. -Finally, your proposal should have the URL of the forum thread in the "Discussions To" field of your proposal front matter. In this way, anyone viewing the proposal can find the conversation where a given proposal was discussed. +Once a proposal has been Accepted, the authors, core devs and Technical Advisory Board can work together with the Council to execute the Deployment Plan (if it's a smart contracts change) or any other changes needed to deploy the proposal. # Copyright Waiver diff --git a/gips/0061-improved-gip-process.md b/gips/0061-improved-gip-process.md new file mode 100644 index 0000000..6b7eb57 --- /dev/null +++ b/gips/0061-improved-gip-process.md @@ -0,0 +1,72 @@ +--- +GIP: 0061 +Title: Improvements to the GIP process +Authors: Pablo Carranza Vélez +Created: 2023-09-28 +Updated: 2023-09-28 +Stage: Draft +Discussions-To: Forum +Category: Process +Depends-On: GIP-0001 +Implementations: +--- + +# Abstract + +This GIP proposes changes to the GIP process, designed to simplify the process and clarify the steps to get a GIP implemented and deployed. + +It proposes removing the so far unused concept of GRP (Graph Request for Proposals), and reducing the number of possible stages for a GIP. It also introduces clearer instructions on how to get a GIP audited, tested and discussed by the community and the Council. + +# Motivation + +Since the introduction of the GIP process in GIP-0001, many proposals have been created, published and accepted by the Council. Most of them have been developed by core developers, and we believe the current process can be improved to make it clearer for non-core-developer contributors to propose changes to the protocol, and to understand the steps that are needed to get a proposal accepted and deployed. + +This GIP therefore aims to simplify the process and bring some clarity so that it's easier for people who want to improve The Graph to bring their ideas to the community, and implement and deploy them if they are accepted. + +# High-Level Description + +GIP-0001 has been restructed to better capture the real process that has been occurring when people proposed changes to the protocol. Some small updates have been made, like replacing mentions of Radicle with the GitHub repository, or updating the list of Editors. The full changeset can be seen in the same Pull Request where this GIP is introduced to the repository. + +GIP-0000 has also been edited slightly to reflect the changes proposed here. + +The main changes proposed to GIP-0001 and the process are described below. + +## Clarify the role of the Editors + +We believe it's important that the GIP process is as permissionless as possible. As such, we think it's important to clarify that Editors should not be able, through inactivity, to stop a GIP from advancing through the process. We add some text to the Editors section to clarify this and make it explicit. + +## Remove the GRP category + +To this date, no "Graph Request for Proposals" have been submitted. To simplify the process, we propose removing this category. + +## Simplified Stages + +The Strawperson and Proposal stages have been removed and merged into the Draft stage. In practice, proposals evolve from a simple abstract to a full blown spec, and tend to change throughout the process, and it's hard to draw the line between different stages. Keeping the stage updated in the GIP takes time, so we believe it's simpler to just differentiate between a proposal that is in progress ("Draft"), one that is ready for acceptance/deployment ("Candidate"), and one that has been concluded ("Accepted/Deferred/Withdrawn/Living"). + +## Self-assigning GIP numbers + +In practice, most GIP authors were self-assigning GIP numbers, to not depend on Editor availability as this could leave a GIP without a number for some time (which makes it harder to reference a GIP in public discussion). Here we propose that authors self-assign a GIP number following clear rules, with Editors being able to re-number if needed to avoid conflicts. + +## A clearer process after publishing a GIP + +The process to get a GIP implemented and accepted by the Council needed some clarification. We had added more detail about the quality assurance process for the different kinds of changes, with additional detail for smart contracts changes. + +The changes also make it explicit that implementation of a GIP can happen in parallel to the governance process. + +We also introduce some mechanisms for authors to advance proposals through the process, using an online form (currently being set up on TypeForm) to: +- Request a speaking slot in one of the periodic community calls +- Request an audit slot +- Request help from core devs to implement a GIP or review an implementation +- Ask the Council to discuss a GIP for acceptance + +Hopefully this form opens a direct way for authors to advance a GIP through the process, and the additional instructions provide more clarity as to what needs to happen before a GIP is ready for deployment. + +# Risks and Security Considerations + +The use of a form to advance proposals through the process, or request audits and other activities, involves a few risks: +- Spam: if the volume of invalid/nonsensical form submissions is too high, it could make it impractical for the Council and core dev contributors filtering them for legitimate submissions to be noticed. If this happens, further changes to the process would be needed to add more validation before sending a submission. +- Single point of failure: if the forms provider goes down, or for whatever reason someone is unable to get the form submission delivered, this could impede them from advancing the proposal or putting forward their request. To avoid the single point of failure, authors are encouraged to use the forum, Discord, or any other public channel to communicate with core devs or The Foundation if they suspect the message was not received. + +# Copyright Waiver + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).