You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
codegen: the emitter's one reflection site (IsClrTypeGenericInNamespace) spells a CLR type by resolving it at emit time against FrameworkOnly while semantic analysis resolved it against the registry — Rule-2 cell, no materialized fact #2320
Contract (CLAUDE.md Rule 2): the RoslynEmitter makes no type decision and performs no reflection; every fact it reads is materialized in semantic analysis (Symbol.CodeGenInfo or a node-keyed SemanticInfo carrier). RoslynEmitter.IsClrTypeGenericInNamespace (src/Sharpy.Compiler/CodeGen/RoslynEmitter.CompilationUnit.cs:588 @ 045ce6b) is the emitter's one remaining reflection site: it decides how to spell a type name (Sharpy.IList vs System.Collections.Generic.IList<T>) by resolving {namespace}.{name}`` {1..4}` through reflection at emit time.
reflection in CodeGen; its comment says "Rule-2 cell (#2250 findings ledger; no tracker yet)" — a known defect comment with no issue (Rule 8)
a materialized fact; no reflection in CodeGen
2
which world it asks (P54 seam divergence, code-read by the class-cure auditor)
since 333de07 the site asks AssemblyVisibility.FrameworkOnly (the shared framework + Sharpy.Core — a process constant, so the P54 contract holds); semantic analysis answers the same question from the compilation's registry visibility ({framework} ∪ {this registry's references}). Its caller IsNetFrameworkNamespace admits any System.*/Microsoft.* namespace, so for a referenced non-framework package in such a namespace (e.g. -r System.Reactive.dll, System.Reactive.Linq) the semantic side sees the generic type and the emitter does not — the two halves of one decision read two different sets
one decision, made once, in semantic analysis
Lane ice (a mismatched spelling surfaces as SPY0908 behind the C# compiler, if it surfaces at all), reach probe (needs a referenced package in a System.*/Microsoft.* namespace whose generic type is spelled through this arm — no program-level repro recorded; cell 2 is code-read).
Acceptance
The spelling decision is recorded on the type symbol's CodeGenInfo (or a node-keyed carrier merged in SemanticInfo.MergeFrom) during semantic analysis, computed from the registry's visibility; IsClrTypeGenericInNamespace and the FrameworkOnly read in CodeGen are deleted.
EmitterCarrierOnlyConformanceTests / ProcessWideResolutionScanTests ratchet the site out (the scan's src/Sharpy.Compiler census drops by one; the emitter names no Discovery.AssemblyVisibility).
A program with a referenced package generic in a System.* namespace prints the same under run before and after (direction record), and a mutation that re-reads FrameworkOnly in the emitter is red.
Found by the P54 (#2250) plan's own trackers list ("Rule-2 emitter reflection: no open tracker — the lead files ONE class issue") and confirmed by the /verify-implementation class-cure auditor @ 045ce6b.
Batching 2026-10-15 @ f8c37f9 — charter .claude/plans/remediation-round-2026-09-20-batching.md §3.0, chore (same band as #2261 part 2, #2311, #2313 cell 0; rides P21e's gate). Ruling R-HM (owner, 2026-10-15): (a) a chore — the emitter's one remaining reflection site becomes a materialized fact.
Internals (read @ f8c37f9): RoslynEmitter.CompilationUnit.cs:588IsClrTypeGenericInNamespace resolves {ns}.{name}`1..4 against AssemblyVisibility.FrameworkOnly to skip a using alias of an open generic (CS0305); its one caller (:510) sits under IsNetFrameworkNamespace (:546), which admits any System.*/Microsoft.* module name, so a referenced package in such a namespace is visible to the checker (registry visibility) and invisible here. Mechanism: one symbol-keyed fact on the imported type symbol's CodeGenInfo ("is an open generic definition"), computed from the registry's visibility in semantic analysis and frozen at MaterializeCodeGenInfo; the method and the FrameworkOnly read are deleted. Guard: EmitterCarrierOnlyConformanceTests / ProcessWideResolutionScanTests drop one census entry (the emitter names no Discovery.AssemblyVisibility); direction record on a program importing a referenced System.*-namespace generic by name (prints the same before and after); mutation (re-read FrameworkOnly in the emitter → red). Semantic + CodeGen → a whole-solution gate; seam-free against P21e. Rejected: (b) a P26 cell (~20 groups out; no layout change rides on this fact). Two-way. Lane / reach: ice · probe. Class tracker: this issue.
Landed (chores band 2026-10-22) on dev @ 4d22212, PR #2346 to mainline. Whole-solution gate 81669/0/7 @ 4d22212 (measured), against 81093/0/7 @ be4664e.
Commit f6cf5c9 (R-HM a).CodeGenInfo.IsOpenGenericDefinition is recorded by CodeGenInfoComputer.ProcessFromImport. It is computed against the registry's own visibility, framework plus references, and freezes at MaterializeCodeGenInfo. The emitter's IsClrTypeGenericInNamespace, its AssemblyVisibility.FrameworkOnly read and the TODO are deleted. SemanticBinding.MergeFrom carries the fact onto as-aliased imports.
Premise correction. Neither EmitterCarrierOnlyConformanceTests nor ProcessWideResolutionScanTests had a census entry for this site, so there was nothing to ratchet out. The new guard is EmitterCarrierOnlyConformanceTests.CodeGenSources_NameNoClrVisibilitySeam. It denies CodeGen every Discovery type that is or carries AssemblyVisibility, derived by reflection, with a synthetic positive and negative control.
Mutation: the emitter re-reading FrameworkOnly turned 1 row red.
Direction: framework imports print the same and the generated C# is byte-identical. A referenced System.Widgets prints the same, and the only C# change is that using Box = …Box; is no longer emitted, because the framework-only read missed Box<T>.
Activity
test(conformance): the P54 ratchets cite an issue by number, not the c…
antonsynd commentedon Oct 15, 2026
Batching 2026-10-15 @ f8c37f9 — charter
.claude/plans/remediation-round-2026-09-20-batching.md§3.0, chore (same band as #2261 part 2, #2311, #2313 cell 0; rides P21e's gate). Ruling R-HM (owner, 2026-10-15): (a) a chore — the emitter's one remaining reflection site becomes a materialized fact.Internals (read @ f8c37f9):
RoslynEmitter.CompilationUnit.cs:588IsClrTypeGenericInNamespaceresolves{ns}.{name}`1..4 againstAssemblyVisibility.FrameworkOnlyto skip ausingalias of an open generic (CS0305); its one caller (:510) sits underIsNetFrameworkNamespace(:546), which admits anySystem.*/Microsoft.*module name, so a referenced package in such a namespace is visible to the checker (registry visibility) and invisible here. Mechanism: one symbol-keyed fact on the imported type symbol'sCodeGenInfo("is an open generic definition"), computed from the registry's visibility in semantic analysis and frozen atMaterializeCodeGenInfo; the method and theFrameworkOnlyread are deleted. Guard:EmitterCarrierOnlyConformanceTests/ProcessWideResolutionScanTestsdrop one census entry (the emitter names noDiscovery.AssemblyVisibility); direction record on a program importing a referencedSystem.*-namespace generic by name (prints the same before and after); mutation (re-readFrameworkOnlyin the emitter → red). Semantic + CodeGen → a whole-solution gate; seam-free against P21e. Rejected: (b) a P26 cell (~20 groups out; no layout change rides on this fact). Two-way. Lane / reach: ice · probe. Class tracker: this issue.refactor(codegen): the emitter performs no reflection — whether an im…
antonsynd commentedon Oct 22, 2026
Landed (chores band 2026-10-22) on
dev@ 4d22212, PR #2346 to mainline. Whole-solution gate 81669/0/7 @ 4d22212 (measured), against 81093/0/7 @ be4664e.Commit f6cf5c9 (R-HM a).
CodeGenInfo.IsOpenGenericDefinitionis recorded byCodeGenInfoComputer.ProcessFromImport. It is computed against the registry's own visibility, framework plus references, and freezes atMaterializeCodeGenInfo. The emitter'sIsClrTypeGenericInNamespace, itsAssemblyVisibility.FrameworkOnlyread and the TODO are deleted.SemanticBinding.MergeFromcarries the fact ontoas-aliased imports.Premise correction. Neither
EmitterCarrierOnlyConformanceTestsnorProcessWideResolutionScanTestshad a census entry for this site, so there was nothing to ratchet out. The new guard isEmitterCarrierOnlyConformanceTests.CodeGenSources_NameNoClrVisibilitySeam. It denies CodeGen every Discovery type that is or carriesAssemblyVisibility, derived by reflection, with a synthetic positive and negative control.Matrix:
OpenGenericImportAliasTests, visibility {framework, referenced} × spelling {bare,as} × name {generic arity group, non-generic}.Mutation: the emitter re-reading
FrameworkOnlyturned 1 row red.Direction: framework imports print the same and the generated C# is byte-identical. A referenced
System.Widgetsprints the same, and the only C# change is thatusing Box = …Box;is no longer emitted, because the framework-only read missedBox<T>.Every acceptance bullet is met. Closing.
Merge pull request #2346 from antonsynd/dev