Skip to content

feat: add OWN053 orphaned-awaitable advisory - #386

Merged
PhysShell merged 1 commit into
mainfrom
feat/own053-orphaned-awaitable
Oct 2, 2026
Merged

PhysShell merged 1 commit into
mainfrom
feat/own053-orphaned-awaitable

Conversation

@PhysShell

Copy link
Copy Markdown
Owner

Что и зачем

Продвигает проверенный H-29 в обычный каталог как advisory OWN053: orphaned awaitable и сразу закрывает post-promotion debt P-OWN053-DOOR.

OWN053 остаётся намеренно узким: локальная переменная получает un-awaited Task<T>/ValueTask<T> от effectful operation и затем нигде в member не наблюдается. Discards, bare expression statements, расширение family B и autofix сюда не входят.

Cutover hygiene

Этот PR собран не из всей research-ветки. research/ownership-semantics-lab-v1 была на десятки исследовательских коммитов впереди main.

Cutover сделан как чистый двухкоммитный slice от актуального main:

  • base: 5323dd426f05d1b91dc3a5d906a2f5afd941f488
  • promotion source: ab2964f15631060a2ab83f2d3864fc1ec73bb1cc
  • door-binding source: 298b305388601ae0a53d592671457afb0ba81f99

Перед переносом проверено, что новые main-коммиты не пересекаются с файлами обоих source-коммитов. Diff ветки: 2 commits, 54 files, 0 extra / 0 missing относительно union двух source-коммитов.

Что входит

  • default-on advisory OWN053 в Python/Rust с byte-parity;
  • additive orphaned_awaitables[] facts;
  • runtime-measured Wolverine/Npgsql case study;
  • strict-door binding списка в Python load() и Rust strict.rs;
  • schema binding sourceLine/sourceColumn/orphanFamily;
  • cp1 validation ledger 294 → 344, старые 294 записей insertion-stable;
  • Rust validation replay без permissive accepts/category mismatch;
  • verdict golden, CLI fixtures, diagnostics ledger, bridge/spec docs;
  • negative strict-door controls и promotion/door evidence.

Проверено на source-ветке

  • full Python suite: rc=0 на clean tree;
  • cargo test --release: rc=0;
  • promoted fixture: 5 OWN053 advisory, 0 findings, exit 0, Python == Rust;
  • malformed OWN053 documents: обе строгие двери reject, exit 2;
  • verdict goldens / digests / CLI fixtures не меняются door-binding шагом.

Не входит

  • изменение wording OWN053;
  • discard / expression-statement support;
  • family-B expansion;
  • autofix;
  • H-26A;
  • прочие ownership-semantics-lab исследования.

Post-promotion debt P-OWN053-WORDING остаётся зарегистрированным и должен быть закрыт до расширения family A/B.

Research branch и paperwork остаются отдельным evidence trail; этот PR несёт только production slice.

…rch 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
@PhysShell
PhysShell force-pushed the feat/own053-orphaned-awaitable branch from 1b1042d to 380b098 Compare October 1, 2026 18:55
@PhysShell
PhysShell marked this pull request as ready for review October 2, 2026 00:38
@PhysShell
PhysShell merged commit 7310f78 into main Oct 2, 2026
74 checks passed
PhysShell added a commit that referenced this pull request Oct 2, 2026
main gained the OWN053 orphaned-awaitable advisory (#386) after this branch was
cut. #386 was written against OwnIR v0; this branch moves the whole contract to
v1. The merged tree is one OwnIR v1 that carries both:

    OWNIR_VERSION 1, LOWERED_VERSION 2
    flow ops      move, borrow_mut            (this branch)
    top level     orphaned_awaitables[]       (#386, additive, both strict doors)
    advisory      OWN053, two frozen families (#386)

Nothing of either side is dropped, and there is no dual-version reading.

Textual conflicts: three, all generated status documents
(docs/generated/p022-{coord-census,cp4-census,shadow-census}.md). Resolved by
regenerating them with their writer, not by picking a side.

The conflict that mattered did not conflict. Git merged
frontend/roslyn/OwnSharp.Extractor/Program.cs cleanly and left #386's new
envelope — the one that carries `orphaned_awaitables` — stamped
`ownir_version = 0`, between two envelopes stamped 1. A scan with an OWN053 site
would have produced facts the v1 core refuses at the door. The IR2 check in
tests/test_ownir.py did not see it: it read only the FIRST stamp in each
producer. It now reads every stamp (`[1, 0, 1]` fails it), and the envelope is
stamped 1.

#386's documents that mean "the current version" are migrated to it, stamp only:
tests/fixtures/verdicts/verdict_own053_orphaned_awaitable.facts.json and the
four H-29 documents under corpus/ownership-lab/h29 (promo-u and the three
malformed door inputs). Their recorded outputs are unchanged, byte for byte, on
both engines, and the merged extractor reproduces promo-u.facts.json exactly
from fx/Orphan.cs: five sites, lines 11/12/21/22/23.

Regenerated with the repository's writers: the validation ledger (294 + 50
controls = 344, the inputs now stamped by OWNIR_VERSION), the Layer 3 verdict
goldens (132 + 1 = 133 cases), the repro digests (135 + 1 = 136 documents) and
the generated status documents. The merge result differs from this branch's
previous head in exactly #386's 56 paths and from both parents in 20; no ledger
outside those moved.

T0: scripts/perf_baseline.py, the workload manifest, the three bindings, the T0
document and the merge-gate files are untouched by this merge. The harness
identity is still 1a26aa63fd5f, the value Amendment 1 recorded.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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