Skip to main content

Classify git diffs using chess.com-style move categories (Brilliant, Blunder, and everything between).

Project description

chess-review-bot

chess.com's Game Review vocabulary — Brilliant!!, Great!, Best, Excellent, Good, Book, Inaccuracy?!, Mistake?, Blunder??, Miss — pointed at a git diff instead of a chess move.

chess-review-bot  ──────────────────────────────────────────────
  Diff:        HEAD~1..HEAD  ·  3 files  ·  +142 / -38 lines
  Accuracy:     71/100
──────────────────────────────────────────────────────────────

  src/auth/session.py                                  Blunder??
    → touches critical path with no matching test changes
    → "chess-review-bot says: hanging your queen in the auth module
       without a single test is how production incidents are born."

  src/utils/formatting.py                              Book
    → dependency/formatting-only change, nothing to see here

  tests/test_session.py                                Great!
    → tests added alongside a meaningful source change

──────────────────────────────────────────────────────────────
Result: FAIL (1 Blunder)  ·  Exit code: 1

The one design decision that matters

Category is never LLM-decided. Deterministic signals (size, test-file overlap, critical-path membership, force-push, revert, commit message quality, credential leakage) run through a fixed rule table. Delete commentary.py — classification doesn't change.

LLM's only job (optional): phrase an already-decided category in one dry sentence. Same lesson as position-evaluator: LLMs are bad at inventing a severity scale, good at picking from a fixed one.

Install

pip install chess-review-bot

Zero required runtime deps. Commentary is an opt-in extra:

pip install "chess-review-bot[commentary]"

No extra / no Gemini key: still classifies and reports correctly, just prints the deterministic reason instead of a generated sentence.

CLI usage

chessreview                       # HEAD~1..HEAD in current repo
chessreview HEAD~5..HEAD          # wider range
chessreview my-change.diff        # saved diff file
git diff | chessreview -          # stdin
Option Description
--critical PATTERN Critical-path glob. Repeatable, adds to defaults.
--only-critical PATTERN Replace default critical-path globs. Repeatable.
--large-threshold N Lines changed = "large". Default 400.
--moderate-threshold N Lines changed = "moderate". Default 100.
--force-pushed Flag as force-pushed (local testing only).
--revert Flag as a revert.
--enable-commentary Gemini one-line commentary. Requires a key.
--gemini-key TEXT Or set GEMINI_API_KEY.
--format [text|json|markdown] Default: text.
--summary One-line output.
--debug Show per-file signals.

Exit codes: 0 clean, 1 Blunder found, 2 tool error.

GitHub Action

- uses: actions/checkout@v4
  with:
    fetch-depth: 0   # needed for force-push ancestry check

- uses: SemTiOne/chess-review-bot@v1
  with:
    github-token: ${{ secrets.GITHUB_TOKEN }}
    gemini-key: ${{ secrets.GEMINI_API_KEY }}   # optional
    fail-on-blunder: 'true'
Input Description Default
github-token pull-requests: write + contents: read. required
gemini-key Optional, enables commentary. ''
critical-paths Newline-separated globs. built-in defaults
large-threshold Lines changed = "large". 400
moderate-threshold Lines changed = "moderate". 100
fail-on-blunder Fail check on any Blunder??. true
post-comment Post/update the PR review card. true

One comment per PR, updated on every push (idempotency marker <!-- chess-review-bot-managed-comment -->) — never a second comment.

### ♟️ chess-review-bot — PR Game Review

**Accuracy: 71/100** · 3 files · +142/-38 · 1 Blunder??

| File | Category | Why |
|---|---|---|
| `src/auth/session.py` | Blunder?? | critical path, no tests, no description |
| `src/utils/formatting.py` | Book | dependency/formatting-only change |
| `tests/test_session.py` | Great! | tests added alongside a real change |

What this deliberately does NOT do

  • Never scores or names a person. Diffs and commits only, never authors. An earlier concept scored people ("most toxic collaborator") — rejected on purpose: a screenshotted report naming someone is an HR incident, and no manager installs a tool that can start a fight on their team.
  • Doesn't find bugs. Severity communication, not a correctness/security scanner. Pair with your existing linters/CI.
  • Commit-message quality is a blunt denylist heuristic, not sentiment analysis.
  • Force-push detection is Action-mode only. Compares synchronize event's before/after SHAs via git merge-base --is-ancestor (needs fetch-depth: 0). CLI can't infer this from reflog — pass --force-pushed to test it locally. (Earlier draft assumed a forced payload field; that field only exists on push events, not pull_request. See CHANGELOG.md.)

Exit codes

Code Meaning
0 No file classified Blunder??
1 At least one Blunder??
2 Tool error (bad input, invalid config, git failure)

Companion tools

  • position-evaluator — the original: chess terminology for personal decisions, not code.
  • env-auditor — finds undocumented, stale, and missing environment variables across JS, Python, Go, Ruby, Shell, and Docker.

Releasing

Bump version in pyproject.toml and CHESSREVIEW_VERSION in action/action.yml (has to match; github.action_ref is not reliable inside composite actions, so this can't be derived automatically, has to be kept in sync by hand every release). Commit, then:

git tag v0.1.1
git push --tags

release.yml runs tests, checks the tag matches pyproject.toml, builds, and publishes to PyPI via Trusted Publishing (OIDC). One-time setup on PyPI: add SemTiOne/chess-review-bot as a pending publisher for workflow release.yml, environment pypi, before the first tag push.

Floating major-version tag: consumers reference @v1, not @v0.1.1 directly; same convention as actions/checkout@v4. After tagging an exact version, move the floating tag to match:

git tag -fa v1 -m "v1"
git push origin v1 --force

Only do this once the exact-version tag (v0.1.1) is already pushed and release.yml has passed — don't move v1 to a commit that hasn't been verified yet.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

chess_review_bot-0.1.1.tar.gz (32.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

chess_review_bot-0.1.1-py3-none-any.whl (22.6 kB view details)

Uploaded Python 3

File details

Details for the file chess_review_bot-0.1.1.tar.gz.

File metadata

  • Download URL: chess_review_bot-0.1.1.tar.gz
  • Upload date:
  • Size: 32.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for chess_review_bot-0.1.1.tar.gz
Algorithm Hash digest
SHA256 43031fa0f04a3e5ec9b41e7326dd148e74e6e7140ffd041f321f42c8ec0ad553
MD5 cd5ade2ae2e51005f1842c2bbb219adf
BLAKE2b-256 304fe74f462476eb0f77281286a07d6e45d4e547d8ac665e7b9cd60aa48bee8b

See more details on using hashes here.

Provenance

The following attestation bundles were made for chess_review_bot-0.1.1.tar.gz:

Publisher: release.yml on SemTiOne/chess-review-bot

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file chess_review_bot-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for chess_review_bot-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 c216a084f8628529bc80a0a1e98ab0e5313ed1ad96e6ae4d36a432591c28d65d
MD5 0f640b365477b910f51096bac163f8b0
BLAKE2b-256 0662609082b70685b16eba052689e1735d5d22273805616a0480d06617efa7cb

See more details on using hashes here.

Provenance

The following attestation bundles were made for chess_review_bot-0.1.1-py3-none-any.whl:

Publisher: release.yml on SemTiOne/chess-review-bot

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page