Skip to content

Migrate git hooks scripts from Bash to Rust #1843

Description

@josecelano

Goal

Replace the three Bash scripts that implement pre-commit checks, pre-push checks, and git hook installation with a single Rust binary that improves testability, type safety, and maintainability, and that adds real-time feedback during long-running checks so developers and automation agents can see hook progress without cancelling valid runs.

Scripts to replace

Script Purpose
contrib/dev-tools/git/hooks/pre-commit.sh Runs fast quality checks (cargo machete --with-metadata, linter, doc tests)
contrib/dev-tools/git/hooks/pre-push.sh Runs comprehensive checks (machete, linters, nightly build, tests, E2E)
contrib/dev-tools/git/install-git-hooks.sh Installs hooks from .githooks/ to .git/hooks/

Motivation

The scripts have grown beyond simple orchestration (engineering policy #3 in AGENTS.md). They now implement structured argument parsing, a multi-step runner with timing and log management, and two output modes — logic that is duplicated across both scripts. This also creates feedback UX and redundant-execution problems:

  • Hooks appear hung during long checks (pre-push takes ~15 min); no intermediate progress is visible.
  • If only Markdown files are staged, the full Rust suite still runs unnecessarily.
  • Hooks re-run even when they already passed for the same set of changes.

Implementation plan (two phases)

Phase 1 — Core migration: implement the same steps as the current scripts using NDJSON output (no --format=text|json switch), switch over, and remove the Bash scripts.

Phase 2 — Enhancements: heartbeat events for long steps, smart step skipping for docs-only commits, and idempotency cache to skip hooks that already passed for the same changes.

Full spec

See docs/issues/open/ for the complete implementation spec once the spec-only PR is merged.

Compliance

The new binary must comply with the global CLI output contract ADR (docs/adrs/20260519000000_define_global_cli_output_contract.md) from day one: no-stdout-result class, NDJSON on stderr, exit codes 0/1/2.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions