Skip to content

Commit e7d33e3

Browse files
authored
Merge pull request #399 from PhysShell/arena/e1a5511b-own-net
docs(h28): resolve the DbCommand residual
2 parents e889f8b + 7de5016 commit e7d33e3

64 files changed

Lines changed: 3426 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: H-28 DbCommand falsifier
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- '.github/workflows/h28-command-falsifier.yml'
7+
- 'corpus/ownership-lab/h28-command/**'
8+
- 'frontend/roslyn/OwnSharp.Extractor/**'
9+
- 'ownlang/**'
10+
- 'docs/notes/h28-npgsql-command-resolution.md'
11+
workflow_dispatch:
12+
13+
permissions:
14+
contents: read
15+
16+
jobs:
17+
h28-required-gates:
18+
name: H-28 required runtime + extractor gates
19+
runs-on: ubuntu-latest
20+
timeout-minutes: 30
21+
steps:
22+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
23+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
24+
with:
25+
python-version: '3.11'
26+
- uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4
27+
with:
28+
dotnet-version: '8.0.x'
29+
- name: Install self-contained PostgreSQL 16 harness
30+
run: python -m pip install 'pgserver==0.1.4'
31+
- name: Run mandatory G1-G3 gates (SKIP is failure)
32+
run: corpus/ownership-lab/h28-command/run.sh all-required
33+
- name: Preserve source facts and runtime observations
34+
if: always()
35+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
36+
with:
37+
name: h28-command-falsifier
38+
if-no-files-found: warn
39+
path: |
40+
corpus/ownership-lab/h28-command/evidence/g3-CommandDispose.facts.json
41+
corpus/ownership-lab/h28-command/evidence/g3-CommandDispose.summaries.json
42+
corpus/ownership-lab/h28-command/evidence/g3-CommandDispose.sarif.json
43+
corpus/ownership-lab/h28-command/evidence/g3-CommandDispose.log
44+
corpus/ownership-lab/h28-command/evidence/g3-*.log
45+
corpus/ownership-lab/h28-command/evidence/runtime-*.log
46+
corpus/ownership-lab/h28-command/evidence/runtime-*.out
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
H-28-CMD: the DbCommand half of the `DataTable.Load(reader)` family.
2+
3+
STATUS
4+
Final verdict: H28-PROVIDER-SPECIFIC, narrowly bounded to Npgsql 10.0.3/PostgreSQL 16 and
5+
Microsoft.Data.Sqlite 10.0.12. Required G1-G3 passed in PR workflow run #38048287923; its
6+
`h28-command-falsifier` artifact contains runtime logs, OwnIR facts, summaries and SARIF. This
7+
does not label OWN001 a false positive or establish a universal provider rule. Read
8+
docs/notes/h28-npgsql-command-resolution.md before interpreting any artifact.
9+
10+
The original H-28 (research/ownership-semantics-lab-v1@298b305, not on main) settled
11+
`DataTable.Load(reader)` for a one-result reader: it IS closed (`RELEASE_IF_LAST_RESULT_SET`,
12+
not BORROW). That same record wrote down one sentence and never classified it:
13+
14+
"what remains is the never-disposed DbCommand `cmd` (an object leak without a
15+
protocol consequence)"
16+
-- h28/scripts/h28_anchors_record.py, consequence_for_the_demanding_instance
17+
18+
This directory records falsifiable source and runtime checks. It does not call OWN001 a false
19+
positive, claim a native leak on Npgsql, or propose a universal rule from these provider runs.
20+
21+
LAYOUT
22+
fx/CommandDispose.cs nine C# methods (A/B/C/D + controls), using abstract ADO.NET types.
23+
G3 confirmed the expected finding anchors in workflow run #38048287923.
24+
fx/CommandDispose.own engine-only manual reduction. This is not C# extraction evidence.
25+
falsifier/Program.cs P1-P5 and G2/P6. P4 is isolated from P1-P3; P6 counts live SQLite
26+
statements via sqlite3_next_stmt, not RSS or forced GC.
27+
falsifier/h28cmd.csproj net8.0, Npgsql 10.0.3, Microsoft.Data.Sqlite 10.0.12; compiles
28+
both the falsifier and fx/CommandDispose.cs.
29+
falsifier/run_with_pgserver.py
30+
keeps the temporary pgserver alive while the .NET test runs.
31+
scripts/verify_g3.py production Roslyn -> OwnIR -> summaries -> core SARIF; exact expected
32+
finding anchors are checked, and all intermediate artifacts saved.
33+
scripts/derive_source_evidence.py
34+
re-fetches 44 upstream excerpts plus the Npgsql finalizer negative
35+
scan. Includes the SQLitePCLRaw opt-in required by sqlite3_next_stmt;
36+
TFM evidence confirms Npgsql 10.0.3 targets net8.0 and
37+
Microsoft.Data.Sqlite 10.0.12 has a netstandard2.0 asset usable by
38+
this net8.0 falsifier. Non-zero = drift.
39+
run.sh PASS/FAIL/SKIP driver. `all-required` fails on any SKIP.
40+
evidence/*.txt source excerpts with repository/ref/path/git blob sha/file sha256/
41+
line range. Local engine output is saved. G3/runtime artifacts are
42+
produced in CI and attached to workflow run #38048287923.
43+
.github/workflows/h28-command-falsifier.yml
44+
runs `all-required` on the PR and preserves results as an artifact.
45+
46+
GATES
47+
./corpus/ownership-lab/h28-command/run.sh engine # Python only; current manual core pass
48+
./corpus/ownership-lab/h28-command/run.sh g3-required # production extractor and core
49+
./corpus/ownership-lab/h28-command/run.sh runtime-required # compile + provider runtime
50+
./corpus/ownership-lab/h28-command/run.sh all-required # mandatory; SKIP is non-zero
51+
python3 corpus/ownership-lab/h28-command/scripts/derive_source_evidence.py
52+
53+
Runtime dependencies: .NET 8 SDK, packages available from NuGet or already restored in cache,
54+
and PostgreSQL 16. The workflow installs pinned pgserver 0.1.4 from PyPI; locally either
55+
`pip install pgserver==0.1.4` or set H28_PG_DSN. There is no curl-only NuGet gate: the script attempts restore with
56+
`--ignore-failed-sources`, so a warm package cache can work offline.
57+
58+
WHAT HAS RUN IN THE PRODUCING SANDBOX
59+
PASS: Python engine reduction, matching three manual OWN001 expectations; 33/33 real-world
60+
corpus cases; whole-tree Ruff; mypy (60 source files); 44 source excerpts + finalizer scan;
61+
Python/shell syntax checks, C# grammar parse (not compilation), and pgserver supervisor
62+
API/Unix-socket DSN preflight (not a .NET/provider falsifier).
63+
PASS IN CI: G1 build/P4, G2 native SQLite statement checks, P5 PostgreSQL prepared-state check,
64+
and G3 production C# extraction all passed in workflow run #38048287923. The exact
65+
artifact is attached to that run; local status metadata is evidence/ci-run-38048287923.txt.
66+
BLOCKED LOCALLY: this sandbox has no .NET SDK, so its `all-required` run returned 1 on G1/G2/G3
67+
SKIPs; see evidence/required-gates-local.txt.
68+
INCOMPLETE: `python tests/run_tests.py` passed its early analysis/codegen checks, then stopped at
69+
checkpoint validation because this checkout is shallow and `cargo` is absent. It is
70+
not counted as a green full-suite run. See evidence/local-validation.txt.
71+
72+
SCOPE
73+
No production analyzer code, OwnIR vocabulary, ownership semantics, or diagnostics are changed.
74+
The normal real-world corpus suite does not glob `corpus/ownership-lab/`; these are experiment
75+
fixtures. G3 now confirms the predicted extraction loss on this exact fixture. Any architecture
76+
follow-up, including #382, remains separate and is not proposed or implemented in this PR.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# H-28-CMD source evidence manifest (declared refs).
2+
# OK/SCAN = re-derived now; MISSING/MARKER-NOT-FOUND = stale or unavailable.
3+
OK npgsql-v10.0.3-target-frameworks.txt npgsql/npgsql@v10.0.3 sha256=fd36c9e18a2c4765 lines=8
4+
OK npgsql-10.0.3-NpgsqlCommand-Dispose.txt npgsql/npgsql@v10.0.3 sha256=6bdde5901d32a633 lines=1712
5+
OK npgsql-10.0.3-NpgsqlCommand-Reset.txt npgsql/npgsql@v10.0.3 sha256=6bdde5901d32a633 lines=1728
6+
OK npgsql-10.0.3-NpgsqlCommand-ctor-SuppressFinalize.txt npgsql/npgsql@v10.0.3 sha256=6bdde5901d32a633 lines=120
7+
OK npgsql-10.0.3-NpgsqlCommand-CreateCachedCommand.txt npgsql/npgsql@v10.0.3 sha256=6bdde5901d32a633 lines=166
8+
OK npgsql-10.0.3-NpgsqlCommand-TraceCommandStart.txt npgsql/npgsql@v10.0.3 sha256=6bdde5901d32a633 lines=1748
9+
OK npgsql-10.0.3-NpgsqlCommand-TraceCommandStop.txt npgsql/npgsql@v10.0.3 sha256=6bdde5901d32a633 lines=1792
10+
OK npgsql-10.0.3-NpgsqlConnection-CreateCommand.txt npgsql/npgsql@v10.0.3 sha256=02ed57055a9e1f02 lines=549
11+
OK npgsql-10.0.3-NpgsqlDataReader-Dispose.txt npgsql/npgsql@v10.0.3 sha256=9c109626d6627b55 lines=1008
12+
OK npgsql-10.0.3-NpgsqlDataReader-DisposeAsync.txt npgsql/npgsql@v10.0.3 sha256=9c109626d6627b55 lines=1037
13+
OK npgsql-10.0.3-NpgsqlDataReader-Close-public.txt npgsql/npgsql@v10.0.3 sha256=9c109626d6627b55 lines=1073
14+
OK npgsql-10.0.3-NpgsqlDataReader-Cleanup.txt npgsql/npgsql@v10.0.3 sha256=9c109626d6627b55 lines=1141
15+
OK npgsql-10.0.3-NpgsqlActivitySource-IsEnabled.txt npgsql/npgsql@v10.0.3 sha256=b7ef8df7f2f66573 lines=17
16+
OK npgsql-10.0.3-NpgsqlActivitySource-SourceName.txt npgsql/npgsql@v10.0.3 sha256=b7ef8df7f2f66573 lines=15
17+
OK npgsql-10.0.3-NpgsqlConnector-PreparedStatementManager.txt npgsql/npgsql@v10.0.3 sha256=7a13d79578e0a087 lines=164
18+
OK npgsql-main-NpgsqlCommand-Dispose.txt npgsql/npgsql@main sha256=fe55e7bb660c4a51 lines=1632
19+
OK npgsql-main-NpgsqlDataReader-Close-public.txt npgsql/npgsql@main sha256=8dfddffefbbb77c7 lines=1096
20+
OK runtime-v8.0.20-DataTable-Load.txt dotnet/runtime@v8.0.20 sha256=469f053f148bd5e4 lines=4969
21+
OK runtime-v10.0.12-DataTable-Load.txt dotnet/runtime@v10.0.12 sha256=dd4002e7407b1b15 lines=4974
22+
OK runtime-v10.0.12-DbCommand-class.txt dotnet/runtime@v10.0.12 sha256=c8f6f56c13b82f05 lines=11
23+
OK runtime-v10.0.12-DbCommand-DisposeAsync.txt dotnet/runtime@v10.0.12 sha256=c8f6f56c13b82f05 lines=245
24+
OK runtime-v10.0.12-DbDataReader-Close-Dispose.txt dotnet/runtime@v10.0.12 sha256=c2f3c2871cbc269f lines=34
25+
OK runtime-v10.0.12-IDbCommand.txt dotnet/runtime@v10.0.12 sha256=5fee96c4567d3894 lines=8
26+
OK runtime-v8.0.20-Activity-Dispose.txt dotnet/runtime@v8.0.20 sha256=2fcfbffca75351dd lines=1006
27+
OK runtime-v8.0.20-Activity-IDisposable.txt dotnet/runtime@v8.0.20 sha256=2fcfbffca75351dd lines=56
28+
OK mssqlite-SqliteCommand-Dispose.txt dotnet/efcore@v10.0.12 sha256=c5d427a5d7016152 lines=216
29+
OK mssqlite-SqliteCommand-DisposePreparedStatements.txt dotnet/efcore@v10.0.12 sha256=c5d427a5d7016152 lines=520
30+
OK mssqlite-SqliteCommand-PrepareAndEnumerate-head.txt dotnet/efcore@v10.0.12 sha256=c5d427a5d7016152 lines=464
31+
OK mssqlite-SqliteCommand-preparedStatements-field.txt dotnet/efcore@v10.0.12 sha256=c5d427a5d7016152 lines=30
32+
OK mssqlite-SqliteDataReader-Close-Dispose.txt dotnet/efcore@v10.0.12 sha256=0712b68bd0b03688 lines=227
33+
OK mssqlite-SqliteConnection-commands-weakrefs.txt dotnet/efcore@v10.0.12 sha256=0fd8dd0cd1ca7e6f lines=31
34+
OK mssqlite-SqliteConnection-Handle.txt dotnet/efcore@v10.0.12 sha256=0fd8dd0cd1ca7e6f lines=129
35+
OK efcore-v10.0.12-SQLitePCLRawVersion.txt dotnet/efcore@v10.0.12 sha256=a31b3e681cac5f15 lines=34
36+
OK mssqlite-v10.0.12-Microsoft.Data.Sqlite-target.txt dotnet/efcore@v10.0.12 sha256=00448ec2082b4c14 lines=18
37+
OK mssqlite-v10.0.12-Core-targets.txt dotnet/efcore@v10.0.12 sha256=b58e8f7587a04c49 lines=18
38+
OK efcore-v10.0.12-default-net-target.txt dotnet/efcore@v10.0.12 sha256=a31b3e681cac5f15 lines=14
39+
OK sqlitepclraw-v2.1.12-sqlite3_next_stmt.txt ericsink/SQLitePCL.raw@v2.1.12 sha256=cab23c3ea0012e85 lines=1028
40+
OK sqlitepclraw-v2.1.12-enable-next-stmt.txt ericsink/SQLitePCL.raw@v2.1.12 sha256=9afd074db410ba78 lines=300
41+
OK sqlitepclraw-v2.1.12-find-stmt-enabled.txt ericsink/SQLitePCL.raw@v2.1.12 sha256=9afd074db410ba78 lines=323
42+
OK runtime-v8.0.20-SafeHandle-finalizer.txt dotnet/runtime@v8.0.20 sha256=3df9d6928d6a8bcb lines=86
43+
OK runtime-v10.0.12-SafeHandle-finalizer.txt dotnet/runtime@v10.0.12 sha256=3df9d6928d6a8bcb lines=86
44+
OK sqlitepclraw-sqlite3_stmt-SafeHandle.txt ericsink/SQLitePCL.raw@v2.1.12 sha256=9afd074db410ba78 lines=195
45+
OK sqlclient-SqlCommand-Dispose.txt dotnet/SqlClient@main sha256=fc8200df4b130136 lines=1883
46+
OK mysqlconnector-MySqlCommand-Dispose.txt mysql-net/MySqlConnector@master sha256=4369c492ce1c1fc1 lines=377
47+
SCAN npgsql-10.0.3-NpgsqlCommand-finalizer-scan.txt npgsql/npgsql@v10.0.3 sha256=6bdde5901d32a633 matches=0
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# H-28 mandatory GitHub Actions gate record
2+
# Captured from gh run view / GitHub Actions API; this is status metadata, not the per-stage log.
3+
run: https://github.com/PhysShell/Own.NET/actions/runs/38048287923
4+
head: 008a21736e83139954d4ed1b34ab89fc8a194a00 (arena/e1a5511b-own-net; PR #399)
5+
{
6+
"conclusion": "success",
7+
"databaseId": 38048287923,
8+
"event": "pull_request",
9+
"headSha": "008a21736e83139954d4ed1b34ab89fc8a194a00",
10+
"jobs": [
11+
{
12+
"name": "H-28 required runtime + extractor gates",
13+
"status": "completed",
14+
"conclusion": "success",
15+
"steps": [
16+
{
17+
"name": "Install self-contained PostgreSQL 16 harness",
18+
"conclusion": "success"
19+
},
20+
{
21+
"name": "Run mandatory G1-G3 gates (SKIP is failure)",
22+
"conclusion": "success"
23+
},
24+
{
25+
"name": "Preserve source facts and runtime observations",
26+
"conclusion": "success"
27+
}
28+
]
29+
}
30+
],
31+
"status": "completed",
32+
"url": "https://github.com/PhysShell/Own.NET/actions/runs/38048287923"
33+
}
34+
artifact:
35+
{"expired":false,"name":"h28-command-falsifier","size_in_bytes":6235}
36+
note: raw run-log and artifact downloads redirect to the Actions results blob service; this sandbox cannot access that host.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# H-28-CMD source citation (auto-derived, do not edit by hand)
2+
# repo : dotnet/efcore
3+
# ref : v10.0.12
4+
# path : eng/Versions.props
5+
# blob sha : 4299bcff02df10cacebb45435c16cd0af9f901f3
6+
# file sha256: a31b3e681cac5f1537ef29e7b81976b4f61533affd7c5857de3d19f469be7c6e
7+
# file bytes : 2726
8+
# marker : '<SQLitePCLRawVersion>'
9+
# region : lines 34..37
10+
# derived by: scripts/derive_source_evidence.py
11+
34| <SQLitePCLRawVersion>2.1.12</SQLitePCLRawVersion>
12+
35| <SQLitePCLRawBundleESqlcipherVersion>2.1.11</SQLitePCLRawBundleESqlcipherVersion>
13+
36| <SQLitePCLRawBundleSqlite3Version>2.1.11</SQLitePCLRawBundleSqlite3Version>
14+
37| <SQLitePCLRawBundleWinsqlite3Version>2.1.11</SQLitePCLRawBundleWinsqlite3Version>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# H-28-CMD source citation (auto-derived, do not edit by hand)
2+
# repo : dotnet/efcore
3+
# ref : v10.0.12
4+
# path : eng/Versions.props
5+
# blob sha : 4299bcff02df10cacebb45435c16cd0af9f901f3
6+
# file sha256: a31b3e681cac5f1537ef29e7b81976b4f61533affd7c5857de3d19f469be7c6e
7+
# file bytes : 2726
8+
# marker : '<DefaultNetCoreTargetFramework>net10.0</DefaultNetCoreTargetFramework>'
9+
# region : lines 14..17
10+
# derived by: scripts/derive_source_evidence.py
11+
14| <DefaultNetCoreTargetFramework>net10.0</DefaultNetCoreTargetFramework>
12+
15| </PropertyGroup>
13+
16| <PropertyGroup Label="Arcade settings">
14+
17| <UsingToolXliff>False</UsingToolXliff>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
corpus/ownership-lab/h28-command/fx/CommandDispose.own:43:3: error: [OWN001] 'command' is owned but not released at end of function (leaks on at least one path) [resource: disposable]
2+
43 | release reader; // DataTable.Load(reader) -> reader.Close()
3+
^
4+
note: 'command' acquired here at corpus/ownership-lab/h28-command/fx/CommandDispose.own:41
5+
corpus/ownership-lab/h28-command/fx/CommandDispose.own:71:32: error: [OWN001] 'command' is owned but not released at end of function (leaks on at least one path) [resource: disposable]
6+
71 | let reader = acquire Reader(command);
7+
^
8+
note: 'command' acquired here at corpus/ownership-lab/h28-command/fx/CommandDispose.own:70
9+
corpus/ownership-lab/h28-command/fx/CommandDispose.own:71:7: error: [OWN001] 'reader' is owned but not released at end of function (leaks on at least one path) [resource: disposable]
10+
71 | let reader = acquire Reader(command);
11+
^
12+
note: 'reader' acquired here at corpus/ownership-lab/h28-command/fx/CommandDispose.own:71
13+
14+
3 errors.
15+
# exit code: 1 (OWN001 is error severity, so a finding run exits 1)
16+
# command: python3 -m ownlang check corpus/ownership-lab/h28-command/fx/CommandDispose.own
17+
# python: Python 3.11.2

0 commit comments

Comments
 (0)