Skip to content

Automated Code Reviews

The Dice Chess Engine uses CodeRabbit for automated pull request reviews. CodeRabbit analyzes every PR against main and provides inline feedback on correctness, performance, and style — with domain-specific awareness of our chess engine architecture.


CodeRabbit is one layer in a multi-stage quality pipeline:

graph LR
    subgraph Local
        A["pre-commit hooks<br/>(betterleaks + scalafmt + actionlint)"] --> B["mise run check<br/>(full gate, before PR)"]
    end
    subgraph CI
        C["sbt scalafmt + scalafix + MUnit"] --> D["SonarCloud"]
        C --> E["CodeRabbit"]
    end
    B -.->|same checks| C

Hooks are managed by lefthook (lefthook.yml).

LayerToolPurpose
Pre-commitbetterleaksIntercept leaked secrets before they reach Git history
Pre-commitscalafmtFormat check on staged .scala/.sbt files
Pre-commitactionlintLint staged GitHub Actions workflow files
CIscalafmtEnforce consistent Scala code formatting
CIscalafixEnforce strict syntax rules (ban null, throw, return)
CIMUnit + scoverageUnit tests with coverage reporting (>85%)
CICodeRabbitAI-powered PR review with domain-specific instructions
CISonarCloudStatic analysis: code smells, vulnerabilities, coverage metrics

Strict Typing & Linting (Scalafix & Compiler Flags)

Section titled “Strict Typing & Linting (Scalafix & Compiler Flags)”

To ensure memory safety, functional purity, and a high-performance codebase, we enforce strict compiler and linter rules. These constraints prevent common anti-patterns like NullPointerExceptions and obscure control flow bugs.

  • -Yexplicit-nulls: Changes the Scala 3 type system so that reference types (like String or AnyRef) are non-nullable by default. This forces developers to use Option[T] to safely represent the absence of a value, eliminating implicit nulls at the compiler level.
  • -language:strictEquality: Requires explicit opt-in (via CanEqual typeclasses) to compare two objects with ==. This catches bug-prone comparisons (like comparing a Square to a Piece) at compile-time instead of silently returning false at runtime.

We actively ban problematic keywords through .scalafix.conf:

  • null: The null keyword is strictly forbidden. This protects the JS boundary (where JS might pass null), forcing us to safely wrap it via Option(value) instead.
  • throw: Throwing exceptions breaks referential transparency and control flow. We use sys.error for truly unrecoverable fatal errors, or Either/Option for business logic errors.
  • return: Explicit return statements are banned because they can cause unintended behavior inside lambdas and closures. We instead rely on Scala 3’s boundary/break constructs for early exit logic, or simply standard functional expressions (if/else).

All CodeRabbit settings live in .coderabbit.yaml at the repository root. The file uses the v2 schema and is version-controlled alongside the codebase.

The review profile is set to assertive, which provides rigorous, performance-oriented feedback — appropriate for a chess engine where micro-optimization and bitwise correctness are critical.

FeatureReason
high_level_summaryAdds noise to PR threads without actionable value
poemDecorative; distracting in a technical engine project
eslintNo hand-written JavaScript — all JS is machine-generated by Scala.js
biomeNo JS/TS source code to format or lint
ToolWhat It Checks
actionlintValidates GitHub Actions workflow YAML syntax and expressions
betterleaksDetects leaked secrets (complements the pre-commit hook)
shellcheckLints shell scripts embedded in mise.toml and CI workflows
markdownlintValidates documentation and README markdown formatting

Build artifacts, generated files, and vendored dependencies are excluded from review to reduce noise:

path_filters:
- "!**/target/**" # SBT build output
- "!**/project/target/**" # SBT meta-build output
- "!dist/**" # NPM package distribution
- "!**/*.lock" # Lock files
- "!**/package-lock.json" # NPM lock file
- "!docs/public/**" # Static assets

CodeRabbit supports path-based review instructions — targeted guidance that activates only when a PR touches specific directories. This gives the AI reviewer domain knowledge about our engine architecture.

Path PatternReview Focus
shared/**/domain/**Opaque type contracts, zero-cost abstraction, bitwise correctness
shared/**/movegen/**Magic Bitboards, GC-free hot paths, Dice Chess rule enforcement
shared/src/test/**Test DSL usage, edge case coverage, JSON fixture validity
.github/workflows/**Pinned action SHAs, consistent Java/Node versions, no redundant tool installs
docs/**Starlight frontmatter, Mermaid syntax, internal link integrity
build.sbtCross-compilation consistency, plugin configuration

When a PR modifies files under shared/**/movegen/**, CodeRabbit receives these instructions:

Prioritize correctness of bitwise shift/mask operations. Flag any heap allocations in hot paths. Verify Magic Bitboard lookup tables are indexed correctly. Check that Dice Chess rules are applied: max 3 micro-moves per turn, maximal micro-move count enforcement, and correct piece filtering by dice roll value.

This ensures the AI reviewer focuses on engine-specific concerns rather than generic code style.


On any PR, you can use comment commands to interact with CodeRabbit:

CommandEffect
@coderabbitai reviewTrigger a full re-review of the PR
@coderabbitai resolveMark all CodeRabbit comments as resolved
@coderabbitai configurationDisplay the current effective configuration
@coderabbitai helpList all available commands