Skip to content

Cross-tool oracle comparison (Infer#/CodeQL) + related-work positioning#21

Merged
PhysShell merged 2 commits into
mainfrom
claude/zen-pasteur-76hfs1
Jun 17, 2026
Merged

Cross-tool oracle comparison (Infer#/CodeQL) + related-work positioning#21
PhysShell merged 2 commits into
mainfrom
claude/zen-pasteur-76hfs1

Conversation

@PhysShell

@PhysShell PhysShell commented Jun 16, 2026

Copy link
Copy Markdown
Owner

Two things: where we sit, and how we check ourselves against the neighbours

Follow-up to the Dapper mining work (#19/#20). We found zero real leaks in
Dapper — a precision win — but a clean run on its own can't tell "correctly found
nothing" from "silently skipped everything". This PR adds an external reference
for exactly that, and writes down honestly where Own.NET stands.

(a) README — "Related work / позиционирование"

A grounded section: we are not the first or best leak detector for C#. Infer#,
CodeQL (cs/local-not-disposed), IDisposableAnalyzers, CA2000/CA2213 are the
recall bar — interprocedural, battle-tested, no "honest skip". Our difference is
model, not coverage: borrow + region + double-dispose / use-after-dispose
in one ownership model, which the leak-only queries don't express. Closest
same-idea-different-language is C++/Rust lifetime work (Polonius,
C++ Lifetime profile, Clang's experimental lifetime-safety) — and their Datalog
fact vocabulary is essentially our OwnIR.

(b) Cross-tool oracle harness

Run Own.NET, Infer#, and CodeQL over the same repo and diff the leak-class
findings:

bucket meaning
agree flagged by us AND an oracle → high confidence
own-only flagged by us, by no oracle → candidate FP, or a catch they can't express
oracle-only flagged by an oracle, not by us → our recall gap

Plus Own.NET-only defect classes (OWN002/OWN003 — no oracle leak-query
equivalent) and oracle out-of-scope hits (null-deref, taint…) as context.

  • scripts/oracle_compare.py — the diff core. Reuses the miner's own-check
    parser; one SARIF parser for both oracles (Infer# and CodeQL both emit SARIF);
    basename + line-window matching (robust to cross-tool path prefixes); --json;
    --selftest (9/9, embedded fixtures).
  • .github/workflows/oracle.ymlworkflow_dispatch running own-check +
    CodeQL (build-mode: none) + Infer# (built binaries) over a target, diffing to
    the run summary + an artifact. Each oracle step is continue-on-error: the
    oracles need the target to build, our extractor doesn't
    — that asymmetry is
    the point.
  • docs/notes/oracle.md — methodology, the three buckets, how to read it, gaps.
  • ci.yml — runs the miner + oracle selftests on every push (not just on dispatch).

Honesty

The comparator is unit-tested and runs anywhere on pre-produced outputs. The
tri-tool orchestration is validated on dispatch, same as mine.yml (no local
Infer#/CodeQL here). Agreement raises confidence; it doesn't prove soundness
(that's the Boogie/Dafny backend, still roadmap).

Verified locally

ruff clean (whole tree) · oracle selftest 9/9 · miner selftest 7/7 ·
run_tests.py exit 0 (analysis 125/125, fuzz 3000, gallery/corpus/wpf/loops/spec/
ownir all green).

🤖 Generated with Claude Code

https://claude.ai/code/session_01Rg8kSk1YT14x7A1vo5zgED


Generated by Claude Code

Summary by CodeRabbit

  • New Features
    • Added an on-demand cross-tool validation workflow that runs Own.NET checks, compares results with Infer# and CodeQL, and publishes a generated oracle report (including artifacts and summaries).
  • Documentation
    • Added README positioning content and a new guide describing how cross-tool comparisons are performed and interpreted.
  • Tests
    • Updated the CI lint stage to run additional Python selftests for evaluation/oracle scripts on every push and pull request.

Validate the leak check against mature C# analysers (Infer#, CodeQL) on the
same code, and state honestly where Own.NET sits among them.

- scripts/oracle_compare.py: diff Own.NET vs Infer#/CodeQL leak findings into
  agree / own-only / oracle-only buckets (plus Own.NET-only defect classes and
  oracle out-of-scope context). Reuses the miner's own-check parser; one SARIF
  parser for both oracles; basename+line matching (--line-tol); --json output;
  --selftest (9/9).
- .github/workflows/oracle.yml: workflow_dispatch running own-check + CodeQL
  (build-mode none) + Infer# (built binaries) over a target, diffing to the run
  summary + an artifact. Each oracle step is continue-on-error -- the oracles
  need the target to build, our extractor does not.
- docs/notes/oracle.md: methodology, the three buckets, how to read it, gaps.
- README: "Related work / позиционирование" -- Infer#/CodeQL/IDisposableAnalyzers/
  CA2000 are the recall bar and the oracle; our difference is borrow + region +
  double-dispose in one model. Closest same-idea-different-language is C++/Rust
  lifetime work (Polonius).
- ci.yml: run the miner + oracle selftests on every push, not just on dispatch.

Verified locally: ruff clean (whole tree), oracle selftest 9/9, miner 7/7,
run_tests.py exit 0 (analysis 125/125, fuzz 3000, gallery/corpus/wpf/loops/spec/
ownir all green).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg8kSk1YT14x7A1vo5zgED
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 084040d2-8bd7-471a-80ea-831b75e7c1cd

📥 Commits

Reviewing files that changed from the base of the PR and between 79ecc6c and 5a533fa.

📒 Files selected for processing (2)
  • .github/workflows/oracle.yml
  • scripts/oracle_compare.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/oracle.yml
  • scripts/oracle_compare.py

📝 Walkthrough

Walkthrough

Adds a cross-tool oracle comparison pipeline to Own.NET. A new scripts/oracle_compare.py script parses Own.NET findings and Infer#/CodeQL SARIF outputs, classifies them into agree/own-only/oracle-only buckets, and renders Markdown and JSON reports. A new oracle.yml GitHub Actions workflow orchestrates the full on-demand comparison. Selftests are wired into the existing CI lint job, and documentation is added in docs/notes/oracle.md and README.md.

Changes

Oracle Cross-Tool Comparison Pipeline

Layer / File(s) Summary
oracle_compare.py: data model, parsing, comparison, and output
scripts/oracle_compare.py
Defines rule-ID constant sets for Own.NET/Infer#/CodeQL, the Finding dataclass with derived fkey, path normalization, Own.NET text and SARIF parsers, core compare bucketing logic, render_md Markdown report, to_json JSON serialization, main CLI entry point, and embedded _selftest fixture validation.
oracle.yml: on-demand cross-tool analysis workflow
.github/workflows/oracle.yml
Creates the oracle (cross-tool) workflow with workflow_dispatch inputs, a comparator selftest gate, target checkout with SHA recording, Own.NET own-check step, CodeQL init/analyze steps (build-mode: none, upload disabled), conditional Infer# build and run steps, a oracle_compare.py diff step assembling SARIF arguments into report.md, step summary publishing, and artifact upload of the report and raw tool outputs.
CI selftest wiring and oracle documentation
.github/workflows/ci.yml, docs/notes/oracle.md, README.md
Adds mine_report.py --selftest and oracle_compare.py --selftest to the lint job so both scripts are validated on every push/PR. Adds docs/notes/oracle.md describing comparison buckets, scoping exclusions, matching mechanics, and v1 honest gaps. Adds a README section contrasting Own.NET against Infer#, CodeQL, and other C# analyzers, with a pointer to the oracle validation workflow.

Sequence Diagram(s)

sequenceDiagram
  participant Trigger as workflow_dispatch
  participant Selftest as oracle_compare.py --selftest
  participant OwnCheck as scripts/own-check.sh
  participant CodeQL as github/codeql-action
  participant InferSharp as microsoft/infersharpaction
  participant Comparator as oracle_compare.py
  participant Summary as GITHUB_STEP_SUMMARY

  Trigger->>Selftest: validate comparator fixtures
  Selftest-->>Trigger: pass/fail
  Trigger->>OwnCheck: scan .cs sources → own.txt
  Trigger->>CodeQL: init + analyze C# (build-mode: none) → codeql.sarif
  Trigger->>InferSharp: dotnet build → _bin, run → infer.sarif
  OwnCheck-->>Comparator: own.txt
  CodeQL-->>Comparator: codeql.sarif (if present)
  InferSharp-->>Comparator: infer.sarif (if present)
  Comparator->>Summary: publish report.md + upload oracle-report artifact
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • PhysShell/Own.NET#19: Introduces scripts/mine_report.py which produces the Own.NET own-check text output that oracle_compare.py parses and cross-references with Infer# and CodeQL findings.

Poem

🐇 Hop, hop — three tools compare,
Infer#, CodeQL, Own.NET declare,
agree / own-only / oracle-only neat,
A SARIF diff wrapped up complete,
The rabbit checks basenames, line by line,
And publishes a report.md so fine! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 43.75% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately summarizes the main change: adding cross-tool oracle comparison capability (Infer#/CodeQL) and positioning documentation, which aligns with all five modified files and the PR objectives.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/zen-pasteur-76hfs1

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/oracle.yml:
- Around line 26-27: The git clone operation using the `--branch` flag does not
accept raw commit SHAs, which conflicts with the documented input specification
that claims to accept branch, tag, or sha. Modify the git clone logic to handle
all three ref types properly by replacing the `git clone --branch "$REF"`
approach with a method that supports commit SHAs, such as cloning without the
branch flag and then using `git checkout` with the ref value, or using `git
fetch` with the ref and then checking it out. Ensure the updated logic works for
branches, tags, and commit SHAs as originally documented in the input
description.

In `@scripts/oracle_compare.py`:
- Around line 131-136: The `parse(text)` call on line 131 returns a tuple of
(findings, unparsed) but the unparsed portion is being discarded with an
underscore assignment, causing silent data loss if the Own.NET parser encounters
unrecognized line formats. Instead of ignoring the unparsed return value,
capture it in a variable and add a check that raises an exception or logs a
warning if any unparsed findings exist, surfacing parser drift issues rather
than silently dropping findings and skewing the comparison results.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6340d09e-be7b-4d5c-bcb3-6eb2a74e3d2d

📥 Commits

Reviewing files that changed from the base of the PR and between b3d24fa and 79ecc6c.

📒 Files selected for processing (5)
  • .github/workflows/ci.yml
  • .github/workflows/oracle.yml
  • README.md
  • docs/notes/oracle.md
  • scripts/oracle_compare.py

Comment thread .github/workflows/oracle.yml
Comment thread scripts/oracle_compare.py Outdated
- oracle.yml: clone then fetch + checkout the ref, so a raw commit SHA works as
  the `ref` input documents (was `git clone --branch`, which only takes a
  branch/tag and would fail a SHA dispatch).
- oracle_compare.py: surface own-check parser drift instead of dropping it.
  build_own now returns the unparsed-line count; main warns on stderr and the
  report header flags it. Chose a non-fatal note over a hard raise: this is eval
  tooling run over third-party repos, so one stray stdout line shouldn't sink the
  whole comparison (the miner surfaces its unparsed count the same way). Selftest
  is now 12/12 and covers the drift path.

Verified: ruff clean (whole tree), oracle selftest 12/12, run_tests.py exit 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg8kSk1YT14x7A1vo5zgED
@PhysShell
PhysShell merged commit 4dbafa7 into main Jun 17, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants