Repository navigation
Online extraction: listed inputs, quoted tool output and aggregate check results are not findings - #72
Open
BasRizk wants to merge 79 commits into
Open
Online extraction: listed inputs, quoted tool output and aggregate check results are not findings#72BasRizk wants to merge 79 commits into
BasRizk wants to merge 79 commits into
Conversation
…findings in collapsed sections
…arve out problems named in summaries; scope tool output
…pt-in model check
…mentation finding
…s on analyzed PRs
…; record unasserted labels
…utputs by fingerprint, survive failed jobs
…ure patterns and check they are specific
… unasserted label gives a reason; kornia fixture
…air deltas over PRs scored in both
…, with --dry-run counts
…with the reason, when it has no rows
…del_name; --reanalyze reuses stored actions, selects unstamped rows, clears labels, warns at --limit
…by the rules that cover them
…t is extracted again (5 of 6 draws)
…sion to the prompt sha256; keep re-analyzed PRs out of 'skipped'; pin the comparison baseline to the pre-change commit
…n PRs in compare_prompts; pin every prompt and formatter per version; 'path-specific instructions'
…uest in the aggregate sentence The rating bullet names priority and impact (the fixtures already label them ratings), and the aggregate-results sentence names the located coverage request as its other exclusion, so the two no longer contradict the tie-break. No new exclusion; extract-v2 digests updated (unreleased).
…omplete status, merged-name ignore The coverage template's free tails let a gate line followed by a concrete problem count as a gate. Scope and remediation are now fixed phrases (touched functions, add missing docstrings to meet the threshold), so anything else makes the item a finding; four such cases are negative tests. Review status also matches did-not-complete / failed / not-run notes and a no-findings note. ignored_tools is checked against the merged username, as db.rs does. The step 1 README names priority and impact ratings and the located coverage request.
…ributors from the results file For each bot it compares two arms on the leaderboard means and lists the PRs whose precision turns undefined or defined (with the shift that causes), the PRs whose own value moves each mean most (with their contribution), and those PRs' matched suggestions in every arm. No LLM call. A test pins the figures the PR description quotes to the results file.
…c763a) The head arm now comes from the exact head prompt; the previous head arm is kept as 'previous revision cee5e6cc'. The figures test_what_moved pins are updated to the new head draw.
The contributions double-counted the change in the PR count. Each mean's change is now split into the cohort effect of PRs leaving (on base values), of PRs entering (on arm values), and each retained PR's change over the shared retained count; the parts sum to the total exactly. Tests: a leaving PR beside a worsening one, an entering PR, and the sum on every bot and arm pair of the results file.
…s; pr_remark rule map Each arm in the results file now has a header row with the sha256 of the EXTRACT_BOT_SUGGESTIONS it was measured with, and a test checks the head arm's equals the shipped prompt. Review status also matches two-word product names and the 'reviewed N out of M changed files and generated no comments' line, as fixed whole-text templates with positive and negative tests. The pr_remark fixture kind maps to the prompt's explicit 'is a finding, wherever it sits' sentence.
…three words; fleetdm review effort is a run setting
On a push after a force-push, github.event.before can name a commit that is no longer in the clone,
and git merge-base then raised. The check now skips a raw sha that git cat-file cannot find, as it
already skips the all-zero sha; a named ref (a pull request's base) still fails loudly. The review
status template allows product names of up to three words ('Qodo Merge Pro review was paused.').
Copilot's 'Review effort: Balanced' on fleetdm/fleet#55421 is a run setting, so its label kind is
run_status; it stays an asserted non-finding with the same pattern.
…ames every pinned input The type patterns behind items_* were written on CodeRabbit's text, so the other bots' run-status notes (Codex 'did not complete' and 'usage limits reached', Qodo 'reviews are paused', Claude 'could not confirm CI', Greptile 'no user flows identified') were counted as code findings. Every unlocated item of the six other bots was read; those notes are now items_run_status, and a test checks the excluded-only PRs' items in every arm that extracted them. Metrics are unchanged. The version-bump comment in prompts.py and the ETL README now list the inputs prompt_pins.py pins, actor matching and analyze_single_pr's arithmetic included.
…through is still a finding Qodo keeps its earlier findings in its summary comment, struck through and marked Resolved or Dismissed, and the head prompt dropped several of them, among them resolved findings matched to the author's fix. One sentence, by kind rather than by vendor, says such a finding is still a finding wherever it is listed: the marker is the finding's state, not review status or run metadata, and the follow-up-confirmation skip covers only the confirmation. A trimmed Qodo fixture (anolilab/neore#451) asserts two resolved findings and one dismissed one; the TajsTokens dismissed finding is now asserted. extract-v2 (unreleased) pins the new prompt digest.
…kept as its own arm Every bot was re-run once on the head prompt with the same harness (CodeRabbit's 313 PRs, the six co-reviewed bots, the step-1-only bots); the previous head's rows stay as 'previous revision 093c763a, one draw', with its prompt sha in the arm header. The head's status notes are typed by hand like the other arms'. what_moved figures in the tests follow the new head. The scylla description-check row (1 of 9 draws on this prompt) and the TajsTokens dismissed finding (2 of 9) are borderline in the model, so they are no longer asserted; the reasons say so. The README step 1 description names resolved and dismissed findings as findings.
…he scylla and TajsTokens rows The 70-word sentence regressed other checks (the scylla description-check row fell to 1 of 9 draws). It is now one sentence beside the collapsed-section rule, and the follow-up-comment skip says in a few words that it covers the confirmation, not the finding it refers to. Chosen from three short wordings on the fixture draws (scylla 5 of 6, zizmor kept out 6 of 6, the Qodo fixture 6 of 6). The scylla row and the TajsTokens dismissed finding are asserted again; extract-v2 pins the new digest.
…s in EXTRACTION_SCOPE_DETAILS.md Every bot was re-run once on the head prompt with the same harness (CodeRabbit's 313 PRs, the six co-reviewed bots, the step-1-only bots); the previous head stays as 'previous revision a2fcbe51, one draw' with its prompt sha in the arm header, and the head's status notes are typed by hand like the other arms'. The per-arm tables, the CodeRabbit type table, the Qodo resolved-findings counts, the ruling counts, the fixture draws for each wording tried and the generated what_moved output now live in prompt_eval/EXTRACTION_SCOPE_DETAILS.md, so the PR description can stay short. The pinned what_moved figures follow the new head.
…ut; README mirrors the prompt pcsx-redux#2544's rating-explanation finding (0 of 6 on the head, 1 of 6 upstream) and local-search-mcp#27's linked-issue row (0 of 6 with both) stay unasserted, with the new counts in their reasons and in the details file. The details file says the dropout lands unevenly (the Claude and Greptile status notes are still extracted) and names status notes by type. The README step 1 description uses the prompt's wording for resolved findings.
… 1 says no more than the prompt One rule for finding labels: a finding stays asserted whatever its pass rate, and its failures are disclosed. pcsx-redux#2544's rating-explanation finding and local-search-mcp#27's linked-issue row are asserted again; with TajsTokens' dismissed finding they are the three the live run fails on the head (also missed by the current upstream prompt). Only overview sentences carry no pattern. The README step 1 description now names product text among the exclusions, a concrete problem the bot itself names, and a tool result posted at a location in the changed code, as the prompt does; the details file paraphrases the bots' status marks.
…wording 2 was chosen README step 1 says a rule violation reported at a specific location in the changed code, as the prompt does. The details file names the rule that chose wording 2 (most clean draws over the four fixtures, 18 of 24 against 17 and 15) and notes the neutral linked-issue row that has no pattern.
…out a model name what_moved reports a mean's change as unavailable when either arm has no PR with both values, and skips the split when no PR is scored in both arms, instead of computing against an invented zero; tests cover both cases, and the output on the results file is byte-identical for every bot and pair of arms. stamped_model_name keeps model_name None when there is no model name rather than storing 'unknown+extract-v2'. The details file says why the chosen wording's CodeRabbit differences favour CodeRabbit, and that the intro's linked-issue wording may contribute to the cubic row's miss (a reword did not help, so it was not adopted).
…s state the wording margins The cubic linked-issue row's kind (check_finding) now maps to the sentence that judges other PR-level content like any other comment, not to a sentence inside the gate bullet that leaves linked-issue checks out. Narrowing that carve-out to title and description checks did not help the row (0 of 6) and lowered the scylla row (1 of 6), so the prompt is unchanged; the details file records both tries and states the wording-choice margins exactly. coverage_only's docstring says its templates follow CodeRabbit's lines, so f is understated more for the other bots.
…lines labelled control With --bot all, coverage_only prints once that f is not comparable across bots (its templates follow CodeRabbit's lines, so f is understated more for the other bots); a test checks it. Copilot's 'Review effort: Balanced' and CodeRabbit's 'Review profile: QUIET' are review settings, so their fixture labels are control rather than run status (both stay asserted non-findings, same patterns). The details file adds the caveat and says both rejected linked-issue tries would have favoured CodeRabbit's score.
…ngs lines labelled alike The details file states what each rejected linked-issue try would have done per fixture and per bot (the scylla CodeRabbit row less often, which would have favoured CodeRabbit; zizmor kept out less often in try 1, against CodeRabbit; TajsTokens' dismissed Qodo finding more often, for Qodo), notes the cross-session noise, and says where the step-1-only PRs live. Qodo's 'Review mode' line is labelled control like Copilot's and CodeRabbit's settings lines; the control rule map now holds the whole bullet sentence including 'configuration or review-settings details'. coverage_only prints its cross-bot caveat for any bot other than CodeRabbit.
…ies' TajsTokens gain named The zizmor head baseline now counts the two live draws like the scylla and TajsTokens baselines (8 of 8), and each rejected linked-issue try is described as worse on the CodeRabbit fixtures and better on TajsTokens.
EXTRACT_BOT_SUGGESTIONS keeps upstream's text and adds one paragraph after its skip rules: skip the inputs the bot lists as used for its review, tool output quoted as context inside a comment is not a finding, a tool result the bot posts at a location as its own comment (or writes up in its own words) is a finding, and findings in review-body or collapsed sections are findings. extract-v2's rules for overviews, ratings, coverage gates, controls, run metadata, resolved findings and title remarks are dropped: on the default Search API input the current prompt extracts nothing from those kinds. EXTRACTION_PROMPT_VERSION = "extract-v3", pinned in tests/test_prompts.py. The wording tests pin the paragraph that is there and check that the dropped rules are absent. The fixture test maps each labelled kind to the sentence that decides it, or to no rule; the live check does not assert non-findings of a kind with no rule (NO_RULE_KINDS). The packaged prompt_eval results were measured on extract-v2, and their test now says so.
…ackaged arms The packaged results' newest arm is the unreleased extract-v2 draft, so it is labelled "extract-v2 af4797d5, one draw" instead of "this PR at head". The version ledger marks extract-v2 as an unreleased draft and extract-v3 as the first released version. Removed, as they only made sense for the draft's rules: EXTRACTION_SCOPE_DETAILS.md (its measurement write-up), coverage_only.py (counts analyses whose only items those rules excluded) and what_moved.py, with their tests. The README's step 1 text describes the one paragraph the prompt adds.
…uest is One sentence added to the extract-v3 paragraph: a status, a metric against a threshold, or a request to add docstrings or tests to "the touched functions" is not a finding, and a request that names a function, or a file and line, in the changed code is. extract-v3 is unreleased, so its ledger entry takes the new digest. The coverage_check fixture labels now have a rule, and the live check asserts them again.
…o the bot's own words An aggregate check result is now defined: a count, a percentage or a pass/fail measured over many functions or files (docstring or test coverage against a threshold). A check that states a specific problem with the pull request, such as its title or description, is not aggregate and is a finding, as the scylladb fixture labels its description-check row. The closing sentence covers only findings the bot states in its own words, so it cannot override the listed-inputs skip. The fixture test maps the description, PR-remark and check-finding kinds to the sentence that keeps them, checks that check labels sit on the side the sentences give, and its docstring says what it can and cannot show. extract-v3 is unreleased: its ledger entry takes the new digest.
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.
What this changes
Step 1 (
EXTRACT_BOT_SUGGESTIONSinonline/etl/llm/prompts.py) gets one new paragraph, after the existing skip rules. The rest of the prompt is unchanged:It also adds a version stamp,
EXTRACTION_PROMPT_VERSION = "extract-v3". Each analysis now storesmodel_nameas"<model>+extract-v3", so analyses made with different prompts can be told apart.tests/test_prompts.pypins the sha256 of every input the version stands for: the step prompts, the code that builds step input, the actor matching, the metric arithmetic, the response schemas and the LLM call. The test fails when one of them changes without a new version. In CI it also compares the table with the one at the merge-base, so a past entry cannot be edited in place.online/etl/README.mddescribes this.Why
This is a correctness fix. The rule is the same for every bot.
The rule is the same for every bot. How much it changes a bot's numbers depends on how often that bot posts such content.
Measured effect
We replayed step 1 and step 3 on a sample of public PRs from the benchmark's stored data. The input is the one the default Search API path builds: every review and every review-thread comment of the bot, across all review rounds, and no issue comments. The human actions were held fixed. The judge was gpt-5.2 at temperature 1.0. P and R use the leaderboard arithmetic: the mean over PRs that have both. Intervals are 95% paired bootstrap intervals over PRs. These numbers come from a sample, and the judge may not be the model you run. They are not what the leaderboard would show after this change.
The whole sample
This run used an earlier wording of the paragraph, without the check-result sentence.
There is no measurable change for CodeRabbit or for the six other bots. Two draws of the unchanged prompt differ by up to 1.2 points. The sample has 395 bot-PR pairs for the six other bots. We stopped spending after 9 of them had only one draw of the new prompt, so the table uses the 386 pairs with two draws each.
The paragraph as shipped
On this input, check results reach step 1 only through review bodies. In the sample, 15 CodeRabbit PRs have a docstring coverage check there. We ran the paragraph as shipped on those 15, on 40 other CodeRabbit PRs picked at random, and on 70 other-bot pairs picked at random. Two draws per arm, against the current prompt:
The change removes every coverage-check item. On the 15 PRs with a coverage check, precision moves up by about 4 points. With 11 scored PRs that is within the noise: two draws of the current prompt differ by -4.2 [-9.2, +0.0] there. Elsewhere there is no measurable change.
Three CodeRabbit reviews in the sample state a title, description or linked-issue check in the review body. Neither the current prompt nor this change extracted an item from them, so nothing was lost there. We read the 5 PRs where this change matched fewer human changes than the current prompt. One lost match was an aggregate coverage item, which this change removes on purpose; the human change it had matched added docstrings. In one PR, two items on the same code were extracted as one. In one, a test-gap item that the current prompt extracted in one of its two draws was not extracted. The rest were the same items, paired differently by the matching step.
The version stamp lets the leaderboard tell analyses made with this prompt from older ones.
Tests
tests/test_prompts.pypins the wording of each sentence of the new paragraph. It also pins the version table.tests/test_extraction_scope_fixtures.pyuses 12 trimmed public review fixtures. It checks that the labelled text reaches step 1, and maps each labelled kind to the prompt sentence that decides it, or explicitly to no rule. It checks that the sentence is in the prompt, and that labels of a kind sit on the side its sentence gives: a description-check row is a finding and a coverage row is not. It cannot show how the model applies the sentences.