Skip to content

No check project compiles Runtime/Integrations, so no WUH rule has ever run there #687

Description

Runtime/Integrations/** — 19 files across Reflex, VContainer and Zenject — is excluded from every Generator~ check project. TypeCheck names the exclusion explicitly ($(RepoRoot)/Runtime/Integrations/**/*.cs), and EditorCheck, TestCheck and EditorTestCheck inherit it. So the shipped analyzers have never run over that tree.

That is not a theoretical gap. Four files carried the same rule-7 violation until #644's audit:

AttributeMetadataCache cache = _metadataCache ?? AttributeMetadataCache.Instance;
if (cache == null) { return; }

AttributeMetadataCache is a ScriptableObject. ?? is a CLR-null test, so a destroyed injected instance is not replaced by the live Instance — it is passed through, and the very next line's Unity == then reads it as null and returns. VContainer's RelationalSceneLoadListener and Zenject's RelationalComponentSceneInitializer bail there: every relational field in that scene stays null, with no log. WUH003 reports exactly this shape, and it never saw the file. The correct form was two lines away in RelationalComponentAssigner the whole time.

The four sites are fixed. This issue is the reason they could exist.

Why the exclusion is there

Each integration asmdef is gated on a third-party DI package define, and none of the three ships a NuGet package a check project could reference. That is the same situation Odin was in, and #347 solved it the same way it needs solving here: a shim declaring only the base classes and interfaces the package's own sources alias.

What would close this

  • Enumerate the external surface each integration binds. Measured today: Reflex.Core, Reflex.Extensions, Reflex.Injectors, Reflex.Enums; VContainer, VContainer.Unity; Zenject. 19 files total, so the surface is small.
  • Add shims under a new check project (or a fourth configuration of an existing one), declaring only what those files name — the Odin shim is the precedent for how narrow that can be.
  • Load both analyzer DLLs, as every other check project does, so WPROTO### and WUH### both fire.
  • Add the new project to scripts/typecheck-controls.js, with an anchor type from Runtime/Integrations/**, so the gate is proven able to fail over that tree rather than merely added.
  • Extend lint-typecheck-asmdef-references and its --probe leg to the new project.

Alternative, if the shims prove too costly

A source linter cannot answer this: the analyzer's own documentation records why the signal has to be the receiver's type, because Vector2? p; p?.x is correct and common. So the choice is the shims or an explicit, recorded decision that this tree is unanalyzed — in which case the decision belongs in .llm/context.md beside rule 7, so the next author knows the rule is unenforced exactly there.

Related: #644, #347, #598.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingchoreci

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions