rigless 0.0.2

Virtual hardware-in-the-loop runtime: run unmodified firmware on an emulated MCU with every peripheral, chip model, and unit of virtual time in Rust; needs the rigless-sidecar package from rigless-labs/qemu
Documentation
# Contributing to Rigless

Thanks for your interest in Rigless. Whether you are fixing a typo, modeling a peripheral, or bringing up a whole board, we are glad you are here. Rigless is one crate in one tree: the runtime, the SoCs, the machines, the generator, and the command line all live here, and one merge request can change any of them together. This guide covers how to get set up, how we work, and where to ask when something is unclear.

## Ways to help

- **Report a bug.** Open an issue with what you ran, what you expected, and what happened. The firmware image and the `rigless run` command line that reproduce it are gold.
- **Improve the docs.** If something confused you, it will confuse the next person too. Small doc fixes are some of the most valuable merge requests we get.
- **Model a peripheral or a chip.** Every MCU block and sensor chip that gets modeled lets more firmware run unmodified. Each model's module opens with a table of what it covers, and an instance with no model bound is register-only.
- **Add an SoC or a machine.** An SoC is a vendor's SVD and the binding written against it; a machine is a module returning a `Machine` with a target for each MCU on the board. They live in `src/soc` and `src/machine`, and the README walks through adding one.
- **Ask questions.** Open an issue with the question label. There are no dumb questions about emulators; they are full of surprises.

## Getting set up

You need a recent stable Rust; `rust-toolchain.toml` pins the exact version and rustup picks it up automatically. A few cargo tools make the checks faster to run locally:

```sh
cargo install cargo-binstall
cargo binstall cargo-nextest cargo-deny cargo-machete
```

Then build and run the tests:

```sh
cargo build
cargo nextest run --all-features
```

Running firmware needs the QEMU sidecar, which is built from our branch of the QEMU repository; the README says where to get a prebuilt one and which release pairs with which. The tests that run firmware fail rather than skip without it.

## Finding something to work on

Issues labeled `good first issue` are scoped so you can finish one in an afternoon. If you want to take on something larger, say so on the issue first so we can talk through the approach together and nobody duplicates work. For anything that touches the sidecar protocol, virtual time, or the shape of a machine, an issue discussion before code saves everyone a rewrite.

## Making a change

1. Fork the repository and create a branch for your change.
2. Keep the change focused. One fix or one feature per merge request is much easier to review, and gets merged faster.
3. Add a test for behavior you add or fix. If you are not sure what to test, ask on the issue and we will help.
4. Run the same checks CI runs, so there are no surprises:

   ```sh
   cargo fmt --all
   cargo clippy --all-targets --all-features -- -D warnings
   cargo nextest run --all-features
   cargo test --doc --all-features
   cargo deny check
   ```

   The tests that run firmware need `rigless-sidecar` on `PATH`, and they fail rather than skip when it is missing, naming what to install. CI runs those four and more: the licence headers, a build with the default features off so the feature gates cannot rot, the docs with warnings denied, `cargo machete`, the loom model and Miri over the shared-memory code, and a publish dry run.

5. Open a merge request. Describe what changed and why, and mention the issue it relates to. If it is not ready yet, mark it as a draft; early feedback is welcome.

We aim to respond to every merge request within a few days. Reviews are conversations: if a comment is unclear, ask, and if you disagree, say so. We are all trying to get to the best version of the change.

## A few things about the code

- **Determinism is the product.** The same firmware, plant, and seed must produce the same trace every time. That means no wall-clock time, no unseeded randomness, and no iteration over unordered collections in the emulation path; a machine with several MCUs steps them in the machine's order every round, so that is fixed too. Clippy is configured to catch the common cases, and reviewers will point out the rest kindly.
- **Comments explain why.** The code says what it does; a comment earns its place by saying why, citing a manual's section, or noting a deliberate shortcut. Public items get a one-line doc comment, private ones a plain `//` where they need one at all.
- **Small and boring wins.** If the standard library or a crate we already depend on does the job, use it. New dependencies are welcome when they carry their weight; mention them in the merge request so we can check the license together.
- **Every source file starts with the two-line license header** you will see at the top of any file here. CI checks for it, so copy it into new files.

## Commit messages

A short imperative sentence that says what the commit does, such as `Add the SPI status flag model`, is all we need. The merge request description is the place for the why and the details.

## License

Rigless is licensed under the Apache License 2.0. By submitting a contribution you agree that it is licensed under the same terms, as section 5 of the license describes. There is no paperwork to sign.

## Security

If you find a security problem, please email wezley.sherman@riglesslabs.com instead of opening a public issue, and we will work with you on a fix and credit.

## Community

Be kind, assume good intent, and remember there is a person on the other side of every comment. We want Rigless to be a place where someone modeling their first peripheral feels as welcome as someone who has shipped flight software for a decade.