Skip to content

Corpus miner: run own-check over public C# repos + aggregate a report#19

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

Corpus miner: run own-check over public C# repos + aggregate a report#19
PhysShell merged 2 commits into
mainfrom
claude/zen-pasteur-76hfs1

Conversation

@PhysShell

@PhysShell PhysShell commented Jun 16, 2026

Copy link
Copy Markdown
Owner

Corpus miner — stress-test the analyser on real repos

Evaluation tooling: clone one public C# repo (shallow) and run the existing own-check pipeline over it, then aggregate the findings into a structured Markdown report. The goal is evaluating the analyser (precision, false-positive patterns, coverage gaps) — a deliberate spot-check, one repo at a time, not a crawler.

Why it's cheap

The Roslyn extractor (P-014 Tier A) builds a best-effort SemanticModel from the runtime's trusted-platform assemblies and is error-tolerant: it reads symbols without a dotnet restore/build of the target, and unresolved external (NuGet) types become an honest OWN050 "unchecked" marker. So mining needs no per-repo build setup — just point it at the .cs.

What's here

  • scripts/mine.sh — clone (--depth 1) + own-check + report → corpus/mined/<slug>/ (gitignored). Needs dotnet/git/Python; guards with a clear message if dotnet is absent.
  • scripts/mine_report.py — dotnet-free aggregator: counts by OWN code / severity / resource kind, the noisiest files, a candidate-leak triage list, and the OWN050 coverage signal. Has --selftest (7/7).
  • .github/workflows/mine.ymlworkflow_dispatch (inputs repo/ref/paths, passed via env, never interpolated into the shell). Publishes the report to the run summary + an artifact, so any repo can be mined without local .NET.
  • corpus/targets.txt — seed list (Dapper, CsvHelper, Newtonsoft.Json, RestSharp).
  • .gitignorecorpus/mined/ (never commit third-party source; reduce real finds into corpus/real-world/ instead).
  • docs/notes/mining.md — usage, how to read the report, the triage loop, honest gaps.
  • own-check.sh — refresh the stale loop caveat (A1 + while/foreach landed).

How to read a report (the point)

  • A clean run is a precision signal, not a dud.
  • A pile of OWN001s is either real leaks (reduce one → corpus/real-world/ regression) or a false-positive pattern → harden the extractor.
  • High OWN050 = coverage gap (unresolved external refs), not a wrong answer.

Honest gaps (v1)

No coverage/skip-rate yet (a method the extractor can't model is silently absent — --stats on the extractor is the planned next step); one target by hand (no auto-discovery); reporting upstream is a separate manual step.

Validation

mine_report --selftest 7/7, ruff check . clean, full suite unaffected (corpus 2/2, ownir 47/47). The dotnet-dependent end-to-end runs in CI — workflow_dispatch only becomes triggerable once mine.yml is on the default branch, so the first real mine (Dapper) runs right after this merges.

https://claude.ai/code/session_01Rg8kSk1YT14x7A1vo5zgED


Generated by Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added an on-demand “corpus mining” workflow to clone a selected public C# repository and run the analyzer over a chosen subpath.
    • Automatically generates aggregated Markdown and JSON mining reports (with triage details) and uploads mining artifacts for review.
  • Documentation

    • Added mining harness documentation covering workflow usage, report structure, and an iterative triage/refinement loop.
  • Chores

    • Ignored mined corpus output in version control and added a curated list of mining seed targets.

… a report

Evaluation tooling for the analyser: clone one public C# repo (shallow) and run
the existing own-check pipeline over it, then aggregate the findings into a
structured Markdown report. Mining is cheap because the extractor needs no
per-repo build (error-tolerant SemanticModel; unresolved external types become
OWN050 "unchecked"), so we just point it at the .cs.

- scripts/mine.sh: clone (--depth 1) + own-check + report; needs dotnet (or CI).
- scripts/mine_report.py: dotnet-free aggregator (counts by code/severity/kind,
  noisiest files, candidate-leak triage, OWN050 coverage signal); --selftest.
- .github/workflows/mine.yml: workflow_dispatch (inputs via env, no injection);
  report to the run summary + artifact, so any repo can be mined without local .NET.
- corpus/targets.txt: seed list (Dapper, CsvHelper, Newtonsoft.Json, RestSharp).
- .gitignore: corpus/mined/ (never commit third-party source; reduce real finds
  into corpus/real-world/ instead).
- docs/notes/mining.md: usage, how to read the report, the triage loop, honest gaps.
- own-check.sh: refresh the stale loop caveat (A1 + while/foreach landed).

mine_report --selftest 7/7, ruff clean, suite unaffected (corpus 2/2). The real
end-to-end mine runs in CI (dotnet); first target Dapper, once the workflow is on
the default branch.

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: 2305e4d4-bda7-41eb-a2b7-7992d1f19559

📥 Commits

Reviewing files that changed from the base of the PR and between a7669e0 and d66b5ff.

📒 Files selected for processing (2)
  • .github/workflows/mine.yml
  • docs/notes/mining.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • docs/notes/mining.md
  • .github/workflows/mine.yml

📝 Walkthrough

Walkthrough

Adds a corpus mining harness for the Own.NET analyzer: a Python report library that parses own-check findings and renders aggregated Markdown/JSON reports; a Bash orchestration script that clones C# repositories, runs the analyzer, and invokes the report generator; a GitHub Actions workflow_dispatch workflow for CI triggering; a seed target list; .gitignore update; and comprehensive usage documentation.

Changes

Corpus Mining Harness

Layer / File(s) Summary
Finding report generation library
scripts/mine_report.py
Adds parse() to convert own-check output lines into structured finding dicts, aggregate() to compute frequency maps by severity/code/kind/file, render_md() to generate Markdown reports with per-code tables, noisiest-files sections, error triage lists, and OWN050 coverage signals. Includes main() CLI with optional JSON export and _selftest() for end-to-end validation.
Repository mining and scanning
scripts/mine.sh, scripts/own-check.sh
Adds mine.sh which validates prerequisites (git, python, dotnet), normalizes target repos into clone URLs and slugged output paths, performs shallow clones at optional refs, runs own-check.sh against configurable paths with separated stdout/stderr capture, records critical errors (rc≥2) without aborting, and invokes mine_report.py. Updates own-check.sh documentation to clarify path-sensitive disposal analysis and --legacy mode scope.
GitHub Actions mining workflow
.github/workflows/mine.yml
Adds workflow_dispatch workflow with repo (required), ref, and paths (optional) inputs; installs Python 3.13 and .NET 8; wires inputs via environment variables into mine.sh; publishes first discovered report.md to step summary (with fallback message); uploads report.md, report.json, findings.txt, and extract.log as the mine-report artifact.
Infrastructure, targets, and documentation
.gitignore, corpus/targets.txt, docs/notes/mining.md
Adds .gitignore entry for corpus/mined/ output; seeds corpus/targets.txt with four IDisposable-dense C# repositories; adds docs/notes/mining.md covering corpus mining purpose, usage instructions (CI and local), report interpretation (code/kind counts, noisiest files, triage), iteration loop, and v1 known gaps (missing coverage stats, manual target selection, no upstream reporting).

Sequence Diagram

sequenceDiagram
  participant Trigger as GitHub Actions
  participant Workflow as mine.yml
  participant MineScript as mine.sh
  participant Git as git clone
  participant Analyzer as own-check.sh
  participant Reporter as mine_report.py
  participant Summary as Step Summary

  Trigger->>Workflow: workflow_dispatch(repo, ref, paths)
  Workflow->>MineScript: REPO/REF/PATHS env vars
  MineScript->>Git: shallow clone --branch ref
  Git-->>MineScript: commit SHA
  MineScript->>Analyzer: run on scan path
  Analyzer-->>MineScript: findings.txt + extract.log
  MineScript->>Reporter: parse findings + aggregate
  Reporter-->>MineScript: report.md + report.json
  MineScript->>Summary: append report.md
  Workflow-->>Trigger: upload mine-report artifact
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 Hop hop, the rabbit mines the code,
Cloning repos down the shallow road,
parse() and aggregate() count each find,
A Markdown report for the curious mind.
OWN050 signals, triage lists galore—
The warren grows richer than ever before! 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% 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 PR title accurately and concisely summarizes the main change: introducing corpus mining tooling that runs own-check over public C# repositories and aggregates results into a report.
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 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.

🧹 Nitpick comments (2)
docs/notes/mining.md (1)

20-22: 💤 Low value

Add language tag to fenced code block.

Markdownlint expects a language identifier on fenced code blocks. Consider adding yaml or text to satisfy the linter and improve consistency.

📝 Proposed fix
-```
+```yaml
 inputs: repo = DapperLib/Dapper   ref = (optional)   paths = (optional subdir)
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @docs/notes/mining.md around lines 20 - 22, The fenced code block showing the
inputs specification is missing a language identifier on the opening fence. Add
a language tag (such as yaml or text) immediately after the opening triple
backticks to satisfy markdownlint requirements and improve code block
consistency. For example, change the opening from toyaml or ```text
before the line containing "inputs: repo = DapperLib/Dapper".


</details>

<!-- cr-comment:v1:bea3245903560f0600a1eed5 -->

</blockquote></details>
<details>
<summary>.github/workflows/mine.yml (1)</summary><blockquote>

`52-53`: _⚡ Quick win_

**Use `find` instead of `ls` for robustness.**

Shellcheck SC2012 recommends `find` to handle filenames with spaces or special characters. While the glob is constrained, `find` is more robust.






<details>
<summary>🛡️ Proposed fix</summary>

```diff
-          report=$(ls corpus/mined/*/report.md 2>/dev/null | head -1 || true)
+          report=$(find corpus/mined -name report.md -type f 2>/dev/null | head -1 || true)
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/mine.yml around lines 52 - 53, The variable assignment for
report uses ls with a glob pattern, which is not robust for handling filenames
with spaces or special characters. Replace the ls command with find to locate
the first report.md file in the corpus/mined directory structure. Use find with
appropriate options like -maxdepth and -name to search for report.md files, pipe
to head -1 to get the first result, and maintain the error redirection and
fallback logic with || true to ensure the script continues even if no file is
found.
```

</details>

<!-- cr-comment:v1:8b2a4dd0ffa56bda2186b2a6 -->

_Source: Linters/SAST tools_

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In @.github/workflows/mine.yml:

  • Around line 52-53: The variable assignment for report uses ls with a glob
    pattern, which is not robust for handling filenames with spaces or special
    characters. Replace the ls command with find to locate the first report.md file
    in the corpus/mined directory structure. Use find with appropriate options like
    -maxdepth and -name to search for report.md files, pipe to head -1 to get the
    first result, and maintain the error redirection and fallback logic with || true
    to ensure the script continues even if no file is found.

In @docs/notes/mining.md:

  • Around line 20-22: The fenced code block showing the inputs specification is
    missing a language identifier on the opening fence. Add a language tag (such as
    yaml or text) immediately after the opening triple backticks to satisfy
    markdownlint requirements and improve code block consistency. For example,
    change the opening from toyaml or ```text before the line containing
    "inputs: repo = DapperLib/Dapper".

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: Repository UI

**Review profile**: CHILL

**Plan**: Pro Plus

**Run ID**: `2accdfed-41f3-441d-8bdb-b364c8b98027`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 0facc5a2b1ff04c8341ce7a663f6f47d276a763f and a7669e0f490ff0648aaa35f28619e05f4e21ca84.

</details>

<details>
<summary>📒 Files selected for processing (7)</summary>

* `.github/workflows/mine.yml`
* `.gitignore`
* `corpus/targets.txt`
* `docs/notes/mining.md`
* `scripts/mine.sh`
* `scripts/mine_report.py`
* `scripts/own-check.sh`

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

…check)

- docs/notes/mining.md: tag the inputs code fence as `text` (markdownlint MD040).
- .github/workflows/mine.yml: locate the report with `find` instead of `ls`
  (shellcheck SC2012 — robust to odd filenames).

https://claude.ai/code/session_01Rg8kSk1YT14x7A1vo5zgED
@PhysShell
PhysShell merged commit d908720 into main Jun 16, 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