Contributing¶
Developer guide for working on irradiate.
Building and testing¶
# Build
cargo build
# Check + lint (must pass before every commit)
cargo check && cargo clippy -- -D warnings
# Run unit tests
cargo test
# Run e2e tests
bash tests/e2e.sh
# Full verification (run before every commit)
cargo check && cargo clippy -- -D warnings && cargo test && bash tests/e2e.sh
Python environment¶
The integration tests and e2e tests need Python 3.10+ with pytest. Set up the fixture venvs with:
cd tests/fixtures/simple_project && uv venv --python 3.12 && uv pip install pytest
cd tests/fixtures/regex_project && uv venv --python 3.12 && uv pip install pytest
Git hooks¶
Install pre-commit hooks:
Runs cargo fmt --check, cargo clippy -- -D warnings, and cargo test before every commit.
Analysis tools¶
# Module dependency graph — outputs graphviz dot format
# Requires: cargo install cargo-modules
cargo modules dependencies --lib --no-fns --no-traits --no-types
# Module tree — shows the crate structure
cargo modules structure --lib
# Render docs locally
# Requires: pip install mkdocs-material mkdocs-minify-plugin
uvx --with mkdocs-material --with mkdocs-minify-plugin mkdocs serve
Project structure¶
irradiate/
├── Cargo.toml
├── src/
│ ├── main.rs # binary entrypoint (clap CLI)
│ ├── lib.rs # library root
│ ├── pipeline.rs # pipeline conductor (phases 1-5)
│ ├── mutation.rs # shared types (Mutation, FunctionMutations)
│ ├── tree_sitter_mutation.rs # mutation engine (27 operators)
│ ├── regex_mutation.rs # regex pattern mutation operators
│ ├── codegen.rs # trampolined source file generation
│ ├── trampoline.rs # trampoline code generation
│ ├── orchestrator.rs # tokio worker pool manager
│ ├── cache.rs # content-addressable result cache
│ ├── stats.rs # coverage + timing collection
│ ├── report.rs # output: terminal, JSON, HTML, GitHub
│ ├── protocol.rs # IPC message types
│ ├── config.rs # pyproject.toml parsing
│ ├── git_diff.rs # incremental mode (--diff)
│ ├── harness.rs # extract embedded Python harness
│ ├── progress.rs # terminal progress bar
│ └── trace.rs # chrome tracing output
├── harness/ # Python harness (embedded via include_str!)
│ ├── __init__.py # active_mutant global, hit recording
│ ├── worker.py # pytest worker process (fork-per-mutant)
│ ├── stats_plugin.py # pytest plugin for stats collection
│ └── import_hook.py # MutantFinder import hook
├── tests/
│ ├── mutation_tests.rs # 282 mutation operator tests
│ ├── proptest_mutation.rs # property-based mutation tests
│ ├── worker_pool_integration.rs
│ ├── fixtures/ # minimal Python projects for testing
│ └── e2e.sh # end-to-end test script
├── vendor/
│ └── mutmut/ # reference implementation (read-only)
└── docs/ # mkdocs site source
Module layering¶
The dependency graph is a clean DAG with four layers. Each layer only imports from layers below it.
Layer 0 (types): protocol, mutation, config
Layer 1 (engines): tree_sitter_mutation, regex_mutation, trampoline, cache, stats, git_diff, harness
Layer 2 (subsystems): codegen, orchestrator, report, progress, trace
Layer 3 (conductor): pipeline
Layer 4 (entry): main
See the Architecture page for the full dependency graph.
Commit guidelines¶
- Run
cargo check && cargo clippy -- -D warnings && cargo testbefore every commit - One logical change per commit
- Keep commits small and incremental
Pre-release checklist¶
- Tests pass:
cargo check && cargo clippy -- -D warnings && cargo test && bash tests/e2e.sh - Version bump: Update
versioninCargo.toml(pyproject.toml reads it via maturin) - CHANGELOG: Add entry with date, version, and what changed. Write for users.
- Docs current: Skim
docs/for stale content. New flags or changed defaults must be documented. - README check: Example output, feature list, comparison table still accurate?
- Smoke test:
cargo build --release && cd ~/projects/hive && irradiate run --sample 0.1 - Git state clean: No uncommitted changes.
- Tag + push:
git tag v0.X.Y && git push && git push --tags
Reference: mutmut naming conventions¶
irradiate follows mutmut's naming loosely:
- Top-level function
foo()→ mangled asx_foo - Class method
Class.foo()→ mangled asxǁClassǁfoo(Unicode separatorǁU+01C1) - Mutant variants:
x_foo__irradiate_orig,x_foo__irradiate_1,x_foo__irradiate_2, ... - Mutant keys:
module.x_foo__irradiate_1 - Metadata files:
mutants/path/to/file.py.meta - Runtime control:
irradiate_harness.active_mutantglobal