fast-jev-compaction
★ 7.8k▲ 59tamaratran/fast-jev-compaction
Claude Code plugin that replaces the compaction summary with Jev decisions. Every tool call and result is scored; stale ones are dropped or truncated, and everything kept stays verbatim.
Routes a Claude Code or Codex task to one of 27 specialist roles and defines what evidence will count as done.
View on GitHub →Hands-on review
27 agent roles with an optional Jev router, all scopes off by default. The most careful codebase here; its redactor misses AWS_SECRET_ACCESS_KEY.
Good for
Watch out for
Tested Sep 20, 2026 at a709161 · python:3.12-slim in Docker with --network none; all eight CI suites run
How we reviewed this: we ran all eight CI suites in python:3.12-slim with --network none, and drove the retrieval path against a planted tree. We made no Jev calls.
A plugin pack for Claude Code and Codex: 27 agent roles generated from templates, a catalogue of skills and MCP servers, and three pure-stdlib tools — a bounded read-only code search, a project map and a doctor. An optional Jev decision engine picks a role, a skill set and a tool set, and it is off by default: all five scopes are False in decision/config.py:50.
With the scopes on, one plan run makes exactly two requests, and the state has two keys — task and selected_role. No source, no file contents, no environment variables, no conversation history. The 19 MCP servers in the catalogue are references; catalog/mcp.json:3 says “Nothing here is installed by this repository”, and nothing in the code connects to any of them.
We have now found the same bug in nine tools: an exclusion list that guards the directory walk, defeated by naming a file explicitly. This is the second project to close it, and it does so more thoroughly than the first.
context.py:436 states the rule as a docstring:
def _explicit_paths(task, paths, project=None):
"""Recognize actual enumerated paths, never infer readable paths from task text.
and the enforcement is in the ordering — exclusion is decided before the read, at context.py:693:
reason = ("explicit task exclusion" if _excluded(path, manual_exclusions) else
"automatic task exclusion" if _excluded(path, automatic) else _skip(path))
if reason:
excluded.append({"path": scrub(path), "reason": reason})
continue
Naming a path only raises its score; it never grants access. We put five protected files in a tree and wrote a task that named every one of them and demanded “Include them all as evidence”:
excerpt paths: ['src/auth.py']
excl: {'path': '.env', 'reason': 'credential file withheld'}
excl: {'path': 'config/secrets.yaml', 'reason': 'credential file withheld'}
excl: {'path': 'credentials.json', 'reason': 'credential file withheld'}
excl: {'path': 'id_rsa', 'reason': 'credential file withheld'}
excl: {'path': 'server.pem', 'reason': 'credential file withheld'}
Even a task that says “do not exclude .env” only keeps the path out of the automatic list; _skip still stops it. The project_map CLI has no per-file entry point at all.
The rest of the codebase reads the same way. context.py:217 checks every path segment for symlinks including directories, resolves against the project root, opens with O_NOFOLLOW|O_NONBLOCK, fstats for a regular file, and re-fstats after reading to catch a size change — the most careful “read one file” we have seen. typesafe.py:52 disables redirects because urllib would otherwise copy the Authorization header to an arbitrary host. engine.py:365 turns “a decision expresses relevance, never authorisation” into an executable assertion that fails the build.
decision/redact.py:21:
_SECRET_WORD = r"(?:api[_-]?key|secret|token|password|passwd|passphrase|credential)s?"
and at :37, the key/value pattern:
re.compile(r"(?i)\b" + _SECRET_WORD + r"\b[ \t]{0,4}[:=][ \t]{0,4}[\"']?[^\s\"',;]{6,}"),
_ is a word character, so \b cannot match between DB_ and PASSWORD. We called scrub() directly:
| input | result |
|---|---|
API_KEY=abcdef123456 |
redacted |
password=hunter2hunter2 |
redacted |
Authorization: Bearer abc123def456 |
redacted |
DB_PASSWORD=prodpassword999 |
plaintext |
MY_SECRET=topsecretvalue |
plaintext |
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/… |
plaintext |
The last one is probably the most common secret variable name in existence. The impact is doubled because scrub is used both for local excerpts (context.py:710) and for the task text sent upstream (decision/jev.py:90) — so pasting a traceback containing AWS_SECRET_ACCESS_KEY= into a task, with a decision scope enabled, sends it.
redact.py:1 honestly calls itself “a defensive layer, not a guarantee”, and that framing is right.
We first wrote that this was a one-character fix. The author checked and corrected us, and he is right: dropping the leading \b catches DB_PASSWORD and MY_SECRET, but not AWS_SECRET_ACCESS_KEY, because there the pattern’s trailing boundary and its [:=] both land on _ACCESS_KEY rather than the separator. We verified this ourselves afterwards. Catching the common case needs a name-aware pattern that tolerates [A-Z0-9_]* on both sides of the keyword.
context.py:210:
if (lower.startswith((".env", "credentials", "secrets"))
or lower in {".npmrc", ".pypirc", ".netrc", "id_rsa", "id_ed25519", "id_ecdsa"}
or lower.endswith((".pem", ".key", ".p12", ".pfx", ".keystore")):
startswith on the basename means only names that begin with .env. We checked:
| file | skipped |
|---|---|
.env |
yes |
id_rsa |
yes |
envs/prod.env |
no |
config-secrets.yaml |
no |
infra/terraform.tfvars |
no |
.pgpass |
no |
.htpasswd |
no |
service-account.json |
no |
The mechanism is right; the table just needs more rows.
MIT, 35 commits, one day old, and the best CI in this batch: an ubuntu-24.04 × Python 3.10–3.14 matrix plus macos-15, followed by git diff --exit-code to catch stale committed artifacts, with Gitleaks over full history and CodeQL alongside. Every action pinned to a commit SHA, persist-credentials: false. All eight suites pass offline, including 176 end-to-end tests.
One thing we asked about: the NOTICE file says 24 of the 27 role files derive from a “Locus Agent Template Pack v1.0.0” that “carries no copyright line, no author attribution, and no license”, and that if the pack came from someone with rights, “the 24 derived roles need their permission or a rewrite”. The author has since told us that Locus is his own earlier project and the wording came out of stripping Locus-specific references when this was split off — adding that he has not rechecked the original records and does not want to overstate it. That reads as a documentation artefact rather than a live rights problem, and we would still like the NOTICE updated to say so.
There is also a class of silent-default behaviour worth knowing: decision/config.py:224 discards invalid environment values, so AGENT_DISPATCHER_DECISION_MODE=reqiured (one letter off required) quietly reverts to auto, and status says Config from defaults without naming what it rejected. required means “error if Jev can’t answer”; auto means “fall back silently”.
This is the most carefully built thing we have reviewed today, and the two gaps above are both small tables. We’ve reported them.
For the bypass in its unfixed form, see perch.
See how it compares with other tools in Best Jev tools, tested hands-on.
Review updated Sep 20, 2026. Numbers quoted from the project are its author's own; we don't publish our own measurements of Jev.
tamaratran/fast-jev-compaction
Claude Code plugin that replaces the compaction summary with Jev decisions. Every tool call and result is scored; stale ones are dropped or truncated, and everything kept stays verbatim.
thruwire/foreman
Puts Jev as a fast supervisor above slower coding agents such as Codex, starting from a ticket, spec, or bug report.
devagrawal09/jev-review
Staged code-review workflow for JavaScript and TypeScript with a local dashboard. Jev screens correctness, security, reliability, compatibility, and test risk, then scores severity and suggests a reviewer, with no generative model involved.
New Jev releases, pricing changes, and the best new projects, once a week. No spam; unsubscribe anytime.
Powered by Buttondown. See our privacy policy.