Skip to content

[RFC #2] Extension-point catalogue for v12 SDK #98

Description

@ChrisonSimtian

RFC #2 — Extension-point catalogue for v12 SDK

Self-RFC. The starter catalogue below is what we'll ship in Fallout.Plugin.Sdk 1.0 unless this discussion adds or removes points.

Context

The SDK exposes a closed set of extension points — surfaces plugins contribute to. Each becomes a public, additive-only contract for the SDK's lifetime. Too few and the SDK is useless; too many and we lock in shapes we haven't validated.

Proposed starter catalogue

Extension point What plugins contribute Maps onto today's...
IBuildMiddleware A handler that runs in one build phase (Initializing / DiscoveringTargets / Planning / Executing / Reporting). The 23 init-pipeline attributes ([InjectParameterValues] etc.).
IHost + IHostDetector A CI host adapter. Detector checks the environment; host emits CI-specific metadata. TeamCity, AzurePipelines, GitHubActions, etc. derived from Host.
IParameterSource Resolves [Parameter]-style values from a custom source (Vault, 1Password, env, args, parameter files). ParameterService reflection logic.
IToolWrapperContribution Registers a new *Tasks static facade for third-party tool wrappers. The 62 first-party tool wrappers in Fallout.Common.Tools.*.
ITargetLifecycleListener Lifecycle callbacks (target running / succeeded / failed / build finished). IOnTargetRunning, IOnTargetSucceeded, etc. (the IBuildExtension hooks).
IOutputSink Receives structured output events for logging, telemetry, or external observability. Serilog enricher hooks.

Why this list

These six unify the four existing extensibility surfaces (lifecycle hooks, component interfaces, CI hosts, tool wrappers) into one coherent set. Each is something a contributor can plausibly ship in a plugin, and each already has a first-party implementation as the reference — nothing speculative.

Component interfaces (ICompile, IPack, etc.) are not in the catalogue: they're public interfaces with default members, and plugins can declare their own (IDeployTerraform) without registering anything. The catalogue is for things that need DI registration to take effect.

Explicit non-starters (for v12)

  • ITargetFactory — plugins replacing target discovery. Too much rope; defer to v13+.
  • IBuildStatePersistence — plugins replacing the resume-file mechanism. Internal-only.
  • IFileSystem / IProcessRunner / IConsoleHost — plugins can consume these but not contribute alternatives.
  • Source-generator plugins — contributors can ship their own source generators alongside their package (.NET supports this directly); the SDK has no special API for them.

Questions for discussion

  1. Is IOutputSink the right shape, or should logging run through Serilog's existing sinks? Default: ship IOutputSink as a thin, easy-to-register wrapper, but also let plugins register Serilog sinks directly via builder.Services. Disagree?
  2. A single IPlugin-level catch-all (like VS's IVsPackage) for things we forgot? Default: no — a back-door defeats a closed catalogue. Add a real extension point when the use case shows up.
  3. Anything missing that a plausible v12 plugin would need? Comment with the use case.

Out of scope (other RFCs)

How to engage

Comment with use cases for missing extension points. "I want to ship a plugin that does X" is the most useful framing — if X needs an extension point we don't have, that's signal.

Decision lands in

When this RFC locks (2026-08-31), the catalogue becomes the spec for the SDK-6 series:

Metadata

Metadata

Assignees

No one assigned

    Labels

    RFCDesign discussion / RFC. Comment with feedback; consensus shapes the implementation.target/vNextTargets the next calendar-version

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions