> For the complete documentation index, see [llms.txt](https://engineering.umh.app/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://engineering.umh.app/engineering/development-process/how-to-build.md).

# 2. How to build

## The rollout plan

**Before the** [**bet**](/engineering/development-process/how-to-decide-what-to-build.md#the-bet)**, the** [**Product Engineer**](/engineering/product-engineer.md) **fills in the rollout plan.** It has four parts:

* the impact, adoption and stability targets that say when the work is done,
* which customers will use the work and in which week,
* a box for each of the [four stages](/engineering/development-process/how-to-ship.md#stages-and-the-feature-flag) of the feature flag,
* the [monitoring ticket](/engineering/development-process/how-to-build/tickets/monitoring.md) that becomes the feature's home after the rollout.

To find customers, the Product Engineer opens a customer validation ticket for the [Product Manager](/product/product-manager.md). It uses the Customer Validation template in Linear. The Product Manager passes it to the [Value Engineers](/culture/working-with-the-rest-of-umh.md#value-engineer) and [Account Executives](/culture/working-with-the-rest-of-umh.md#account-executive). The ticket says what the feature changes for the customer and what feedback we want back.

[The rollout ticket](/engineering/development-process/how-to-build/tickets/rollout.md) says what each target needs and has the template.

## Before you write code

**Before the bet, agree on the approach with the** [**Code Owners**](/engineering/product-engineer/code-owner.md) **of the parts you will change.** A change that touches several parts has several Code Owners. If a Code Owner first sees the approach in the pull request and would have taken a different one, the discussion turns into "but it is already like this" or "I already coded it".

**Every change has a spec, and at its smallest it is the first three parts of the** [**PR template**](https://github.com/united-manufacturing-hub/united-manufacturing-hub/blob/staging/.github/PULL_REQUEST_TEMPLATE.md)**: the problem, what we are shipping and what we are not shipping.** You write those anyway.

Work with a rollout ticket has the spec as a Linear document linked from the ticket. Use whatever format you like. We are still finding out which works best. Name any [preparatory refactoring](/engineering/development-process/how-to-build/coding-standards/code-quality/simplicity.md#prepare-clean-abstractions) in it.

**A change that needs a** [**threat model**](/engineering/development-process/how-to-build/coding-standards/architecture/security.md#threat-model) **gets it with the spec.**

**A spike is optional.** A spike is a throwaway first version of the change. It shows whether the approach is technically feasible, which [abstractions](/engineering/development-process/how-to-build/coding-standards/code-quality/abstractions.md) and terms the code already has, and where the existing code is too [complex](/engineering/development-process/how-to-build/coding-standards/code-quality/simplicity.md) for the change. Use what you learn for the spec. Then throw the spike away.

### Two-way doors

**Move fast on two-way doors.** In [Amazon's 2015 letter to shareholders](https://www.sec.gov/Archives/edgar/data/1018724/000119312516530910/d168744dex991.htm), Jeff Bezos calls them decisions that are "changeable, reversible". Most changes are two-way doors. A new screen in the [Management Console](https://docs.umh.app/management-console) is one example. If it goes wrong, we ship a fix and nothing is lost.

### One-way doors

**A change that can lose customer data or stop a production line is a one-way door.** In the same letter, Bezos calls such decisions "irreversible or nearly irreversible".

Changes to the data infrastructure are one-way doors. The data infrastructure is everything that moves or stores the customer's data, such as [benthos-umh](https://docs.umh.app/benthos-umh) and [Redpanda](https://redpanda.com) in [umh-core](https://docs.umh.app/). Changes to anything that can stop the data infrastructure from running are one-way doors too. One example is the config worker in umh-core. It can refuse to start umh-core.

If a customer loses data in an upgrade, they notice it immediately. No update can bring that data back. To keep such a loss as small as possible, umh-core stores data in Redpanda for a retention period before forwarding it.

Because of this, a one-way door gets extra care. When you talk to the Code Owners, also agree which of the two your change is. Ideally you already know which one it is. The Code Owner then double-checks your answer.

For a one-way door, consider [testing beyond regression tests](/engineering/development-process/how-to-build/testing.md#beyond-regression-tests): mutation testing, fault injection, property-based testing or formal verification.

## While you build

**Start from the** [**spec**](#before-you-write-code)**.** Where there is none, write it before you write code.

**Every change in behaviour comes with a test that goes red without the change.** You are responsible for every test in your pull request, whoever or whatever wrote it. [Testing](/engineering/development-process/how-to-build/testing.md) says which cases your tests cover. Follow our [Coding standards](/engineering/development-process/how-to-build/coding-standards.md), for example [Error management](/engineering/development-process/how-to-build/coding-standards/architecture/error-management.md) and [FSMv2 workers](/engineering/development-process/how-to-build/coding-standards/architecture/fsmv2-workers.md).

A [refactoring](/engineering/development-process/how-to-build/coding-standards/code-quality/simplicity.md#prepare-clean-abstractions) needs no new test that goes red. The existing tests stay green. Where a refactoring changes a signature, update the tests that call it, but not what they check. If no test covers the code yet, first add one that passes before and after the refactoring.

## The pull request

**Every pull request follows our** [**PR template**](https://github.com/united-manufacturing-hub/united-manufacturing-hub/blob/staging/.github/PULL_REQUEST_TEMPLATE.md)**.** The template has four parts: the problem, what we are shipping, what we are not shipping, and confidence. Confidence is optional. A pull request stays in draft until it is ready for review. [Readability](/engineering/development-process/how-to-build/coding-standards/code-quality/readability.md) applies to the PR description as much as to the code.

**Before you request a review, check that the pull request carries its** [**changelog**](/engineering/development-process/how-to-ship/changelog.md) **entry**, written as that page describes. Where there is no entry to write, set the repository's changelog-waiver label and say why in the pull request.

Under Confidence, write down how you got confident that the change works, and how the reviewer can too. That can be a test that went red first, a screenshot, a recording, a Storybook story, a report with numbers from before and after, or a screen share. Because a [Product Owner](/engineering/product-engineer/product-owner.md) mostly needs to see what the [user](/product/who-we-build-for.md#our-users) will see, a screenshot, a recording or a Storybook story fits them best. Write this part yourself, without an LLM. It describes how you got confident.

### Stacked pull requests

**Split larger changes into** [**stacked pull requests**](https://docs.github.com/en/pull-requests/get-started/about-stacked-prs)**.** A part with its own Code Owner or Product Owner gets its own pull request. That way each reviewer gets only the changes that are theirs. Small pull requests also get reviewed faster.

A bug you find while building gets its own pull request at the bottom of the stack. Then the fix can merge and be released before the feature that sits on top of it. If the fix sat on top instead, the reviewers of the feature pull requests below it would review code that still has the bug. That can lead to confusing review comments.

A refactoring, such as a preparatory refactoring, also gets its own pull request at the bottom of the stack. Kent Beck calls refactoring and adding behaviour [two hats](https://martinfowler.com/articles/preparatory-refactoring-example.html) that you wear one at a time. The reviewer of the refactoring only checks that the behaviour did not change. The reviewer of the feature sees only the new behaviour. A refactoring of a [one-way door](#one-way-doors) is still a one-way door.

Each pull request goes to review when it is ready. The reviewer can still read the whole stack to see the full feature. Each pull request must pass CI and be safe to release on its own. We release many small changes. [How to ship](/engineering/development-process/how-to-ship.md) explains how.

## Code review

**Before anyone else reviews your pull request, Claude reviews it, and before the merge a person other than you approves it.** [Code review](/engineering/development-process/how-to-build/code-review.md) says who reviews, what they check and how each review thread ends.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://engineering.umh.app/engineering/development-process/how-to-build.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
