CONTRIBUTING.md
Contributing to strata
Design authority lives in ../proposal/ — start with 01-design-principles.md
(P-1..P-11) and the decisions register ../proposal/decisions.md (D-001–D-080).
Code that contradicts a settled decision is wrong even if it works.
Promotion rule: probes → crates
Probe code (../probes/) is rewritten with its tests carried, never
copied. A promotion PR states which probe it promotes; the probe's test
corpus and gap ledger come along as the crate's test suite. Probe code itself
is a design artifact, not a dependency.
Invariants that gate merges
- D-053 fuzz suites: fmt/parse invariants are CI-fuzzed from day one —
idempotence (
fmt∘fmt = fmt), lossless round-trip (text(tree) == input, including comment count and anchors), parse-error input returned untouched, cross-platform determinism. - No-panic: tool crates must not panic on any input; malformed input yields
P-9 diagnostics (
strata-diag/0, seedocs/diagnostics.md), never a crash. - Determinism (P-6): no wall clock, no env reads, no iteration-order
nondeterminism, no HashMap ordering in any output path.
cargo xtask ciruns the test suite twice and byte-compares generated artifacts; a diff fails the build.
Run the full gate locally before pushing:
| 1 | cargo xtask ci # whole workspace |
| 2 | cargo xtask ci -p strata-cli # scoped, while sibling crates are mid-build |
| 3 | cargo xtask circt # source → compiler → pinned external CIRCT gate |
(fmt-check → clippy -D warnings → tests ×2 + artifact byte-compare.)
The CIRCT contract compiles the Counter source fixture through strata compile
before passing the generated MLIR through the pinned full CIRCT bundle and
Icarus Verilog. Set CIRCT_BIN to the bundle's bin directory, or put its
tools on PATH; see tests/circt/README.md. Ordinary CI does not assume this
external toolchain is installed. Set STRATA_CI_CIRCT=1 to explicitly include
the fail-closed CIRCT contract in cargo xtask ci; the CI log states when it
was not requested.
Spec divergences
If implementation forces a divergence from ../proposal/, do not silently
adapt: record it in a SPEC-ISSUES.md at the crate root (what diverged, why,
which proposal section/decision it touches). These files feed back into
../proposal/ — a divergence is resolved either by fixing the code or by a
decisions-register event, never by drift.