Skip to content

Latest commit

 

History

History
79 lines (60 loc) · 3.45 KB

development.md

File metadata and controls

79 lines (60 loc) · 3.45 KB

Development

How we work on Wafersmith. Setting up a machine is in getting-started.md; the rules for contributions are in CONTRIBUTING.md.

Workflow

  1. Branch from main: feature/<topic>, fix/<topic> or docs/<topic>.
  2. Make the change with its tests and its documentation (user guide, API reference, configuration, CHANGELOG under "Unreleased").
  3. Run the checks below locally.
  4. 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.

Checks (what CI runs)

.github/workflows/ci.yml runs on every push to main and every pull request:

cargo fmt --all --check
cargo clippy --workspace --all-targets --locked -- -D warnings
DATABASE_URL=postgres://wafer:wafer@127.0.0.1:5442/wafersmith cargo test --workspace --locked
pnpm --filter @wafersmith/web typecheck && pnpm --filter @wafersmith/web build

CI 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.

Conventions

  • Rust: edition 2024, rustfmt.toml (max width 120), no clippy warnings. Errors that reach people are written in plain language (ApiError messages are shown in the UI).
  • TypeScript: strict mode; no unused code. API types live in apps/web/src/api.ts and 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 Wafersmith header, and are never edited by hand.
  • AI calls use strict tool schemas; the server validates everything the model returns and records usage with spend::record against the per-person budget.
  • Security: read the trust boundaries in architecture.md; untrusted Verilog is simulated through wafer_sim::on_big_stack and gate::with_slot, and flow outputs are read with wafer_jobs::read_inside.

Database migrations

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.

Tests

  • 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 by tests/common, and a mock Messages API for the AI features (no network, no cost).
  • Simulator conformance: crates/wafer-sim/tests/conformance/*.v must print exactly what Icarus Verilog prints (scripts/gen-sim-expected.sh regenerates the references).
  • Design evals: tests/evals.rs checks the eval task references; the evals themselves run against a live API and the model, by hand (evals.md).

Adding a feature: checklist

  • 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.md under "Unreleased"
  • Tried in the app, end to end