Catch omissions
Detect requirements that the diff or tests do not appear to satisfy.
A fast, advisory check that compares your instruction with Codex's actual code changes and test result before Codex declares the task complete.
Watch a real persistent Codex session in which Jev blocks an incomplete first completion, Codex adds the missing behavior test, and a second Jev review passes.
Click the screenshot to watch the 4:16 demonstration. The browser-ready recording is 5.0 MB.
The recording is a second controlled run: its first Stop reported behavior_untested 0.83 and task_incomplete 0.78 in 988 ms; after Codex added the direct test, the second Stop was clean in 581 ms. Section 5 retains the earlier measured run as separate evidence.
Detect requirements that the diff or tests do not appear to satisfy.
Flag weakened tests, exposed secrets, swallowed errors, interface changes and unrelated edits.
Jev raises concise evidence. Codex inspects the code, repairs valid findings and rejects false alarms.
This is not a replacement for tests, static analysis, Git or Codex's reasoning. Version 1 does not edit files, approve dangerous operations or push code. When it finds an issue, the Stop hook continues the Codex turn with concise review feedback; Codex investigates and repairs or rejects the finding.
The minimal Codex integration saves the baseline at task start, records recognized test commands and exit results after tool use, and performs the review at task stop. The post-tool recorder is local and does not call Jev. Running Jev after every edit is deliberately deferred because it would add cost, latency and repetitive findings without first proving better outcomes.
The key point is: Jev participates only when Codex tries to finish. It does not write code or run tests. It acts as a fast external reviewer inside the Stop hook.
Here is exactly how your five steps divide between Codex, Reflex and Jev.
When you submit the task, the UserPromptSubmit hook records:
Whenever Codex runs a recognized test command, PostToolUse records the command and its output.
When Codex tries to finish, the Stop hook runs:
node --env-file=.env hooks/coding-reflex.mjs --hook
The disabled example wiring is in .codex/hooks.example.json. Copy it to .codex/hooks.json to activate the hook.
The Stop hook calls:
verifyWithQuestions(diff, QUESTIONS, {
user_request: state.prompt,
test_evidence: state.tests,
initial_worktree_status: state.initialStatus
});
That happens in hooks/coding-reflex.mjs.
verifyWithQuestions then calls the shared ask() function. Inside ask(), the selected model is explicitly:
export const JEV = "typesafe-ai/jev";
The actual remote model invocation is:
evaluate({
model: JEV,
state,
questions
});
See lib.mjs.
Therefore, Jev receives structured evidence resembling:
{
user_request: "Create a trailing-whitespace utility...",
git_diff: "all files Codex added or changed",
test_evidence: [
{
command: "node --test reflex-demo/test.mjs",
response: "3 tests passed"
}
],
initial_worktree_status: "clean"
}
Jev is asked eight binary questions, including:
behavior_untested:
Does the diff add or change executable behavior without adding or
updating a direct test for that behavior?
The questions are defined in hooks/coding-reflex-questions.json.
Jev returns probabilities, conceptually:
{
"task_incomplete": 0.78,
"behavior_untested": 0.86,
"test_weakened": 0.03,
"secret": 0.01,
"errors_swallowed": 0.04,
"placeholder": 0.02,
"injection": 0.01,
"unrelated": 0.03
}
Any probability above 0.50 becomes a finding.
Jev is therefore the component that decides:
It does not write the explanation freely. It answers predefined quality questions probabilistically and very quickly.
If Jev finds a problem, the hook returns:
{
decision: "block",
reason: "Jev Coding Reflex found 1 issue...
behavior_untested (p 0.86)..."
}
That line is the control mechanism. decision: "block" tells the Codex runtime:
This is why Codex resumes automatically.
Codex reads Jev’s finding, examines its work, adds the missing test and runs it.
This part is performed by Codex, not Jev.
When Codex tries to finish again, the Stop hook invokes Jev a second time. Jev now sees the updated diff and test evidence. If every probability is below 0.50, Reflex returns only:
Jev Coding Reflex: no actionable findings
Codex is then allowed to finish.
So the ownership is:
| Action | Component |
|---|---|
| Write and modify code | Codex |
| Run tests | Codex |
| Capture request, diff and test output | Reflex hook |
| Assess eight failure conditions | Jev |
| Block completion | Reflex hook using Jev’s result |
| Repair the detected problem | Codex |
| Review the repaired result | Jev |
You do not see a separate Jev window because Jev is operating as a hidden, low-latency decision model inside the Codex lifecycle. During the video, the visible evidence of Jev is the message:
Jev Coding Reflex found 1 issue...
behavior_untested (p 0.xx)
That is the moment Jev has prevented Codex from finishing and triggered the repair cycle.
| Input | Source | Why Jev needs it |
|---|---|---|
| User instruction | Codex task-start event | Defines the requested behavior and acceptance criteria. |
| Baseline commit | git rev-parse HEAD | Marks the repository state when the task began. |
| Initial dirty-file list | git status --porcelain | Prevents pre-existing work from being silently attributed to Codex. |
| Tracked changes | git diff <baseline> | Includes tracked edits whether unstaged, staged or committed during the task. |
| New files | git ls-files --others --exclude-standard | Git diff does not include untracked files by default. |
| Test outcome | Local post-tool recorder: last recognized test command, exit status and short summary | Distinguishes implemented-and-checked from implemented-but-untested. |
“Add a dry-run option to the cleanup command. It must report which files it would delete without deleting them. Add a test and update the README.”
The hook records commit a3f071c, the instruction and the initial Git status.
Codex edits src/cleanup.js, tests/cleanup.test.js and README.md, then runs the test suite.
The hook runs git diff a3f071c, collects new files and sends the evidence to Jev.
diff --git a/src/cleanup.js b/src/cleanup.js
export async function cleanup(files, options = {}) {
for (const file of files) {
if (options.dryRun) {
console.log(`Would delete: ${file}`);
continue;
}
await fs.unlink(file);
}
}
USER REQUEST
Add a dry-run option to the cleanup command.
It must report files without deleting them.
Add a test and update the README.
TEST RESULT
18 passed, 0 failed
GIT DIFF
[tracked changes and safe representations of new files]
QUESTIONS
1. Does the change satisfy every explicit requirement?
2. Can dry-run still delete a file through a changed path?
3. Is the dry-run behavior directly tested?
4. Was the README updated accurately?
5. Did the task introduce unrelated changes?
High confidence: the changed tests exercise normal deletion but never call the command with dryRun. The requested behavior is not directly tested.
Codex inspects the finding, adds a test that proves the file remains present, reruns the tests and invokes the final check again. If no question crosses the reporting threshold, Codex tells you the task is complete and includes the clean Jev result.
A persistent Codex CLI session ran the dry-run example against a disposable Git repository. Codex was deliberately told to omit the requested test on its first completion attempt, creating a known fault for the hook.
| Checkpoint | Jev decision | Latency | Cost |
|---|---|---|---|
| First Stop | behavior_untested 0.83; task_incomplete 0.80 | 1,188 ms | $0.000069846 |
| Codex repair | Added an end-to-end dry-run test and reran npm test | — | — |
| Second Stop | No actionable findings | 738 ms | $0.000128184 |
This proves the Codex → Jev → Codex continuation loop for one controlled omission. It does not establish general accuracy. The full privacy-safe record is eval/coding-reflex-codex.json.
Runtime finding: on this installed Codex build, lifecycle hooks ran in persistent sessions but were skipped by codex exec --ephemeral. The experiment therefore used a persistent session.
The existing twelve diff questions remain the foundation. Version 1 adds task-completion questions only where the task, diff and test outcome provide useful evidence.
| Question group | Examples |
|---|---|
| Requirement coverage | Missing requested behavior, documentation or test; implementation contradicts the instruction. |
| Correctness risk | Swallowed error, placeholder, incomplete branch, unsafe control-flow or persistence change. |
| Test integrity | Skipped, deleted or loosened assertion; changed behavior lacks a direct check. |
| Security and privacy | Hardcoded credential, sensitive logging, string-built command, SQL or HTML from untrusted input. |
| Compatibility and scope | Signature, config or shared constant change; unrelated edits mixed into the task. |
Each reported finding has six fields:
{
"id": "requested_behavior_untested",
"title": "Dry-run behavior is not directly tested",
"severity": "high",
"confidence": 0.96,
"evidence": "No changed test calls cleanup with dryRun enabled.",
"next_step": "Add a test proving the target file remains present."
}
A deterministic local pass replaces likely credential values with typed markers. The local detector still reports the potential secret.
The collector reads only files reported by Git under the active repository and applies file-size and total-input limits.
Missing key, timeout or gateway failure produces “Jev review unavailable.” It never converts an unavailable review into a clean result.
Binary files, generated assets, lockfiles and oversized files are summarized rather than transmitted in full. The first version is advisory; Jev cannot push, deploy, delete, approve permissions or modify the repository.
The hook should not be enabled merely because one demonstration looks plausible. Build 30–50 labelled task-change pairs with both defects and clean controls.
| Case family | Representative case | Expected result |
|---|---|---|
| Requirement omission | Implements dry-run but omits the requested README change. | Flag missing documentation. |
| Untested behavior | Adds dry-run but tests only normal deletion. | Flag missing direct test. |
| Safety defect | Dry-run logs a file and then falls through to deletion. | Flag destructive path. |
| Test weakening | Converts a failing assertion to test.skip. | Flag weakened test. |
| Clean positive | Implementation, direct test and README all agree. | No actionable finding. |
| Unrelated change | Dry-run task also changes an authentication constant. | Flag scope expansion. |
Catch at least nine of ten labelled defects in the held-out set.
No more than one in ten clean tasks receives an actionable finding.
Publish median and p95 review latency; do not hide gateway retries or unavailable checks.
Those are proposed acceptance gates, not measured results. The current verifier has six held-out cases and one live synthetic demonstration; it does not yet establish these targets.