# Platform Design Proposal Process

This document describes the kind of code changes that require an accepted design proposal, the process for creating,
reviewing, and merging platform design proposals, and how accepted proposals can be updated.

The purpose of the design proposal process is to increase the quality of designs for larger and impactful changes
before time is invested in the code. Higher quality designs reduce misdirected time investments and performance testing
costs.

The status of all design proposals can be viewed
at [Platform Design Proposals](https://github.com/orgs/hashgraph/projects/73/views/1) project board.

---

## Design Proposal Criteria

If code changes fall into one of the categories below, then an accepted design proposal is required before the code can
merge.

1. Publicly available inputs/outputs/API including disk
2. Core behaviors
3. Any non-trivial change that is expected or is likely to impact performance (some judgement must be applied)
4. Changes to interactions between major systems or teams (platform, services, mirror node, devops, etc.)
5. Module Structure & Repos

---

## Design Proposal Process Flow

![](designProposalFlow.drawio.svg)

## Creating A Proposal

All proposals have an owner who is responsible for taking it through the process to completion. Proposals must be
presented in the form of a PR containing the proposal in a subdirectory of `platform-sdk/docs/proposals/`. Proposals may
contain diagrams and supporting materials. Diagrams must be created with DrawIO and exported in SVG format. All content
must be editable (i.e. no images). The only exception is for images that are generated by code, like the wiring diagram.
These may be drawn on to indicate the intended changes and included as an image.

If any APIs were developed in code as part of the design process, it may be included in the proposal directly or in the
subdirectory of the proposal, but not merged into the source code of the platform.

While in the draft phase the proposal may be updated and modified as needed. It is best practice to solicit review from
stakeholders to surface any potential change requests while the proposal is in the draft phase. All grammar and spelling
errors should be caught during this phase.

### Creating a Draft Proposal

1. Create a new branch for the proposal.
2. Create a subdirectory of `platform-sdk/docs/proposals/` with the name of the proposal.
3. Copy the template `template.md` into the subdirectory and give it an appropriate name.
4. Fill out the template with the details of the proposal, removing any irrelevant sections or adding new sections as
   needed. Diagrams and other files may be included in the proposal directory and linked from the proposal.
5. Create a draft PR with the proposal documents.
6. Put the draft PR in the [Platform Design Proposals](https://github.com/orgs/hashgraph/projects/73/views/1) board in
   the `Draft` status.
7. Solicit feedback from stakeholders and other design collaborators.
8. Iterate on the proposal until it is ready for voting. All open comments should be resolved while in the draft stage.

### Submitting a Proposal for Voting

When the proposal is ready for voting, take the following steps:

1. Ensure all comments are resolved.
2. Mark the PR as `Ready for Review`
3. Update the status of the PR in
   the [Platform Design Proposals](https://github.com/orgs/hashgraph/projects/73/views/1) board to `Voting`

Requests for immaterial changes can be addressed by pushing additional commits to the existing proposal
PR while in `Voting`. Examples of immaterial changes are spelling or grammar errors, wording changes that do not modify
meaning or intent, and formatting changes. Examples of material changes include changes to behaviors or APIs, addition
or removal of diagrams, etc. If any material changes are needed, the PR must be closed and moved to the `Superseded`
status. A new proposal PR is prepared and voting is restarted. The `Superseded` PR must reference the new PR to
create an auditable history.

---

## Voting on A Proposal

Votes follow the [Apache Voting](https://www.apache.org/foundation/voting.html#expressing-votes-1-0-1-and-fractions)
scheme. Votes range between -1 to -0, +0 to +1 with the following semantics:

* -1: is a veto.
* -0 >= x > -1: is a vote generally against the proposal.
* +0 <= x < +1: is a vote generally in favor of the proposal.
* +1: is a vote in favor of the proposal.

The magnitude of the numeric value of the vote indicates the strength of the sentiment behind the vote.

+1 votes are expressed by approving the PR. -1 votes are expressed by "Requesting Changes" on the PR and
must be accompanied by a comment explaining the reason for the veto. Votes greater than -1 but less than +1 are cast
using comments in the "Conversations" tab, not using inline comments.

---

## Acceptance of A Proposal

A proposal becomes `Accepted` when the following criteria have been fulfilled:

1. The proposal has been in the Voting state for at least 3 business days. Business days are defined as Monday through
   Friday.
2. The proposal must have at least three +1 votes from platform code owners.
3. The proposal must not have any -1 votes from platform code owners or architects.

Once accepted, the proposal is merged and moved to the `Accepted` status in
the [Platform Design Proposals](https://github.com/orgs/hashgraph/projects/73/views/1) board. Once this is complete,
implementation of the proposal may begin.

---

## Superseding A Proposal

A proposal is superseded by a new proposal when material changes are needed once voting has started. The old proposal
must contain link to the new proposal indicating that has been superseded. After the proposal has been updated, the PR's
status in the [Platform Design Proposals](https://github.com/orgs/hashgraph/projects/73/views/1) project should be
changed to `Superseded` and closed.

---

## Withdrawing A Proposal

A proposal may be withdrawn after voting occurs. The proposal must contain a comment with a reason for the withdrawal.
After the proposal has been updated, the PR's status in
the [Platform Design Proposals](https://github.com/orgs/hashgraph/projects/73/views/1) project should be changed
to `Withdrawn` and closed.

---

## Delivery of A Proposal

Once an accepted proposal has been completely implemented, tested, the code merged into `develop`, and the feature is
planned to be enabled for production, the proposal's content should be merged with the documentation of the platform
in `platform-sdk/docs` (or other relevant location such as `module-info.java`), as applicable, and removed
from `platform-sdk/docs/proposals`. Once the feature is live on mainnet, the status of the proposal PR in the proposal
project should be changed to `Delivered`.

---

## Design Proposal State Machine

![](designProposalStateMachine.drawio.svg)

## Modifying an Accepted Design Proposal

It is common that during implementation of a design, something is discovered that requires a material change to the
documented design. When this occurs, the design proposal must be updated via a modification proposal. Keeping the design
up to date ensures that the documentation remains up to date and always reflects the intended and actual design. It also
provides an opportunity for those who voted on and approved the accepted proposal to review the changes and weigh in on
the resulting design. Modification proposals follow the same process and flow as normal design proposals.

If a non-material change needs to be made, the proposal document can be updated outside the proposal process as part of
a normal PR. Examples of non-material changes are:

- correcting a typo or grammar mistake
- correcting labels in a diagram
- updating the name of something which does not affect the intent of the design

If you are unsure if a certain change is material or not, please
contact [@poulok](https://github.com/poulok), [@a-saksena](https://github.com/a-saksena),
or [@rbair](https://github.com/rbair).
