Skip to content

ci: lint gates (clippy, ruff, thaw-lint) + contributor rails#94

Merged
matteso1 merged 1 commit into
mainfrom
ci/lint-gates-and-thaw-lint
Jun 25, 2026
Merged

ci: lint gates (clippy, ruff, thaw-lint) + contributor rails#94
matteso1 merged 1 commit into
mainfrom
ci/lint-gates-and-thaw-lint

Conversation

@matteso1

@matteso1 matteso1 commented Jun 25, 2026

Copy link
Copy Markdown
Member

Now that two of us are shipping PRs, this adds deterministic CI gates + a project-specific linter so the pipeline stays clean — without a one-shot tree cleanup that would collide with the open PRs (#87, #93).

lint CI job

  • cargo clippy -D warnings tree-wide — the workspace is clean today, so this is a pure regression guard.
  • thaw-lint tree-wide — every ERROR rule is currently green.
  • ruff --select F,E9 on changed Python only — new/touched code must be clean; the ~36 pre-existing real-bug findings (mostly unused imports) don't block anyone. The ratchet to a tree-wide gate is documented in CONTRIBUTING.md. (cargo fmt --check is intentionally deferred — a full cargo fmt touches ~16 files and would conflict with open Rust PRs.)

tools/thaw_lint.py — the project-specific footgun linter

Small, dependency-free, scans git ls-files (so it never wanders into gitignored build output). Two tiers — ERROR fails CI, WARN just surfaces — plus # thaw-lint: allow inline suppression. Rules encode the "cost me hours" constraints from CLAUDE.md:

Rule Tier
import thaw_native (the wheel installs the module thaw) ERROR
personal @icloud.com email in tracked files ERROR
archived matteso1/thaw URL ERROR
leftover breakpoint() / pdb.set_trace() ERROR
retracted speedup multipliers (17.2x/12.6x/9.7x/5.9x) in README/site ERROR
hard-set VLLM_ALLOW_INSECURE_SERIALIZATION (must be setdefault) ERROR
curl … | bash in our own scripts WARN

17 unit tests cover detection and the false-positive guards (dependency specs, thaw_native_version dict keys, rustup's curl … | sh, docs that legitimately retract the numbers).

The linter's first real catch

Fixed 20 stale matteso1/thaw URLs (the repo moved to thaw-ai/thaw; the old one is archived and 404s clone scripts) across Cargo.toml, demo + pod scripts, docs, and notebooks.

Contributor rails

CONTRIBUTING.md + a PR template: the branch/PR loop, the gates and how to run them locally, the ruff ratchet, receipt/benchmark hygiene, the format-vs-transport ownership boundary, and the release version-file gotcha.

Verification

  • python tools/thaw_lint.py → clean (2 expected WARNs)
  • pytest tests/test_thaw_lint.py → 17 passed
  • ruff check --select F,E9 on changed files → clean
  • cargo clippy --workspace --exclude thaw-py --all-targets → zero warnings locally

Summary by CodeRabbit

  • New Features

    • Added automated repository hygiene checks for Python and Rust during CI.
    • Introduced a project-wide linting tool with clear pass/warn behavior and line-level exemptions.
  • Bug Fixes

    • Updated clone/install references throughout docs, demos, notebooks, and scripts to use the current repository location.
  • Documentation

    • Added detailed contribution guidance, including PR scope, verification steps, lint/test expectations, and release notes requirements.
  • Tests

    • Added coverage for the new linting rules and allowed exceptions.

Two engineers are now shipping PRs, so add deterministic gates and a
project-specific linter that keep the pipeline clean without a one-shot
tree cleanup that would collide with in-flight work.

lint CI job (.github/workflows/test.yml):
- cargo clippy -D warnings, tree-wide (the workspace is clean today, so
  this is a regression guard)
- thaw-lint, tree-wide (every ERROR rule is currently green)
- ruff --select F,E9 on CHANGED Python only — new/touched code must be
  clean; the ~36 legacy real-bug findings don't block the open PRs. The
  ratchet to a tree-wide gate is documented in CONTRIBUTING.

tools/thaw_lint.py: a small, dependency-free regex linter over
`git ls-files` with ERROR (fails CI) / WARN tiers and `# thaw-lint: allow`
inline suppression. Rules encode CLAUDE.md's "cost me hours" constraints:
import thaw_native, personal @iCloud email, archived matteso1/thaw URL,
leftover debugger, retracted speedup multipliers in README/site, and
hard-set VLLM_ALLOW_INSECURE_SERIALIZATION. 17 unit tests cover detection
plus the false-positive guards (dep specs, dict keys, rustup curl|sh,
docs that legitimately retract numbers).

Fix the linter's first real catch: 20 stale matteso1/thaw URLs (the repo
moved to thaw-ai/thaw; the old one is archived) across Cargo.toml, demo +
pod scripts, docs, and notebooks.

CONTRIBUTING.md + PR template: the branch/PR loop, the gates and how to
run them locally, the ruff ratchet, receipt/benchmark hygiene, the
format-vs-transport ownership boundary, and the release version-file gotcha.
@vercel

vercel Bot commented Jun 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
site Ignored Ignored Jun 25, 2026 12:41am

Request Review

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds a new thaw-lint script, wires it into tests and CI, expands contribution guidance, and updates repository references in docs, notebooks, demos, scripts, and metadata to thaw-ai/thaw.

Changes

PR guidance and lint enforcement

Layer / File(s) Summary
PR template and contributor guide
.github/pull_request_template.md, CONTRIBUTING.md
PR sections, checklists, local checks, lint rule guidance, receipt requirements, GPU guidance, and release steps are added.
thaw-lint core
tools/thaw_lint.py
New rule definitions, file scoping, suppression handling, file discovery, CLI output, and exit codes are implemented.
thaw-lint tests
tests/test_thaw_lint.py
Rule-specific cases cover matches, allowed look-alikes, suppression markers, and rule metadata.
lint workflow
.github/workflows/test.yml
The workflow installs ruff, runs changed-file ruff checks, executes tools/thaw_lint.py, and adds Rust clippy steps.

Repository reference migration

Layer / File(s) Summary
Repo URL docs and notebooks
Cargo.toml, docs/BENCHMARKS.md, docs/SETUP.md, notebooks/*.ipynb
Manifest metadata and user-facing setup instructions now point to the thaw-ai/thaw repository URL.
Repo URL scripts
demos/*.sh, scripts/pod-*.sh
Demo and pod scripts update clone, pull, and remote-scrub commands plus PAT comments to the thaw-ai/thaw repository URL.

Sequence Diagram(s)

sequenceDiagram
  participant Runner as GitHub Actions runner
  participant ThawLint as tools/thaw_lint.py
  participant Git as git
  participant Files as git-tracked files

  Runner->>ThawLint: python tools/thaw_lint.py
  ThawLint->>Git: git rev-parse --show-toplevel
  Git-->>ThawLint: repo root
  ThawLint->>Git: git ls-files
  Git-->>ThawLint: tracked paths
  loop each tracked file
    ThawLint->>Files: read and scan lines
  end
  ThawLint-->>Runner: WARN/ERROR findings and exit code
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐇 I nibble the lint weeds, tidy and bright,
Hop through the checks till the burrows feel right.
New paths point home to thaw-ai/thaw today,
With whiskers up high, we’re on our way.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.54% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main CI lint gates and contributor guidance added in this PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/lint-gates-and-thaw-lint

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
demos/setup_runpod.sh (1)

23-23: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

A && B || C is not if-then-else here.

If the directory exists and cd thaw succeeds but git pull fails (e.g., transient network error), the || branch still runs git clone into the existing checkout, which then fails. Consider an explicit if.

♻️ Explicit if/else
-[ -d thaw ] && cd thaw && git pull || (git clone https://github.com/thaw-ai/thaw.git && cd thaw)
+if [ -d thaw ]; then
+    cd thaw && git pull
+else
+    git clone https://github.com/thaw-ai/thaw.git && cd thaw
+fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@demos/setup_runpod.sh` at line 23, The current shell one-liner in the setup
logic uses an unsafe A && B || C pattern, so a failed git pull after cd thaw can
incorrectly fall through to git clone inside an existing checkout. Refactor the
setup flow around the thaw checkout into an explicit if/else that handles the
“directory exists” and “clone vs update” cases separately, preserving the
existing thaw path and git pull behavior without attempting to clone into an
existing repository.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/test.yml:
- Around line 20-24: The workflow uses floating action versions, so update every
action reference in the test workflow to a pinned commit SHA instead of tags
like actions/checkout@v4, actions/setup-python@v5,
dtolnay/rust-toolchain@stable, and Swatinem/rust-cache@v2. Apply the same fix to
all repeated workflow sections in this file so every uses entry is locked to a
specific commit hash.
- Around line 29-31: The Ruff installation step in the test workflow is unpinned
and can drift as new releases are published, changing lint behavior
unexpectedly. Update the install command in the workflow to use an explicit Ruff
version so the CI environment is stable; the relevant step is the “Install ruff”
entry in the test workflow.

In `@CONTRIBUTING.md`:
- Around line 65-66: The CONTRIBUTING.md reference is using the archived repo
slug that triggers the no-archived-repo-url lint gate. Update the wording in the
affected sentence to avoid the literal deprecated token, or add the appropriate
inline suppression if this doc must intentionally mention it; make the change in
the CONTRIBUTING.md guidance text that references the repo slug so thaw-lint no
longer flags it.

In `@demos/run_quick_test.sh`:
- Line 13: The bootstrap curl-pipe-bash line in run_quick_test.sh is
intentionally allowed, so suppress the thaw-lint no-curl-pipe-bash finding
inline on that exact command. Update the commented bootstrap invocation in
run_quick_test.sh using the linter’s supported suppression syntax so the PR’s
lint job stays clean while preserving the documented fresh-pod setup behavior.

---

Nitpick comments:
In `@demos/setup_runpod.sh`:
- Line 23: The current shell one-liner in the setup logic uses an unsafe A && B
|| C pattern, so a failed git pull after cd thaw can incorrectly fall through to
git clone inside an existing checkout. Refactor the setup flow around the thaw
checkout into an explicit if/else that handles the “directory exists” and “clone
vs update” cases separately, preserving the existing thaw path and git pull
behavior without attempting to clone into an existing repository.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3a20efa7-34e5-4d0b-ab43-2cbecbdabbd1

📥 Commits

Reviewing files that changed from the base of the PR and between 985345c and 951c57d.

📒 Files selected for processing (17)
  • .github/pull_request_template.md
  • .github/workflows/test.yml
  • CONTRIBUTING.md
  • Cargo.toml
  • demos/bench_cold_cache.sh
  • demos/run_quick_test.sh
  • demos/run_stress_test.sh
  • demos/setup_runpod.sh
  • docs/BENCHMARKS.md
  • docs/SETUP.md
  • notebooks/gpu_benchmark.ipynb
  • notebooks/quickstart.ipynb
  • scripts/pod-bench-freeze.sh
  • scripts/pod-validate-kv.sh
  • scripts/pod-validate-s3.sh
  • tests/test_thaw_lint.py
  • tools/thaw_lint.py

Comment on lines +20 to +24
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: actions/setup-python@v5

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify non-SHA-pinned actions in workflows
rg -n 'uses:\s+[[:alnum:]_.-]+/[[:alnum:]_.-]+@[^[:space:]]+' .github/workflows \
  | rg -v '@[0-9a-fA-F]{40}$'

Repository: thaw-ai/thaw

Length of output: 1642


Pin all workflow actions to commit SHAs. actions/checkout@v4, actions/setup-python@v5, dtolnay/rust-toolchain@stable, and Swatinem/rust-cache@v2 are all still floating refs in this workflow; the same pattern also appears at lines 64-68, 90-94, and 111-113.

🧰 Tools
🪛 zizmor (1.26.1)

[warning] 20-22: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 20-20: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 24-24: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/test.yml around lines 20 - 24, The workflow uses floating
action versions, so update every action reference in the test workflow to a
pinned commit SHA instead of tags like actions/checkout@v4,
actions/setup-python@v5, dtolnay/rust-toolchain@stable, and
Swatinem/rust-cache@v2. Apply the same fix to all repeated workflow sections in
this file so every uses entry is locked to a specific commit hash.

Source: Linters/SAST tools

Comment on lines +29 to +31
- name: Install ruff
run: pip install ruff

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check for unpinned ruff installs across workflows/docs/scripts
rg -n "pip install .*ruff(\\s|$)" .github/workflows CONTRIBUTING.md .github/pull_request_template.md

Repository: thaw-ai/thaw

Length of output: 210


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== .github/workflows/test.yml (around install step) ==\n'
cat -n .github/workflows/test.yml | sed -n '1,120p'

printf '\n== ruff references in repo ==\n'
rg -n --hidden --glob '!.git' --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' '\bruff\b|ruff==' .

Repository: thaw-ai/thaw

Length of output: 6580


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== .github/workflows/test.yml (around install step) ==\n'
cat -n .github/workflows/test.yml | sed -n '1,120p'

printf '\n== ruff references in repo ==\n'
rg -n --hidden --glob '!.git' --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' '\bruff\b|ruff==' .

Repository: thaw-ai/thaw

Length of output: 6580


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== .github/workflows/test.yml (around install step) ==\n'
cat -n .github/workflows/test.yml | sed -n '1,120p'

printf '\n== ruff references in repo ==\n'
rg -n --hidden --glob '!.git' --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' '\bruff\b|ruff==' .

Repository: thaw-ai/thaw

Length of output: 6580


Pin Ruff in .github/workflows/test.yml:29-30. pip install ruff resolves the latest release at runtime, so the lint gate can change behavior over time. Use an explicit version instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/test.yml around lines 29 - 31, The Ruff installation step
in the test workflow is unpinned and can drift as new releases are published,
changing lint behavior unexpectedly. Update the install command in the workflow
to use an explicit Ruff version so the CI environment is stable; the relevant
step is the “Install ruff” entry in the test workflow.

Comment thread CONTRIBUTING.md
Comment on lines +65 to +66
- **`matteso1/thaw` URLs** → the repo lives at `thaw-ai/thaw`; the old one is
archived and 404s clone scripts.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

CONTRIBUTING.md currently violates the new no-archived-repo-url gate.

This exact line is tripping CI (thaw-lint), so the PR cannot pass as-is. Reword to avoid the literal token or add inline suppression where you intentionally document the deprecated slug.

Suggested fix
-- **`matteso1/thaw` URLs** → the repo lives at `thaw-ai/thaw`; the old one is
+- **Archived repo URLs** (old owner/repo slug) → the repo lives at `thaw-ai/thaw`; the old one is
   archived and 404s clone scripts.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- **`matteso1/thaw` URLs** → the repo lives at `thaw-ai/thaw`; the old one is
archived and 404s clone scripts.
- **Archived repo URLs** (old owner/repo slug) → the repo lives at `thaw-ai/thaw`; the old one is
archived and 404s clone scripts.
🧰 Tools
🪛 GitHub Actions: test / 0_lint (clippy, ruff, thaw-lint).txt

[error] 65-65: thaw-lint (no-archived-repo-url): Point at github.com/thaw-ai/thaw — matteso1/thaw is archived. 'matteso1/thaw' URLs should be updated to 'thaw-ai/thaw'.

🪛 GitHub Actions: test / lint (clippy, ruff, thaw-lint)

[error] 65-65: thaw-lint failed ([no-archived-repo-url]). Point at github.com/thaw-ai/thaw — matteso1/thaw is archived.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CONTRIBUTING.md` around lines 65 - 66, The CONTRIBUTING.md reference is using
the archived repo slug that triggers the no-archived-repo-url lint gate. Update
the wording in the affected sentence to avoid the literal deprecated token, or
add the appropriate inline suppression if this doc must intentionally mention
it; make the change in the CONTRIBUTING.md guidance text that references the
repo slug so thaw-lint no longer flags it.

Source: Pipeline failures

Comment thread demos/run_quick_test.sh
# export HF_TOKEN=hf_xxxxx
# export GITHUB_PAT=ghp_xxxxx
# curl -sSL https://raw.githubusercontent.com/matteso1/thaw/main/demos/run_quick_test.sh | bash -s -- --setup
# curl -sSL https://raw.githubusercontent.com/thaw-ai/thaw/main/demos/run_quick_test.sh | bash -s -- --setup

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

thaw-lint flags this curl-pipe-bash bootstrap line.

The new thaw-lint gate emits [no-curl-pipe-bash] here. This is the documented fresh-pod bootstrap, so the pattern is intentional. To keep the PR's own lint job clean, add the inline suppression the linter supports.

🔧 Add inline suppression
-#   curl -sSL https://raw.githubusercontent.com/thaw-ai/thaw/main/demos/run_quick_test.sh | bash -s -- --setup
+#   curl -sSL https://raw.githubusercontent.com/thaw-ai/thaw/main/demos/run_quick_test.sh | bash -s -- --setup  # thaw-lint: allow
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# curl -sSL https://raw.githubusercontent.com/thaw-ai/thaw/main/demos/run_quick_test.sh | bash -s -- --setup
# curl -sSL https://raw.githubusercontent.com/thaw-ai/thaw/main/demos/run_quick_test.sh | bash -s -- --setup # thaw-lint: allow
🧰 Tools
🪛 GitHub Actions: test / 0_lint (clippy, ruff, thaw-lint).txt

[warning] 13-13: thaw-lint: [no-curl-pipe-bash] Prefer git clone + run from the checkout over curl-pipe-bash.

🪛 GitHub Actions: test / lint (clippy, ruff, thaw-lint)

[warning] 13-13: thaw-lint warning ([no-curl-pipe-bash]): Prefer git clone + run from the checkout over curl-pipe-bash.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@demos/run_quick_test.sh` at line 13, The bootstrap curl-pipe-bash line in
run_quick_test.sh is intentionally allowed, so suppress the thaw-lint
no-curl-pipe-bash finding inline on that exact command. Update the commented
bootstrap invocation in run_quick_test.sh using the linter’s supported
suppression syntax so the PR’s lint job stays clean while preserving the
documented fresh-pod setup behavior.

Source: Pipeline failures

@matteso1 matteso1 merged commit 45bcc97 into main Jun 25, 2026
8 of 9 checks passed
@matteso1 matteso1 deleted the ci/lint-gates-and-thaw-lint branch June 25, 2026 00:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant