Thank you for your interest in contributing to Bloodhound! This document provides guidelines and instructions for contributing.
Please be respectful and constructive in all interactions. We welcome contributors of all backgrounds and experience levels.
- Rust 1.70+ (stable)
- Docker (for integration tests)
- Git
# Clone the repository
git clone https://github.com/nerdsane/bloodhound.git
cd bloodhound
# Build the project
cargo build
# Run tests
cargo test
# Run with verbose output
cargo run -- --verbose run --compose examples/simple/docker-compose.yml --seed 42bloodhound/
├── src/
│ ├── main.rs # CLI entry point
│ ├── lib.rs # Library exports
│ ├── error.rs # Typed error system (SimulationError, ActorError)
│ ├── actor/ # Actor-based simulation architecture
│ │ ├── mod.rs # Actor trait and infrastructure
│ │ ├── time.rs # TimeActor (virtual clock)
│ │ ├── fault.rs # FaultActor (fault scheduling/injection)
│ │ ├── events.rs # EventCollectorActor (trace recording)
│ │ ├── vm.rs # VmActor (wraps Vm, lifecycle, faults)
│ │ └── workload.rs # WorkloadActor (operation generation)
│ ├── buggify/ # BUGGIFY fault injection macros
│ │ └── mod.rs # Deterministic probabilistic fault injection
│ ├── tigerstyle/ # TigerStyle assertion macros
│ │ └── mod.rs # assert_precondition!, assert_postcondition!, etc.
│ ├── harness/ # Test harness infrastructure
│ │ └── mod.rs # ScenarioBuilder for deterministic tests
│ ├── hypervisor/ # VM lifecycle and determinism control
│ │ ├── vm.rs # VM management
│ │ ├── time.rs # Virtual time system
│ │ ├── snapshot.rs # State snapshots
│ │ ├── cow.rs # Copy-on-write storage
│ │ └── qemu/ # QEMU integration
│ ├── fault/ # Fault injection
│ │ ├── network.rs # Network faults
│ │ ├── disk.rs # Disk faults
│ │ └── process.rs # Process faults
│ ├── explore/ # State space exploration
│ │ ├── explorer.rs # Basic explorer
│ │ ├── multiverse.rs # Full multiverse explorer
│ │ ├── coverage.rs # Coverage tracking
│ │ └── property.rs # Property checking
│ ├── container/ # Docker/container integration
│ │ ├── compose.rs # docker-compose parsing
│ │ ├── translate.rs # Container to VM translation
│ │ └── orchestrator.rs
│ ├── debug/ # Time-travel debugging
│ │ ├── trace.rs # Execution traces
│ │ ├── replay.rs # Replay engine
│ │ ├── gdb.rs # GDB protocol
│ │ └── debugger.rs # Main debugger
│ ├── simulation/ # Simulation runner
│ │ ├── runner.rs # Async simulation loop
│ │ └── coordinator.rs # Actor-based SimulationCoordinator
│ ├── workload/ # Workload generation
│ │ └── http.rs # HTTP workload driver
│ └── config.rs # Configuration parsing
├── benches/ # Benchmarks
├── examples/ # Example projects
├── tests/
│ ├── regression_harness.rs # Deterministic scenario tests
│ └── actor_vm_integration.rs # VM actor integration tests
└── docs/ # Documentation
master- Main development and release branch- Feature branches:
feature/description - Bug fixes:
fix/description
- Fork the repository
- Create a feature branch from
develop - Make your changes
- Add tests for new functionality
- Ensure all tests pass:
cargo test - Ensure code is formatted:
cargo fmt - Ensure no clippy warnings:
cargo clippy - Submit a pull request
Follow conventional commits:
type(scope): description
[optional body]
[optional footer]
Types:
feat: New featurefix: Bug fixdocs: Documentation changestest: Adding/updating testsrefactor: Code refactoringperf: Performance improvementchore: Build/tooling changes
Example:
feat(explore): add coverage-guided frontier prioritization
Implements weighted priority calculation for state exploration
that considers coverage, depth, and recency.
# Run all tests
cargo test
# Run specific test
cargo test test_name
# Run tests with output
cargo test -- --nocapture# Run all benchmarks
cargo bench
# Run specific benchmark
cargo bench bench_nameIntegration tests require Docker and are marked #[ignore]:
# Run integration tests
cargo test -- --ignored- Document all public items with
///doc comments - Include examples where helpful
- Use
#[doc(hidden)]for internal items that must be public
Update the README when:
- Adding new features
- Changing CLI interface
- Modifying configuration format
- Title: Clear, descriptive title
- Description: Explain what and why
- Testing: Describe how to test changes
- Breaking Changes: Note any breaking changes
- At least one approval required
- CI must pass
- No merge conflicts
Releases follow semantic versioning (MAJOR.MINOR.PATCH):
- MAJOR: Breaking changes
- MINOR: New features (backward compatible)
- PATCH: Bug fixes
To release:
- Update version in
Cargo.toml - Update CHANGELOG.md
- Create git tag:
git tag v0.x.y - Push tag:
git push origin v0.x.y - CI will build and publish release
- Open an issue for bugs or features
- Discussions for questions and ideas
- Tag maintainers for urgent items
- Cross-platform (Linux, macOS, Windows)
- TCG mode provides full CPU control
- Well-documented internals
- Native snapshot support
- Efficient snapshot storage
- Fast state forking for exploration
- Minimal disk I/O
- Eliminates CPU scheduling non-determinism
- Simplifies state capture
- Required for true determinism
We follow TigerStyle principles. See CLAUDE.md for full details.
-
Use assertion macros for pre/postconditions and invariants:
use crate::tigerstyle::{assert_precondition, assert_postcondition}; fn transfer(from: &mut Account, to: &mut Account, amount: u64) -> Result<()> { assert_precondition!(amount > 0, "amount must be positive"); // ... implementation }
-
Use typed errors (
SimulationError,ActorError), not string errors -
Prefer early returns over deep nesting
-
Use BUGGIFY for deterministic fault injection in tests:
if buggify!("disk_write_fail", 0.01) { return Err(DiskError::WriteFailed); }
-
Watch for non-determinism: Use
BTreeMapoverHashMap, seeded RNG, virtual time
- Use
cargo benchbefore and after performance changes - Minimize allocations in hot paths
- Prefer stack allocation where possible
- Use appropriate data structures (HashMap vs BTreeMap)
- Never include secrets in commits
- Report security issues privately
- Follow secure coding practices
By contributing, you agree that your contributions will be licensed under the MIT License.