Skip to content

refactor: pre-create evaluator submodules for v0.2.0 features#142

Merged
unclesp1d3r merged 34 commits into
mainfrom
62-refactor-pre-create-evaluator-submodules-for-v020-features
Mar 5, 2026
Merged

refactor: pre-create evaluator submodules for v0.2.0 features#142
unclesp1d3r merged 34 commits into
mainfrom
62-refactor-pre-create-evaluator-submodules-for-v020-features

Conversation

@unclesp1d3r
Copy link
Copy Markdown
Member

@unclesp1d3r unclesp1d3r commented Mar 5, 2026

Summary

This PR includes infrastructure improvements, evaluator module refactoring, and CLI UX enhancements for the v0.2.0 milestone.

Evaluator Module Refactor

  • Split monolithic offset.rs into submodules: absolute.rs, indirect.rs, relative.rs
  • Split monolithic operators.rs into submodules: equality.rs, comparison.rs, bitwise.rs
  • Updated AGENTS.md to reflect new module structure

CLI UX Improvements (rmagic)

  • Added short flags: -j (json), -m (magic-file), -s (strict), -b (use-builtin), -t (timeout-ms)
  • Proper ArgGroup for --json/--text mutual exclusion
  • --use-builtin now conflicts with --magic-file (previously use-builtin silently won)
  • --timeout-ms uses value_parser range validation (1-300000) for parse-time feedback
  • --generate-completion <SHELL> flag for shell completion generation (bash, zsh, fish, etc.)
  • Graceful Ctrl+C handling with ctrlc crate (exit code 130, "Interrupted" message)
  • Buffered stdout output via BufWriter<StdoutLock> (single flush instead of per-file)
  • Examples moved to after_help so they appear after Options in --help output
  • strip = true added to release and dist profiles

Toolchain & MSRV

  • Bumped MSRV from 1.85 to 1.89
  • Updated rust-toolchain.toml and CI workflow to use stable channel
  • Fixed new clippy lints: collapsible_if (let-chains), manual_is_multiple_of

Dependency & Tooling Updates

  • Added clap_complete and ctrlc dependencies
  • Updated versions of Rust tools and dependencies in mise.toml and dist-workspace.toml
  • Added pipx and bun to mise.toml

Workflow Enforcement

  • Added hookify rules to block manual edits to release.yml, unsigned commits/tags, and emoji in PRs

Tests

  • 7 new CLI integration tests: help, version, completion, short flags, json/text conflict, timeout range validation
  • Updated existing tests for new --use-builtin/--magic-file conflict behavior
  • 982 tests passing, 0 clippy warnings

Test plan

  • just ci-check passes locally
  • cargo nextest run -- 982 tests pass
  • cargo clippy --all-targets -- -D warnings -- zero warnings
  • cargo fmt -- --check -- clean
  • CI passes on GitHub
  • Manual verification: rmagic --help, rmagic --version, rmagic --generate-completion bash

🤖 Generated with Claude Code

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>
Pre-create evaluator submodule directories for upcoming v0.2.0 features.
Split offset.rs into offset/{mod,absolute,indirect,relative}.rs and
operators.rs into operators/{mod,equality,comparison,bitwise}.rs.
Update AGENTS.md module structure documentation to match.

Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Ran dist init to update cargo-dist version, regenerating release.yml
and dist-workspace.toml formatting.

Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
@unclesp1d3r unclesp1d3r self-assigned this Mar 5, 2026
Copilot AI review requested due to automatic review settings March 5, 2026 04:07
@unclesp1d3r unclesp1d3r linked an issue Mar 5, 2026 that may be closed by this pull request
5 tasks
@dosubot dosubot Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Mar 5, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 5, 2026

Caution

Review failed

Pull request was closed or merged during review

Summary by CodeRabbit

  • New Features

    • Shell completion generation and graceful Ctrl-C interruption; local hooks to block unsigned commits/tags and warn on emoji in PRs; release workflow protected from manual edits.
  • Chores

    • Bumped Rust/tooling versions and updated CI/tool pins; upgraded cargo-dist to v0.31.0; added version pins for Python and Bun.
  • Refactor

    • Evaluator implementation reorganized into focused submodules (internal; no user-facing API changes).
  • Documentation

    • Expanded release, contributing, and developer docs with signing, workflow protection, and tooling guidance.

Walkthrough

Reorganizes evaluator into offset and operator submodules with dispatchers and stubs; adds CLI completion, buffered writer I/O, and Ctrl‑C interruption handling; introduces local hooks blocking unsigned commits/tags and edits to the generated release workflow; bumps cargo-dist to v0.31.0, updates tool pins, and wide documentation/test updates.

Changes

Cohort / File(s) Summary
Hook Configuration
.claude/hookify.block-release-workflow-edit.local.md, .claude/hookify.block-unsigned-commits.local.md, .claude/hookify.block-unsigned-tags.local.md, .claude/hookify.warn-emoji-in-prs.local.md
Add local hooks to block edits to auto-generated release workflow, block unsigned commits/tags, and warn/enforce ASCII-only PR titles/bodies.
Release & Dist Config
.github/workflows/release.yml, dist-workspace.toml
Bump cargo-dist installer to v0.31.0 and normalize/expand dist-workspace settings (archives, flags, github attestations/releases, publish jobs).
Tooling & Pins
mise.toml, .bun-version, .python-version, rust-toolchain.toml, .github/workflows/ci.yml
Update many tool pins and defaults; add .bun/.python version files; switch rust-toolchain to stable and add components; CI now installs rustfmt/clippy.
Evaluator — Operators (restructure)
src/evaluator/operators.rs (deleted), src/evaluator/operators/mod.rs, src/evaluator/operators/equality.rs, src/evaluator/operators/comparison.rs, src/evaluator/operators/bitwise.rs
Remove monolithic operators file; add operators/ submodules (equality, comparison, bitwise), implement per-operator logic, add apply_operator dispatcher and tests.
Evaluator — Offsets (restructure)
src/evaluator/offset/mod.rs, src/evaluator/offset/absolute.rs, src/evaluator/offset/indirect.rs, src/evaluator/offset/relative.rs
Introduce offset/ submodule with resolve_offset dispatcher, keep resolve_absolute_offset, add stubs for indirect/relative, map OffsetError→LibmagicError, and add tests.
CLI & I/O Changes
src/main.rs, tests/cli_integration_tests.rs
Add --generate-completion (clap_complete), route output via BufWriter passed into process_file/output_result, add Ctrl‑C interruption (AtomicBool) and update tests and CLI conflict handling.
Manifest / Cargo
Cargo.toml, dist-workspace.toml, mise.toml
Bump rust-version, add deps (clap_complete, ctrlc), enable strip = true in release/dist profiles, and update distribution/tooling config.
Docs & Release Process
AGENTS.md, docs/src/architecture.md, docs/src/release-process.md, many docs/** files
Document evaluator reorganization, require signed commits/tags, note release workflow is auto-generated/protected, bump documented Rust MSRV to 1.89, and apply broad documentation formatting updates.
Parser / Small Logic Tweaks
src/evaluator/offset/absolute.rs, src/evaluator/mod.rs, src/output/mod.rs, src/parser/...
Refactor absolute-offset logic, consolidate timeout/enrichment guards, replace modulo checks with is_multiple_of, and adjust related tests.
Pre-commit & CI
.pre-commit-config.yaml, CONTRIBUTING.md, .claude/skills/SKILL.md
Reconfigure pre-commit hooks (types, local shellcheck), expand mdformat deps, add cargo-audit hook, and bump documented Rust MSRV to 1.89.
Misc / Presentation
README.md, many docs/** files, .github/workflows/ci.yml
Various presentational and formatting-only updates across README, documentation, CI, and test expectations.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant User as "User (CLI)"
    participant Main as "src/main.rs\nCLI entry"
    participant Runner as "run_analysis"
    participant Processor as "process_file"
    participant DB as "MagicDatabase"
    participant Writer as "BufWriter"
    participant Interrupt as "Ctrl‑C (AtomicBool)"

    rect rgba(200,220,255,0.5)
    User->>Main: invoke CLI (args, --generate-completion?)
    Main->>Main: emit completion & exit (if requested)
    end

    rect rgba(220,255,200,0.5)
    Main->>Runner: start run_analysis(args, interrupted)
    Runner->>Processor: for each input -> process_file(writer,...)
    Processor->>DB: evaluate rules / query database
    DB-->>Processor: EvaluationResult
    Processor->>Writer: write output (text/json)
    Writer-->>User: flush output
    end

    rect rgba(255,220,200,0.5)
    Interrupt->>Runner: set interrupted flag (Ctrl‑C)
    Runner->>Processor: observe interrupted -> stop, flush writer, return early
    Main->>User: exit with code 130
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐰 I hop through diffs with a twitch and grin,

Submodules sprout where the old ones had been.
Hooks mend the gates, completions hum bright,
Buffers hold answers till Ctrl‑C says goodnight.
Carrots for tests — review, then take flight!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the main change: pre-creating evaluator submodules for v0.2.0 features, which is directly supported by the extensive refactoring of offset.rs and operators.rs into hierarchical submodules.
Description check ✅ Passed The description provides comprehensive coverage of the PR scope including evaluator refactoring, CLI improvements, toolchain updates, and test additions, all of which are substantially present in 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 62-refactor-pre-create-evaluator-submodules-for-v020-features

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 markdownlint-cli2 (0.21.0)
.claude/hookify.block-unsigned-commits.local.md

markdownlint-cli2 v0.21.0 (markdownlint v0.40.0)
Finding: .claude/hookify.block-unsigned-commits.local.md /*.md !CHANGELOG.md !.venv/ !/node_modules/ !/pycache/ !/*.tpl.md !/.mdc !.kiro/steering/.md
Linting: 84 file(s)
TypeError: Cannot read properties of undefined (reading 'slice')
at applyFix (file:///usr/local/lib/node_modules/markdownlint-cli2/node_modules/markdownlint/lib/markdownlint.mjs:1295:10)
at applyFixes (file:///usr/local/lib/node_modules/markdownlint-cli2/node_modules/markdownlint/lib/markdownlint.mjs:1369:26)
at file:///usr/local/lib/node_modules/markdownlint-cli2/markdownlint-cli2.mjs:758:31
at async Promise.all (index 0)
at async Promise.all (index 0)
at async main (file:///usr/local/lib/node_modules/markdownlint-cli2/markdownlint-cli2.mjs:1001:23)
at async file:///usr/local/lib/node_modules/markdownlint-cli2/markdownlint-cli2-bin.mjs:14:22

AGENTS.md

markdownlint-cli2 v0.21.0 (markdownlint v0.40.0)
Finding: AGENTS.md /*.md !CHANGELOG.md !.venv/ !/node_modules/ !/pycache/ !/*.tpl.md !/.mdc !.kiro/steering/.md
Linting: 84 file(s)
TypeError: Cannot read properties of undefined (reading 'slice')
at applyFix (file:///usr/local/lib/node_modules/markdownlint-cli2/node_modules/markdownlint/lib/markdownlint.mjs:1295:10)
at applyFixes (file:///usr/local/lib/node_modules/markdownlint-cli2/node_modules/markdownlint/lib/markdownlint.mjs:1369:26)
at file:///usr/local/lib/node_modules/markdownlint-cli2/markdownlint-cli2.mjs:758:31
at async Promise.all (index 2)
at async Promise.all (index 0)
at async main (file:///usr/local/lib/node_modules/markdownlint-cli2/markdownlint-cli2.mjs:1001:23)
at async file:///usr/local/lib/node_modules/markdownlint-cli2/markdownlint-cli2-bin.mjs:14:22

docs/README.md

markdownlint-cli2 v0.21.0 (markdownlint v0.40.0)
Finding: docs/README.md /*.md !CHANGELOG.md !.venv/ !/node_modules/ !/pycache/ !/*.tpl.md !/.mdc !.kiro/steering/.md
Linting: 84 file(s)
TypeError: Cannot read properties of undefined (reading 'slice')
at applyFix (file:///usr/local/lib/node_modules/markdownlint-cli2/node_modules/markdownlint/lib/markdownlint.mjs:1295:10)
at applyFixes (file:///usr/local/lib/node_modules/markdownlint-cli2/node_modules/markdownlint/lib/markdownlint.mjs:1369:26)
at file:///usr/local/lib/node_modules/markdownlint-cli2/markdownlint-cli2.mjs:758:31
at async Promise.all (index 2)
at async Promise.all (index 0)
at async main (file:///usr/local/lib/node_modules/markdownlint-cli2/markdownlint-cli2.mjs:1001:23)
at async file:///usr/local/lib/node_modules/markdownlint-cli2/markdownlint-cli2-bin.mjs:14:22

  • 1 others

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

@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented Mar 5, 2026

Merge Protections

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

🟢 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 dependencies Pull requests that update a dependency file evaluator Rule evaluation engine and logic labels Mar 5, 2026
@coderabbitai coderabbitai Bot added documentation Improvements or additions to documentation enhancement New feature or request testing Test infrastructure and coverage labels Mar 5, 2026
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 5, 2026

Codecov Report

❌ Patch coverage is 96.66395% with 41 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/main.rs 57.97% 29 Missing ⚠️
src/evaluator/offset/mod.rs 93.25% 6 Missing ⚠️
src/evaluator/operators/mod.rs 98.96% 3 Missing ⚠️
src/output/mod.rs 50.00% 2 Missing ⚠️
src/evaluator/offset/absolute.rs 96.42% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@dosubot
Copy link
Copy Markdown
Contributor

dosubot Bot commented Mar 5, 2026

Related Documentation

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

libMagic-rs

architecture /libmagic-rs/blob/main/docs/src/architecture.md
View Suggested Changes
@@ -124,9 +124,17 @@
 **Structure:**
 
 - `mod.rs`: Main evaluation engine with `EvaluationContext` and `RuleMatch`
-- `offset.rs`: Offset resolution (absolute, relative, from-end)
 - `types.rs`: Type interpretation with endianness handling and signedness coercion
-- `operators.rs`: Comparison and bitwise operations
+- `offset/`: Offset resolution submodule
+  - `mod.rs`: Dispatcher (`resolve_offset`) and re-exports
+  - `absolute.rs`: `OffsetError`, `resolve_absolute_offset`
+  - `indirect.rs`: `resolve_indirect_offset` stub (issue #37)
+  - `relative.rs`: `resolve_relative_offset` stub (issue #38)
+- `operators/`: Operator application submodule
+  - `mod.rs`: Dispatcher (`apply_operator`) and re-exports
+  - `equality.rs`: `apply_equal`, `apply_not_equal`
+  - `comparison.rs`: `compare_values`, `apply_less_than`/`greater_than`/`less_equal`/`greater_equal`
+  - `bitwise.rs`: `apply_bitwise_and`, `apply_bitwise_and_mask`
 
 **Implemented Features:**
 

✅ Accepted

CI/CD And Merge Queue Configuration
View Suggested Changes
@@ -245,7 +245,7 @@
 
 ### Configuration
 
-[cargo-dist v0.30.3 is configured](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/dist-workspace.toml#L7) with:
+[cargo-dist v0.31.0 is configured](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/dist-workspace.toml#L7) with:
 - **CI Backend**: [GitHub](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/dist-workspace.toml#L9)
 - **Installers**: [shell and homebrew](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/dist-workspace.toml#L11)
 - **Target Platforms**: [7 targets including aarch64 and x86_64 for Apple, Linux, and Windows](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/dist-workspace.toml#L13-L21)
@@ -267,7 +267,9 @@
 
 3. **Complex Logic**: The workflow contains [intricate logic for cross-platform builds, artifact handling, and conditional execution](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/.github/workflows/release.yml#L73-L96) that cargo-dist manages automatically.
 
-4. **Version-Specific**: The workflow is tied to [cargo-dist v0.30.3](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/.github/workflows/release.yml#L67). Manual modifications could break compatibility.
+4. **Version-Specific**: The workflow is tied to [cargo-dist v0.31.0](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/.github/workflows/release.yml#L67). Manual modifications could break compatibility.
+
+5. **Local Enforcement**: The project includes a hookify rule (`hookify.block-release-workflow-edit.local.md`) that blocks attempts to modify `release.yml` locally, catching this mistake before it reaches CI.
 
 ### Release Process
 
@@ -351,6 +353,17 @@
 ### GPG Commit Signing
 
 While the background context mentions GPG commit signing as mandatory, no configuration or enforcement for GPG commit signing was found in the repository configuration files. The repository currently only enforces DCO sign-off (legal certification), not GPG cryptographic signatures.
+
+### Local Enforcement Hooks
+
+The project includes several hookify rules to prevent common CI/CD and contribution mistakes locally:
+
+- **hookify.block-release-workflow-edit.local.md** - Blocks manual edits to `.github/workflows/release.yml`, preventing accidental modifications to the auto-generated cargo-dist workflow
+- **hookify.block-unsigned-commits.local.md** - Blocks commits without DCO sign-off (`git commit` without `-s`), catching missing sign-offs before they reach CI
+- **hookify.block-unsigned-tags.local.md** - Blocks unsigned tags, requiring `git tag -s` for GPG-signed tags
+- **hookify.warn-emoji-in-prs.local.md** - Warns when creating PRs that may contain emoji characters, which violate the project's style guidelines
+
+These hooks complement the CI/CD enforcement by catching issues in the local development environment before code is pushed.
 
 ### PR Checklist
 

✅ Accepted

Parser-Evaluator Architecture
View Suggested Changes
@@ -4,7 +4,7 @@
 
 The parser module is responsible for [converting text-based magic files into hierarchical AST structures](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/parser/mod.rs#L11-L18). It consists of multiple specialized sub-modules: `grammar.rs` (implementing nom-based parsers), `ast.rs` (defining AST node structures), `preprocessing.rs` (handling line continuations and directives), and `hierarchy.rs` (building parent-child rule relationships). The evaluator module consumes the AST and executes rules against file buffers through a [three-stage process](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/mod.rs#L298-L314): offset resolution (determining where to read), type interpretation (reading typed values with endianness support), and operator application (comparing values). This clean separation allows the parser to evolve independently from evaluation logic, provides a serializable intermediate representation, and enables potential alternative evaluator implementations.
 
-The architecture follows a clear data flow pipeline: **Magic File Text → Parser → AST → Evaluator → Match Results**. The AST serves as the contract between modules, with [MagicRule as the primary data structure](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/parser/ast.rs#L175-L192) carrying offset specifications, type information, operators, values, messages, and hierarchical children. The evaluator's specialized sub-modules ([offset.rs](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/offset.rs), [types.rs](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/types.rs), [operators.rs](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/operators.rs)) each handle specific aspects of AST interpretation, demonstrating single-responsibility design principles.
+The architecture follows a clear data flow pipeline: **Magic File Text → Parser → AST → Evaluator → Match Results**. The AST serves as the contract between modules, with [MagicRule as the primary data structure](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/parser/ast.rs#L175-L192) carrying offset specifications, type information, operators, values, messages, and hierarchical children. The evaluator's specialized sub-modules ([offset/](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/offset), [types.rs](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/types.rs), [operators/](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/operators)) each handle specific aspects of AST interpretation, demonstrating single-responsibility design principles.
 
 ## Parser Module Architecture
 
@@ -121,15 +121,23 @@
 
 ### Module Organization
 
-The [evaluator module](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator) is organized into five specialized files:
+The [evaluator module](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator) is organized into specialized submodules:
 
 - **`mod.rs`**: Main evaluation engine with `evaluate_rules()`, `evaluate_single_rule()`, and `EvaluationContext` management (2,639 lines)
-- **`offset.rs`**: Offset resolution for converting `OffsetSpec` to absolute byte positions (476 lines)
+- **`offset/`**: Offset resolution submodule for converting `OffsetSpec` to absolute byte positions
+  - **`mod.rs`**: Dispatcher (`resolve_offset`) and public API re-exports
+  - **`absolute.rs`**: Absolute offset resolution with `OffsetError` and `resolve_absolute_offset()`
+  - **`indirect.rs`**: Indirect offset stub (pointer dereferencing, not yet implemented)
+  - **`relative.rs`**: Relative offset stub (not yet implemented)
 - **`types.rs`**: Type interpretation for reading typed values with endianness support (1,505 lines)
-- **`operators.rs`**: Operator application for comparing values (1,621 lines)
+- **`operators/`**: Operator application submodule for comparing values
+  - **`mod.rs`**: Dispatcher (`apply_operator`) and public API re-exports
+  - **`equality.rs`**: Equality operations (`apply_equal`, `apply_not_equal`)
+  - **`comparison.rs`**: Ordering comparisons (`compare_values`, `apply_less_than`, `apply_greater_than`, `apply_less_equal`, `apply_greater_equal`)
+  - **`bitwise.rs`**: Bitwise operations (`apply_bitwise_and`, `apply_bitwise_and_mask`)
 - **`strength.rs`**: Rule strength calculation for prioritization (874 lines)
 
-Each sub-module exposes public functions and types while encapsulating implementation details, following [single-responsibility principles](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/mod.rs#L1-L8).
+Each sub-module exposes public functions and types while encapsulating implementation details, following [single-responsibility principles](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/mod.rs#L1-L8). The modular structure prepares the codebase for future v0.2.0 feature additions.
 
 ### Evaluation Pipeline
 
@@ -156,9 +164,9 @@
 
 ### Offset Resolution
 
-The [offset.rs module](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/offset.rs) converts `OffsetSpec` variants to absolute byte positions:
-
-**Absolute Offsets**: Positive values are offsets from file start; negative values are offsets from file end.
+The [offset/ submodule](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/offset) converts `OffsetSpec` variants to absolute byte positions. The implementation is organized into separate files for each offset type, with `offset/mod.rs` providing the `resolve_offset()` dispatcher function.
+
+**Absolute Offsets** (handled by `absolute.rs`): Positive values are offsets from file start; negative values are offsets from file end.
 ```rust
 resolve_absolute_offset(0, buffer)   // First byte
 resolve_absolute_offset(-1, buffer)  // Last byte
@@ -173,9 +181,9 @@
 let resolved_offset = buffer_len - offset_from_end;
 ```
 
-The implementation includes comprehensive bounds checking and [special handling for `i64::MIN`](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/offset.rs#L92-L95) to prevent arithmetic overflow.
-
-**Indirect Offsets** (pointer dereferencing) and **Relative Offsets** are currently [parsed but not yet implemented](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/offset.rs#L161-L168) in the evaluator, returning appropriate errors.
+The implementation includes comprehensive bounds checking and [special handling for `i64::MIN`](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/offset/absolute.rs#L92-L95) to prevent arithmetic overflow.
+
+**Indirect Offsets** (pointer dereferencing, handled by `indirect.rs`) and **Relative Offsets** (handled by `relative.rs`) are currently parsed but not yet implemented in the evaluator, returning appropriate errors.
 
 ### Type Interpretation and Endianness
 
@@ -227,9 +235,9 @@
 
 ### Operator Application
 
-The [operators.rs module](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/operators.rs) implements comparison and bitwise operations:
-
-**Equality with Cross-Type Coercion**:
+The [operators/ submodule](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/operators) implements comparison and bitwise operations. The implementation is organized into separate files by operation category, with `operators/mod.rs` providing the `apply_operator()` dispatcher function.
+
+**Equality with Cross-Type Coercion** (from `equality.rs`):
 ```rust
 pub fn apply_equal(left: &Value, right: &Value) -> bool {
     match (left, right) {
@@ -243,9 +251,9 @@
 }
 ```
 
-The implementation [uses `i128` for cross-type integer comparisons](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/operators.rs#L62-L64) to safely handle the full range of both `u64` and `i64` values without overflow.
-
-**Comparison Operators**:
+The implementation [uses `i128` for cross-type integer comparisons](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/operators/equality.rs#L62-L64) to safely handle the full range of both `u64` and `i64` values without overflow.
+
+**Comparison Operators** (from `comparison.rs`):
 ```rust
 pub fn compare_values(left: &Value, right: &Value) -> Option<Ordering> {
     match (left, right) {
@@ -263,7 +271,7 @@
 
 Comparison operators (`<`, `>`, `<=`, `>=`) use `compare_values` to perform ordering comparisons. Same-type comparisons use native Rust ordering, while cross-type integer comparisons use `i128` coercion to safely compare `u64` and `i64` values without overflow. Incomparable type combinations (e.g., integers and strings) return `None` and evaluate to false.
 
-**Bitwise AND Operations**:
+**Bitwise AND Operations** (from `bitwise.rs`):
 ```rust
 pub fn apply_bitwise_and(left: &Value, right: &Value) -> bool {
     match (left, right) {
@@ -483,9 +491,9 @@
 | [`src/parser/format.rs`](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/parser/format.rs) | Magic file format detection | ~90 |
 | [`src/parser/loader.rs`](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/parser/loader.rs) | File system loading and directory merging | ~310 |
 | [`src/evaluator/mod.rs`](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/mod.rs) | Main evaluation engine and context management | 2,639 |
-| [`src/evaluator/offset.rs`](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/offset.rs) | Offset resolution (absolute, relative, indirect) | 476 |
+| [`src/evaluator/offset/`](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/offset) | Offset resolution submodule (absolute, relative, indirect) | ~290 |
 | [`src/evaluator/types.rs`](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/types.rs) | Type interpretation with endianness support | 1,505 |
-| [`src/evaluator/operators.rs`](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/operators.rs) | Operator application and value comparison | 1,621 |
+| [`src/evaluator/operators/`](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/operators) | Operator application submodule (equality, comparison, bitwise) | ~1,930 |
 | [`src/evaluator/strength.rs`](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/evaluator/strength.rs) | Rule strength calculation for prioritization | 874 |
 | [`src/lib.rs`](https://github.com/EvilBit-Labs/libmagic-rs/blob/e925ef6b3f2208fc8805a728ba3de55956f4447a/src/lib.rs) | Integration layer (MagicDatabase) coordinating parser and evaluator | ~1,000 |
 

✅ Accepted

release-process /libmagic-rs/blob/main/docs/src/release-process.md
View Suggested Changes
@@ -164,13 +164,15 @@
 # Create release branch
 git checkout -b release/v0.2.0
 
-# Commit version updates
+# Commit version updates (must be signed)
 git add Cargo.toml CHANGELOG.md README.md
-git commit -m "chore: bump version to 0.2.0"
+git commit -s -m "chore: bump version to 0.2.0"
 
 # Push release branch
 git push origin release/v0.2.0
 ```
+
+**Note:** Commits must be signed with DCO (`-s` flag). The local enforcement hook `.claude/hookify.block-unsigned-commits.local.md` blocks unsigned commits.
 
 #### 2. Final Testing
 
@@ -201,10 +203,12 @@
 git checkout main
 git pull origin main
 
-# Create and push tag
-git tag -a v0.2.0 -m "Release version 0.2.0"
+# Create and push tag (must be signed)
+git tag -s v0.2.0 -m "Release version 0.2.0"
 git push origin v0.2.0
 ```
+
+**Note:** Tags must be GPG-signed. The local enforcement hook `.claude/hookify.block-unsigned-tags.local.md` prevents unsigned tags from being created.
 
 ### GitHub Release
 
@@ -237,7 +241,7 @@
 # Update version to next development version
 # Cargo.toml: version = "0.3.0-dev"
 git add Cargo.toml
-git commit -m "chore: bump version to 0.3.0-dev"
+git commit -s -m "chore: bump version to 0.3.0-dev"
 git push origin develop
 ```
 
@@ -274,8 +278,10 @@
 
 # Commit fix
 git add .
-git commit -m "fix: critical security vulnerability in offset parsing"
-```
+git commit -s -m "fix: critical security vulnerability in offset parsing"
+```
+
+**Note:** All commits must be signed with DCO (`-s` flag).
 
 #### 2. Test Hotfix
 
@@ -302,14 +308,16 @@
 
 # Commit and tag
 git add Cargo.toml CHANGELOG.md
-git commit -m "chore: bump version to 0.2.1"
-git tag -a v0.2.1 -m "Hotfix release 0.2.1"
+git commit -s -m "chore: bump version to 0.2.1"
+git tag -s v0.2.1 -m "Hotfix release 0.2.1"
 
 # Push hotfix
 git push origin hotfix/v0.2.1
 git push origin v0.2.1
 ```
 
+**Note:** Both commits and tags must be signed.
+
 #### 4. Merge Back
 
 ```bash
@@ -331,7 +339,7 @@
 Releases are automated by two complementary tools:
 
 - **release-plz**: Manages crates.io publishing, version bumping, changelog generation, and git tagging
-- **cargo-dist**: Builds cross-platform binaries, Homebrew formulas, SBOM, and GitHub Releases
+- **cargo-dist** (v0.31.0): Builds cross-platform binaries, Homebrew formulas, SBOM, and GitHub Releases
 
 ### How It Works
 
@@ -370,8 +378,12 @@
 | File | Purpose |
 |------|---------|
 | `release-plz.toml` | release-plz configuration (crates.io, tags, changelog) |
-| `dist-workspace.toml` | cargo-dist configuration (binaries, Homebrew, SBOM) |
+| `dist-workspace.toml` | cargo-dist v0.31.0 configuration (binaries, Homebrew, SBOM) |
 | `cliff.toml` | git-cliff changelog template (shared by both tools) |
+
+### Workflow Protection
+
+The release workflow (`.github/workflows/release.yml`) is auto-generated by cargo-dist. Manual modifications are blocked by the local enforcement hook `.claude/hookify.block-release-workflow-edit.local.md`. To update the release workflow, modify `dist-workspace.toml` and run `cargo dist generate`.
 
 ### Authentication
 

✅ Accepted

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

How did I do? Any feedback?  Join Discord

Copy link
Copy Markdown

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 refactors the evaluator module by splitting monolithic files (operators.rs and the offset logic within absolute.rs) into focused submodules, preparing the codebase for v0.2.0 features like indirect/relative offset support. It also updates dependencies, the release workflow, adds local hookify enforcement files, and updates AGENTS.md to reflect the new structure.

Changes:

  • Split operators.rs into operators/mod.rs (dispatcher), operators/equality.rs, operators/comparison.rs, and operators/bitwise.rs; split offset logic into offset/mod.rs (dispatcher), offset/absolute.rs, offset/indirect.rs (stub), and offset/relative.rs (stub).
  • Updated tool and dependency versions across mise.toml, mise.lock, dist-workspace.toml, and release.yml (cargo-dist 0.31.0, Rust 1.93.1, Python 3.14.3, etc.).
  • Added four local hookify enforcement files to block unsigned commits/tags, manual release workflow edits, and warn about emoji in PRs.

Reviewed changes

Copilot reviewed 17 out of 18 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/evaluator/operators/mod.rs New dispatcher: re-exports submodule functions, hosts apply_operator and integration tests
src/evaluator/operators/equality.rs Moved apply_equal/apply_not_equal and their tests
src/evaluator/operators/comparison.rs Moved compare_values and comparison operators with tests
src/evaluator/operators/bitwise.rs Moved apply_bitwise_and, new apply_bitwise_and_mask function, and tests
src/evaluator/operators.rs Deleted monolithic file (all content moved to submodules)
src/evaluator/offset/mod.rs New dispatcher: resolve_offset and integration tests
src/evaluator/offset/absolute.rs Trimmed to only absolute offset logic and its tests
src/evaluator/offset/indirect.rs New stub for indirect offset resolution
src/evaluator/offset/relative.rs New stub for relative offset resolution
AGENTS.md Updated evaluator directory tree to reflect new submodule structure
mise.toml / mise.lock Bumped tool/dependency versions
dist-workspace.toml Updated cargo-dist to 0.31.0, minor formatting changes
.github/workflows/release.yml Updated cargo-dist installer URL to v0.31.0
.claude/hookify.*.local.md Four new local enforcement hook files

Comment thread src/evaluator/offset/mod.rs Outdated
Copilot AI review requested due to automatic review settings March 5, 2026 04:20
@unclesp1d3r unclesp1d3r review requested due to automatic review settings March 5, 2026 04:20
Copilot AI review requested due to automatic review settings March 5, 2026 04:21
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Copilot AI review requested due to automatic review settings March 5, 2026 05:20
@dosubot dosubot Bot added size:XXL This PR changes 1000+ lines, ignoring generated files. and removed size:XL This PR changes 500-999 lines, ignoring generated files. labels Mar 5, 2026
Copy link
Copy Markdown

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

Copilot reviewed 66 out of 68 changed files in this pull request and generated 3 comments.

Comment thread docs/src/cli-usage.md Outdated
Comment thread docs/src/cli-reference.md Outdated
Comment thread docs/CLI_REFERENCE.md Outdated
- Extract map_offset_error helper to deduplicate error mapping in
  resolve_offset for Absolute and FromEnd arms
- Pin dtolnay/rust-toolchain to commit hash instead of unpinned master ref
- Fix docs incorrectly stating --use-builtin takes precedence over
  --magic-file; they are now mutually exclusive (conflicts_with)
- Exclude .claude/ directory from mdformat pre-commit hook

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
coderabbitai[bot]
coderabbitai Bot previously approved these changes Mar 5, 2026
…hain

The quality job used dtolnay/rust-toolchain to install stable with
rustfmt and clippy, but mise-action then overrode it by setting
RUSTUP_TOOLCHAIN to the pinned version (1.93.1). On cache miss,
mise installs the toolchain without rustfmt, causing cargo-fmt to
fail. Remove the redundant action and add an explicit rustup
component add step after mise to guarantee components are present.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
coderabbitai[bot]
coderabbitai Bot previously approved these changes Mar 5, 2026
Copy link
Copy Markdown

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

Copilot reviewed 66 out of 68 changed files in this pull request and generated 1 comment.

Comment thread docs/src/cli-reference.md Outdated
…tion

Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Include -j, -m, -b, -s, -t short flags alongside their long-form
equivalents in all CLI documentation tables.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
Copilot AI review requested due to automatic review settings March 5, 2026 06:01
@coderabbitai coderabbitai Bot added the output Result formatting and output generation label Mar 5, 2026
Copy link
Copy Markdown

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

Copilot reviewed 66 out of 68 changed files in this pull request and generated no new comments.

Signed-off-by: UncleSp1d3r <unclesp1d3r@evilbitlabs.io>
coderabbitai[bot]
coderabbitai Bot previously approved these changes Mar 5, 2026
@unclesp1d3r unclesp1d3r enabled auto-merge (squash) March 5, 2026 06:12
@unclesp1d3r unclesp1d3r merged commit cd49704 into main Mar 5, 2026
27 of 28 checks passed
@unclesp1d3r unclesp1d3r deleted the 62-refactor-pre-create-evaluator-submodules-for-v020-features branch March 5, 2026 06:14
@github-actions github-actions Bot mentioned this pull request Mar 5, 2026
mergify Bot pushed a commit that referenced this pull request Mar 5, 2026
## 🤖 New release

* `libmagic-rs`: 0.3.1 -> 0.3.2 (✓ API compatible changes)

<details><summary><i><b>Changelog</b></i></summary><p>

<blockquote>

## [0.3.2] - 2026-03-05

### Refactor

- Pre-create evaluator submodules for v0.2.0 features
([#142](#142))
<!-- generated by git-cliff -->
</blockquote>


</p></details>

---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli Command-line interface and tools dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation enhancement New feature or request evaluator Rule evaluation engine and logic io File I/O and memory mapping output Result formatting and output generation size:XXL This PR changes 1000+ lines, ignoring generated files. testing Test infrastructure and coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor: pre-create evaluator submodules for v0.2.0 features

3 participants