You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Jev can cheaply decide narrow local support questions, but it cannot replace open-ended or multi-step code review.
How
Use Jev as an active first-stage verifier that keeps clear support, drops clear ordinary contradictions, and defers uncertainty plus protected findings to the existing reasoning verifier.
Test Plan
bun test
bun run typecheck
bun run lint
bun run llp:check
bun run build
After merge, configured reviews use Jev directly; missing credentials or failed calls follow the prior verification path.
Overall PR risk: Medium. The change modifies the verification pipeline to add an optional Jev classifier that can keep or drop findings before the reasoning verifier runs. It is gated behind a root-only jev config block and absent by default, but the PR adds this block to the repository's own config, so the cascade is active once TYPESAFE_API_KEY is set. Four warnings identify issues with documentation and code: the workflow comment contradicts the actual Jev behavior and does not disclose that source is sent to TypeSafe, the template comment omits the same disclosure, code can wrongly drop findings that have no readable source, and a Jev model substitution is misreported to the user as an OpenCode fallback.
🔗 Review setup:
This PR changes code the reviewer prompts cite (src, src/tests, src/config/load.ts, src/config/schema.ts, src/core/auth.ts, and 4 more). Check that the guidance quoting it is still correct.
🟡 Warning (4)
Workflow comment misstates Jev activation and disclosure posture — .github/workflows/expo-code-review.yml:93(security) · id:1eb70fb05e22 Confidence: High — the config, schema, and docs changed in this PR all agree Jev has no enabled flag and is active once configured. Impact if shipped: Medium — maintainers reading this comment will wrongly believe Jev is inactive while source is being sent to TypeSafe. Suggested remediation: Update the comment to disclose actual behavior: "Optional Jev verification credential; active once the root config declares a jev block. Enabling it sends bounded file source to TypeSafe. No shadow mode, no enabled flag."
Evidence and reasoning
The comment claims the Jev evaluator is "Shadow-only" and "unused while config.jev.enabled is false." No enabled field exists in the jev schema; src/config/schema.ts defines only model, minConfidence, timeoutMs, and maxContextChars. The README added in this PR states: "There is no shadow mode or separate enabled flag." llp/0014-jev-selective-verification.explainer.md confirms "There is no separate enabled flag and no shadow phase."
The same PR adds a populated jev block to .expo-agents/code-review/config.jsonc, so Jev is active in this repository once TYPESAFE_API_KEY is set. Yet the comment sits next to the secret mapping and claims it stays "shadow-only" and "unused" — the opposite of shipped behavior.
Moreover, the comment fails to disclose that enabling Jev sends up to 30000 characters of repository source per finding to api.typesafe.ai, a provider separate from the model provider. The config schema documents this reason ("ROOT-ONLY because it sends bounded source context to a separate provider"), but the workflow comment omits it entirely.
A maintainer could enable the secret believing the cascade is inert, not realizing it immediately changes verification behavior and sends repository source to an external provider.
Scaffolded jev block does not disclose that repository source leaves the repo — templates/config.jsonc:51(security) · id:0cb0a185ac92 Confidence: High — traced buildJevState back to inspectEvidence, which returns whole file contents up to maxContextChars. Impact if shipped: Medium — an adopter can enable jev and send private repository source to api.typesafe.ai without a warning in the template. Suggested remediation: Add a disclosure line: "Enabling this sends bounded repository SOURCE (up to maxContextChars per finding) to api.typesafe.ai, a provider separate from your model provider. Enable it only where that source may be shared."
Evidence and reasoning
This template scaffolds into every adopting repo. Adopters read the comments to decide if the block is safe to enable.
The data path: verifyFindings calls inspectEvidence, which returns file text as sourceContext. verifyFindings passes that to evaluateFindingsWithJev. buildJevState bounds it to maxContextChars (default 30000) and sends it to https://api.typesafe.ai, a provider separate from the model provider.
So enabling jev sends up to 30000 characters of repository source per finding to a third party. The comment block does not disclose this. It only names the credential.
The repo's own convention requires this disclosure. The adjacent research block explicitly warns about sharing search terms with "Brave and the documentation providers." The schema records the reason: "ROOT-ONLY because it sends bounded source context to a separate provider." The template drops that disclosure.
Jev can drop a finding when no source context was read — src/core/verify.ts:182(correctness) · id:1869ac49106d Confidence: High — inspectEvidence returns empty sourceContext for unreadable or out-of-tree files, and verifyFindings passes them to Jev. Impact if shipped: Medium — a real finding can be dropped with no source evidence behind the drop. Suggested remediation: Only build a Jev candidate when presence !== "unknown" and sourceContext is non-empty. Findings with no readable source must keep the pre-Jev path.
Evidence and reasoning
inspectEvidence returns { presence: "unknown", sourceContext: "" } when the resolved path fails pathInside or readFile throws. verifyFindings maps every checked finding into the Jev candidate list without filtering on presence or empty sourceContext. If Jev answers contradicted, jevDisposition returns "drop" for any ordinary finding, and the reasoning verifier never runs.
This is reachable. scrubAmbientRuntimeConfig deletes AGENTS.md, CLAUDE.md, .claude, and .env* from the review tree, so readFile fails for findings about those files. Previously such a finding took the else branch and was kept as "non-critical." Now it can be suppressed by Jev with no source at all. LLP 0014 states that missing context must defer, but the code does not enforce that precondition.
Jev model substitution is misreported as an OpenCode fallback — src/core/review.ts:1121(correctness) · id:57cd5da39bbd Confidence: High — direct trace through trackModel and the coverage-note builder. Impact if shipped: Medium — a user gets wrong diagnosis and wrong fix steps when the Jev provider changes its model id. Suggested remediation: Give the jev-verifier bucket its own substitution branch instead of falling through the engineOf[bucket] ?? "opencode" default, so the coverage note names TypeSafe/Jev, not OpenCode.
Evidence and reasoning
trackModel("jev-verifier", verification.jev.configuredModel, verification.jev.actualModel) reuses substitution logic built for the two reviewer engines. If TypeSafe returns an actualModel differing from the configured jev.model alias, trackModel adds "jev-verifier" to substitutedBuckets.
At src/core/review.ts:975, the code maps each substituted bucket to an engine with engineOf[bucket] ?? "opencode". engineOf is built only from reviewer-agent ids; "jev-verifier" is never a key, so the fallback always resolves to "opencode". This makes subEngines.has("opencode") true, which appends guidance about OpenCode fallbacks to the coverage note. That guidance is wrong: Jev never runs through OpenCode, and the named settings (agents' model, coordinator.model, REVIEWER_MODEL) do not affect it. A maintainer debugging the warning would investigate the wrong subsystem.
This review is advisory — it never blocks a merge and never auto-approves.
LipLoody
changed the title
Add Jev shadow evaluation
[ecr] add Jev selective verification
Sep 21, 2026
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
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.
Why
Jev can cheaply decide narrow local support questions, but it cannot replace open-ended or multi-step code review.
How
Use Jev as an active first-stage verifier that keeps clear support, drops clear ordinary contradictions, and defers uncertainty plus protected findings to the existing reasoning verifier.
Test Plan
bun testbun run typecheckbun run lintbun run llp:checkbun run build