Releases: Juror-AI/juror
Release list
v1.4.3 — reliable QA egress on DinD
Juror v1.4.3 makes post-merge browser QA reliable on Docker-in-Docker runners such as TextCortex CFKE.
Highlights:
- bypass broken Docker embedded alias DNS by addressing the allowlisted egress proxy through its inspected internal-network IP
- validate the inspected address against supported non-public Docker network ranges before credential handoff
- preserve the credential-bearing runtime's internal-only network, exact-origin egress boundary, Chromium sandbox, and immutable image verification
- add regression coverage for standard and custom Docker address pools
v1.4.2 — hardened QA runtime
Juror v1.4.2 hardens the isolated post-merge browser QA runtime.
Highlights:
- keep Codex Responses on auth-appropriate HTTPS endpoints through the controller-owned allowlisted proxy, with inherited
NO_PROXYbypasses removed - restore sandboxed Chromium startup for arbitrary non-root runner identities by providing a private writable home
- verify namespace and seccomp-BPF protection on native amd64 before release, including a passwd-less numeric UID/GID
- preserve npm, Action-source, SBOM, image, and provenance verification through the existing trusted release workflows
v1.4.1 — post-merge browser QA
Juror post-merge browser QA is ready for protected staging workflows.
Highlights:
- plan and execute affected browser journeys against a verified merged deployment
- run in a sandboxed, public multi-architecture QA image with provenance and SBOM attestations
- bootstrap authenticated staging sessions and bind secret browser headers to exact trusted origins
- select a dedicated GitHub deployment environment while preserving staging as the security tier
- preserve valid empty evidence payloads during report finalization
- publish the exact packed npm tarball through the corrected trusted-publishing path
v1.4.0 — native DeepSeek harness
DeepSeek models now run through the native CodeWhale harness instead of opencode.
Highlights:
- route DeepSeek V4 Flash through CodeWhale 0.9.7
- preserve interleaved DeepSeek reasoning across tool calls
- isolate reviews in a private, read-only runtime with hardened environment floors
- report provider token usage and update the GitHub Action installer and compatibility docs
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