Skip to content

Releases: valentynkit/jev-belay

Release list

0.2.0

Choose a tag to compare

@valentynkit valentynkit released this 20 Sep 09:09
v0.2.0
ef719db

Added

  • The plugin asks for its settings when it is enabled: the TypeSafe key (kept in the
    Keychain), the claims_done threshold, the decision log, shadow mode, and a regex for
    your own check command. Each arrives as CLAUDE_PLUGIN_OPTION_<NAME> and wins over the
    plain environment variable.
  • Subagent work counts. The hook reads the subagents/ files next to the session
    transcript, keeps the ones carrying this turn's prompt id, and merges them into the turn
    by timestamp, so a turn that delegated its edits no longer looks like one that changed
    nothing.
  • Shadow mode: the whole pipeline runs, the turn still ends, and a stop it would have
    blocked prints jev-belay would have blocked this turn: and the reason through
    systemMessage, which Claude Code shows to you and not to the model.
  • The closing message is read from the Stop payload's last_assistant_message when the
    host sends it, so the 300 ms re-read is paid only on older hosts.
  • belay.mjs stats (verdict counts, calls, cost, latency p50 and p90, the last 14 days),
    belay.mjs last (the last decision, rendered), and belay.mjs doctor (key, host
    version, hook registration, transcripts readable, a round trip through a fake; --live
    makes one real call).
  • Two skills: /jev-belay:why explains the last decision, /jev-belay:doctor reads the
    doctor's output back and names the fix for anything that failed.
  • Belt 2 reads nextest, deno, ruff, mypy, mocha, rspec, minitest, phpunit, playwright,
    swift, ctest and biome summaries, plus two compiler shapes, rustc's error[E0119]: and
    go's file.go:12:3:, which decide fail when no runner summary follows them. A compile
    error used to read as a passing check in a cargo check or a go build.
  • test/runners/ holds a captured or documented output per runner belt 2 claims to know,
    passing and failing, so a belt change has something to fail against.
  • A check command of your own: set the check option (or JEV_BELAY_CHECK) to a regex
    and belt 1 tests it next to the built-in runners. An invalid regex is ignored.

Changed

  • tui.mjs holds the live view, the replay, stats, last and doctor. belay.mjs is
    the hook and imports it lazily, so the hook path never parses the TUI.
  • .env.example is gone. Nothing ever read it, and the README told people to copy it.
  • The claims_done threshold is 0.70, up from 0.65: on the re-extracted corpus, with
    subagent turns folded in, 0.70 is the lowest cutoff holding wrong blocks under 2%, and
    it catches the same 7 of 12 false dones.
  • A check regex that matches the empty string is ignored like a broken one, since .*
    would make every Bash call a passing check. An RSpec error outside the examples is a
    failure whatever the failure count says. The rustc rule needs the numbered diagnostic or
    cargo's closing line, so git push is no longer quoted as a failed check.

Fixed

  • A threshold that is not a number no longer disables blocking silently; it falls back to
    the default.
  • The plugin install never delivered a key. The README pointed at a .env file that
    neither the hook nor Claude Code reads, so a plugin user got "no key", exit 0, forever,
    with nothing saying so.
  • A compile error in a cargo check or a go build read as a passing check, which sent
    Jev a state saying a check passed and put the same claim in the nudge.

Measured

  • The ablation on the re-extracted corpus (2,694 stops, 477 reaching the gate, 17.7%),
    same 100-stop audit slice with 12 false dones, direct API, jev-1.13.0, 2026-09-20:
    AUROC 0.777 for the wording alone, 0.886 with the evidence gate, 0.976 for the full
    hook, interval 0.915 to 1.000. On the 76 gated stops: 0.967 against 0.844. At 0.70:
    8 blocks in 100, 7 right. Median call 1,222 input tokens, $0.00005, 346 ms.