Skip to content

docs(oracle): first Dapper three-way — the Infer# trio is ownership-transfer (precision win)#27

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

docs(oracle): first Dapper three-way — the Infer# trio is ownership-transfer (precision win)#27
PhysShell merged 1 commit into
mainfrom
claude/zen-pasteur-76hfs1

Conversation

@PhysShell

Copy link
Copy Markdown
Owner

What the first Dapper three-way actually showed

Follow-up to #26: I verified the 3 Infer# leak-class findings from the first real three-way run against Dapper's source, and wrote the result into docs/notes/oracle.md as a worked example.

Verdict: the Infer# trio is ownership-transfer — i.e. Infer# false positives, not our recall gap.

All three are WrappedBasicReader / DbWrappedReader in SqlMapper:

  • WrappedBasicReader.Dispose() forwards to _reader.Dispose() — it's a caller-owned disposal handle.
  • ExecuteReader* does return DbWrappedReader.Create(cmd, reader) — the reader is handed to the caller (who disposes it).
  • The GetRowParser / GetDbDataReader adapter wraps the caller's own reader — disposing it would close the caller's reader.

So Infer# flags "not closed" exactly on the returns-IDisposable pattern — the escape / ownership-transfer case Own.NET's model deliberately treats as not a leak. Our 0 is the correct verdict here; Infer#'s 3 look like over-reports. The oracle surfaced a precision strength, not a weakness.

(CodeQL's 2 — cs/dispose-not-called-on-throw — are exception-path disposal, which we don't model by design. And own-only 0 also reflects coverage we under-analyse — async/interprocedural — which is why the section reiterates the case for the extractor --stats.)

Docs-only; no code/workflow change.

🤖 Generated with Claude Code


Generated by Claude Code

…rship-transfer

Verified the 3 Infer# leak-class findings from the first real run against Dapper's
source: all are `WrappedBasicReader`/`DbWrappedReader` whose ownership is transferred
to the caller (`ExecuteReader*` returns `DbWrappedReader.Create(...)`; the
`GetRowParser`/`GetDbDataReader` adapter wraps the caller's own reader). The wrapper's
`Dispose()` forwards to `_reader.Dispose()` — it's the holder's disposal handle. So
Infer# over-reports on the returns-IDisposable pattern, exactly the escape/
ownership-transfer case Own.NET's model treats as not-a-leak: our 0 is correct,
Infer#'s 3 are likely false positives (a precision data-point, not a recall gap).

CodeQL's 2 (`cs/dispose-not-called-on-throw`) are exception-path disposal, which we
don't model by design. `own-only 0` also reflects coverage (async/interprocedural we
under-analyse) — motivates the extractor `--stats`. Docs-only.

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.

@PhysShell PhysShell merged commit 121fd7c into main Jun 17, 2026
16 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