Skip to main content
The Crimsonland project enforces strict verification requirements to ensure deterministic parity and code quality.

Required Pre-Commit Checks

Before committing changes, you must verify your code passes all checks.

Quick Verification

just check
This runs the complete verification suite:
1

Linting

uv run ruff check .
Fast linting for code quality issues.
2

Import Validation

uv run lint-imports
Enforces import contracts (e.g., grim must not import crimson).
3

Type Checking

uv run ty check src tests
Type validation using the ty type checker.
4

Documentation Validation

uv run scripts/check_docs.py
Validates documentation structure and links.
5

Structural Code Scanning

sg scan
sg test
ast-grep rules for enforcing code patterns.
6

Test Suite

uv run pytest
Full test suite (200+ tests).
7

Zig Build & Tests (if applicable)

just check-zig
Zig compilation and test suite.

Pre-Commit Hooks

Automatically run verification checks on commit and push.

Installation

prek install -c prek.toml -t pre-commit -t pre-push

Hook Stages

Runs on git commit, file-scoped fast checks:
  • ruff check (linting)
  • import-linter (import contracts)
  • ty check (type checking)
  • scripts/check_docs.py (docs validation)
  • sg scan (ast-grep)
  • ziglint (Zig linting, if applicable)
Manual run:
prek run --stage pre-commit
ziglint behavior is configured in crimson-zig/.ziglint.zon (Z024 disabled).

CI-Equivalent Local Runs

Run the exact checks that CI will run:

Python/Docs/Tooling Changes

For changes to src/, tests/, docs/, tools/:
just check && uv build

Zig-Only Changes

For changes to crimson-zig/:
just check-zig
This runs:
cd crimson-zig && zig build test --summary all
cd crimson-zig && zig build -Doptimize=ReleaseFast
cd crimson-zig && zig build wasm

Mixed Changes

For changes to both Python and Zig:
just check && uv build
just check-zig

Individual Verification Steps

Linting

# Run ruff linter
uv run ruff check .

# Auto-fix safe issues
uv run ruff check --fix .

# Show all issues (including fixed)
uv run ruff check --fix --show-fixes .
Ruff configuration is in pyproject.toml:
  • Line length: 120
  • Enabled rules: B007, B017, B023, B904, COM812, I001, PGH003, PT017, RUF012, RUF100, S113, S607, TRY004, UP035
  • Ignored: E402

Import Contracts

# Validate import structure
uv run lint-imports
Enforces contracts defined in pyproject.toml:
The engine layer (grim) must remain independent of game logic (crimson).
Perk implementations and runtime must stay out of selection and availability logic.
Selection and availability must not import perk implementations directly.

Type Checking

# Check source and tests
uv run ty check src tests

# Check only source
uv run ty check src

# Check only tests
just ty-tests

Documentation Validation

# Validate docs structure
uv run scripts/check_docs.py

# Build docs site
just docs-build

# Serve docs locally
zensical serve

AST-grep Scanning

# Run configured rules
sg scan

# Test ast-grep rules
sg test

# Apply fixes (example)
sg run -p 'pattern' -r 'replacement' src -U

Testing

# Run all tests
uv run pytest

# Run with coverage
just test-cov

# Run specific test file
uv run pytest tests/test_gameplay.py
See Testing Guide for detailed test instructions.

Build Verification

# Build Python package
uv build

# Build Zig (if applicable)
cd crimson-zig && zig build

Verification Failures

Linting Failures

Most linting issues can be auto-fixed:
uv run ruff check --fix .
For issues that can’t be auto-fixed, address them manually or use inline ignores sparingly:
# Only when justified and documented
from legacy_module import old_function  # noqa: F401

Type Checking Failures

Do not cast to Any or use .get()/getattr() to dodge typing. Fix the schema/boundary/model instead.
Common fixes:
  • Add type annotations to function signatures
  • Use proper type guards for conditionals
  • Define typed dataclasses for structured data
  • Fix boundary parsing to return typed objects

Import Contract Violations

If lint-imports fails:
  1. Review the contract - Is the import genuinely needed?
  2. Restructure - Can the dependency be inverted?
  3. Extract interface - Should there be a shared protocol?

Test Failures

For test failures:
  1. Read the failure message - What assertion failed?
  2. Check parity evidence - Does this match native behavior?
  3. Isolate the test - Run it individually with -v
  4. Debug - Use --pdb to drop into debugger
See Testing Guide for debugging techniques.

Skipping Checks (Discouraged)

Skipping checks should be rare and justified. CI will still run all checks.

Skip Pre-Commit Hook

# Only when absolutely necessary
git commit --no-verify

Skip Pre-Push Hook

# Only when absolutely necessary
git push --no-verify

Verification Best Practices

Run Checks Frequently

Run just check frequently during development, not just before committing.

Fix Issues Immediately

Address verification failures as they arise, don’t accumulate technical debt.

Understand Failures

Don’t blindly fix verification failures. Understand why the check exists.

Use Hooks

Install pre-commit and pre-push hooks to catch issues early.

Next Steps

Testing Guide

Deep dive into testing practices

Parity Workflow

Learn the parity-first development approach

Code Style

Follow project coding standards

Tooling Guide

Explore development tools and scripts

Build docs developers (and LLMs) love