feat: Jev v0.3 merge-ready with structured memory advice and Command Code hardening - #2
Merged
Merged
Conversation
… and budget ledger
Path(sys.executable).resolve() turns a POSIX venv/pipx/uv interpreter
(bin/python -> base python symlink) into the base interpreter, which
cannot import jev_decision. Every generated MCP entry and skill command
on macOS/Linux therefore failed to start. Windows keeps its resolved
physical path for MSIX-virtualized runtimes.
Claude Code passes an unset ${NAME} through as literal text, so its
environment reference now uses the ${NAME:-} empty default like
Command Code.
The package check now launches the generated interpreter and imports
the package, so CI exercises the actual entry instead of sys.executable.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018LueFkPH1uD3FYT56QuZ5S
Claude Code (and possibly other clients) passes an unset ${NAME} env
reference through as literal text. The placeholder passed the printable-
ASCII key check, so every call failed authentication while leaving a
worst-case budget hold. Environment loading and presence status now treat
${NAME}, ${NAME:-}, ${env:NAME}, {env:NAME}, $NAME and %NAME% as unset;
storage and the TypeScript constructor reject them as credentials.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018LueFkPH1uD3FYT56QuZ5S
The credential/private-name filter ran over every component of the absolute path, including the approved root's own ancestors. Any workspace under a directory such as auth-service/, oauth_app/, secrets-manager/ or token.bridge/ rejected every evidence read with credential_or_private_file_denied. Names are now screened below the most specific approved root that grants access (the root itself is explicit operator consent). Paths outside textual roots and exact-path recovery keep the previous whole-path screen. Denied names inside the root (.env, .git, secrets/, *.pem, credentials.*) are still refused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018LueFkPH1uD3FYT56QuZ5S
JevClient(api_key=...) and JevClient() with TYPESAFE_API_KEY/JEV_API_KEY returned runtime_disabled until `jev setup` had run, so the README's first Python example silently did nothing for a new user. Supplying a key to a library client before any saved configuration now opts in with the default daily budget and shared ledger. CLI and MCP pass their loaded runtime explicitly and still stay offline until setup; a saved configuration (including a disabled one) is always respected, and an unexpanded placeholder never opts in. CLI results for a fresh installation now include a hint pointing to `jev setup` instead of a bare runtime_disabled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018LueFkPH1uD3FYT56QuZ5S
The version was repeated in pyproject, __init__, the HTTP User-Agent, the MCP server version, the package check and CI artifact names. jev_decision/_version.py is now the only Python source (setuptools reads it dynamically); a test keeps the TypeScript package, lockfile and User-Agent in step with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018LueFkPH1uD3FYT56QuZ5S
MCP-only integration leaves the primary model to decide whether to call jev_guard_command, which spends its tokens and depends on compliance. The fast path for a System 1 check is the harness's own pre-tool hook. `jev hook run HARNESS` reads one hook payload (Claude Code, Command Code, Codex, Cursor, Gemini CLI) and can only add friction: - ask-capable hooks (Claude Code, Cursor) get "ask", forcing the normal approval prompt for a flagged command; - allow/deny-only hooks (Command Code, Codex, Gemini CLI) get "deny" with a reason, by default only in no-prompt sessions (bypass/yolo), so a person never loses the chance to approve; --when always blocks in every mode. It never answers "allow". Simple read-only commands (ls, cat, git status, ... without shell syntax or private-file arguments) skip the request. Every local failure (no setup, no key, budget, timeout, malformed input, stale arguments) exits 0 with no decision, because exit 2 means block. JEV_HOOK=off disables it; JEV_HOOK_THRESHOLD tunes it (default 0.8). `jev hook config HARNESS` prints the exact settings fragment to merge. The Python command guard now gives every Choice category and the Noul explicit criteria (provider guidance; matches the TypeScript guard) and reports category_probabilities. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018LueFkPH1uD3FYT56QuZ5S
Most MCP clients send every tool's input schema to the primary model on each request. jev_decide advertised both the native map and legacy array forms (6.5 KB), so the six tools cost about 10 KB (~2.5K tokens) of model context per request. Discovery now advertises only the preferred array form (2.7 KB; ~960 fewer tokens per request across the tool list), while the server still validates calls against the complete schema, so native ID-keyed maps and legacy prompt/options/scale inputs keep working. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018LueFkPH1uD3FYT56QuZ5S
Python 3.14 is the current stable release and Node 24 the active LTS, so both join the matrices (TypeScript jobs no longer fail fast). The Windows key dialog no longer names one specific harness. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018LueFkPH1uD3FYT56QuZ5S
A zero daily budget (the interactive setup default) disables provider calls, and decide/guard/verify/doctor --live then reported a bare runtime_disabled. Results now carry a corrective hint for both a fresh installation and a zero budget. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018LueFkPH1uD3FYT56QuZ5S
The MCP server, JSON CLI and TypeScript client all accept a list of
plain {id, type, instructions, criteria} objects, but the Python library
only took typed dataclasses or a native ID-keyed map, so examples could
not be copied between interfaces. Python now accepts the same objects
(including the legacy prompt/options/scale spellings) with the same
validation.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018LueFkPH1uD3FYT56QuZ5S
The README opened with qualification caveats and several paragraphs of policy before a user could install anything. It now leads with what Jev is, a four-step quickstart (install, setup, connect a harness, optional guard hook), a harness table, a copy-pasteable Python example, the MCP tool list and the provider's usage guidance, and keeps the evidence and qualification boundaries in their own sections. docs/HOOKS.md documents the escalate-only shell guard for all five harnesses; the Command Code guide gains a guard section and the 1.72.4 hook-runner evidence; integration, migration and specification docs cover the interpreter, placeholder, library opt-in and name-screen changes. Skills tell agents never to rephrase a command to evade the guard. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018LueFkPH1uD3FYT56QuZ5S
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018LueFkPH1uD3FYT56QuZ5S
Reading private data is itself a sensitive effect, so the read-only shortcut no longer skips commands with absolute, drive-qualified or parent-relative path arguments (cat /etc/shadow, head ../other/x). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018LueFkPH1uD3FYT56QuZ5S
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018LueFkPH1uD3FYT56QuZ5S
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
…d credential formatting parity
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Incorporates merge-readiness updates, Windows hook guards, Python 3.14/Node 24 CI, structured memory advice, and explicit Jev consent and evidence scope.