Skip to content

P-015: emit DI captive codeFlows + fold diagnostics tests into the suite#119

Merged
PhysShell merged 2 commits into
mainfrom
claude/p015-codeflows-wiring
Jun 26, 2026
Merged

P-015: emit DI captive codeFlows + fold diagnostics tests into the suite#119
PhysShell merged 2 commits into
mainfrom
claude/p015-codeflows-wiring

Conversation

@PhysShell

@PhysShell PhysShell commented Jun 26, 2026

Copy link
Copy Markdown
Owner

What & why

The reachability-slice follow-up promised in #118, now that the evidence builders (ownlang/evidence.py) are on main. #118 added the model + builders; this wires them through the OwnIR SARIF path so a DI captive actually ships its ordered retention slice (the "why is this held, and through what?" trace relatedLocations can't express), and runs the diagnostics tests in CI.

Changes

  • ownlang/ownir.pyFinding gains an ordered flow field; _sarif_result emits it as SARIF codeFlows; _di_findings builds each DI001–DI005 flow from the captive's dependency path and a name→registration-site map via evidence.di_path_steps. A captive now carries both its consuming-ctor relatedLocation and the ordered singleton → [transient →]* scoped slice.
  • tests/test_ownir.py — assert the EmailSender direct (2-hop) and ReportService transitive (3-hop, transient pass-through) codeFlows, alongside the existing relatedLocations checks (now 151 bridge checks).
  • tests/run_tests.py — fold tests/test_diagnostics.py (added in P-015: structured reachability-slice evidence for diagnostics #118 but not yet aggregated) into the suite, so the empty-evidence invariant + slice ordering run in CI.

Testing

Run locally before pushing:

  • python tests/run_tests.py → full suite green (ownir: 151/151, diagnostics: PASS)
  • ruff check . → clean
  • mypy (--strict on ownlang) → clean

This closes the two follow-ups noted in #118 (the ownir.build_sarif wiring and the run_tests.py aggregation); both were deferred there only because they couldn't be edited safely over the API — done here against a local checkout where the suite runs.

🤖 Generated with Claude Code


Generated by Claude Code

Summary by CodeRabbit

  • New Features

    • Added step-by-step dependency-injection reachability traces to diagnostic findings.
    • Enhanced SARIF export to include code-flow/thread-flow traces alongside related locations when available.
  • Bug Fixes

    • Improved DI diagnostic metadata for direct and transitive findings, including more precise reachability slicing and ordered hop sequences.
  • Tests

    • Strengthened DI bridge assertions to validate exact reachability trace content and SARIF code-flow outputs.
    • Updated the test runner to run the added diagnostics suite and factor its result into the overall exit status.

The reachability-slice follow-up to PR #118, now that the evidence builders
(ownlang/evidence.py) are on main: wire them through the OwnIR SARIF path and
run the diagnostics tests in CI.

- ownlang/ownir.py: Finding gains an ordered `flow` field; _sarif_result emits
  it as a SARIF `codeFlows` (the step-through retention trace relatedLocations
  cannot express); _di_findings builds each DI001-005 flow from the captive's
  dependency `path` and a name->registration-site map via evidence.di_path_steps.
  A DI captive now ships both its consuming-ctor relatedLocation AND the ordered
  singleton -> [transient ->]* scoped retention slice.
- tests/test_ownir.py: assert the EmailSender direct (2-hop) and ReportService
  transitive (3-hop, transient pass-through) codeFlows, on top of the existing
  relatedLocations checks (now 151 bridge checks).
- tests/run_tests.py: fold tests/test_diagnostics.py (added in #118 but not yet
  aggregated) into the suite so the empty-evidence invariant and slice ordering
  run in CI.

Local: full suite green (ownir 151/151, diagnostics PASS), ruff + mypy --strict clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkpSWNx7ARLpQeAs13kkyA

Copy link
Copy Markdown
Owner Author

Reviewer orientation

Follow-up to #118 — turns the now-merged evidence builders into live SARIF output.

The payload: a DI captive's SARIF result now carries codeFlows, the ordered retention path. Concretely, for the fixture's EmailSender (direct) and ReportService (transitive through a transient):

ReportService (Startup.cs:15, captor)
  → via 'UnitOfWork'      (Startup.cs:16, transient pass-through)
    → captures scoped service 'AppDbContext' (Startup.cs:13)

Where to look: ownlang/ownir.py — the flow field on Finding, the codeFlows splice in _sarif_result, and loc_by_name + the di_path_steps(...) calls in _di_findings.

Verified locally (against a checkout, which is why this could land vs. #118's deferral): python tests/run_tests.py green (ownir: 151/151, diagnostics: PASS), ruff check . clean, mypy clean. Purely additive — relatedLocations and every existing SARIF field are unchanged; codeFlows only appears on findings that carry a path.


Generated by Claude Code

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 2c0761ba-bedf-4ca0-9a16-4811645c7fc3

📥 Commits

Reviewing files that changed from the base of the PR and between cbe1646 and 6c3aa4f.

📒 Files selected for processing (1)
  • tests/test_ownir.py

📝 Walkthrough

Walkthrough

The PR threads ordered DI reachability traces through findings, emits SARIF codeFlows from those traces, extends DI finding generation with path steps, and adds regression coverage plus diagnostics suite execution.

Changes

DI reachability flow plumbing

Layer / File(s) Summary
Flow contract and SARIF output
ownlang/ownir.py
Finding adds ordered flow data, and SARIF emits codeFlows when flow data is present.
DI finding flow population
ownlang/ownir.py
_di_findings builds registration lookups and assigns di_path_steps(...) flows to DI001 through DI005 findings.
Diagnostics regressions
tests/run_tests.py, tests/test_ownir.py
The test runner includes test_diagnostics, and the ownir tests assert DI001 through DI005 flow tuples plus the exported SARIF thread-flow lines.

Sequence Diagram(s)

sequenceDiagram
  participant _di_findings
  participant Finding
  participant code_flow
  participant SARIF_result
  _di_findings->>Finding: set flow steps
  Finding->>code_flow: flow tuple
  code_flow->>SARIF_result: codeFlows
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • PhysShell/Own.NET#118: Introduced di_path_steps and code_flow, which this PR uses to populate Finding.flow and SARIF codeFlows.
  • PhysShell/Own.NET#107: Extends the same DI finding emission pipeline for DI005, which this PR now annotates with flow steps.
  • PhysShell/Own.NET#65: Touches the DI004 pipeline that this PR extends with ordered reachability flow data and related tests.

Poem

I’m a rabbit with a tracing nose,
through DI hops, the path just glows.
Steps in order, neat and bright,
SARIF twinkles in the night.
🐇

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: DI captive codeFlows emission and adding diagnostics tests to the suite.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/p015-codeflows-wiring

Comment @coderabbitai help to get the list of available commands.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{}

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

🧹 Nitpick comments (1)
tests/test_ownir.py (1)

824-833: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Consider adding flow/codeFlows coverage for DI002–DI005.

The PR wires flow=di_path_steps(...) into DI002, DI003, DI004, and DI005 findings, but the new regression assertions only pin DI001 (em/rs). The other four families—particularly DI004/DI005, where the finding anchors at the call/store site while the flow begins at the registration site—now emit codeFlows with no test guarding the ordering or the per-family end_label ("weakly captures scoped service", "leaks transient IDisposable", "caches scoped service"). A regression there would slip through.

Want me to draft flow assertions for the existing DI002–DI005 bridge fixtures?

🤖 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 824 - 833, Add regression coverage for the
remaining DI finding families in the existing ownir tests, not just DI001.
Extend the assertions around the fixture checks that exercise DI002, DI003,
DI004, and DI005 so they validate the full flow/codeFlows shape produced by
di_path_steps, including the correct step ordering and family-specific end_label
values such as “weakly captures scoped service”, “leaks transient IDisposable”,
and “caches scoped service”. Use the existing finding lookups in the test block
near the DI001 assertion as the place to mirror the same flow validation for
each component family.
🤖 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.

Nitpick comments:
In `@tests/test_ownir.py`:
- Around line 824-833: Add regression coverage for the remaining DI finding
families in the existing ownir tests, not just DI001. Extend the assertions
around the fixture checks that exercise DI002, DI003, DI004, and DI005 so they
validate the full flow/codeFlows shape produced by di_path_steps, including the
correct step ordering and family-specific end_label values such as “weakly
captures scoped service”, “leaks transient IDisposable”, and “caches scoped
service”. Use the existing finding lookups in the test block near the DI001
assertion as the place to mirror the same flow validation for each component
family.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 864edf07-d91a-4ce6-97f7-64a08a988730

📥 Commits

Reviewing files that changed from the base of the PR and between 4f18cb7 and cbe1646.

📒 Files selected for processing (3)
  • ownlang/ownir.py
  • tests/run_tests.py
  • tests/test_ownir.py

The wiring added a flow to every DI family but the tests only pinned DI001.
Assert the full reachability slice for DI002 (weak captive), DI003 (transient
IDisposable), DI004 (service-locator) and DI005 (scope-cached) bridge fixtures:
each ends with its family-specific end_label, and DI004/DI005 explicitly pin the
invariant that the slice begins at the REGISTRATION site even though the finding
anchors at the call/store site.

ownir bridge checks: 157/157. ruff + mypy --strict clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkpSWNx7ARLpQeAs13kkyA
@PhysShell
PhysShell merged commit f4fc42d into main Jun 26, 2026
26 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