Skip to content

What is this pt.2#9

Merged
PhysShell merged 9 commits into
mainfrom
claude/codegen-bugs-tests-670240
Jun 15, 2026
Merged

What is this pt.2#9
PhysShell merged 9 commits into
mainfrom
claude/codegen-bugs-tests-670240

Conversation

@PhysShell

@PhysShell PhysShell commented Jun 15, 2026

Copy link
Copy Markdown
Owner

ideas ideas

Summary by CodeRabbit

  • New Features
    • Added OwnIR versioning (ownir_version) with stricter fact-to-checker lowering.
    • Enhanced WPF lifetime leak detection for timer .Stop()-released subscriptions and clearer resource-kind tagging.
    • Published the roadmap and draft proposals (P-004 through P-012).
  • Bug Fixes
    • Improved robustness of OwnIR processing: invalid/unknown facts now fail cleanly with consistent, concise errors.
  • Tests
    • Expanded fixture sets and assertions for WPF timers, disposable fields, ignored Subscribe(), pooled buffers, and local IDisposable handling (including CI coverage).

claude added 2 commits June 15, 2026 10:15
Three structural fixes to the OwnIR bridge so adding patterns (timers,
IDisposable fields, region/escape facts) is additive rather than a rewrite:

- Map verdicts back to C# by Diagnostic.subject (a structured name#line
  identity), not by regex-scraping the human message. Generic `acquire`
  now stamps `sym.origin` like buffers already did, so OWN001 on a
  subscription carries its handle. Changing a message no longer silently
  drops a finding.
- Fail loudly instead of silently dropping: any error the core reports on
  the lowered facts that the bridge cannot attribute to a known handle now
  raises OwnIRError with an actionable message — a swallowed leak is the
  worst outcome for a leak checker.
- Version the fact contract (`ownir_version`/OWNIR_VERSION). The extractor
  stamps it and the core rejects a mismatch at load with a clear message,
  rather than mis-reading a drifted vocabulary. Malformed JSON and bad
  facts now surface as one-line CLI errors, not tracebacks.

Also split __main__.check_module out of _collect as the AST-level entry to
the one checker, so the next pattern can build a Module directly instead of
re-serialising to .own text and re-parsing it.
A long design discussion covered far more ground than the current spec/
proposals reflect, and such threads evaporate. Systematise it so every idea
raised is on the record for consideration (drafts, not commitments).

- docs/ROADMAP.md — the strategy hub: the one-sentence pitch, design
  philosophy (one checker; bug-driven expansion; narrow intraprocedural C#
  frontend), P0–P3 priorities, the five milestones, the "what static analysis
  can/can't catch" reality matrix, why not a full Rust-style borrow checker,
  and an honesty note on the (proxy, not measured) error statistics.
- P-004 WPF/UI lifetime leak profile (extends P-001: timers, IDisposable
  subscription fields, ignored Subscribe, escape→OWN014).
- P-005 IDisposable ownership profile (local/field not disposed, double
  dispose, use-after-dispose, transfer).
- P-006 DI lifetime / captive dependency (DI001–003; WeakReference is not the
  fix; IServiceScopeFactory remedy).
- P-007 ArrayPool/Span borrow-view profile (POOL001–005; replay corpus).
- P-008 Effects & resources (declared use !Db/Log/Clock, capabilities, layer
  policies; Wybe/Plasma/Mercury/Clean background).
- P-009 No-GC / allocation-free regions (OwnNoGc policy; OWN-GC001–007).
- P-010 Richer type disciplines (branded/refinement/units/typestate now;
  dependent/GADT/HKT/row/existential/modal deferred).
- P-011 Editor tooling & syntax highlighting (TextMate → CLI JSON → LSP →
  semantic tokens → tree-sitter).
- P-012 Real-world bug corpus & GitHub/Roslyn mining pipeline.
- proposals/README.md index updated; all link back to ROADMAP.

Docs only — no code or behaviour change.
@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 15, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds OWNIR_VERSION stamping and strict validation end-to-end across the Roslyn extractor, Python load(), and fixtures. Extends the extractor to detect timer events, disposable fields, ignored subscriptions, and pooled buffers with resource kind metadata. Replaces regex-based diagnostic subject scraping with structured _handle_of() lookup and assigns stable Symbol.origin identities. Refactors check_module in __main__.py and adds OwnIRError handling to cmd_ownir. Adds comprehensive samples and fixtures for WPF timer/field/subscription and ArrayPool patterns. Introduces docs/ROADMAP.md and nine new draft proposals (P-004–P-012) defining lifetime ownership, DI, effects, policies, types, tooling, and corpus research priorities.

Changes

OwnIR Versioning and Diagnostic Attribution Pipeline

Layer / File(s) Summary
OwnIR schema versioning and load-time validation
ownlang/ownir.py, tests/fixtures/ownir/sample.facts.json
Adds OWNIR_VERSION = 0 constant and OwnIRError exception. Updates schema documentation and JSON example to include ownir_version field and optional resource kind discriminators (subscription, timer, disposable, subscribe, pool, local-disposable) with corresponding [resource: ...] kind tags. Rewrites load() to validate JSON structure, enforce ownir_version integer gating, and type-check components/subscriptions arrays with early OwnIRError raising. Updates sample fixture with ownir_version field.
OwnIR lowering by resource kind and structured subject mapping
ownlang/ownir.py
to_own() validates component/subscription object shapes and lowers each subscription by resource discriminator into synthetic resource types (Subscription, Timer, Disposable, Subscribe, PooledBuffer). check_facts() implements _handle_of() to extract handles from structured Diagnostic.subject, maps core diagnostics to subscriptions, and renders leak messages with resource-specific Finding.kind tags including local-disposable case.
Symbol origin and CLI error handling
ownlang/cfg.py, ownlang/__main__.py
cfg.py assigns stable name#line origin identity to acquired symbols for structural diagnostic attribution. __main__.py extracts check_module() helper to isolate diagnostics computation from parsing, adds OwnIRError import, and wraps cmd_ownir's check_facts(load(path)) in exception handling with stderr message and exit code 2.
Roslyn extractor resource detection and versioning
frontend/roslyn/OwnSharp.Extractor/Program.cs
Detects timer events (Tick/Elapsed) with Stop() receiver .Stop() patterns for release heuristics; identifies owned disposable fields and their disposal sites; flags ignored Subscribe(...) call sites with dropped tokens; correlates ArrayPool<T>.Rent with .Return per member; detects local IDisposable without using. Adds syntax helpers for receiver/event/type classification. Emits resource kind field and ownir_version=0 in generated facts JSON.

Test Samples, Fixtures, and CI Validation

Layer / File(s) Summary
WPF timer lifecycle sample and fixture
frontend/roslyn/samples/TimerViewModel.cs, tests/fixtures/ownir/timer.facts.json
Adds TimerViewModel (unreleased DispatcherTimer subscription) and CleanTimerViewModel (IDisposable stops timer). Creates fixture with subscription records and differing release status for each variant.
IDisposable field lifecycle sample and fixture
frontend/roslyn/samples/DisposableFieldViewModel.cs, tests/fixtures/ownir/disposable.facts.json
Adds ReportViewModel (unreleased CancellationTokenSource field) and CleanReportViewModel (IDisposable disposes field). Creates fixture with subscription records mapping fields to release status.
Ignored Subscribe token sample and fixture
frontend/roslyn/samples/MessengerViewModel.cs, tests/fixtures/ownir/subscribe.facts.json
Adds InboxViewModel (ignores Subscribe() returned token), CleanInboxViewModel (IDisposable disposes token), and IMessenger interface. Creates fixture with subscription record for ignored token.
ArrayPool rent/return sample and fixture
frontend/roslyn/samples/PooledBufferSample.cs, tests/fixtures/ownir/pool.facts.json
Adds Hasher.LeakyHash() (unreturned pooled buffer) and CleanHash() (returns buffer in finally). Creates fixture with pool subscription records for leaky/clean variants.
Local IDisposable sample and fixture
frontend/roslyn/samples/LocalDisposableSample.cs, tests/fixtures/ownir/local_disposable.facts.json
Adds Loader.Leaky() (unguarded local), Guarded() (using var), and Transfer() (ownership transfer). Creates fixture with local-disposable subscription records.
Test infrastructure: version validation and fixture helpers
tests/test_ownir.py
Adds _write_facts() and _load_raises() helpers for in-memory fixture validation and error testing. Extends run() with ownir_version stamping validation, mismatch rejection, and legacy version tolerance. Adds assertions for timer/disposable/subscribe/pool/local-disposable leaks with [resource: ...] kind tags and clean-version non-reporting.
CI workflow integration
.github/workflows/ci.yml
Adds TimerViewModel.cs and DisposableFieldViewModel.cs to Roslyn extraction inputs. Extends assertions to validate timer, field, subscribe, pool, and local-disposable leaks with corresponding [resource: ...] tags and absent clean versions. Updates final success message to enumerate all validated leak categories.

Roadmap and Proposal Documentation

Layer / File(s) Summary
Roadmap: philosophy, constraints, priorities, and proposal index
docs/ROADMAP.md, docs/proposals/README.md
Adds comprehensive ROADMAP.md defining framing (lifetime/resource bugs C# can't express), design constraints (single checker, bug-driven, narrow C# frontend), priority tiers (P0–P3) with diagnostic targets, milestone progression, static-detectability reality matrix, and measurement-vs-estimates disclaimer. Updates proposals README index to list P-004–P-012 with draft status and references ROADMAP.
P-001 resolved architecture decisions
docs/proposals/P-001-csharp-extractor.md
Updates Next section to explicitly call out IDisposable field handling and region-fact emission for OWN014 with reference to P-004. Replaces open questions with resolved decisions: extractor→versioned OwnIR JSON→Python core, JSON stamping with ownir_version, structured Diagnostic.subject mapping for verdict attribution.
P-004 & P-005: WPF lifetime and IDisposable ownership
docs/proposals/P-004-wpf-lifetime-profile.md, docs/proposals/P-005-idisposable-ownership.md
Adds P-004 (WPF001–WPF005 subscription rules with resource-fact vocabulary, implementation increments, non-goals, open questions) and P-005 (D1–D5 use-after-dispose findings with acquire/release vocabulary, detectability properties, non-goals, pipeline sketch, open questions).
P-006 & P-007: DI lifetimes and ArrayPool/Span
docs/proposals/P-006-di-lifetimes.md, docs/proposals/P-007-arraypool-span.md
Adds P-006 (DI001–DI003 singleton/scoped/leak diagnostics with static-graph registration/constructor approach) and P-007 (POOL001–POOL005 borrow-view findings with resource mapping from pool operations and span/memory views).
P-008 & P-009: Effects and no-GC regions
docs/proposals/P-008-effects-and-resources.md, docs/proposals/P-009-nogc-regions.md
Adds P-008 (directional named resources with acquire/release, EFF001–EFF004 enforcement rules, effects-union sketches, rationale, open questions) and P-009 (allocation-free region DSL/policy, attribute surface, forbidden/allowed constructs, OWN-GC001–OWN-GC007, open questions).
P-010 & P-011: Type disciplines and editor tooling
docs/proposals/P-010-type-disciplines.md, docs/proposals/P-011-editor-tooling.md
Adds P-010 (branded/opaque/refinement/unit/typestate type dimensions via analyzer/generator) and P-011 (staged .own editor support: TextMate grammar, JSON diagnostics CLI, LSP with semantic tokens, optional tree-sitter).
P-012: Bug corpus mining pipeline
docs/proposals/P-012-bug-corpus-mining.md
Adds P-012 (four-stage GitHub→Roslyn→telemetry→corpus pipeline for calibrated priority measurement, pipeline sketch, proxy-based priority table, detectability categories, replay-corpus targets, open questions on repo selection and re-scan cadence).

Sequence Diagram(s)

sequenceDiagram
  participant Roslyn as Roslyn<br/>Extractor
  participant JSONFacts as facts.json<br/>(ownir_version=0)
  participant Load as load()
  participant ToOwn as to_own()
  participant ParseCheck as parse &<br/>check_facts()
  participant HandleOf as _handle_of()
  participant Finding as Finding<br/>[resource: ...]
  
  Roslyn->>JSONFacts: emit subscriptions<br/>+ resource kinds<br/>+ ownir_version=0
  JSONFacts->>Load: read JSON
  Load->>Load: validate ownir_version<br/>components/subscriptions
  Load-->>ToOwn: validated facts dict
  ToOwn->>ToOwn: map resource→<br/>synthetic type<br/>preserve metadata
  ToOwn-->>ParseCheck: lowered OwnLang<br/>module + handle map
  ParseCheck->>ParseCheck: parse module
  ParseCheck->>ParseCheck: check with core
  ParseCheck->>HandleOf: extract from<br/>Diagnostic.subject
  HandleOf-->>ParseCheck: subscription handle
  ParseCheck->>Finding: create with<br/>resource kind tag
  Finding-->>ParseCheck: Finding rendered
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~28 minutes

Possibly related PRs

  • PhysShell/Own.NET#8: Both PRs extend the Roslyn → Python ownir pipeline; this PR adds version gating, structured subject-based lookup, timer/field/subscribe/pool resource detection, Symbol origin identity, and comprehensive fixture coverage on top of prior fact-emission infrastructure.

Poem

🐇 Hop, hop, the versions align,
A stamped ownir_version — a wonderful sign!
No more regex scraping, we've found a new way,
_handle_of finds the facts, bright as day.
Timers tick safe, nine proposals bloom true,
The roadmap's grand vision starts breaking on through! 🌿✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 48.15% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The pull request title 'What is this pt.2' is vague and does not describe the main changeset. The PR actually implements local IDisposable leak detection (OWN001, P-005 D1) with significant documentation, extractor logic, and test coverage, but the title provides no meaningful context about these changes. Replace the vague title with a descriptive summary such as 'Implement local IDisposable leak detection (OWN001)' or 'Add local-disposable resource detection to OwnIR analysis' to clearly communicate the primary change.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
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/codegen-bugs-tests-670240

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.

Actionable comments posted: 2

🧹 Nitpick comments (1)
docs/proposals/P-008-effects-and-resources.md (1)

84-84: 💤 Low value

Minor style improvements (LanguageTool hints).

Three small wordiness and punctuation notes for polish:

  • Line 84: "in search of a bug" is slightly wordy. Consider: "not a philosophical purity analyzer chasing a bug." or similar.
  • Line 146: The word "exactly" is used twice in close proximity (also line 160). Consider removing one occurrence for variety.
  • Line 159: The section has 14 exclamation marks across 5962 characters, creating visual heaviness. This is partly due to the ! effect syntax (e.g., use !Db), but consider easing one or two punctuation marks to improve readability—e.g., change the closing question (line 161) to a period.

Also applies to: 146-146, 159-159

🤖 Prompt for AI Agents
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/proposals/P-008-effects-and-resources.md` at line 84, In
docs/proposals/P-008-effects-and-resources.md, apply three style refinements for
better readability and variety: At line 84, replace the phrase "in search of a
bug" with a more concise alternative such as "chasing a bug" to reduce
wordiness. At line 146, remove one occurrence of the word "exactly" to avoid
repetition with the same word appearing at line 160. At line 159, reduce the
visual heaviness of exclamation marks by changing the closing question mark on
line 161 to a period, which will improve overall readability while maintaining
the natural effect syntax throughout the document.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/proposals/P-008-effects-and-resources.md`:
- Around line 55-70: The document lists five behaviors that should be caught
(including "Unpaired protocol" for Rent without Return and BeginTransaction
without Commit/Rollback) but only provides four diagnostic codes
(EFF001–EFF004). Add a new diagnostic code EFF005 to the diagnostics section to
explicitly cover the unpaired protocol violation case, with a description that
references the specific scenarios like Rent without Return and BeginTransaction
without Commit/Rollback.

In `@ownlang/ownir.py`:
- Around line 153-156: The function's return type annotation is `str | None`,
but the `getattr(diag, "subject", None)` call on line 153 returns an untyped
`Any` in mypy strict mode, causing a type violation when `.split()` is called.
Add an `isinstance(subject, str)` check in addition to the existing `if not
subject` check to narrow the type and satisfy mypy strict mode. The condition
should verify both that subject is truthy and that it is specifically a string
type before proceeding to the `.split()` call.

---

Nitpick comments:
In `@docs/proposals/P-008-effects-and-resources.md`:
- Line 84: In docs/proposals/P-008-effects-and-resources.md, apply three style
refinements for better readability and variety: At line 84, replace the phrase
"in search of a bug" with a more concise alternative such as "chasing a bug" to
reduce wordiness. At line 146, remove one occurrence of the word "exactly" to
avoid repetition with the same word appearing at line 160. At line 159, reduce
the visual heaviness of exclamation marks by changing the closing question mark
on line 161 to a period, which will improve overall readability while
maintaining the natural effect syntax throughout the document.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 524e9ac4-e342-4869-be8c-8d4fab94d9c0

📥 Commits

Reviewing files that changed from the base of the PR and between 4ac2ae7 and 903eb40.

📒 Files selected for processing (18)
  • docs/ROADMAP.md
  • docs/proposals/P-001-csharp-extractor.md
  • docs/proposals/P-004-wpf-lifetime-profile.md
  • docs/proposals/P-005-idisposable-ownership.md
  • docs/proposals/P-006-di-lifetimes.md
  • docs/proposals/P-007-arraypool-span.md
  • docs/proposals/P-008-effects-and-resources.md
  • docs/proposals/P-009-nogc-regions.md
  • docs/proposals/P-010-type-disciplines.md
  • docs/proposals/P-011-editor-tooling.md
  • docs/proposals/P-012-bug-corpus-mining.md
  • docs/proposals/README.md
  • frontend/roslyn/OwnSharp.Extractor/Program.cs
  • ownlang/__main__.py
  • ownlang/cfg.py
  • ownlang/ownir.py
  • tests/fixtures/ownir/sample.facts.json
  • tests/test_ownir.py

Comment thread docs/proposals/P-008-effects-and-resources.md
Comment thread ownlang/ownir.py
claude added 3 commits June 15, 2026 14:17
A Tick/Elapsed handler on a started timer is a Timer resource: the running
timer strong-refs the handler's owner, so an undetached one leaks it (OWN001,
tagged [resource: timer]). Released by a matching `-=` OR a `Stop()` on the
same receiver (e.g. `_timer.Stop()` in Dispose).

- ownir.py: optional `resource` field per subscription ("subscription" default
  | "timer"); a Timer resource in the prelude (kind "timer"); timer-specific
  finding message + kind tag. The field is additive, so it does NOT bump
  ownir_version — an older core just reads every entry as a subscription.
- Roslyn extractor: classify `Tick`/`Elapsed` handlers as timers; a timer is
  released by `-=` or a `Stop()` on the same receiver; emit `resource`.
- Sample TimerViewModel.cs (leaking timer + Stop()-in-Dispose clean one) and a
  hand-written timer.facts.json fixture; test_ownir pins the timer leak,
  the [resource: timer] tag, and silence on the stopped timer.
- wpf-extractor CI job runs the timer sample and asserts the timer leak +
  [resource: timer] tag, and that the stopped timer stays silent.
- Docs: P-004/P-001/ROADMAP mark WPF002 built.

Python bridge verified locally (11/11 ownir checks); the extractor is
CI-validated (dotnet is CI-only).
An IDisposable field the class constructs (`new`) but never disposes leaks it
(OWN001, tagged [resource: disposable field]). "Owned, not injected" = the
field is assigned a `new` in this class; "released" = a `<field>.Dispose()`
call exists somewhere in the class.

- ownir.py: new "disposable" resource kind (Disposable resource, kind
  "disposable field"); optional `type` names the field's declared type in the
  message. Additive — no ownir_version bump. Docstring now describes
  `subscriptions` as the (historically named) owned-resource list with a
  `resource` discriminator.
- Roslyn extractor: detect disposable fields by a curated type heuristic
  (syntax-only — no semantic model), gated on the class `new`ing the field so
  injected/borrowed disposables are not flagged; released iff disposed.
- Sample DisposableFieldViewModel.cs (leaking CTS + one disposed in Dispose)
  and a disposable.facts.json fixture; test_ownir pins the leak, the type in
  the message, the [resource: disposable field] tag, and silence on the
  disposed one. CI asserts the same on the real extractor output.
- Docs: P-004/P-005/ROADMAP mark WPF003 built.

Python bridge verified locally (14/14); extractor CI-validated.
A `X.Subscribe(...)` whose IDisposable result is ignored (the call stands as a
bare statement, not assigned/returned/added) drops the subscription token, so
it is never disposed and leaks (OWN001, tagged [resource: subscription token]).

- ownir.py: new "subscribe" resource kind (maps to the Subscription resource /
  subscription-token tag, with its own "result ignored" message). Additive — no
  ownir_version bump.
- Roslyn extractor: flag member-access `x.Subscribe(...)` calls whose parent is
  an ExpressionStatement (result discarded); member-access only, to avoid bare
  void `Subscribe(...)` helpers. A captured-and-disposed token is not flagged.
- Sample MessengerViewModel.cs (ignored Subscribe + captured/disposed clean
  one) and a subscribe.facts.json fixture; test_ownir pins the leak, the
  "ignored" message, and the [resource: subscription token] tag. CI asserts the
  same on the real extractor output.
- Docs: P-004 marks WPF004 built.

Python bridge verified locally (16/16); extractor CI-validated.

@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.

Actionable comments posted: 1

♻️ Duplicate comments (1)
ownlang/ownir.py (1)

197-200: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

mypy --strict still failing: getattr returns Any, so the return type is violated.

The pipeline failure on line 200 is the same issue flagged in the prior review. The suggested fix (adding isinstance(subject, str) guard) has not been applied yet. This blocks CI.

Suggested fix
 def _handle_of(diag: object) -> str | None:
     subject = getattr(diag, "subject", None)
-    if not subject:
+    if not isinstance(subject, str) or not subject:
         return None
     return subject.split("#", 1)[0]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ownlang/ownir.py` around lines 197 - 200, The getattr call on the `diag`
object returns `Any` type, which causes mypy --strict to fail when calling the
`.split()` method on `subject` without proper type narrowing. Add an
`isinstance(subject, str)` guard after the existing falsy check to narrow the
type from `Any` to `str` before calling `.split("#", 1)[0]` on it. This ensures
the function satisfies strict type checking while maintaining the same logic.

Source: Pipeline failures

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_ownir.py`:
- Around line 153-154: The test assertion at line 153 in the test_ownir.py file
expects the disposable field finding to be at line 11, but the _cts field is
actually declared at line 10 in DisposableFieldViewModel.cs, which is what the
CI correctly reports. Update the expected line number in the assertion from 11
to 10 to match the actual field declaration location.

---

Duplicate comments:
In `@ownlang/ownir.py`:
- Around line 197-200: The getattr call on the `diag` object returns `Any` type,
which causes mypy --strict to fail when calling the `.split()` method on
`subject` without proper type narrowing. Add an `isinstance(subject, str)` guard
after the existing falsy check to narrow the type from `Any` to `str` before
calling `.split("#", 1)[0]` on it. This ensures the function satisfies strict
type checking while maintaining the same logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ebe7aa7a-459c-43ba-9c55-2f7b2b0d30c8

📥 Commits

Reviewing files that changed from the base of the PR and between 148f053 and 3efc926.

📒 Files selected for processing (9)
  • .github/workflows/ci.yml
  • docs/ROADMAP.md
  • docs/proposals/P-004-wpf-lifetime-profile.md
  • docs/proposals/P-005-idisposable-ownership.md
  • frontend/roslyn/OwnSharp.Extractor/Program.cs
  • frontend/roslyn/samples/DisposableFieldViewModel.cs
  • ownlang/ownir.py
  • tests/fixtures/ownir/disposable.facts.json
  • tests/test_ownir.py
✅ Files skipped from review due to trivial changes (4)
  • tests/fixtures/ownir/disposable.facts.json
  • docs/ROADMAP.md
  • docs/proposals/P-005-idisposable-ownership.md
  • docs/proposals/P-004-wpf-lifetime-profile.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/ci.yml
  • frontend/roslyn/OwnSharp.Extractor/Program.cs

Comment thread tests/test_ownir.py Outdated
An ArrayPool/MemoryPool buffer Rent'ed but never Return'ed leaks (pool
exhaustion / GC pressure) — OWN001, tagged [resource: pooled buffer]. The
first finding of the flagship borrow-view profile, in the same flat
acquire/release model as the WPF resources.

- ownir.py: new "pool" resource kind (PooledBuffer resource, kind "pooled
  buffer", Rent/Return verbs). Additive — no ownir_version bump.
- Roslyn extractor: detect `<pool>.Rent(...)` assigned to a variable/field
  (receiver text contains "pool"); released iff a `Return(buf)` with that
  identifier exists. Matched PER MEMBER so a `buf` returned in one method does
  not mask a same-named leak in another.
- Sample PooledBufferSample.cs (leaky Rent + rent/return-in-finally clean one)
  and a pool.facts.json fixture; test_ownir pins the leak, the rented/returned
  message, and the [resource: pooled buffer] tag. CI asserts the leaky buffer
  is reported and the returned one is silent.
- Docs: P-007/ROADMAP mark POOL001 built.

Python bridge verified locally (18/18); extractor CI-validated.

@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.

Actionable comments posted: 1

♻️ Duplicate comments (1)
tests/test_ownir.py (1)

157-158: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix disposable-field expected line number (off by one).

At Line 157, the assertion still expects line 11, but the finding location is line 10 for _cts in DisposableFieldViewModel.cs. This will fail the test even when behavior is correct.

Proposed fix
-        if (d0.file, d0.line, d0.code) != ("DisposableFieldViewModel.cs", 11, "OWN001"):
+        if (d0.file, d0.line, d0.code) != ("DisposableFieldViewModel.cs", 10, "OWN001"):
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_ownir.py` around lines 157 - 158, The test assertion in the
disposable field check is expecting the wrong line number. The assertion that
validates d0.line should expect line 10 instead of line 11, as the _cts field in
DisposableFieldViewModel.cs is located at line 10, not line 11. Update the
hardcoded line number in the condition that checks (d0.file, d0.line, d0.code)
to use 10 instead of 11.

Source: Pipeline failures

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/roslyn/OwnSharp.Extractor/Program.cs`:
- Around line 200-205: The Return detection in the foreach loop iterating over
InvocationExpressionSyntax is too restrictive compared to the Rent detection
logic. Currently it only matches bare IdentifierNameSyntax arguments in the
invocation, which means it won't recognize qualified member access patterns like
this._buf. Instead of checking if the argument expression is an
IdentifierNameSyntax and extracting its text directly, use the FieldName()
method (which already handles both simple and qualified identifier patterns) to
extract the argument name and add it to the returned collection, matching the
pattern used for Rent detection.

---

Duplicate comments:
In `@tests/test_ownir.py`:
- Around line 157-158: The test assertion in the disposable field check is
expecting the wrong line number. The assertion that validates d0.line should
expect line 10 instead of line 11, as the _cts field in
DisposableFieldViewModel.cs is located at line 10, not line 11. Update the
hardcoded line number in the condition that checks (d0.file, d0.line, d0.code)
to use 10 instead of 11.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8dda99f2-bc98-4485-beaa-76137dc76659

📥 Commits

Reviewing files that changed from the base of the PR and between 3efc926 and 4e276f0.

📒 Files selected for processing (11)
  • .github/workflows/ci.yml
  • docs/ROADMAP.md
  • docs/proposals/P-004-wpf-lifetime-profile.md
  • docs/proposals/P-007-arraypool-span.md
  • frontend/roslyn/OwnSharp.Extractor/Program.cs
  • frontend/roslyn/samples/MessengerViewModel.cs
  • frontend/roslyn/samples/PooledBufferSample.cs
  • ownlang/ownir.py
  • tests/fixtures/ownir/pool.facts.json
  • tests/fixtures/ownir/subscribe.facts.json
  • tests/test_ownir.py
✅ Files skipped from review due to trivial changes (5)
  • tests/fixtures/ownir/subscribe.facts.json
  • tests/fixtures/ownir/pool.facts.json
  • docs/ROADMAP.md
  • docs/proposals/P-007-arraypool-span.md
  • docs/proposals/P-004-wpf-lifetime-profile.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • ownlang/ownir.py

Comment thread frontend/roslyn/OwnSharp.Extractor/Program.cs Outdated
A local the method `new`s of an IDisposable type, never disposed and not
guarded by `using` (and not returned/passed/assigned out), leaks — OWN001,
tagged [resource: disposable]. The local analog of WPF003's owned fields; the
canonical CA2000 leak.

- ownir.py: new "local-disposable" resource kind (Disposable resource, tag
  "disposable", with its own message). Additive — no ownir_version bump.
- Roslyn extractor: per-member detection of `new`'d IDisposable locals;
  released iff disposed; conservatively excludes `using`-guarded locals and
  ones whose ownership may leave the scope (returned / passed as an argument /
  assigned out — transfer is ambiguous syntactically, P-005 D5).
- Sample LocalDisposableSample.cs (leaky local + a `using` one + a returned/
  transferred one) and a local_disposable.facts.json fixture; test_ownir pins
  the leak, the type in the message, and the [resource: disposable] tag. CI
  asserts the leaky local is reported and the using/returned ones are silent.
- Docs: P-005 marks D1 built (and D2 via WPF003).

Python bridge verified locally (20/20); extractor CI-validated.

@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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Around line 167-172: The local-disposable CI assertion block is incomplete
compared to other resource checks. It currently only verifies the leak text
"local IDisposable 'leaky'" and checks that certain strings are absent, but it
does not assert the resource-kind tag "resource: disposable" or the source file
"LocalDisposableSample.cs". To achieve parity with other resource checks and
prevent kind-mapping regressions from slipping through, add additional grep
assertions in this block to verify both the resource-kind tag and the source
file are present in the output, similar to what is done in corresponding checks
for other resource types.

In `@frontend/roslyn/OwnSharp.Extractor/Program.cs`:
- Around line 234-239: The disposal detection logic in the foreach loop
iterating through InvocationExpressionSyntax only checks for the "Dispose"
method name, but since IsDisposableType() includes IAsyncDisposable types, it
must also detect DisposeAsync calls to avoid false positives. Modify the
condition that checks m.Name.Identifier.Text == "Dispose" to also match
"DisposeAsync", either by using an OR condition to check for both method names
or by extending the check to accommodate async disposal patterns.

In `@frontend/roslyn/samples/LocalDisposableSample.cs`:
- Around line 8-21: The sample code shows a line-anchor drift where the Leaky
method's MemoryStream allocation and the Guarded method's MemoryStream
allocation have shifted to different line numbers than what the fixture contract
expects. To fix this, you must realign the contract by either updating the
fixture's asserted line locations to match the current positions of the
allocations (Line 12 for Leaky and Line 20 for Guarded), or by adding or
removing blank lines in the sample code to restore the allocations to their
originally expected line numbers (10 and 18). Choose whichever approach
maintains consistency with the rest of your test infrastructure and fixture
contracts.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 27b3f3b5-0f38-4f8a-befe-f2a20519a9c3

📥 Commits

Reviewing files that changed from the base of the PR and between 4e276f0 and e7637a3.

📒 Files selected for processing (7)
  • .github/workflows/ci.yml
  • docs/proposals/P-005-idisposable-ownership.md
  • frontend/roslyn/OwnSharp.Extractor/Program.cs
  • frontend/roslyn/samples/LocalDisposableSample.cs
  • ownlang/ownir.py
  • tests/fixtures/ownir/local_disposable.facts.json
  • tests/test_ownir.py
✅ Files skipped from review due to trivial changes (2)
  • tests/fixtures/ownir/local_disposable.facts.json
  • docs/proposals/P-005-idisposable-ownership.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/test_ownir.py
  • ownlang/ownir.py

Comment thread .github/workflows/ci.yml
Comment thread frontend/roslyn/OwnSharp.Extractor/Program.cs
Comment on lines +8 to +21
// A MemoryStream created but never disposed and not in a `using`: leak. The
// core reports OWN001 [resource: disposable] at the declaration.
public static long Leaky()
{
var leaky = new MemoryStream();
leaky.WriteByte(1);
return leaky.Length; // never disposed => leak
}

// `using` guarantees disposal — not flagged.
public static long Guarded()
{
using var guarded = new MemoryStream();
guarded.WriteByte(1);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Line-anchor drift breaks the sample↔fixture contract for local-disposable checks.

The leaky allocation now occurs at Line 12 (and guarded allocation at Line 20), but the fixture contract is anchored to lines 10/18, and CI logs already show the leak reported at 12-12. This will cause brittle failures in checks that assert exact C# locations.

Please realign one side of the contract: either update the fixture/asserted locations to 12/20, or keep the sample’s anchored statements at the expected lines.

🧰 Tools
🪛 GitHub Actions: CI / 4_C# leak extractor (Roslyn) - OwnIR - core.txt

[error] 12-12: OWN001: local IDisposable 'leaky' (type 'MemoryStream') is created but never disposed (leak) [resource: disposable]

🪛 GitHub Actions: CI / C# leak extractor (Roslyn) - OwnIR - core

[error] 12-12: OWN001: local IDisposable 'leaky' (type 'MemoryStream') is created but never disposed (leak) [resource: disposable]

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

In `@frontend/roslyn/samples/LocalDisposableSample.cs` around lines 8 - 21, The
sample code shows a line-anchor drift where the Leaky method's MemoryStream
allocation and the Guarded method's MemoryStream allocation have shifted to
different line numbers than what the fixture contract expects. To fix this, you
must realign the contract by either updating the fixture's asserted line
locations to match the current positions of the allocations (Line 12 for Leaky
and Line 20 for Guarded), or by adding or removing blank lines in the sample
code to restore the allocations to their originally expected line numbers (10
and 18). Choose whichever approach maintains consistency with the rest of your
test infrastructure and fixture contracts.

Source: Pipeline failures

claude added 2 commits June 15, 2026 15:27
…ge cases

Verified each of the 7 review threads against the code; all valid, all minimal:

- mypy --strict (the actual red CI): _handle_of returned Any from getattr;
  narrow with isinstance(subject, str) before .split(). Confirmed clean with
  `mypy` + `ruff check .`.
- extractor: ArrayPool Return detection now uses FieldName() so
  `pool.Return(this._buf)` matches the rented `this._buf` (was a false-positive
  leak for qualified fields).
- extractor: disposal detection (both owned-field and local) now matches
  `DisposeAsync()` as well as `Dispose()` — IsDisposableType already accepts
  IAsyncDisposable, so an awaited DisposeAsync was a false positive.
- CI: local-disposable check now also asserts the source file and the exact
  `[resource: disposable]` tag (parity with the other resource checks; the
  trailing `]` avoids matching `disposable field`).
- P-008: add EFF005 for the unpaired-protocol case the prose already lists.
- fixtures/tests: realign the hand-written disposable/local fixture line
  anchors to the actual sample declarations (10/21 and 12) so the fixtures
  faithfully mirror the samples.

Tests 20/20; mypy + ruff clean locally.
… CI)

The C# leak-extractor CI job has been red since WPF003 landed: IsDisposableType
matched `*Timer` (and `DispatcherTimer`/`Timer`), so a DispatcherTimer field was
reported as a "disposable field" needing Dispose(). DispatcherTimer is not even
IDisposable, and a timer's release is Stop()/detach (the WPF002 pattern) — so
this double-reported every timer and false-positived CleanTimerViewModel (a
correctly Stop()'d timer), breaking the "stopped timer not reported" assertion.

Fix: exclude timer types from the disposable-field/local heuristic; timers are
owned by the WPF002 timer pattern. Caught only in CI (dotnet is CI-only) — the
local Python bridge suite cannot exercise the extractor heuristic.
@PhysShell
PhysShell merged commit 4c1b71a into main Jun 15, 2026
15 checks passed
PhysShell pushed a commit that referenced this pull request Jul 15, 2026
…port

Real N2-D1b evidence (qodec-n2d1b-miner-pilot.yml CI runs #9-#11) showed
Gradle's own daemon architecture always needs SOME loopback TCP port,
chosen by the OS -- two independent argv/env-only workarounds to avoid
this both failed identically with "java.net.BindException: Permission
denied". Sandboy's own tcp_bind is a fixed port list (Landlock scopes
ports, not addresses, per this repo's own README) with no way to express
"any port, loopback only", so there is no small, correct port allowlist
to add for this case.

Add network_enforcement_mode: Option<String> to Policy, with exactly one
accepted value, "outer-netns-loopback-only". When set (and only when
tcp_connect/tcp_bind are both empty -- a fixed port list alongside this
mode is contradictory and a hard error): Landlock's own TCP bind/connect
mediation is skipped entirely for that ruleset, relying solely on the
caller having already placed the process inside a network namespace with
no route beyond loopback. Filesystem, seccomp, and env_clear mediation
are completely unaffected -- only the .handle_access(AccessNet::...) call
becomes conditional. Left unset (the default): byte-for-byte the same
behavior as every prior policy.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146FG6sjNiVaQEbCUZkzSy6
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