Repository navigation
research: manual ground-truth check, adjudication and corrected hidden rates - #60
Merged
Merged
Conversation
gt_sample.py now also writes items.json: the sampled findings shuffled under neutral ids, without the harness's answer, the stratum or the schemes' outcomes. sample.csv's new item column is the key back to the truth. A persisting finding becomes a pair item (same issue at the old and the new line?), an introduced one an introduced item (new in this commit, or existed before?). The labelling page and a second rater both work from this file. Signed-off-by: Vichitra Attri <mevichitra@gmail.com>
gt_agreement.py reads the key (sample.csv) and each rater's labels by blinded item id, a JSON file or the labelling page's exported documents, and writes agreement.md: per item kind and per stratum, how often the rater confirms the harness's truth (Wilson intervals, unclear left out), and Cohen's kappa between two raters with the items to adjudicate. Signed-off-by: Vichitra Attri <mevichitra@gmail.com>
An LLM agent labelled the 100 blinded items of items.json as a second, independent rater: it read only items.json, never the key or the results. One verdict and a one-sentence reason per item. The file name asks the human rater not to open it before labelling, so their labels stay independent. Signed-off-by: Vichitra Attri <mevichitra@gmail.com>
An introduced item had no code from before the commit, only the diff, and 36 items had no diff hunk near the line, so a rater could not see whether the issue existed before. items.json now gives each introduced item the old code at the same place, found with the ground truth's line map: the flagged line itself when it maps back (before_mapped), else the old code around the point where it was inserted. Ids, order and pair items are unchanged. Signed-off-by: Vichitra Attri <mevichitra@gmail.com>
The agent relabelled the introduced items from the corrected items.json, which now shows the old code at the same place, with instructions that no longer assume an untouched line means the issue existed (whole- function rules can newly fire on an unchanged line). It read only its own blinded copy of the 40 items. Signed-off-by: Vichitra Attri <mevichitra@gmail.com>
gt_agreement.py gains --adjudicated (the final verdict per item, each with its source) and --results (the replays the sample came from). The report then scores the adjudicated verdicts and estimates each content scheme's hidden rate without the ground-truth errors: every hidden finding of those schemes lies in the new_but_matched stratum, so its count is scaled by the share of that scheme's sampled matches the adjudication confirms as truly new, with a Wilson range. --human-kind limits the person's labels to one item kind, and --agent can be repeated so a later round overrides an earlier one. Signed-off-by: Vichitra Attri <mevichitra@gmail.com>
The labels of both rounds, the human rater's confirmation of the 14 harness errors the agent flagged, the adjudicated verdicts with their sources, the scores (agreement.md) and a README that describes the procedure, including the first round's flaw: introduced items showed no code from before the commit, so the human rater's round-1 labels on them are not used. The line diff holds for 59 of 60 persisting findings and 30 of 40 introduced ones; its errors concentrate where a scheme matched an introduced finding (10 of 20). claims.md adds G1-G6, marks the hidden rates as upper bounds (SonarQube's corrects from 1.47% to about 0.24%) and notes that Bandit's own findings were not checked; outline.md's threats section says the same. Signed-off-by: Vichitra Attri <mevichitra@gmail.com>
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.
Summary
Adds the manual check of the harness's ground truth (the line diff of
linemap.py) that the paper's threats section needs, and the tooling behind it. A seeded, stratified sample of 100 CodeGuard findings was labelled by a human rater and, independently, by an LLM agent rater. Neither saw the harness's answer or the other's labels. The disagreements were then adjudicated. The ground truth holds for 59 of 60 persisting findings but only 30 of 40 introduced ones. Its errors sit where a scheme matched an "introduced" finding, so the paper's hidden rates are upper bounds: SonarQube's corrects from 1.47% to about 0.24%.Type of change
research/, not part of the released package)Checklist
git commit -s— DCO sign-off on all commitspytestpasses locallyruff check research/andruff format --check research/cleanMYPYPATH=src mypy --strict research/finding_identitycleanresearch/What changed
Tooling
gt_sample.pyalso writesitems.json: the sampled findings shuffled under neutral ids, without the harness's answer, the stratum or any scheme's outcome.sample.csvgains theitemkey column. Introduced items carry the old code at the same place, found with the line map (corresponding_old_line).gt_agreement.py(new) scores raters against the key, per item kind and per stratum, with Wilson intervals, and computes agreement between two raters.--adjudicatedscores the final verdicts.--resultsestimates each content scheme's hidden rate with the ground-truth errors removed.--human-kindlimits the person's labels to one kind, and--agentcan be repeated so a later round overrides an earlier one.Data and write-up (
paper/ground_truth_check/)adjudicated.json(final verdict and source per item),agreement.md(scores), and aREADME.mddescribing the procedure.claims.mdadds G1–G6, marks the hidden rates as upper bounds, and notes that Bandit's own findings were not checked;outline.md's threats section says the same.Results
new_but_matchedagree_newThe errors are findings that persisted while the line diff lost them: the line was edited past the similarity threshold, or moved out of a removed block. Corrected hidden rates on CodeGuard findings:
sonar1.47 → 0.24 (0.07–0.66),github0.81 → 0.41,line_text1.17 → 0.87,codeguard1.87 → 1.31.Three sampled complexity and nesting findings (F036, F065, F076) sit on an unchanged
defline and both raters called them "existed". Re-running the rule on both versions shows each function was not reported before the commit pushed it over the limit, so they are new. They are recorded inadjudicated.jsonwith the re-run as the source.Test evidence
New tests cover Cohen's kappa against hand-computed values, the verdict mapping for both item kinds, loading labels from a file and from the labelling page's exported documents, per-stratum scoring, the corresponding-line lookup, and the hidden-rate correction.
Notes for reviewer
claims.md.Generated by Claude Code