Skip to content

fix(trace-path): follow own-class calls and ignore test doubles - #138

Merged
spelech merged 1 commit into
mainfrom
fix/trace-path-same-class-and-test-doubles
Nov 12, 2026
Merged

spelech merged 1 commit into
mainfrom
fix/trace-path-same-class-and-test-doubles

Conversation

@spelech

@spelech spelech commented Nov 12, 2026

Copy link
Copy Markdown
Owner

Problem

With Code Mode on the real repository, a trace from ToolsController.PublishInstance did not reach ToolSuperRepository.GetToolAccessPreflight, the call that caused a real bug (a query outside the open transaction). A step-by-step trace showed three causes:

  1. Calls without a receiver stay bare. ToolService.PublishInstance calls GetByInstanceId(id, transaction), and ToolInstanceReader.GetByInstanceId calls GetAccessPreflightAsync(...). Both were stored as bare names, so the walk could not tell which class they meant.
  2. Test doubles count as implementations. IToolInstanceReader has one real implementation and fakes in the test project. With more than one implementation, the walk stopped at IToolInstanceReader.GetByInstanceId.
  3. Production code is linked to test code. transaction.Commit() (a var from BeginTransaction()) resolved to ToolExecutionAuthorizationTests.RecordingTransaction.Commit, because that fake is the only class with a Commit method in the index.

Fix

  • csharp_receiver_types.py: Method(...) and this.Method(...) are stored as OwnClass.Method when the enclosing type declares the method. Inherited methods and local functions stay bare.
  • graph_traversal.py: symbols in test code are marked. Classes in test code do not count as interface implementations. When the caller is production code, test candidates are dropped; if only test candidates match, the call stays unresolved.
  • route_specificity.is_test_route_file (the shared test-code check) also detects .NET test projects (App.Tests, App.Test) and folders such as Unit Tests, and file names that end in Test.cs.

C# repositories must be indexed again to get the own-class targets. The test-double rules work at query time.

Tests

tests/test_trace_path_own_class_and_test_doubles.py (4 tests; 3 fail on the old code): test-code detection, own-class and this. calls, an inherited method stays bare, and an end-to-end trace (controller → service → own method → reader through an interface with a fake → own preflight method → repository) that reaches the repository in both directions and contains no test classes.

🤖 Generated with Claude Code

A trace from ToolsController.PublishInstance stopped before the repository
call that caused a real bug, for three reasons:

- A C# call without a receiver (`GetByInstanceId(...)`, `this.Method()`) was
  stored as the bare method name, so the walk could not tell which class it
  meant. It is now stored as `OwnClass.Method` when the enclosing type
  declares that method.
- A fake that implements an interface in a test project counted as a second
  implementation, so `IToolInstanceReader.GetByInstanceId` did not map to
  `ToolInstanceReader.GetByInstanceId`. Test classes no longer count as
  implementations.
- Production code was linked to test code: `transaction.Commit()` resolved
  to a fake `RecordingTransaction.Commit` in a test project. When the caller
  is production code, test candidates are dropped; with only test candidates,
  the call stays unresolved.

Test-code detection now also covers .NET test projects (`App.Tests`) and
folders such as `Unit Tests`. C# repositories must be indexed again to get
the own-class targets.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@spelech
spelech merged commit 24a9b55 into main Nov 12, 2026
15 checks passed
@spelech
spelech deleted the fix/trace-path-same-class-and-test-doubles branch November 12, 2026 22:34
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.

1 participant