How we work on Wafersmith. Setting up a machine is in getting-started.md; the rules for contributions are in CONTRIBUTING.md.
- Branch from
main:feature/<topic>,fix/<topic>ordocs/<topic>. - Make the change with its tests and its documentation (user guide, API reference, configuration, CHANGELOG under "Unreleased").
- Run the checks below locally.
- Open a pull request using the template; CI must pass and a maintainer reviews and merges.
main is always releasable. Commit messages have a short imperative subject (≤ 72 characters),
a blank line, and a body that says what changed and why.
.github/workflows/ci.yml runs on every push to main and every pull request:
cargo fmt --all --checkcargo clippy --workspace --all-targets --locked -- -D warningsDATABASE_URL=postgres://wafer:wafer@127.0.0.1:5442/wafersmith cargo test --workspace --lockedpnpm --filter @wafersmith/web typecheck && pnpm --filter @wafersmith/web buildCI provides Postgres and Verible, and builds the WebAssembly modules. Tests that run LibreLane in
Docker are opt-in (cargo test -p wafer-jobs --test docker -- --ignored) and stay local.
- Rust: edition 2024,
rustfmt.toml(max width 120), no clippy warnings. Errors that reach people are written in plain language (ApiErrormessages are shown in the UI). - TypeScript: strict mode; no unused code. API types live in
apps/web/src/api.tsand mirror the server's JSON. - Comments explain why, not what; module headers (
//!) say what a module is for. - Generated files (example testbenches, chip top level, adapters) come from deterministic code,
carry a
// Generated by Wafersmithheader, and are never edited by hand. - AI calls use strict tool schemas; the server validates everything the model returns and
records usage with
spend::recordagainst the per-person budget. - Security: read the trust boundaries in architecture.md; untrusted Verilog
is simulated through
wafer_sim::on_big_stackandgate::with_slot, and flow outputs are read withwafer_jobs::read_inside.
Add a new file crates/wafer-api/migrations/NNNN_<what>.sql (next number, never edit an applied
one). It runs when the API starts and in every sqlx::test.
- Unit tests next to the code (
#[cfg(test)] mod tests), for pure logic: spec compilation, block checks, licence rules, gate verdicts. - API tests in
crates/wafer-api/tests/: a real Postgres per test (sqlx::test), tokens signed bytests/common, and a mock Messages API for the AI features (no network, no cost). - Simulator conformance:
crates/wafer-sim/tests/conformance/*.vmust print exactly what Icarus Verilog prints (scripts/gen-sim-expected.shregenerates the references). - Design evals:
tests/evals.rschecks the eval task references; the evals themselves run against a live API and the model, by hand (evals.md).
- Server code with plain-language errors, role checks (
authorize) and limits where it costs resources - Unit and API tests
- Web UI, typechecked
- Documentation: the user guide page, api.md, configuration.md if
it adds a variable, and
CHANGELOG.mdunder "Unreleased" - Tried in the app, end to end