Rulebearing Playground Coverage Schemas GitHub

ADR-0061: A type is attributed to a file its developer wrote; a source generator's output under obj/ only when the type is in no other

Context

Compiled mode gives every type one file, and the type's own dependencies (its base class, the interfaces it implements, its fields' and attributes' types) become that file's edges. ADR-0011 takes the file from the portable PDB: Roslyn's TypeDefinitionDocuments record when there is one, else the document of the type's first constructor, else the first sequence point of any of its methods.

A partial type can be split between a file its developer wrote and a file a source generator wrote. Roslyn records a generator's output under the project's intermediate folder, for example Src/Melville.Pdf.LowLevel/obj/Release/net10.0/Melville.Generators.INPC/<generator>/ComputeOwnerPasswordV3.4E021623.g.cs. A singleton generator writes the type's constructor there, so the constructor rule picks the generated file. In that case ComputeOwnerPasswordV3 : ComputeOwnerPasswordV2, written in ComputeOwnerPasswordV3.cs, has no edge to its base class from that file. The edge comes from the generated file instead, which no path rule over the source tree names.

The nightly found it. Source mode's precision against compiled mode on DrJohnMelville/Pdf was 70.75% on every night from 2026-10-03 to 2026-10-08, against the 90% target of plan 0003, Step 14. In that graph 208 of 777 modules were files under obj/. Source mode never reads obj/, since discovery skips it as build output, so every edge compiled mode credited there was one source mode could not agree with.

Decision

A type is attributed to a file someone wrote whenever the PDB names one. The candidates keep ADR-0011's order: the documents of TypeDefinitionDocuments, then the constructor's document, then each method's first point. The first candidate outside build output is taken. A document is build output when its path passes through a folder discovery never searches (bin, obj, artifacts, node_modules, .git, .vs). One list decides both what discovery reads and what attribution avoids.

A type only a generator declares keeps the generated file. When every candidate is build output, the first one is taken, as before. The type is still attributed by the PDB (attribution: pdb), and its edges are still in the graph.

Method bodies are not moved. An edge that comes from code a generator wrote stays in the generated file's module, because that is where the code is.

Consequences

Alternatives considered