Skip to content

Commit ad17d7b

Browse files
authored
Merge pull request #419 from PhysShell/research/p014-reference-coverage
docs(evidence): P-014 reference coverage — GO-P014-BOUNDED-DESIGN / NO-PRODUCTION (research only)
2 parents c6e8a3c + f24f32e commit ad17d7b

41 files changed

Lines changed: 3070 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# P-014 reference-resolution coverage — pre-registration
2+
3+
Written 2026-10-21 04:45 +05, before any measuring run. Budget: 0.25 agent-day to the first GO/KILL decision,
4+
counted from 04:37. Not extended.
5+
6+
## 0. Current state, checked in code (`main` `c6e8a3c1`, `frontend/roslyn/OwnSharp.Extractor/Program.cs`)
7+
8+
| Claim | Verdict | Where |
9+
|---|---|---|
10+
| All inputs go into one `CSharpCompilation.Create("own", …)` with default options | confirmed | `:5983-5985` |
11+
| The framework set is the extractor **process's** `TRUSTED_PLATFORM_ASSEMBLIES`; the extractor targets `net8.0`, so on this host that is the Microsoft.NETCore.App **8.0.31 implementation**, not the target TFM's reference pack | confirmed | `:5889-5894`; `OwnSharp.Extractor.csproj:5` |
12+
| `--ref-dir` and the auto-added project `bin/` are loaded recursively, **first simple filename wins**, and any name already in TPA is skipped | confirmed | `:5911-5933`, `:536-547` |
13+
| No MSBuild evaluation: a `.csproj` is resolved by text to a source set | confirmed | `:276-292` |
14+
| No quantitative semantic-binding report; `--stats` counts flow-locals coverage only | confirmed | `:5993-5997` |
15+
| Also seen: trees are parsed with default `CSharpParseOptions`, with no preprocessor symbols; SDK implicit/global usings are not generated | confirmed | `:5867` |
16+
17+
The last row is a **source-set** effect, not a reference effect. It is measured separately (mode C) and never
18+
credited to references.
19+
20+
## 1. Inputs (fixed now; chosen by rule, not by expected gain)
21+
22+
**Rule.**
23+
1. Take every corpus repository that has a `project.assets.json` already on disk and whose sources are present:
24+
the 3 design-B sweep repositories that have one, plus the direction-research pairs whose assets list packages
25+
that all exist by id/version in the local global cache.
26+
2. From the sweep repositories take all 3. From the qualifying pairs take the 2 that are WPF/desktop
27+
applications (BB84.IPTV, FluentFlyout); the other qualifying ones are libraries (LiteDB, MarkView).
28+
3. In each repository take the largest non-test, non-sample project by `.cs` count.
29+
30+
| # | Project | SHA | Kind | TFM measured | Assets packages / present by id in global cache |
31+
|---|---|---|---|---|---|
32+
| P1 | Flow-Launcher/Flow.Launcher — `Flow.Launcher/Flow.Launcher.csproj` | `2efbf865` | WPF app, 3 project references | `net9.0-windows10.0.19041.0` | 165 / 89 |
33+
| P2 | git-ecosystem/git-credential-manager — `src/Core/Core.csproj` | `e66693fa` | library | `net10.0` | 37 / 17 |
34+
| P3 | nats-io/nats.net — `src/NATS.Client.JetStream/NATS.Client.JetStream.csproj` | `176e52bc` | multi-targeted library, 1 project reference | **`net8.0`** (fixed; of netstandard2.0/2.1/net8.0/net10.0) | 28 / 19 |
35+
| P4 | BoBoBaSs84/BB84.IPTV — `src/BB84.IPTV.M3U.Editor/BB84.IPTV.M3U.Editor.csproj` (pair #36 base) | `e9ab4f28` | desktop app, 3 project references | `net10.0` | 87 / 87 |
36+
| P5 | MERURUXD/FluentFlyout — `FluentFlyoutWPF/FluentFlyout.csproj` (pair #3 base) | `911dfda6` | WPF app | `net10.0-windows10.0.22000.0` (first listed) | 19 / 19 |
37+
38+
**Provenance of the artifacts** (recorded, not trusted):
39+
- **P1–P3.** The assets were written on 2026-10-17 between 17:22 and 17:30 by CodeQL buildless extraction. That
40+
is before the D13 isolation (2026-10-18). Their `packageFolders` (`codeqldb/working/packages`, the VS shared
41+
folder) no longer hold the packages.
42+
- **P4–P5.** The assets come from the isolated pair restores of 2026-10-18.
43+
- **Package hashes.** For **every** package of all five, the `sha512` in the assets differs from the
44+
`.nupkg.sha512` in the global cache. Same id and version, different package file. Package identity is therefore
45+
**not provable**, and every mode-B reference is labelled `APPROXIMATION`.
46+
47+
**Local SDK/TFM.**
48+
- Runtimes: NETCore.App 6.0.36 / 8.0.31 / 10.0.12; AspNetCore.App and WindowsDesktop.App 8.0.31 / 10.0.12.
49+
- Reference packs: Microsoft.NETCore.App.Ref, AspNetCore.App.Ref and WindowsDesktop.App.Ref 8.0.31 and 10.0.12;
50+
NETStandard.Library.Ref 2.1.0.
51+
- **There is no 9.0 reference pack**, so P1's exact TFM is `UNAVAILABLE_UNDER_D13`. P1's mode B uses the 10.0.12
52+
packs and is labelled `TFM-APPROX`.
53+
54+
## 2. Modes (one instrument, identical sources and options in every mode)
55+
56+
**Common to all modes.**
57+
- **Sources.** All `.cs` files under the project directory, excluding `bin`/`obj`, as the extractor's `.csproj`
58+
path resolves them. The list is written to disk once and used by every mode.
59+
- **Parse options.** `CSharpParseOptions.Default` (no defines), as the extractor uses.
60+
- **Compilation options.** `new CSharpCompilationOptions(DynamicallyLinkedLibrary)`.
61+
62+
| Mode | References |
63+
|---|---|
64+
| **A, current** | every DLL of `shared/Microsoft.NETCore.App/8.0.31`, i.e. the extractor process's TPA. Plus the project's `bin/` (absent in all five), first filename wins |
65+
| **B, project-specific (`APPROXIMATION`)** | the target TFM's reference pack(s): NETCore.App.Ref, plus AspNetCore/WindowsDesktop.App.Ref when the assets' `frameworkReferences` name them. Plus, for every package in `targets[<TFM>]`, its `compile` assets (excluding `_._`) from the global cache. A package missing from the cache is recorded, never substituted. No DLL from another TFM; no name-based replacement of a framework assembly |
66+
| **C, source-set probe (not part of A/B)** | A plus one generated file of the SDK default global usings for the project's SDK. It measures how much binding loss is source-set rather than reference |
67+
68+
Project-to-project references are not built, so in every mode their types bind only if the project's own sources
69+
declare them. This is recorded as a `source set` cause.
70+
71+
**R3 (extractor chain).** The unchanged extractor, built offline from `main` with packages from the local cache
72+
only. It runs with `--flow-locals`, as in `own-check`:
73+
74+
- **A-ext:** as shipped.
75+
- **B-ext:** `OWN_EXTRA_REF_DIRS` = the same framework reference packs as B, plus `--ref-dir` for each package
76+
`compile` folder of B.
77+
78+
The extractor keeps its TPA first, so B-ext is the best that **today's** extractor can be given, and it is not
79+
identical to B. Both are reported.
80+
- **Core:** the Python reference core (`python -m ownlang ownir`, the `own-check` default). No Rust core is built
81+
on this host, and building one needs cargo dependencies, so that is skipped.
82+
83+
## 3. Metrics (all with numerators and denominators)
84+
85+
Per project and mode:
86+
- **Method binding.** `InvocationExpressionSyntax` sites counted as resolved (`Symbol` non-null),
87+
ambiguous/candidates (`CandidateSymbols` > 0, `Symbol` null), or unresolved.
88+
- **Type binding.** `TypeSyntax` in declarations, `new`, base lists, parameters and fields, counted as resolved or
89+
`IErrorTypeSymbol`.
90+
- **Event binding.** `+=`/`-=` whose left side is a member access, counted as `IEventSymbol`, other symbol, or
91+
unresolved.
92+
- **Compiler errors** by code, with CS0012, CS0246, CS0234, CS1061, CS0103 and CS0117 broken out.
93+
- **R2, per site.** Every site whose status differs between A and B, recorded with file:line, expression, both
94+
statuses, `SymbolKind`, containing type, signature and containing assembly.
95+
96+
Classification:
97+
- `RECOVERED_CORRECT`;
98+
- `RECOVERED_WRONG`: B binds but to a symbol whose containing assembly is not the package or framework assembly
99+
that declares the named type, or A had a different symbol;
100+
- `STILL_UNRESOLVED`;
101+
- `AMBIGUOUS`;
102+
- `NOT_COMPARABLE`.
103+
104+
A fixed random sample of 10 `RECOVERED` sites per project (seed `20261021`) is checked by reading the code.
105+
- **Cause categories** for sites unresolved in A: fixed by B → `missing/mismatched reference`; fixed by C only →
106+
`source set (implicit usings)`; type declared in a referenced project → `source set (project reference)`;
107+
unresolved in all modes → `still unresolved` (unattributed). The B-vs-A difference attributable to TFM (8.0
108+
implementation vs target reference pack) is reported where B binds a framework-only member.
109+
- **R3.** Extractor stats, OwnIR fact counts by kind (`functions`, `subscriptions`, `services`, flow `acquire`,
110+
OWN050), and core findings by rule, for A-ext vs B-ext. Every finding change is listed and triaged as TP / FP /
111+
UNCLEAR by reading the code. A chain `reference → symbol → fact → diagnostic` is written for each change, and
112+
where it breaks, the break point is named, including #382-type lowering.
113+
114+
## 4. Controls (synthetic, in `controls/`, run through the same instrument; written before the first run)
115+
116+
| # | Control | Expected |
117+
|---|---|---|
118+
| K1 | sources and references already consistent (BCL only) | A == B, no site changes |
119+
| K2 | two emitted assemblies with the same filename `Lib.dll`, different identity/version, in two folders | A's first-filename-wins is recorded; B takes only the one its manifest names |
120+
| K3 | one package with `lib/net8.0` and `lib/netstandard2.0` | B uses only the TFM the manifest selects |
121+
| K4 | two source "projects" declaring the same FQN `Dup.T` | recorded as ambiguous/conflict, never `RECOVERED_CORRECT` |
122+
| K5 | an external `event` and an external `int` field, both used with `+=` | B binds the event as `IEventSymbol` and the field not as an event |
123+
| K6 | a type from an assembly that is not provided | unresolved in A and B; nothing invented |
124+
| K7 | `#if NET8_0 … #else … #endif` | both modes see the same branch (no defines); recorded as a source-set limit |
125+
126+
## 5. Decision (thresholds fixed now)
127+
128+
**`GO-P014-BOUNDED-DESIGN` only if all of the following hold:**
129+
1. **N1.** At least 2 independent projects show reference-caused binding loss in A, meaning sites fixed by B and
130+
not by C. The loss must be at least 5% of that project's invocation sites **and** at least 20 sites.
131+
2. **N3.** In each of those projects, at least 9 of the 10 sampled `RECOVERED` sites are `RECOVERED_CORRECT`.
132+
K1–K6 pass.
133+
3. **N4.** At least one triaged useful change in OwnIR facts or core findings, A-ext vs B-ext. That is: a new TP,
134+
or a removed FP, or an OWN050 replaced by a correct fact. A change in compiler diagnostics alone does not count.
135+
4. **N2 and cost.** B's references come from on-disk artifacts without any build, restore or MSBuild evaluation,
136+
and the cost of shipping them is bounded without `MSBuildWorkspace`.
137+
138+
**`KILL-P014-REFERENCE-INVESTMENT`** if any of:
139+
- fewer than 2 projects meet item 1;
140+
- recovered sites are wrong (item 2 fails), or a control fails;
141+
- the gain stops at compiler diagnostics (item 3 fails);
142+
- B needs a forbidden action;
143+
- the budget runs out.
144+
145+
**`INCONCLUSIVE-P014`** if item 1 holds for exactly one project and the reason the others cannot be measured is
146+
input availability (packages missing from the cache, or the TFM pack absent), not a measured null effect. The
147+
sample is not widened after the first run.

0 commit comments

Comments
 (0)