Skip to content

Commit 380b098

Browse files
committed
feat: add OWN053 orphaned-awaitable advisory (clean port of the research promotion onto main, strict-door binding included)
OWN053 "orphaned awaitable": a local initialised by an un-awaited Task / ValueTask invocation of an effectful operation (the unwrapped result is a real disposable, or the member is a connection / transaction lifecycle call) that is never referenced again in its member. Default-on advisory in both engines with an identical message, rendered as a warning, never the exit code, hidden at --verbosity quiet; no automatic fix. The scope is frozen as measured in ownership-semantics-lab H-29: discards, expression statements, stored / passed / returned awaitables and lambdas are untouched; new lifecycle members enter only by witnesses. Provenance: a re-port onto main 5323dd4 of research/ownership-semantics-lab-v1 commits ab2964f (promotion) and 298b305 (P-OWN053-DOOR), carrying ONLY the OWN053 hunks. Unlike a file-level copy of those two commits, this port does not bring the research branch's content along: the extractor gains one detector (CollectOrphanedAwaitables), one holder and the additive facts branch instead of 1,900 lines of env-gated research seams; ownlang/ownir.py gains the family set, the strict-door block, the check_facts call and the finding builder instead of the H-20 / resource-effects E3 / P-037-X seams; spec/OwnIR.md and the schema gain §9, the §4.2 note, the orphanedAwaitable / orphanFamily definitions and nothing of params[].ordinal or flag_var; tests/test_ownir_validation_fixtures.py keeps main's #383 writer contract and gains the orphaned_awaitables section on top of it; tests/test_p037_evidence.py is untouched because main has none of the research read sites; the Rust diagnostics catalogue and the diagnostics ledger (47 -> 48) are included, which the file-level copy had lost. Extractor: the sites are collected into the ADDITIVE top-level facts list orphaned_awaitables (absent when there is no site, so such a document is byte-identical to the pre-OWN053 shape; ownir_version unchanged). On the committed fixture corpus/ownership-lab/h29/fx/Orphan.cs the production build finds exactly the five frozen primary sites of the H-29 scan and none of the eleven twins; the facts equal the research build's modulo the research-only params[].ordinal field. Strict doors: both load() and the Rust strict door validate the list last in BR-D1 order (array of objects; non-empty local / callee as identity, file string, line in the §4.2 domain, column as every other column, method / result_type string-or-null, family from the closed set as vocabulary). cp1 ledger 294 -> 344 controls, appended insertion-stable on top of #383's writer; the Rust validation replay reports no permissive accept and no category mismatch. Schema bound to sourceLine / sourceColumn / orphanFamily (pinned to ownlang/ownir.py::_ORPHAN_FAMILIES); binding map BOUND; coordinate census door slots; checkpoint documents regenerated. Verification on this tree: the fixture through both CLIs (5 advisory OWN053, 0 findings, exit 0, Python == Rust); three malformed documents refused by both CLIs with exit 2 (corpus/ownership-lab/h29/door); CLI fixtures, verdict goldens (one new synthetic case), diagnostics ledger and repro digests regenerated; full Python suite and cargo test --release green; the extractor builds with main's pre-existing warning only. Not included (registered in Own.NET-paperwork): P-OWN053-WORDING (family-specific message tails) stays open and precedes any family A/B expansion; discards / expression statements / family-B expansion / autofix / H-26A are not earned. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Am9eQwzNfbugH72eVKetC2
1 parent 464de8d commit 380b098

56 files changed

Lines changed: 2266 additions & 77 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
P-OWN053-DOOR: orphaned_awaitables[] bound at both OwnIR strict doors (after the OWN053 promotion;
2+
prereg frozen in Own.NET-paperwork before code). Produced by the PRODUCTION build of this tree, from
3+
the repository root.
4+
5+
promo-u.door.py.txt / promo-u.door.rust.txt
6+
../promotion/promo-u.facts.json through both CLIs, whose path IS the strict door: accepted,
7+
5 advisory OWN053, 0 findings, exit 0, Python == Rust -- the rule and the message did not move.
8+
neg-garbage.facts.json an entry whose local is a list, callee an object, result_type a number
9+
(the exact shape the unbound list rendered as a real OWN053)
10+
neg-line_above.facts.json an entry with line 2147483648 (above the §4.2 domain; the unbound
11+
list degraded it to 0)
12+
neg-family.facts.json an entry with family "C_whatever" (outside the closed set)
13+
neg-*.py.txt / neg-*.rust.txt
14+
both CLIs refuse each document with exit code 2 (ordinary bad input) naming the same rule;
15+
the message text differs by language, as the cp1 ledger allows (verdict + category are the
16+
cross-language contract, tests/fixtures/ownir_validation.json section orphaned_awaitables).
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"ownir_version": 0, "module": "M", "orphaned_awaitables": [{"local": "tx", "callee": "T.M/0", "file": "Q.cs", "line": 1, "family": "C_whatever"}]}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
corpus/ownership-lab/h29/door/neg-family.facts.json: error: orphaned awaitable 'family' must be one of ['A_owned_result', 'B_protocol_lifecycle'], got 'C_whatever'
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
corpus/ownership-lab/h29/door/neg-family.facts.json: error: orphaned awaitable 'family' must be one of ["A_owned_result", "B_protocol_lifecycle"], got "C_whatever"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"ownir_version": 0, "module": "M", "orphaned_awaitables": [{"local": ["what", "is", "this"], "callee": {"oops": 1}, "file": "Q.cs", "line": 119, "result_type": 12345}]}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
corpus/ownership-lab/h29/door/neg-garbage.facts.json: error: orphaned awaitable 'local' must be a non-empty string, got ['what', 'is', 'this']
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
corpus/ownership-lab/h29/door/neg-garbage.facts.json: error: orphaned awaitable: 'local' must be a non-empty string
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"ownir_version": 0, "module": "M", "orphaned_awaitables": [{"local": "tx", "callee": "T.M/0", "file": "Q.cs", "line": 2147483648}]}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
corpus/ownership-lab/h29/door/neg-line_above.facts.json: error: orphaned awaitable 'line' must be a source line in [0, 2147483647], got 2147483648 (spec/OwnIR.md §4.2)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
corpus/ownership-lab/h29/door/neg-line_above.facts.json: error: orphaned awaitable 'line' must be a source line in [0, 2147483647], got 2147483648 (spec/OwnIR.md §4.2)

0 commit comments

Comments
 (0)