Skip to content

M2 decision: DynamicProxyGenAssembly2 InternalsVisibleTo — keep as recorded mechanism or replace the seam (N1) #25

Closed

Description

@Blind-Striker

Source: multi-agent review of PR #16, UNVERIFIED-FINDER. 2026-08-13. M-anchor: M2 (decide once, cheap either way). Maintainer decision — recommendation below is to close as-is.

src/OpenCode.Sdk/Properties/AssemblyInfo.cs:5-6 declares [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] so PipelineTests can Substitute.For<IEnvironmentProvider>() (internal seam). The review notes AGENTS.md's "fake only published contracts" posture and that the friend grant exposes all internals to any DynamicProxy user in-process.

Recommendation: keep, close. This is a solved-once, deliberately recorded mechanism in this repo (NSubstitute over internal seams requires the DynamicProxy friend; paired with PolyUseEmbeddedAttribute=true to avoid CS0121 in friend assemblies). Reopening a recorded decision needs new evidence, and "a hostile in-process DynamicProxy user" is not a threat model for an SDK consumer process. If the maintainer prefers encapsulation purity anyway, the alternative is a hand-written internal fake for IEnvironmentProvider (named test collaborator), dropping the friend attribute — small, but trades away NSubstitute ergonomics for every future internal seam. Do not remove the attribute before an approved replacement seam exists (verifier's own caveat).

Activity

  1. Blind-Striker commented on Aug 14, 2026

    @Blind-Striker
    CollaboratorAuthor

    Maintainer decision: keep, close. The DynamicProxyGenAssembly2 friend grant is the standard NSubstitute/Castle mechanism for mocking internal seams (IEnvironmentProvider) and is a deliberately recorded solved-once mechanism in this repo, paired with PolyUseEmbeddedAttribute against CS0121. Internals are not a security boundary (reflection reaches them regardless), and a hostile in-process DynamicProxy user is not a threat model for an SDK consumer process. If encapsulation purity is ever preferred, the recorded alternative is a hand-written internal fake replacing the friend attribute — to be done only after that replacement seam exists.

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

    needs-triageMaintainer needs to evaluate this issueready-for-humanRequires human implementation or decision

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions