Skip to content

Add nightly#935

Merged
yihozhang merged 5 commits into
mainfrom
nightly
Jul 6, 2026
Merged

Add nightly#935
yihozhang merged 5 commits into
mainfrom
nightly

Conversation

@yihozhang

Copy link
Copy Markdown
Collaborator

A screenshot of the nightly below

image

I was not too careful about the nightly design, but just to get something in there for now, and we can further iterate.

@yihozhang yihozhang requested a review from a team as a code owner June 25, 2026 00:11
@yihozhang yihozhang requested review from saulshanabrook and removed request for a team June 25, 2026 00:11
@codecov-commenter

codecov-commenter commented Jun 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.75%. Comparing base (7d102db) to head (7f11137).
⚠️ Report is 12 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #935      +/-   ##
==========================================
+ Coverage   86.54%   86.75%   +0.21%     
==========================================
  Files          89       90       +1     
  Lines       26804    27110     +306     
==========================================
+ Hits        23197    23519     +322     
+ Misses       3607     3591      -16     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@saulshanabrook

Copy link
Copy Markdown
Member

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added a new make nightly workflow for running scheduled benchmarks.
    • Generates an HTML dashboard and machine-readable results for easier performance review.
  • Bug Fixes

    • Improved benchmark handling by skipping very fast or unsupported runs and enforcing run time limits.
  • Chores

    • Updated ignored files and paths to keep generated benchmark output out of version control.

Walkthrough

Adds a nightly benchmark workflow that discovers .egg test programs, probes and measures them across thread and proof configurations, renders an HTML dashboard with JSON results, and exposes the run through make nightly.

Changes

Nightly benchmark workflow

Layer / File(s) Summary
Harness setup
scripts/nightly_bench.py
Defines nightly benchmark thresholds, configuration tables, exclusions, and git/logging helpers.
Benchmark selection
scripts/nightly_bench.py
Discovers benchmark programs under tests/, applies proof-mode filters, and builds the egglog command line.
Probe and calibration
scripts/nightly_bench.py
Runs qualification probes, selects warmup and run counts, and calibrates timeout-wrapper usage.
Measurement sweep
scripts/nightly_bench.py
Measures benchmark cells with hyperfine, handles status outcomes, builds the release binary, and orchestrates the benchmark sweep.
HTML report
scripts/nightly_bench.py
Renders the sortable benchmark dashboard, skipped summaries, metadata, and embedded column-sorting script.
Entrypoint and wiring
scripts/nightly_bench.py, Makefile, CHANGELOG.md, .gitignore
Adds the CLI entrypoint that writes results.json and index.html, exposes make nightly, records the workflow in the changelog, and ignores nightly output and __pycache__/.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 31.58% 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
Title check ✅ Passed The title is concise and clearly points to the newly added nightly feature.
Description check ✅ Passed The description is related to the change and includes a screenshot of the nightly page.
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 nightly

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 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 `@scripts/nightly_bench.py`:
- Around line 293-304: The qualification logic in nightly_bench.py is skipping
rows as “too-fast” when the standard or proof probe fails, which hides
timeout/error results from the report. Update the skip decision around the
std_probe/proof_probe flow and the later measured-data threshold so that rows
with probe errors or timeouts are still kept and reported, using the existing
std_qualifies, proof_qualifies, and skipped handling to distinguish real
failures from genuinely fast benchmarks.
- Around line 178-194: The timeout fallback in calibrate_timeout() is disabling
the per-run cap for hyperfine when `timeout` is missing or deemed too slow,
which allows a single hung repeat to block far too long. Update the timeout
handling so hyperfine() still enforces a strict per-run limit using the existing
probe()/subprocess backstop path, and only use TIMEOUT_PREFIX as an optional
wrapper rather than the sole enforcement mechanism. Make sure the logic around
calibrate_timeout(), probe(), and hyperfine() keeps the 2-minute per-run cap
active in all cases, including the no-`timeout` and slow-`timeout` branches.
- Line 524: The list comprehension in the configs construction uses the
ambiguous variable name l, which Ruff flags as E741. Update the comprehension in
the CONFIGS unpacking to use a descriptive name for the label field in the
configs mapping so the nightly_bench script stays lint-clean and the intent
remains clear.
- Around line 127-129: The requires_proofs() helper only matches direct children
of tests/proofs, so nested benchmark files are missed. Update requires_proofs()
in scripts/nightly_bench.py to detect any path under the tests/proofs tree by
checking the full ancestor path (for example via path.parts or path.parents)
instead of only path.parent.name, so files like tests/proofs/foo/bar.egg are
treated as proof-required.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d8cd1420-b6bd-47d4-b37b-3a7e03fc56f0

📥 Commits

Reviewing files that changed from the base of the PR and between e4a6535 and 5bb42af.

📒 Files selected for processing (4)
  • .gitignore
  • CHANGELOG.md
  • Makefile
  • scripts/nightly_bench.py
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: benchmark (ubuntu-latest, proof_testing_math)
🧰 Additional context used
📓 Path-based instructions (1)
CHANGELOG.md

📄 CodeRabbit inference engine (CLAUDE.md)

Update CHANGELOG.md with a concise bullet when making major changes such as breaking changes or new features.

Files:

  • CHANGELOG.md
🪛 ast-grep (0.44.0)
scripts/nightly_bench.py

[error] 100-102: Avoid command injection
Context: subprocess.check_output(
["git", "-C", str(REPO_ROOT), *args], text=True, stderr=subprocess.DEVNULL
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(command-injection-python)


[error] 154-159: Use of unsanitized data to create processes
Context: subprocess.run(
egglog_cmd(path, threads, proof),
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
timeout=RUN_TIMEOUT,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(os-system-unsanitized-data)


[error] 100-102: Command coming from incoming request
Context: subprocess.check_output(
["git", "-C", str(REPO_ROOT), *args], text=True, stderr=subprocess.DEVNULL
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(subprocess-from-request)


[error] 154-159: Command coming from incoming request
Context: subprocess.run(
egglog_cmd(path, threads, proof),
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
timeout=RUN_TIMEOUT,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(subprocess-from-request)


[error] 198-199: Command coming from incoming request
Context: subprocess.run(["timeout", str(RUN_TIMEOUT), "true"],
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(subprocess-from-request)


[error] 217-228: Command coming from incoming request
Context: subprocess.run(
[
"hyperfine",
"--warmup", str(warmup),
"--runs", str(runs),
"--export-json", tmp_json,
shell_cmd,
],
capture_output=True,
text=True,
timeout=backstop,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(subprocess-from-request)


[error] 267-271: Command coming from incoming request
Context: subprocess.run(
["cargo", "build", "--release", "--bin", "egglog",
"--manifest-path", str(REPO_ROOT / "Cargo.toml")],
check=True,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(subprocess-from-request)


[info] 527-527: use jsonify instead of json.dumps for JSON output
Context: json.dumps(payload, indent=2)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[warning] 231-231: File path is request-/variable-derived; validate and normalize to prevent path traversal.
Context: open(tmp_json)
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(open-filename-from-request)

🪛 Ruff (0.15.18)
scripts/nightly_bench.py

[error] 101-101: subprocess call: check for execution of untrusted input

(S603)


[error] 102-102: Starting a process with a partial executable path

(S607)


[warning] 136-136: Boolean-typed positional argument in function definition

(FBT001)


[warning] 147-147: Boolean-typed positional argument in function definition

(FBT001)


[error] 155-155: subprocess call: check for execution of untrusted input

(S603)


[warning] 155-155: subprocess.run without explicit check argument

Add explicit check=False

(PLW1510)


[warning] 185-185: Using the global statement to update TIMEOUT_PREFIX is discouraged

(PLW0603)


[error] 199-199: subprocess call: check for execution of untrusted input

(S603)


[warning] 199-199: subprocess.run without explicit check argument

Add explicit check=False

(PLW1510)


[error] 199-199: Starting a process with a partial executable path

(S607)


[warning] 204-204: Boolean-typed positional argument in function definition

(FBT001)


[error] 218-218: subprocess call: check for execution of untrusted input

(S603)


[warning] 218-218: subprocess.run without explicit check argument

Add explicit check=False

(PLW1510)


[error] 219-225: Starting a process with a partial executable path

(S607)


[warning] 240-240: Boolean-typed positional argument in function definition

(FBT001)


[error] 268-268: subprocess call: check for execution of untrusted input

(S603)


[error] 269-270: Starting a process with a partial executable path

(S607)


[warning] 294-294: Boolean positional value in function call

(FBT003)


[warning] 295-295: Boolean positional value in function call

(FBT003)


[warning] 312-312: Boolean positional value in function call

(FBT003)


[warning] 313-314: Use elif instead of else then if, to reduce indentation

Convert to elif

(PLR5501)


[warning] 318-318: Boolean positional value in function call

(FBT003)


[warning] 330-330: Function definition does not bind loop variable cells

(B023)


[error] 524-524: Ambiguous variable name: l

(E741)

🔇 Additional comments (3)
Makefile (1)

1-1: LGTM!

Also applies to: 10-15

CHANGELOG.md (1)

5-5: LGTM!

.gitignore (1)

12-12: LGTM!

Also applies to: 28-29

Comment thread scripts/nightly_bench.py
Comment on lines +127 to +129
def requires_proofs(path: Path) -> bool:
"""Programs under tests/proofs/ only make sense with proofs enabled."""
return path.parent.name == "proofs"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Detect all files under tests/proofs/, not only direct children.

Because discovery uses TEST_DIR.rglob("*.egg"), nested files like tests/proofs/foo/bar.egg would be treated as plain benchmarks and get non-proof cells instead of .

Proposed fix
 def requires_proofs(path: Path) -> bool:
     """Programs under tests/proofs/ only make sense with proofs enabled."""
-    return path.parent.name == "proofs"
+    try:
+        path.relative_to(TEST_DIR / "proofs")
+    except ValueError:
+        return False
+    return True
📝 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
def requires_proofs(path: Path) -> bool:
"""Programs under tests/proofs/ only make sense with proofs enabled."""
return path.parent.name == "proofs"
def requires_proofs(path: Path) -> bool:
"""Programs under tests/proofs/ only make sense with proofs enabled."""
try:
path.relative_to(TEST_DIR / "proofs")
except ValueError:
return False
return True
🤖 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 `@scripts/nightly_bench.py` around lines 127 - 129, The requires_proofs()
helper only matches direct children of tests/proofs, so nested benchmark files
are missed. Update requires_proofs() in scripts/nightly_bench.py to detect any
path under the tests/proofs tree by checking the full ancestor path (for example
via path.parts or path.parents) instead of only path.parent.name, so files like
tests/proofs/foo/bar.egg are treated as proof-required.

Comment thread scripts/nightly_bench.py
Comment on lines +178 to +194
def calibrate_timeout() -> None:
"""Decide whether wrapping runs in `timeout` is cheap enough to use.

GNU coreutils `timeout` adds ~1ms; some reimplementations add ~100ms, which
would dominate fast benchmarks. We only use the wrapper when its overhead is
negligible; either way the per-run cap is also enforced by probe() and by a
subprocess-level backstop in hyperfine()."""
global TIMEOUT_PREFIX
if not shutil.which("timeout"):
log("Note: `timeout` not found; per-run cap enforced via probe only.")
return
best = min(_time_true() for _ in range(3))
if best < 0.025:
TIMEOUT_PREFIX = ["timeout", str(RUN_TIMEOUT)]
else:
log(f"Note: `timeout` overhead is {best * 1000:.0f}ms; not wrapping runs "
"with it (per-run cap still enforced via probe and backstop).")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Do not disable the per-run timeout during hyperfine measurements.

When timeout is missing or considered too slow, the script falls back to only RUN_TIMEOUT * (warmup + runs) + 30; a single hung repeat can then stall one cell for many minutes instead of the promised 2-minute per-run cap.

Proposed fix
 def calibrate_timeout() -> None:
@@
     global TIMEOUT_PREFIX
-    if not shutil.which("timeout"):
-        log("Note: `timeout` not found; per-run cap enforced via probe only.")
-        return
-    best = min(_time_true() for _ in range(3))
-    if best < 0.025:
-        TIMEOUT_PREFIX = ["timeout", str(RUN_TIMEOUT)]
-    else:
+    timeout_bin = shutil.which("timeout")
+    if not timeout_bin:
+        sys.exit("`timeout` not found; required to enforce the per-run cap.")
+    best = min(_time_true(timeout_bin) for _ in range(3))
+    TIMEOUT_PREFIX = [timeout_bin, str(RUN_TIMEOUT)]
+    if best >= 0.025:
         log(f"Note: `timeout` overhead is {best * 1000:.0f}ms; not wrapping runs "
-            "with it (per-run cap still enforced via probe and backstop).")
+            "would violate the per-run cap, so measurements may include wrapper overhead.")
 
 
-def _time_true() -> float:
+def _time_true(timeout_bin: str) -> float:
     start = time.perf_counter()
-    subprocess.run(["timeout", str(RUN_TIMEOUT), "true"],
+    subprocess.run([timeout_bin, str(RUN_TIMEOUT), "true"],
                    stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

Also applies to: 212-214

🧰 Tools
🪛 Ruff (0.15.18)

[warning] 185-185: Using the global statement to update TIMEOUT_PREFIX is discouraged

(PLW0603)

🤖 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 `@scripts/nightly_bench.py` around lines 178 - 194, The timeout fallback in
calibrate_timeout() is disabling the per-run cap for hyperfine when `timeout` is
missing or deemed too slow, which allows a single hung repeat to block far too
long. Update the timeout handling so hyperfine() still enforces a strict per-run
limit using the existing probe()/subprocess backstop path, and only use
TIMEOUT_PREFIX as an optional wrapper rather than the sole enforcement
mechanism. Make sure the logic around calibrate_timeout(), probe(), and
hyperfine() keeps the 2-minute per-run cap active in all cases, including the
no-`timeout` and slow-`timeout` branches.

Comment thread scripts/nightly_bench.py
Comment on lines +293 to +304
# Qualification probes: the single-thread standard run and the proof run.
std_probe = None if req else probe(path, 1, False)
proof_probe = None if proof_excluded(path) else probe(path, 1, True)
proof_supported = proof_probe is not None and proof_probe[0]

std_qualifies = std_probe is not None and std_probe[0] and std_probe[1] >= MIN_BENCH_SECONDS
proof_qualifies = proof_supported and proof_probe[1] >= MIN_BENCH_SECONDS

if not (std_qualifies or proof_qualifies):
reason = "errored" if (req and not proof_supported) else "too-fast"
skipped.append({"name": name, "reason": reason})
continue

Copy link
Copy Markdown
Contributor

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

Keep timeout/error benchmarks in the report instead of skipping them as too-fast.

If the standard/proof qualification probe fails or times out, std_qualifies/proof_qualifies are false, and the later measured-data threshold can skip all-error rows as too-fast. That hides the exact failures the dashboard says it reports.

Proposed fix
         std_qualifies = std_probe is not None and std_probe[0] and std_probe[1] >= MIN_BENCH_SECONDS
         proof_qualifies = proof_supported and proof_probe[1] >= MIN_BENCH_SECONDS
+        std_failed = std_probe is not None and not std_probe[0]
+        proof_required_failed = req and proof_probe is not None and not proof_probe[0]
 
-        if not (std_qualifies or proof_qualifies):
+        if not (std_qualifies or proof_qualifies or std_failed or proof_required_failed):
             reason = "errored" if (req and not proof_supported) else "too-fast"
             skipped.append({"name": name, "reason": reason})
             continue
@@
         measured = [c["mean"] for c in cells.values() if "mean" in c]
-        if not measured or max(measured) < MIN_BENCH_SECONDS:
+        has_failure = any(c.get("status") in {"timeout", "error"} for c in cells.values())
+        if not has_failure and (not measured or max(measured) < MIN_BENCH_SECONDS):
             skipped.append({"name": name, "reason": "too-fast"})
             continue

Also applies to: 320-325

🧰 Tools
🪛 Ruff (0.15.18)

[warning] 294-294: Boolean positional value in function call

(FBT003)


[warning] 295-295: Boolean positional value in function call

(FBT003)

🤖 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 `@scripts/nightly_bench.py` around lines 293 - 304, The qualification logic in
nightly_bench.py is skipping rows as “too-fast” when the standard or proof probe
fails, which hides timeout/error results from the report. Update the skip
decision around the std_probe/proof_probe flow and the later measured-data
threshold so that rows with probe errors or timeouts are still kept and
reported, using the existing std_qualifies, proof_qualifies, and skipped
handling to distinguish real failures from genuinely fast benchmarks.

Comment thread scripts/nightly_bench.py
**meta,
"min_bench_seconds": MIN_BENCH_SECONDS,
"run_timeout_seconds": RUN_TIMEOUT,
"configs": [{"key": k, "label": l, "threads": t, "proof": p} for k, l, t, p in CONFIGS],

Copy link
Copy Markdown
Contributor

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

Rename the ambiguous comprehension variable.

Ruff flags l as E741 here; using descriptive names keeps this new script lint-clean.

Proposed fix
-        "configs": [{"key": k, "label": l, "threads": t, "proof": p} for k, l, t, p in CONFIGS],
+        "configs": [
+            {"key": key, "label": label, "threads": threads, "proof": proof}
+            for key, label, threads, proof in CONFIGS
+        ],
📝 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
"configs": [{"key": k, "label": l, "threads": t, "proof": p} for k, l, t, p in CONFIGS],
"configs": [
{"key": key, "label": label, "threads": threads, "proof": proof}
for key, label, threads, proof in CONFIGS
],
🧰 Tools
🪛 Ruff (0.15.18)

[error] 524-524: Ambiguous variable name: l

(E741)

🤖 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 `@scripts/nightly_bench.py` at line 524, The list comprehension in the configs
construction uses the ambiguous variable name l, which Ruff flags as E741.
Update the comprehension in the CONFIGS unpacking to use a descriptive name for
the label field in the configs mapping so the nightly_bench script stays
lint-clean and the intent remains clear.

Source: Linters/SAST tools

@codspeed-hq

codspeed-hq Bot commented Jun 25, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 36 untouched benchmarks
⏩ 226 skipped benchmarks1


Comparing nightly (7f11137) with main (64b4548)

Open in CodSpeed

Footnotes

  1. 226 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@oflatt

oflatt commented Jun 25, 2026

Copy link
Copy Markdown
Member

@yihozhang and I discussed, I'm going to port this to use eval-live
https://github.com/oflatt/eval-live

Replace the hand-rolled HTML/CSS/JS table in nightly_bench.py with
eval-live (https://github.com/oflatt/eval-live), which provides
in-browser filtering over the benchmark results.

render_html() now flattens the per-benchmark cells into eval-live row
objects (one row per benchmark, one column per configuration) and embeds
eval_live.css()/js() plus initEvalLive() into a self-contained page.
Skipped programs are surfaced as a second table. Measured cells stay
numeric so the column filters offer numeric dropdowns; not-applicable
cells render as an em-dash and timeout/error cells keep their status
string.

- Add scripts/requirements.txt pinning eval-live (git dependency).
- `make nightly` now installs scripts/requirements.txt first, and
  nightly_bench.py fails fast if eval-live is missing before the sweep.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Render nightly benchmark report with eval-live
oflatt-claude and others added 2 commits June 29, 2026 10:21
`make nightly` ran `pip install` directly, which fails on PEP 668
externally-managed systems (Debian/Python 3.12 on the nightly server)
with "This environment is externally managed". Install eval-live into a
local venv instead, and run nightly_bench.py with that venv's python so
its `import eval_live` resolves. The venv is gitignored.

Co-authored-by: oliver <oflatt@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
After the venv fix, the build failed with cargo 1.75.0 rejecting the
crate's 2024 edition ("feature `edition2024` is not stabilized"). The
nightly host's PATH puts a system cargo ahead of the rustup shim, so
rust-toolchain.toml (pinned to 1.91.0) is ignored. Prepend ~/.cargo/bin
to PATH at startup so the rustup shim — which reads rust-toolchain.toml
and installs the pinned toolchain on demand — wins; hyperfine lives there
too. Mirrors eggcc's nightly. Verified the shim resolves to 1.91.0 in-repo.

Co-authored-by: oliver <oflatt@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@yihozhang yihozhang merged commit 4141a97 into main Jul 6, 2026
35 checks passed
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.

5 participants