Skip to content

test(fuzz): Enhance fuzzing capabilities and CI workflows with documentation#10

Merged
mergify[bot] merged 19 commits intomainfrom
feat/fuzzing
Mar 9, 2026
Merged

test(fuzz): Enhance fuzzing capabilities and CI workflows with documentation#10
mergify[bot] merged 19 commits intomainfrom
feat/fuzzing

Conversation

@unclesp1d3r
Copy link
Member

This pull request introduces coverage-guided fuzz testing and property-based testing to the project, along with new CI workflows to ensure ongoing compatibility and fuzz safety. It adds a dedicated fuzz workspace, exposes internal APIs for fuzzing, and updates documentation and CI configuration to support these enhancements.

Fuzzing and Property-Based Testing

  • Added a new fuzz/ workspace with two fuzz targets: fuzz_read_bounded (structured input for bounded reads) and fuzz_map_file (round-trip mapping integrity), using cargo-fuzz and nightly Rust. [1] [2] [3]
  • Introduced the __fuzz feature flag to expose the internal read_bounded function for fuzz targets, with appropriate visibility and documentation warnings. (Ff803458L139R139, [1] [2]
  • Added proptest as a dev-dependency and documented property tests for both map_file and read_bounded. (Ff803458L139R139, AGENTS.mdL73-R113)

Continuous Integration and Merge Protections

  • Added .github/workflows/fuzz.yml and .github/workflows/compat.yml for weekly fuzzing and compatibility checks across Rust versions, including merge queue gating and artifact uploads for fuzz crashes. [1] [2]
  • Updated .mergify.yml to gate merges on the results of fuzz and compatibility workflows, allowing merges only if checks are successful or neutral.
  • Enhanced local CI simulation in justfile with new recipes for running and dry-running all workflows using act, including schedule-only workflows.

Documentation and Configuration Updates

  • Expanded AGENTS.md and GOTCHAS.md with detailed instructions and caveats for fuzzing, property tests, CI workflow triggers, and internal API exposure. [1] [2] [3]
  • Updated Cargo.toml to lower MSRV to 1.85, add the __fuzz feature, and include proptest as a dev-dependency. (Cargo.tomlL15-R23, Ff803458L139R139)
  • Minor updates to justfile, mise.toml, and other docs for linting, testing, and tool version bumps. [1] [2] [3]

References: [1] [2] [3] Ff803458L139R139, [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16]

Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
…ments

Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
… compatibility

Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
@unclesp1d3r unclesp1d3r self-assigned this Mar 9, 2026
Copilot AI review requested due to automatic review settings March 9, 2026 00:52
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Mar 9, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 9, 2026

Caution

Review failed

Failed to post review comments

Summary by CodeRabbit

  • Chores

    • Added weekly fuzzing and compatibility testing workflows
    • Configured merge gating for fuzz and compatibility checks
    • Added local CI simulation commands
  • Tests

    • Introduced property-based testing with proptest
    • Added fuzz targets for coverage-guided fuzzing
  • Documentation

    • Updated contributing guidelines with testing instructions
    • Enhanced development documentation with testing procedures
  • Refactor

    • Lowered minimum Rust version requirement from 1.89 to 1.85

Walkthrough

Adds fuzzing and compatibility CI, lowers MSRV to 1.85, exposes an internal read_bounded for fuzzing, adds cap-probing logic to read_bounded, introduces a fuzz workspace with two targets, and adds proptest property tests and related documentation and config updates.

Changes

Cohort / File(s) Summary
CI Workflows
.github/workflows/compat.yml, .github/workflows/fuzz.yml
Adds weekly compatibility and fuzzing GitHub Actions workflows, matrixing Rust toolchains and fuzz targets, with PR and manual triggers, concurrency, and artifact upload.
Merge Queue Rules
.mergify.yml
Adds check-success-or-neutral entries to gate merges on new compat and fuzz workflow variants.
Fuzz Workspace & Targets
fuzz/Cargo.toml, fuzz/fuzz_targets/fuzz_read_bounded.rs, fuzz/fuzz_targets/fuzz_map_file.rs
New non-published fuzz crate linking local crate with __fuzz feature; two libfuzzer targets exercising read_bounded and map_file.
Library API & Logic
src/load.rs, src/lib.rs
Makes read_bounded pub (feature-gated via __fuzz), adds overflow-probing when a cap is provided, and re-exports it under the fuzz feature.
Property Tests
tests/prop_map_file.rs
Adds proptest-based round-trip tests for map_file and an empty-file rejection test.
Cargo / Dev deps
Cargo.toml
Lowers rust-version to 1.85, adds __fuzz feature, adds proptest to dev-dependencies, and excludes /fuzz from packaging.
Docs & Guides
AGENTS.md, GOTCHAS.md, CONTRIBUTING.md, docs/src/*.md
Documents fuzzing, proptest, CI workflows, local CI with act, and testing commands; updates testing/development docs.
Local CI / Taskfile
justfile
Adds local act simulation targets and includes new workflows in lint-actions checks (duplicated block present).
Ignore & Tooling
.gitignore, mise.toml
Ignores fuzz/artifacts/ and fuzz/corpus/; bumps release-plz version.
Top-level lib metadata
src/lib.rs
Feature-gated, doc-hidden re-export pub use load::read_bounded;.

Sequence Diagram(s)

sequenceDiagram
  participant GitHub as "GitHub Actions"
  participant Runner as "Runner (ubuntu-latest)"
  participant Checkout as "checkout@v4"
  participant Toolchain as "rustup / rust-toolchain"
  participant Cargo as "cargo / cargo-fuzz"
  participant Artifact as "artifact storage"

  Note over GitHub: Trigger: schedule / PR / manual
  GitHub->>Runner: start job (compat / fuzz)
  Runner->>Checkout: checkout code (pin tag)
  Runner->>Toolchain: install toolchain (matrix)
  Toolchain->>Cargo: build / test or install cargo-fuzz
  Cargo->>Cargo: run cargo build/test OR cargo fuzz run <target>
  alt fuzz found crash
    Cargo->>Artifact: upload crash artifacts
    Artifact->>GitHub: artifact available (30d)
  end
  Runner->>GitHub: job status (success/neutral/failure)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

size:XL

Poem

🐇 I nibble bytes and chase the fuzz,

probing caps and bounding us,
Tests that bounce and workflows sing,
Artifacts saved from every fling —
A tiny hare, rejoicing in the fuzz!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the main changes: introducing fuzzing capabilities (fuzz targets, workflows, documentation) and CI workflow enhancements.
Description check ✅ Passed The description comprehensively details the fuzzing, property-based testing, CI workflows, and documentation updates included in the PR, directly aligning with the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/fuzzing

Comment @coderabbitai help to get the list of available commands and usage tips.

@mergify
Copy link

mergify bot commented Mar 9, 2026

Merge Protections

Your pull request matches the following merge protections and will not be merged until they are valid.

🟢 📃 Configuration Change Requirements

Wonderful, this rule succeeded.

Mergify configuration change

  • check-success = Configuration changed

🟢 CI must pass

Wonderful, this rule succeeded.

All CI checks must pass. Release-plz PRs are exempt because they only bump versions and changelogs (code was already tested on main), and GITHUB_TOKEN-triggered force-pushes suppress CI.

  • check-success = coverage
  • check-success = quality
  • check-success = test
  • check-success = test-cross-platform (macos-latest, macOS)
  • check-success = test-cross-platform (ubuntu-22.04, Linux)
  • check-success = test-cross-platform (ubuntu-latest, Linux)
  • check-success = test-cross-platform (windows-latest, Windows)

🟢 Do not merge outdated PRs

Wonderful, this rule succeeded.

Make sure PRs are within 10 commits of the base branch before merging

  • #commits-behind <= 3

@dosubot dosubot bot added enhancement New feature or request github_actions Pull requests that update GitHub Actions code labels Mar 9, 2026
@coderabbitai coderabbitai bot added documentation Improvements or additions to documentation size:XL This PR changes 500-999 lines, ignoring generated files. lgtm PR approved by repo maintainer for merge. labels Mar 9, 2026
@codecov
Copy link

codecov bot commented Mar 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds comprehensive fuzzing and property-based testing infrastructure to the mmap-guard crate, along with CI workflows and documentation. It exposes an internal function (read_bounded) behind a feature flag for fuzz targets, adds two cargo-fuzz targets, two proptest test suites, and two new CI workflows (weekly fuzzing and Rust version compatibility matrix).

Changes:

  • Added fuzz/ workspace with two coverage-guided fuzz targets (fuzz_read_bounded, fuzz_map_file), __fuzz feature flag for internal API exposure, and proptest-based property tests for both map_file and read_bounded.
  • Added .github/workflows/fuzz.yml and .github/workflows/compat.yml CI workflows with merge queue gating via Mergify's check-success-or-neutral, plus local CI simulation recipes in justfile using act.
  • Lowered MSRV from 1.89 to 1.85 (edition 2024 minimum), updated documentation (AGENTS.md, GOTCHAS.md, docs/src/testing.md), bumped tool versions in mise.toml/mise.lock, and added fuzz artifact paths to .gitignore.

Reviewed changes

Copilot reviewed 15 out of 17 changed files in this pull request and generated no comments.

Show a summary per file
File Description
fuzz/Cargo.toml New fuzz workspace with libfuzzer-sys, tempfile, and __fuzz feature dependency on mmap-guard
fuzz/fuzz_targets/fuzz_read_bounded.rs Structured fuzz target for read_bounded with Arbitrary-derived input
fuzz/fuzz_targets/fuzz_map_file.rs Fuzz target for map_file round-trip integrity via temp files
src/lib.rs Conditional #[doc(hidden)] re-export of read_bounded under __fuzz feature
src/load.rs Changed read_bounded to pub, added clippy allow attributes, added proptest property tests
tests/prop_map_file.rs Integration property test for map_file round-trip and empty file rejection
Cargo.toml MSRV lowered to 1.85, added __fuzz feature, added proptest dev-dependency, excluded /fuzz from package
.github/workflows/fuzz.yml Weekly nightly fuzzing workflow with crash artifact upload
.github/workflows/compat.yml Weekly Rust version compatibility matrix (stable, stable-2, stable-5, MSRV)
.mergify.yml Added check-success-or-neutral merge conditions for fuzz and compat checks
justfile Added act-based local CI simulation recipes (dry-run, run, per-workflow, per-job)
AGENTS.md Documented fuzzing targets, property tests, __fuzz feature, and CI workflows
GOTCHAS.md Documented fuzzing caveats, act gotchas, and action SHA verification
docs/src/testing.md Updated test organization table to include load.rs tests
.gitignore Added fuzz/artifacts/ and fuzz/corpus/
mise.toml Bumped release-plz to 0.3.157
mise.lock Reformatted TOML and updated tool checksums/versions

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@dosubot
Copy link
Contributor

dosubot bot commented Mar 9, 2026

Related Documentation

6 document(s) may need updating based on files changed in this PR:

DaemonEye

CI and Automation Hooks
View Suggested Changes
@@ -8,6 +8,8 @@
 - `docs.yml`: Documentation build and deployment to GitHub Pages ([docs.yml](https://github.com/EvilBit-Labs/DaemonEye/blob/a169b6886897bf281c27ce9d86d4738233658cd4/.github/workflows/docs.yml)).
 - `codeql.yml`: Code analysis and security scanning ([codeql.yml](https://github.com/EvilBit-Labs/DaemonEye/blob/a169b6886897bf281c27ce9d86d4738233658cd4/.github/workflows/codeql.yml)).
 - `scorecard.yml`: Supply-chain security analysis using OpenSSF Scorecard ([scorecard.yml](https://github.com/EvilBit-Labs/DaemonEye/blob/main/.github/workflows/scorecard.yml)).
+- `fuzz.yml`: Coverage-guided fuzzing with cargo-fuzz on nightly Rust.
+- `compat.yml`: Compatibility testing across multiple Rust toolchain versions.
 
 **Scorecard Supply-Chain Security Workflow**
 
@@ -20,6 +22,28 @@
 - Supports optional configuration for private repositories and branch protection checks.
 
 This workflow helps maintainers monitor supply-chain security posture and enables consumers to access Scorecard results and badges. For details on configuration and authentication, see the [Scorecard Action documentation](https://github.com/ossf/scorecard-action).
+
+**Fuzz Workflow**
+
+The `fuzz.yml` workflow runs coverage-guided fuzzing using `cargo-fuzz` on nightly Rust. It is triggered by a weekly schedule (Monday 06:00 UTC), pull requests targeting the `main` branch, and `workflow_dispatch` for manual runs. The workflow uses conditional execution: it only runs on merge queue PRs (via `startsWith(github.head_ref, 'mergify/merge-queue/')`) to avoid consuming CI resources on regular PRs.
+
+The workflow uses a matrix strategy with `fail-fast: false` over two fuzz targets:
+- `fuzz_read_bounded`: Tests bounded read operations with structured input.
+- `fuzz_map_file`: Tests round-trip mapping integrity for file operations.
+
+Each target runs for 60 seconds by default (configurable via the `FUZZ_SECONDS` environment variable). The workflow installs the nightly toolchain and `cargo-fuzz`, executes each fuzz target, and uploads crash artifacts on failure with 30-day retention. This enables maintainers to review crashes discovered during fuzzing runs.
+
+**Compatibility Workflow**
+
+The `compat.yml` workflow tests the project across multiple Rust toolchain versions to ensure compatibility. It is triggered by a weekly schedule (Monday 06:00 UTC), pull requests targeting the `main` branch, and `workflow_dispatch` for manual runs. Like the fuzz workflow, it uses conditional execution to run only on merge queue PRs.
+
+The workflow uses a matrix strategy with `fail-fast: false` over the following toolchains:
+- `stable`: The latest stable Rust release.
+- `stable minus 2 releases`: Compatibility with recent prior stable versions.
+- `stable minus 5 releases`: Broader backward compatibility testing.
+- `1.85.0`: The minimum supported Rust version (MSRV), which is the edition 2024 minimum.
+
+For each toolchain, the workflow runs `cargo build` and `cargo test` with default features to validate that the project compiles and passes tests across supported Rust versions.
 
 **Workflow Triggers and Automation Hooks**
 
@@ -63,6 +87,10 @@
 
 The project uses Mergify (`.mergify.yml`) to automate handling of bot-generated pull requests, streamlining dependency updates and automated maintenance PRs. Mergify automatically approves and merges PRs from Dependabot, Dosubot, and release-plz after CI checks pass, and keeps these PRs up to date with the main branch.
 
+Both the fuzz and compatibility workflows integrate with Mergify's merge protections using `check-success-or-neutral` conditions. This two-step CI pattern allows the workflows to be skipped on regular PRs (reducing CI resource consumption), but enforces that they must pass if they run in the merge queue. If either workflow fails during a merge queue run, the merge is blocked. The Mergify configuration includes checks for all matrix jobs in both workflows:
+- Fuzz workflow: `fuzz (fuzz_read_bounded)` and `fuzz (fuzz_map_file)`
+- Compatibility workflow: `compat (stable)`, `compat (stable minus 2 releases)`, `compat (stable minus 5 releases)`, and `compat (1.85.0)`
+
 **Maintaining and Extending Automation Workflows**
 
 To maintain and extend the automation workflows:

❌ Declined

mmap-guard

CI Pipeline And Cross-Platform Testing
View Suggested Changes
@@ -13,6 +13,10 @@
 ### Overview and Triggers
 
 [The main CI workflow defined in `.github/workflows/ci.yml` runs on every push to main and on all pull requests](https://app.dosu.dev/documents/2ac8341a-733e-4e85-bb1d-750a84dccb16). The workflow consists of four distinct jobs that execute sequentially with dependencies.
+
+Additional specialized workflows run on weekly schedules and merge queue events:
+- **`.github/workflows/fuzz.yml`** — Coverage-guided fuzz testing with cargo-fuzz
+- **`.github/workflows/compat.yml`** — Rust version compatibility testing across stable, stable-2, stable-5, and MSRV
 
 ### Job 1: Quality
 
@@ -66,6 +70,34 @@
 - **SHA-pinned GitHub Actions** — Instead of `actions/checkout@v3`, uses full SHA like `actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd` to prevent tag-mutation attacks
 - **Minimal permissions** — `permissions: contents: read` by default (least privilege)
 - **Concurrency control** — `cancel-in-progress: true` setting prevents resource waste
+
+### Fuzz Workflow (fuzz.yml)
+
+The fuzz workflow performs coverage-guided fuzzing to discover edge cases and potential panics:
+
+- **Triggers**: Weekly schedule (Mondays 06:00 UTC), merge queue events, manual dispatch
+- **Toolchain**: Requires nightly Rust for cargo-fuzz
+- **Fuzz Targets**: Matrix strategy tests both `fuzz_read_bounded` and `fuzz_map_file` targets
+- **Duration**: Each target runs for 60 seconds (`FUZZ_SECONDS=60`)
+- **Artifacts**: Automatically uploads crash artifacts with 30-day retention on failure
+- **Gating**: Uses `check-success-or-neutral` in merge protection to allow skipped scheduled runs
+
+The workflow only executes on merge queue PRs or scheduled runs, not on regular pull requests. This design avoids blocking every PR with long-running fuzz tests while still validating changes before merge.
+
+### Compatibility Workflow (compat.yml)
+
+The compatibility workflow validates behavior across Rust versions:
+
+- **Triggers**: Weekly schedule (Mondays 06:00 UTC), merge queue events, manual dispatch
+- **Rust Versions**: Matrix tests across:
+  - `stable` — Latest stable release
+  - `stable minus 2 releases` — Two releases behind
+  - `stable minus 5 releases` — Five releases behind
+  - `1.85.0` — MSRV (Minimum Supported Rust Version for edition 2024)
+- **Jobs**: Build and test execution for each version
+- **Gating**: Uses `check-success-or-neutral` in merge protection to allow skipped scheduled runs
+
+Like the fuzz workflow, this only runs on merge queue PRs or weekly schedules to avoid blocking regular development while ensuring compatibility before merge.
 
 ## Platform-Specific Testing
 
@@ -146,6 +178,15 @@
 
 **Important configuration note:** [Mergify evaluates from the main branch configuration, meaning changes to Mergify rules in feature branches won't take effect until merged to main](https://app.dosu.dev/documents/4a2f4809-90bd-4455-8ea1-c7f927f66ce4).
 
+Merge conditions include:
+- **Core CI workflows**: All jobs from the main CI pipeline must pass (quality, test, test-cross-platform, coverage)
+- **Weekly workflows**: Fuzz and compatibility checks use `check-success-or-neutral` conditions, which:
+  - Block merge if the workflow ran and failed
+  - Allow merge if the workflow didn't run (neutral status)
+  - Gate merge queue PRs but not regular PRs
+
+This design ensures weekly fuzz and compatibility tests validate changes entering the merge queue without blocking every PR during regular development.
+
 Release workflow:
 1. **Release PR Creation**: release-plz creates a PR with version bumps and CHANGELOG
 2. **Automated Merge**: [Mergify automatically merges the PR after DCO checks pass](https://app.dosu.dev/documents/0e7b2ef2-fec8-41e2-af4c-7ece10a919d3)
@@ -195,6 +236,17 @@
 
 [Based on background context, mise-managed cargo subcommands must be invoked as standalone binaries](https://app.dosu.dev/documents/4a2f4809-90bd-4455-8ea1-c7f927f66ce4) (e.g., `dist plan` not `cargo dist plan`).
 
+### Local Workflow Simulation with act
+
+The justfile provides recipes for testing GitHub Actions workflows locally using `act`:
+
+- `just act-run <workflow>` — Run a specific workflow locally
+- `just act-dry-run <workflow>` — Dry-run a workflow to validate syntax and steps
+- `just act-run-workflow <workflow> [event]` — Run workflow with custom event trigger
+- `just act-run-job <workflow> <job> [event]` — Run specific job from a workflow
+
+The `lint-actions` command validates all workflow files including `compat.yml` and `fuzz.yml` using actionlint.
+
 ### Pre-commit Hook Behavior
 
 [Pre-commit hooks run automatically on `git commit`](https://app.dosu.dev/documents/cc55aa67-9430-4d02-9574-59b9b3651de4):
@@ -280,7 +332,9 @@
 | File Path | Purpose | Key Features |
 |-----------|---------|--------------|
 | `.github/workflows/ci.yml` | Main CI pipeline | quality, test, test-cross-platform, coverage jobs |
-| `.mergify.yml` | Merge protection rules | Auto-merge configuration for DCO verification |
+| `.github/workflows/fuzz.yml` | Fuzzing workflow | Weekly coverage-guided fuzzing with cargo-fuzz, nightly toolchain |
+| `.github/workflows/compat.yml` | Compatibility testing | Weekly validation across Rust versions (stable, stable-2, stable-5, MSRV) |
+| `.mergify.yml` | Merge protection rules | Auto-merge configuration with check-success-or-neutral for weekly workflows |
 | `Cargo.toml` | Lint configuration | `[workspace.lints.clippy]` with pedantic/nursery/cargo groups |
 | `src/lib.rs` | Crate-level configuration | `#![deny(clippy::undocumented_unsafe_blocks)]` |
 | `src/map.rs` | Test organization | Successful mapping, empty file rejection, missing file tests |
@@ -288,7 +342,7 @@
 | `src/file_data.rs` | Test organization | `Deref`/`AsRef` impls, empty variant tests |
 | `mise.toml` | Tool management | Development tool versions and installation |
 | `.pre-commit-config.yaml` | Pre-commit hooks | Format, lint, audit, and security checks |
-| `justfile` | Task automation | `ci-check`, `coverage-check`, `audit`, `deny` recipes |
+| `justfile` | Task automation | `ci-check`, `coverage-check`, `audit`, `deny`, `act-run` recipes |
 | `deny.toml` | Dependency policies | License allowlist, banned crates, source restrictions |
 
 ## Related Topics

[Accept] [Decline]

CI/CD Pipeline Security
View Suggested Changes
@@ -118,13 +118,23 @@
 
 ### Security Workflows
 
-Three specialized security workflows run on scheduled intervals:
+Five specialized security and quality workflows run on scheduled intervals:
 
 - **audit.yml** — Daily execution of cargo-audit with automatic issue creation
 - **security.yml** — Daily cargo-deny and cargo-outdated checks
 - **scorecard.yml** — Weekly OSSF Scorecard assessment
+- **fuzz.yml** — Weekly coverage-guided fuzz testing with cargo-fuzz
+- **compat.yml** — Weekly compatibility testing across Rust toolchain versions
 
 These workflows operate independently of the main CI pipeline, ensuring security monitoring continues even when no code changes are being made.
+
+#### Fuzzing Workflow
+
+The `fuzz.yml` workflow performs coverage-guided fuzz testing to discover edge cases and potential security vulnerabilities. Running weekly and on merge queue events, it executes two fuzz targets (`fuzz_read_bounded` and `fuzz_map_file`) for 60 seconds each using cargo-fuzz on nightly Rust. The workflow implements a matrix strategy to parallelize execution, with minimal read-only permissions and automatic artifact upload for any discovered crashes. Merge protection uses `check-success-or-neutral` conditions, allowing merges when the workflow is skipped on scheduled runs while still gating merges when triggered by pull requests.
+
+#### Compatibility Workflow
+
+The `compat.yml` workflow validates functionality across multiple Rust toolchain versions to ensure broad compatibility. Running weekly and on merge queue events, it tests against stable, stable minus 2 releases, stable minus 5 releases, and the MSRV (Minimum Supported Rust Version) of 1.85.0. The workflow executes the full build and test suite on each toolchain version with a fail-fast: false strategy to collect results from all versions. Like the fuzzing workflow, it uses `check-success-or-neutral` merge protection to allow optional scheduled runs while gating merges when triggered.
 
 ### Local CI Parity
 
@@ -159,6 +169,10 @@
 
 The release workflow represents a critical exception to this pattern. The `release-plz-pr` job sets `cancel-in-progress: false` to prevent race conditions during release preparation, ensuring that release version calculations and changelog generation complete atomically even if new commits arrive during execution.
 
+### Merge Queue Protection
+
+The `.mergify.yml` configuration implements sophisticated merge protection that accommodates both required and optional CI workflows. Core workflows (quality, test, coverage) use `check-success` conditions that require explicit passing status before merge. Weekly workflows (fuzz, compat) use `check-success-or-neutral` conditions that allow merges when checks are skipped (neutral status on scheduled runs) while still blocking merges if the workflows run and fail. This design ensures that optional scheduled workflows don't block routine development while still providing gate protection when triggered by pull requests or merge queue events.
+
 ### Credential Security
 
 Workflow checkout operations use `persist-credentials: false` for security-sensitive operations, particularly in the OSSF Scorecard workflow. This prevents GitHub credentials from being persisted to the local Git configuration, reducing the risk of credential exposure if subsequent workflow steps are compromised.
@@ -330,6 +344,8 @@
 | `.github/workflows/security.yml` | Daily security monitoring | cargo-deny policy checks, cargo-outdated analysis |
 | `.github/workflows/scorecard.yml` | Supply chain assessment | Weekly OSSF Scorecard runs, SARIF upload to code-scanning |
 | `.github/workflows/audit.yml` | Vulnerability scanning | Daily cargo-audit execution, automatic issue creation |
+| `.github/workflows/fuzz.yml` | Weekly fuzz testing | Coverage-guided fuzzing with cargo-fuzz, crash artifact upload |
+| `.github/workflows/compat.yml` | Rust version compatibility | Testing across stable, MSRV, and historical toolchains |
 | `.github/workflows/release-plz.yml` | Automated releases | Version bumping, changelog generation, crates.io publication |
 | `.github/dependabot.yml` | Dependency automation | Weekly updates for Cargo, GitHub Actions, DevContainers |
 | `deny.toml` | Dependency policies | License allowlist, banned crates, source restrictions |

✅ Accepted

CONTRIBUTING /mmap-guard/blob/main/CONTRIBUTING.md
View Suggested Changes
@@ -8,13 +8,13 @@
 
 ## Gotchas
 
-Before working in a specific area, check [GOTCHAS.md](GOTCHAS.md) for hard-won lessons and edge cases organized by domain. It covers unsafe code rules, clippy/rustdoc pitfalls, CI quirks, pre-commit hook behavior, and platform-specific mmap limitations.
+Before working in a specific area, check [GOTCHAS.md](GOTCHAS.md) for hard-won lessons and edge cases organized by domain. It covers unsafe code rules, clippy/rustdoc pitfalls, CI quirks, pre-commit hook behavior, platform-specific mmap limitations, and fuzzing with cargo-fuzz.
 
 ## Getting Started
 
 ### Prerequisites
 
-- **Rust 1.89+** (edition 2024, stable toolchain)
+- **Rust 1.85+** (edition 2024, stable toolchain)
 - **Git** for version control
 - **[mise](https://mise.jdx.dev/)** for tool management (recommended)
 
@@ -45,6 +45,7 @@
 - **cargo-llvm-cov** — code coverage
 - **cargo-audit** / **cargo-deny** — security auditing
 - **cargo-about** — third-party license notices
+- **cargo-fuzz** — coverage-guided fuzzing (requires nightly)
 - **just** — task runner
 - **pre-commit** — git hooks
 - **mdbook** — documentation
@@ -166,6 +167,13 @@
 
 # Check coverage
 just coverage-check               # 85% threshold
+
+# Run property tests
+cargo test --test prop_map_file
+
+# Run fuzz targets (requires nightly)
+cargo +nightly fuzz run fuzz_read_bounded -- -max_total_time=60
+cargo +nightly fuzz run fuzz_map_file -- -max_total_time=60
 ```
 
 ### Writing Tests
@@ -174,6 +182,8 @@
 - Use `#[cfg(test)]` modules with `#[allow(clippy::unwrap_used, clippy::expect_used)]`
 - Include doc tests for public API examples
 - Test both success and error cases
+- Property tests using `proptest` are included in the test suite
+- Fuzz targets live in the `fuzz/` workspace and require nightly
 
 Example test structure:
 
@@ -232,7 +242,7 @@
 - **Style** — Follows project conventions, passes `cargo fmt` and `cargo clippy -- -D warnings`
 - **Documentation** — Public APIs have rustdoc with examples, AGENTS.md updated if architecture changes
 
-CI checks run before merge, including quality checks, tests, coverage, and cross-platform tests (Ubuntu, macOS, Windows).
+CI checks run before merge, including quality checks, tests, coverage, and cross-platform tests (Ubuntu, macOS, Windows). Weekly workflows run fuzzing (`fuzz.yml`) and compatibility checks across Rust versions (`compat.yml`). These weekly workflows use `check-success-or-neutral` for merge gating, allowing merges when checks are skipped on regular PRs but blocking merges if they fail in the merge queue.
 
 ### Developer Certificate of Origin (DCO)
 

✅ Accepted

development /mmap-guard/blob/main/docs/src/development.md
View Suggested Changes
@@ -27,6 +27,39 @@
 | `just docs-build`      | Build mdBook + rustdoc                            |
 | `just docs-serve`      | Serve docs locally with live reload               |
 
+### Running Tests
+
+**Standard tests:**
+
+```bash
+just test
+```
+
+**Property-based tests:**
+
+```bash
+cargo test --test prop_map_file
+```
+
+Property tests use [proptest](https://github.com/proptest-rs/proptest) to verify round-trip integrity with randomized inputs.
+
+**Fuzz tests:**
+
+Fuzzing requires nightly Rust and `cargo-fuzz`. Install it first:
+
+```bash
+cargo install cargo-fuzz
+```
+
+Run a specific fuzz target (available targets: `fuzz_read_bounded`, `fuzz_map_file`):
+
+```bash
+cargo +nightly fuzz run fuzz_read_bounded
+cargo +nightly fuzz run fuzz_map_file
+```
+
+Fuzz tests use the `__fuzz` feature flag to expose internal APIs for testing. This feature is for internal use only and should not be enabled in production code.
+
 ## Pre-commit Hooks
 
 Pre-commit hooks run automatically on `git commit`:
@@ -49,3 +82,10 @@
 2. **test** — nextest + release build
 3. **test-cross-platform** — Linux (x2), macOS, Windows
 4. **coverage** — llvm-cov uploaded to Codecov
+
+**Weekly scheduled workflows:**
+
+- **fuzz** — runs fuzzing tests (`fuzz_read_bounded`, `fuzz_map_file`) with nightly Rust. Also runs on merge queue PRs.
+- **compat** — tests Rust version compatibility across stable, stable-2, stable-5, and MSRV 1.85. Also runs on merge queue PRs.
+
+These weekly workflows use `check-success-or-neutral` conditions for merge gating, allowing merges when the checks pass or are skipped.

✅ Accepted

Development Gotchas
View Suggested Changes
@@ -1,6 +1,6 @@
 # Development Gotchas
 
-**Development Gotchas** is a collection of hard-won lessons and edge cases for the [mmap-guard](https://app.dosu.dev/documents/a1bf6f67-562d-4d5f-9d49-688984805808) project, organized by domain to help developers avoid common pitfalls. [Referenced in CONTRIBUTING.md](https://app.dosu.dev/documents/b8635631-0830-4473-b032-29493824f509), this documentation captures critical knowledge about unsafe code rules, clippy/rustdoc configuration, CI tooling quirks, pre-commit hook behavior, and platform-specific memory-mapped I/O limitations.
+**Development Gotchas** is a collection of hard-won lessons and edge cases for the [mmap-guard](https://app.dosu.dev/documents/a1bf6f67-562d-4d5f-9d49-688984805808) project, organized by domain to help developers avoid common pitfalls. [Referenced in CONTRIBUTING.md](https://app.dosu.dev/documents/b8635631-0830-4473-b032-29493824f509), this documentation captures critical knowledge about unsafe code rules, clippy/rustdoc configuration, fuzzing and property testing, CI tooling quirks, pre-commit hook behavior, and platform-specific memory-mapped I/O limitations.
 
 The mmap-guard project is a [safe, memory-mapped file I/O library for Rust](https://app.dosu.dev/documents/a1bf6f67-562d-4d5f-9d49-688984805808) that wraps `memmap2::Mmap::map()` behind a safe API so downstream crates can use `#![forbid(unsafe_code)]`. The project [maintains exactly one unsafe block in src/map.rs](https://app.dosu.dev/documents/c69dde4e-b575-4b10-8afc-db5b4b3278b9) and enforces strict code quality standards through comprehensive linting, testing, and automation.
 
@@ -84,6 +84,60 @@
 ### CI and Private Items
 
 Based on background context, CI uses `--document-private-items` when building rustdoc. Links to private modules break without this flag, so contributors should link to public items instead to ensure documentation builds correctly in all contexts.
+
+---
+
+## Fuzzing and Property Testing
+
+### The `__fuzz` Feature Flag
+
+The `__fuzz` feature flag exposes internal APIs for fuzz testing while keeping them hidden from the public documentation:
+
+- **Leading underscores indicate internal-only** — The feature name `__fuzz` signals that it is not part of the stable public API
+- **`#[doc(hidden)]` prevents public documentation** — The re-exported `read_bounded` function is marked `#[doc(hidden)]` so it won't appear on docs.rs
+- **Do not use in production code** — This feature exists solely for fuzz targets and should never be enabled by downstream crates
+
+### Fuzz Targets
+
+The project includes two fuzz targets in the `fuzz/` directory:
+
+- **`fuzz_read_bounded`** — Tests bounded reads with structured input (offset, length, buffer size)
+- **`fuzz_map_file`** — Tests round-trip mapping integrity with arbitrary file contents
+
+### Fuzz Target Requirements
+
+Fuzz targets have specific toolchain and configuration requirements:
+
+- **Nightly Rust required** — Fuzz targets use `cargo-fuzz` and `libfuzzer-sys`, which require nightly
+- **Separate workspace with edition 2021** — The `fuzz/Cargo.toml` uses edition 2021 (not 2024) to avoid compatibility issues with nightly tooling
+- **RUSTUP_TOOLCHAIN override needed in CI** — CI workflows that run fuzz targets must set `RUSTUP_TOOLCHAIN: nightly` as an environment variable, since `rust-toolchain.toml` overrides `rustup default`
+
+### Property Tests vs. Fuzz Tests
+
+The project uses both fuzzing and property-based testing:
+
+- **Property tests use `proptest`** — Run on stable Rust as part of `cargo test`
+- **Fuzz tests use `cargo-fuzz`** — Require nightly and run separately
+- **`read_bounded` proptest lives in `src/load.rs`** — It's a unit test (not in `tests/`) because it needs access to the private function
+
+### Clippy Exceptions for Fuzz-Exposed Functions
+
+`read_bounded` requires clippy exceptions because it's exposed for fuzzing:
+
+- **`#[allow(unreachable_pub)]`** — Clippy flags `pub` functions in private modules, even when re-exported conditionally
+- **`#[allow(clippy::missing_errors_doc)]`** — Clippy expects error documentation for public functions, but this is `#[doc(hidden)]`
+
+These exceptions represent a deliberate trade-off: enabling comprehensive fuzz coverage requires exposing internal APIs, even if they violate clippy's preferred API design patterns.
+
+### `arbitrary` Derive Macro Import
+
+Based on the PR diff, fuzz targets use `#[derive(Arbitrary)]` from `libfuzzer-sys::arbitrary`:
+
+```rust
+use libfuzzer_sys::arbitrary::{self, Arbitrary};
+```
+
+The `self` import is required because the derive macro references `arbitrary::` by path. Do not remove it, or the derive will fail.
 
 ---
 
@@ -180,9 +234,91 @@
 3. **test-cross-platform** — Linux (x2), macOS, Windows
 4. **coverage** — llvm-cov uploaded to Codecov
 
+### Weekly Scheduled Workflows
+
+The project includes two weekly workflows for ongoing quality assurance:
+
+- **fuzz.yml** — Runs coverage-guided fuzz testing on two targets (`fuzz_read_bounded`, `fuzz_map_file`) for 60 seconds each, uploading crash artifacts if failures occur
+- **compat.yml** — Tests compatibility across multiple Rust versions (stable, stable minus 2, stable minus 5, MSRV 1.85.0)
+
+Both workflows trigger on:
+
+- Weekly schedule (Monday 06:00 UTC)
+- Pull requests to main (only when in merge queue)
+- Manual workflow dispatch
+
+### Merge Queue Gating with `check-success-or-neutral`
+
+[Mergify uses `check-success-or-neutral` conditions](https://app.dosu.dev/documents/0e7b2ef2-fec8-41e2-af4c-7ece10a919d3) for weekly workflows to allow merges when scheduled workflows haven't run:
+
+- **If workflow runs and succeeds** — merge proceeds
+- **If workflow runs and fails** — merge blocked
+- **If workflow is skipped (not in merge queue)** — merge proceeds (neutral status)
+
+This prevents scheduled-only workflows from blocking normal PR merges while still catching issues when they do run.
+
+### Action SHA Verification
+
+Always verify pinned GitHub Action SHAs before use. The PR diff shows actions pinned to specific commit SHAs (e.g., `actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd`). Verify SHAs with:
+
+```bash
+gh api repos/{owner}/{repo}/commits/{sha} --jq '.sha'
+```
+
+Do not fabricate or guess SHAs — use only verified commit references.
+
 ### Local CI Parity
 
 [Run `just ci-check` locally for full CI parity](https://app.dosu.dev/documents/cc55aa67-9430-4d02-9574-59b9b3651de4) before submitting changes.
+
+### Local CI Simulation with `act`
+
+The `justfile` includes recipes for running GitHub Actions workflows locally using `act`:
+
+- **`just act-dry-run`** — Dry-run all workflows (ci, audit, compat, fuzz, security) without starting containers
+- **`just act-run`** — Run all workflows locally in Docker containers
+- **`just act-run-workflow <workflow>`** — Run a specific workflow (e.g., `just act-run-workflow fuzz`)
+- **`just act-run-job <workflow> <job>`** — Run a specific job from a workflow
+
+### `act` Platform Quirks
+
+Running workflows locally with `act` has several platform-specific gotchas:
+
+#### Docker Root User
+
+`act` Docker containers run as root, which causes issues with Unix permission tests:
+
+- Tests that use `chmod 000` to trigger `PermissionDenied` errors will false-positive because root bypasses file permission checks
+- This is a limitation of `act`, not the test code itself
+
+#### Architecture Flags
+
+On Apple Silicon Macs, use the `--container-architecture linux/amd64` flag to avoid image pull failures:
+
+```bash
+act --container-architecture linux/amd64
+```
+
+The `justfile` includes this flag by default in the `act_flags` variable.
+
+#### Schedule-Only Workflows
+
+Workflows that trigger only on `schedule` or `pull_request` need special event arguments:
+
+- **Default event:** `act` defaults to the `push` event
+- **Override required:** Use `workflow_dispatch` as the event argument for schedule-only workflows
+
+The `justfile` handles this automatically by passing `workflow_dispatch` to the audit, compat, fuzz, and security workflows.
+
+### Linting Workflow Files
+
+The `lint-actions` recipe validates workflow YAML files, including the weekly workflows:
+
+```bash
+just lint-actions
+```
+
+This validates `compat.yml` and `fuzz.yml` along with the core CI workflows.
 
 ---
 

✅ Accepted

Note: You must be authenticated to accept/decline updates.

How did I do? Any feedback?  Join Discord

@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. size:XL This PR changes 500-999 lines, ignoring generated files. labels Mar 9, 2026
Copilot AI review requested due to automatic review settings March 9, 2026 02:45
@unclesp1d3r unclesp1d3r review requested due to automatic review settings March 9, 2026 02:45
@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Mar 9, 2026
@unclesp1d3r
Copy link
Member Author

@Mergifyio queue

@mergify
Copy link

mergify bot commented Mar 9, 2026

Merge Queue Status

Rule: default


This pull request spent 4 minutes 45 seconds in the queue, including 4 minutes 33 seconds running CI.

Required conditions to merge
  • check-success = coverage
  • check-success = quality
  • check-success = test
  • check-success = test-cross-platform (macos-latest, macOS)
  • check-success = test-cross-platform (ubuntu-22.04, Linux)
  • check-success = test-cross-platform (ubuntu-latest, Linux)
  • check-success = test-cross-platform (windows-latest, Windows)
  • all of [🛡 Merge Protections rule CI must pass]:
    • check-success = coverage
    • check-success = quality
    • check-success = test
    • check-success = test-cross-platform (macos-latest, macOS)
    • check-success = test-cross-platform (ubuntu-22.04, Linux)
    • check-success = test-cross-platform (ubuntu-latest, Linux)
    • check-success = test-cross-platform (windows-latest, Windows)
  • all of [🛡 Merge Protections rule Do not merge outdated PRs]:
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-success = DCO
    • check-neutral = DCO
    • check-skipped = DCO
  • any of [🛡 GitHub repository ruleset rule main]:
    • check-neutral = Mergify Merge Protections
    • check-skipped = Mergify Merge Protections
    • check-success = Mergify Merge Protections

@mergify mergify bot added the queued label Mar 9, 2026
mergify bot added a commit that referenced this pull request Mar 9, 2026
@mergify mergify bot merged commit ce5a5ee into main Mar 9, 2026
21 checks passed
@mergify mergify bot deleted the feat/fuzzing branch March 9, 2026 03:26
@mergify mergify bot removed the queued label Mar 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request github_actions Pull requests that update GitHub Actions code lgtm PR approved by repo maintainer for merge. size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants