Releases: Juror-AI/juror
Release list
v1.3.3 — cache GitHub Actions dependencies
Juror now caches its compiled runtime and pinned model harnesses between GitHub Actions runs, avoiding repeated builds and CLI installations on warm runs.
What's Changed
- perf(action): cache dependencies between runs by @cderinbogaz in #38
Full Changelog: v1.3.2...v1.3.3
v1.3.2 — fast jury defaults to low thinking
The default fast jury now runs GPT-5.6 Luna and DeepSeek V4 Flash at low thinking, reducing review latency and cost. This release also includes all fixes and documentation merged since v1.3.1.
What's Changed
- fix: keep pricing.json $meta.updated at least as fresh as its entries by @AshSgDe29071999 in #29
- fix: show harness display labels on referee and verify receipt rows by @AshSgDe29071999 in #31
- test: add direct unit coverage for redact() and redactWith() by @AshSgDe29071999 in #28
- fix: validate JUROR_LOG_LEVEL and document it in CLI usage by @AshSgDe29071999 in #30
- docs: point README benchmark at the real corpus file by @AshSgDe29071999 in #23
- docs: keep the benchmark example on the installed juror binary by @cderinbogaz in #34
- docs: document the generic-openai harness in harness-notes.md by @AshSgDe29071999 in #32
- docs: surface Greptile benchmark in README by @cderinbogaz in #36
- fix(config): lower fast jury thinking by @cderinbogaz in #37
New Contributors
- @AshSgDe29071999 made their first contribution in #29
Full Changelog: v1.3.1...v1.3.2
v1.3.1 — fast jury steps down to high reasoning
Steps the default fast jury down one level. Both jurors now run the same tier.
| before | after | |
|---|---|---|
| GPT-5.6 Luna (Codex/OpenAI) | max |
high |
| DeepSeek V4 Flash (opencode/Fireworks) | high |
high |
Measured effect
Same PR, same model, only the reasoning effort differs:
| Luna | input | output | cost |
|---|---|---|---|
max |
7.8M | 65.3k | $0.37 |
high |
1.7M | 22.0k | $0.11 |
4.6× fewer input tokens, 70% cheaper. Since Luna dominated the bill, a two-model fast review drops from roughly $0.45 to $0.19 — about 58% off.
For a repo running Juror on 37 PRs a weekday with reviews re-firing on each push, that is roughly $33 → $14 a weekday, or **$740 → ~$310 a month**.
This is a single-PR measurement, not an adjudicated quality comparison. Findings were still produced at high; whether the deeper max pass was catching defects high misses is a separate question that needs a proper corpus. If you want maximum depth, --preset high or ultra are unchanged.
The 1800s timeout stays
Deliberate. It is a kill switch for a hung harness, not a latency target — a faster jury finishing well inside it costs nothing extra. Tightening it would re-introduce the v1.2.0 failure where a slow model is killed at the finish line and silently publishes nothing.
Also fixed
A test had quietly gone vacuous. hands out an independent copy each call mutates reasoning_effort to max to prove defaultConfig() returns an independent object — but when the default itself became max in v1.2.0, the mutation stopped differing from the default and the assertion could no longer fail. Moving the default to high restores the contrast it was written to check.
Full changelog: v1.3.0...v1.3.1
v1.3.0 — track Juror's spend separately
Juror now reads its own provider keys
Until now Juror read the same OPENAI_API_KEY everything else on your runner uses, so its spend was indistinguishable from the rest of that account's usage.
It now reads JUROR_-prefixed variables, so you can issue Juror a dedicated provider key that bills, rotates, and caps on its own:
env:
JUROR_OPENAI_API_KEY: ${{ secrets.JUROR_OPENAI_API_KEY }}
JUROR_ANTHROPIC_API_KEY: ${{ secrets.JUROR_ANTHROPIC_API_KEY }}
JUROR_XAI_API_KEY: ${{ secrets.JUROR_XAI_API_KEY }}
JUROR_FIREWORKS_API_KEY: ${{ secrets.JUROR_FIREWORKS_API_KEY }}Review cost then shows up as its own line in provider billing instead of being mixed into whatever else that key does.
Nothing breaks
This is not a breaking change. The unprefixed names still work as a fallback, so existing installs keep running untouched and can migrate whenever they like. A prefixed key wins when both are set.
Only the variable you set is renamed. Each vendor CLI is still handed the credential under the name it expects — Claude Code, opencode, and Grok authenticate from their own environment, so renaming what they receive would leave them unauthenticated with no visible error.
Verified live, not just in tests
The last bug in this code path typechecked and unit-tested cleanly while disabling every OpenAI model, so this was exercised end-to-end on a real PR:
- Prefixed only, bare names unset — both harnesses authenticated and billed real tokens (Codex 7.8M in, opencode 1.8M in), 6 findings published
- Bare only, prefixed unset — both models still selected
334 tests, 5 of them new: precedence, blank-key shadowing, custom secret names, and an assertion that no harness is ever handed a prefixed name.
Full changelog: v1.2.1...v1.3.0
v1.2.1 — raise the per-model timeout wall
Patch release closing the known issue shipped with v1.2.0.
Fixed: the default jury could lose a model at the finish line
v1.2.0 moved the default fast jury to GPT-5.6 Luna at max reasoning without moving the wall that kills it. per_model_timeout_seconds stayed at 900s, a value sized for low.
Measured across a 10-PR benchmark:
| Luna wall-clock | Result |
|---|---|
| 900s | killed, published nothing from that model |
| 813s | 90% of the wall |
| 751s | 83% of the wall |
One hard failure in ten, two near-misses. The worst part was the failure mode: the review completed, reported success, and silently missed half its jury.
per_model_timeout_seconds now defaults to 1800.
This value is a kill switch for a hung harness, not a latency target. A run that finishes early costs nothing extra — models bill for what they consume, and each still stops at the first of its own timeout_seconds override or your budget ceiling. Doubling the wall does not make any review slower. It only stops a legitimate slow run from being destroyed just before it returns.
The old behaviour is one line away:
review:
per_model_timeout_seconds: 900Applies to all four presets, which is deliberate — balanced runs Terra at max and ultra runs seven models including three Codex ones, so they sat under the same wall.
Upgrading
uses: juror-ai/juror@v1 picks this up with no change. If you pinned @v1.2.0, move to @v1.2.1 — and if you are still on v1.0.x or v1.1.0, upgrade regardless: those releases could not authenticate any OpenAI model at all (fixed in v1.2.0).
Full changelog: v1.2.0...v1.2.1
v1.2.0 — Codex authentication fix
Fixed: Codex models never authenticated
Every OpenAI model — GPT-5.6 Luna, Sol, and Terra — was failing on all four presets, including the default.
Juror builds a private CODEX_HOME for each run so user OAuth state, MCP servers, and global config cannot enter a review. That home starts empty, and Codex reads credentials only from $CODEX_HOME/auth.json — it ignores OPENAI_API_KEY in the environment. So Codex sent no Authorization header and every turn died on 401 Unauthorized before billing anything.
It surfaced as no usable report, not as an auth error, which is why it survived v1.0.0 and v1.1.0.
Juror now writes the same credential file codex login --with-api-key produces, at mode 0600, inside the home its permission profile already denies to model-run shell commands.
If you are on v1.0.x or v1.1.0 and supplied an OPENAI_API_KEY, your reviews were running without any OpenAI model. Upgrade.
Changed: fast jury reasoning settings
fast became the default preset in v1.1.0, so its settings decide out-of-the-box quality:
| Model | Before | After |
|---|---|---|
| GPT-5.6 Luna (Codex/OpenAI) | low |
max |
| DeepSeek V4 Flash (opencode/Fireworks) | low |
high |
DeepSeek stays at high rather than max: max is a valid variant, but in benchmarking it returned findings with no path and they were dropped.
Benchmark
Across 10 merged PRs spanning backend concurrency, a DB migration, CI, and web (2–33 files each), the fast jury published 43 findings for $4.25, against 13 from an incumbent reviewer on the same PRs. These counts are unadjudicated — per docs/benchmarking.md, mapping a report to a real defect is human work. Treat it as volume, not recall.
Known issue
Luna at max runs close to the 900s per_model_timeout_seconds. In the 10-PR benchmark one PR hit the wall and published nothing from Luna, and two more finished within 17% of it. If you review large diffs, raise it:
review:
per_model_timeout_seconds: 1800Full changelog: v1.1.0...v1.2.0
v1.1.0
fast is now the default jury preset.
The default jury changes from three models to two:
Before (balanced) |
After (fast) |
|
|---|---|---|
| Jury | GPT-5.6 Terra max · Grok 4.5 high · Kimi K3 max |
GPT-5.6 Luna low · DeepSeek V4 Flash low |
| Referee / verifier | kimi-k3 |
deepseek-v4-flash-0731 |
Lower latency and cost by default. If you relied on the previous default, pin it explicitly — nothing else changes:
# .juror.yml
preset: balancedor --preset balanced on the CLI, or preset: balanced on the Action.
Minor rather than patch because this changes behaviour for anyone who had not pinned a preset. This release also reconciles the npm package version with the GitHub release version.
Initial Release
What's Changed
- feat: build multi-model PR review pipeline by @cderinbogaz in #1
- docs: add three-step quickstart for adopting Juror by @cderinbogaz in #2
- chore: rename to Juror AI and repoint slug at juror-ai/juror by @cderinbogaz in #3
- chore: release v1.0.0 by @cderinbogaz in #4
New Contributors
- @cderinbogaz made their first contribution in #1
Full Changelog: https://github.com/Juror-AI/juror/commits/v1.0.1
v1.0.0
First public release.
N frontier models review your PR in parallel, each through its own native agent harness. Reports about the same defect collapse into one. Every review prints its own receipt.
Usage
- uses: juror-ai/juror@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}See the README for the three-step setup. Any provider key you omit is skipped with a note in the receipt — one key gets you a working single-model review.