See [docs/prs/2026-10-17-PR#117-doccheck-variant-b.md](docs/prs/2026-10-17-PR%23117-doccheck-variant-b.md). Replaces the economy-model summary of the doc check with one Jev call per changed file, and adds a data-outflow check. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed-on: #117 Co-authored-by: claude-code <claude-code@javagil.de>
10 KiB
PR#117: Jev Checks Each Changed File Against the PR Document
Version: minor
WARNING: This document describes only the change applied in this PR. It may already be outdated once the next PR is merged. Historic PR documentation is not maintained along with new PRs; treat it as a snapshot.
Problem
The document check of PR#47 and PR#116 runs in two models: an economy model summarizes the diff without the PR document, then Jev compares each section of the PR document and each summarized change with the summary. The summary is a second provider, a second cost and a second source of error: a change that the summary words loosely or drops never reaches Jev. It also hides where a change sits: the summary names files, but Jev never sees the diff itself.
For the main use of the check, the hs.hsadmin.ng backend, the summary buys nothing. Jev reads about 32000 tokens of state, enough for the PR document and one file's diff. A measurement on 2026-10-17 showed that Jev reads a file's diff directly as well as it reads a summary of it, and that a backdoor woven into an on-topic file, which the summary hides, is caught by a question about data outflow.
Non-Goals
- No change of the four contradiction questions of PR#47 beyond rewording them from the summary to the file diff.
- The PR document, written by the author, must not lower the judgments about security or weakened checks; the data-outflow question is a judgment of the diff, not of the document.
- No per-language detection of comment-only changes; the existing mechanical rule decides what is trivial.
- A PR document that claims every change in vague words can still hide one; Jev judges the text as written.
Specification
Feature: Jev checks each changed file against the PR document
Scenario#117.01: a file diff that contradicts a test claim gives ORANGE
… so that a PR document that claims tests the code does not add waits for a human.
- Given Jev rates the diff of a changed file as contradicting a test claim of the PR document from
orange_minon - When werkrevisor reviews the PR with
[doc_check] - Then a line comment at the file states the contradiction as ORANGE
Verified by
Scenario#117.02: a file unrelated to the PR document gives a hint
… so that a by-catch gets declared, or a change that does not belong to the PR gets reverted.
- Given Jev rates the diff of a changed file as unrelated to the PR document from
unrelated_minon - When werkrevisor reviews the PR with
[doc_check] - Then a hint at the file names the change as not required by the PR document
Verified by
Scenario#117.03: a file that sends customer data outside gives a data-outflow hint
… so that a backdoor woven into an on-topic file is caught before a human reads the PR.
- Given Jev rates the diff of a changed file as sending personal or customer data to a URL from
exfil_minon - When werkrevisor reviews the PR with
[doc_check] - Then a hint at the file names the possible data outflow
Verified by
Scenario#117.04: each changed code file is checked against the PR document in one step
… so that the check needs no economy model and no second provider.
- Given a PR with a changed PR document and two changed code files
- When werkrevisor reviews the PR with
[doc_check] - Then the review checks each code file against the PR document for a contradiction, an unrelated change and a data outflow
- and no economy model summarizes the diff
Verified by
Scenario#117.05: a mechanical file is not sent to Jev
… so that an import-only or whitespace-only change costs no Jev call.
- Given a changed file whose every changed line is an import or whitespace
- When werkrevisor reviews the PR with
[doc_check] - Then Jev gets no state for that file
Verified by
Scenario#117.06: a resolved hint is not repeated while the file and the PR document stay unchanged
… so that the author can answer a hint once.
- Given the author resolved the hint about a file
- When werkrevisor reviews a new commit with the same PR document and the same diff of that file
- Then werkrevisor does not repeat the hint
Verified by
Scenario#117.07: the usage record logs the values per file
… so that the thresholds can be calibrated on real PRs.
- When werkrevisor writes the usage record
- Then the record holds the file, the line and the value of each question for every judged file
Verified by
Scenario#117.08: a deleted file is checked and its hint sits on the PR document
… so that a deletion that the PR document does not require does not pass unseen.
- Given a PR that deletes a file, which Jev rates as unrelated to the PR document from
unrelated_minon - When werkrevisor reviews the PR with
[doc_check] - Then one hint at the PR document names the deleted file
Verified by
Scenario#117.09: a hint on a documentation file holds the merge
… so that an unrelated change or a data outflow in a Markdown file does not pass unseen.
- Given Jev flags a changed documentation file, and
[review] doc_hint_line_commentsis off - When werkrevisor reviews the PR with
[doc_check] - Then the hint is a line comment on that file, so it holds the merge until it is resolved
Verified by
Solution
doccheck.judgesends one Jev call per changed file outside the PR documents and the mechanical files. The state holds the PR document, the diff of that one file and the conventions of the repository.- The economy-model summary is gone:
no
SUMMARY_PROMPT, nosummarize, noparse_summary, no OpenRouterdoc_check_client. The four contradiction questions of PR#47 are reworded from the summary to the diff of the file; the unrelated question of PR#116 and a new data-outflow question join them in the same call. - A new key
[doc_check] exfil_min, default 0.7, sets the value from which a data outflow gives a hint.[doc_check]no longer needsmodel,input_price_usd_per_mtok,output_price_usd_per_mtok,max_output_tokens,max_diff_charsorprovider_order; the check is Jev alone. - A flagged file gets one line comment at its first changed line, as ORANGE for a test-claim contradiction, else as a hint; like every hint, it holds the merge until it is resolved. A deleted or deletion-only file has no line in its new version, so the check judges it too and collects its hint in one comment at the PR document.
- A PR document check finding carries
from_doc_check, so it holds the merge even on a documentation file; the documentation exception of_plan_line_comments, which turns a model hint on a doc file into a free hint, does not apply to it. The comment holds a fingerprint of the file path, its diff and the PR document, so a resolved hint does not come back while both stay unchanged, but an ORANGE one does. - The usage record holds the values per file as
doc_check_judgments;doc_summary_*anddoc_coverage_judgmentsare gone. The check is Jev cost only; the statistics service already tolerates the missingdoc_summary_*. [doc_check]is switched on in config/hsadmin-ng.toml.- The diagrams drop the economy-model summary step; the check is one Jev step "PR document vs each file".
- werkrevisor 0.49.0.
Measurement
Re-run live on 2026-10-17 with the state and questions of this PR, against the hs.hsadmin.ng backend
(hostsharing/hs.hsadmin.ng), Jev jev-latest.
The false-positive set is 103 non-trivial main-code file diffs from 15 merged PRs (#299 to #329),
each judged with its own PR document.
The positive is a backdoor woven into a topic-matching file,
which sends customerEmail and the invoice total by an HTTP query to an external host, disguised as a template fetch.
| question | backdoor (6 runs) | 103 real files |
|---|---|---|
| data-outflow | 6 of 6 from 0.97, median 0.98 | 0 of 103 from 0.5, max 0.13, median 0.02 |
| unrelated (PR#116) | 0 of 6, max 0.25 | 0 of 103 from 0.3, max 0.29, median 0.03 |
The data-outflow question separates the backdoor from every real file;
the unrelated question misses the backdoor, because the file is on topic, and gives no hint on a real file.
The real files stay below 0.3 for both questions, while a planted change reached 0.7 to 0.98 in PR#116,
so unrelated_min = 0.7 and exfil_min = 0.7 sit in a wide gap and stay unchanged.
The four contradiction questions keep the separation of PR#47 when they read the file diff instead of the summary:
a planted "no test changed" still reaches 0.71 and more, unchanged documents stay below 0.2.
Release Notes
[doc_check]now checks each changed file directly against the PR document, without an economy-model summary, and flags a change that sends personal or customer data to an external service.
Open Questions
- Keep the data-outflow question as a hint or make it ORANGE?
A hint from
exfil_minon; it holds the merge until the author resolves it. ORANGE needs a calibration on real flagged PRs first. - What counts as a trivial file that needs no Jev call? The existing mechanical rule: a file whose every changed line is an import, a whitespace change or a rename. Comment-only changes are rare and cheap and are not detected separately.
- Which value for
unrelated_minandexfil_min? Both stay at 0.7: on 103 real file diffs both questions stay below 0.3, see "Measurement", while a planted change reached 0.7 to 0.98 in PR#116.
Follow-up PRs
- Calibrate
hint_minon the usage records of real PRs, and decide whether the data-outflow question becomes ORANGE.