glreview

GitLab code review tracking for scientific software

Track, persist, and enforce module-level review coverage
across your entire codebase.

The Problem

PR review tells you a diff was approved.
It doesn't tell you whether a module has been reviewed.

The Solution

📋

Track

Module-level review state with assignees, issues, and commit history

💾

Persist

JSON registry lives in your repo — versioned, diffable, portable

⚙️

Integrate

CI gates, AI-assisted reviews, MR creation, badge generation

needs_review
in_progress
reviewed
changed

Quick Start

Configure

# pyproject.toml [tool.glreview] sources = ["src/**/*.py"] exclude = ["**/_version.py"]

Initialize

Terminal
$ glreview init Initialized glreview with 18 modules Registry: .glreview/registry.json Next steps: 1. Commit the .glreview/ directory 2. Run 'glreview status' to see review coverage 3. Run 'glreview ci-config' for GitLab CI setup $ git add .glreview/ && git commit -m "init glreview" [main abc1234] init glreview 2 files changed, 154 insertions(+)

Review Workflow

needs_review
start →
in_progress
signoff →
reviewed
Terminal
$ glreview start src/glreview/service.py --assignee @alice Creating review issue for src/glreview/service.py... ✓ Review started for src/glreview/service.py Issue: https://git.ligo.org/chad.hanna/glreview/-/issues/42 Assignee: @alice When review is complete, run: glreview signoff src/glreview/service.py $ glreview signoff src/glreview/service.py --reviewer @alice Checking issue #42... State: closed ✓ src/glreview/service.py Status: reviewed Commit: def5678abcdef Reviewers: @alice Issue: https://git.ligo.org/chad.hanna/glreview/-/issues/42

Status Dashboard

Terminal
$ glreview status Review Progress: [███████████████░░░░░] 75% Modules: 15/20 reviewed Lines: 12,450/16,200 (77%) ◐ In Progress (2) src/glreview/service.py Assignee: @alice Issue: https://git.ligo.org/.../issues/42 ○ Needs Review (3) src/glreview/claude.py (580 lines) src/glreview/git.py (210 lines) src/glreview/templates.py (95 lines) ✓ Reviewed (15) All 15 reviewed modules are up to date.

AI-Assisted Review

1. Generate context

Terminal
$ glreview claude-init Found 18 modules to analyze... Running Claude analysis (opus)... ✓ Project context generated File: .glreview/context.json Modules analyzed: 18 Next steps: 1. Review .glreview/context.json 2. Commit the context file 3. Run 'glreview claude-sync' after significant changes

2. Run review

Terminal
$ glreview claude-review src/glreview/service.py Running Claude review (opus)... Using context for src/glreview/service.py Including 2 test file(s) ============================================================ CLAUDE REVIEW RESULTS ============================================================ REQUIRED 1. error-handling: Missing validation on user input in start_review() at line 142. Sanitize before GitLab API call. SUGGESTED 1. docs: Add docstring to _resolve_commit() 2. naming: Rename tmp to cached_result ============================================================ ✓ Posted review to GitLab issue ✓ Set label review::required

AI Fix

Automatically apply fixes from review findings

Terminal
$ glreview claude-fix src/glreview/service.py --batch --create-mr Fetching review from issue #42... Batch mode: fixing 1 REQUIRED items Running Claude fix (opus) in batch mode... ============================================================ CLAUDE FIX RESULTS ============================================================ Added input validation to start_review(): - Sanitize path argument against traversal - Validate assignee format before API call - Added test: test_start_review_validation ============================================================ Fix session complete. ✓ MR created: https://git.ligo.org/.../merge_requests/7

Or review everything at once: glreview batch-start --claude-review

CI Integration

.gitlab-ci.yml

stages: - test - review review: stage: review image: python:3.12 script: - pip install glreview - glreview ci --report REVIEW_COVERAGE.md # Block release without 100% coverage release-gate: stage: review script: - pip install glreview - glreview ci --fail-under 100 rules: - if: $CI_COMMIT_TAG

CI Output

GitLab CI
$ glreview ci --fail-under 100 Review coverage: 75% (15/20 modules) Report written to REVIEW_COVERAGE.md FAIL: 2 reviewed module(s) have changed: src/glreview/foo.py (reviewed at abc1234) src/glreview/bar.py (reviewed at def5678) FAIL: Review coverage 75% < 100% ERROR: Job failed: exit code 1

Configuration

# pyproject.toml [tool.glreview] sources = ["src/**/*.py"] # glob patterns for modules exclude = ["**/_version.py"] # files to skip # Priority rules — match patterns to review levels [[tool.glreview.priority]] pattern = "src/glreview/cli.py" # exact module path level = "critical" # critical | high | normal reviewers_required = 2 # require multiple reviewers [[tool.glreview.priority]] pattern = "src/glreview/*.py" # glob matching level = "high" reviewers_required = 1 # Claude AI configuration (optional) [tool.glreview.claude] review_instructions = """ Focus on scientific correctness and numerical stability. Flag any hardcoded physical constants. """ fix_instructions = """ Preserve all existing test coverage. Follow numpy docstring conventions. """

Architecture

CLI
cli.py
cli_claude.py
cli_ci.py
▼ ▼ ▼
Service
service.py
claude.py
▼ ▼
Core
registry.py
config.py
models.py
▼ ▼
Infra
git.py
gitlab.py
templates/

Clean layer separation — each layer only depends on layers below it

Get Started

Terminal
$ pip install glreview
  1. 1Add [tool.glreview] to pyproject.toml
  2. 2Run glreview init
  3. 3Start reviewing with glreview start
  4. 4Add CI with glreview ci-config

git.ligo.org/chad.hanna/glreview

MIT License · Python 3.10+