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
- 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?
- 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.
- 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:
RFC #2 — Extension-point catalogue for v12 SDK
Self-RFC. The starter catalogue below is what we'll ship in
Fallout.Plugin.Sdk1.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
IBuildMiddleware[InjectParameterValues]etc.).IHost+IHostDetectorTeamCity,AzurePipelines,GitHubActions, etc. derived fromHost.IParameterSource[Parameter]-style values from a custom source (Vault, 1Password, env, args, parameter files).ParameterServicereflection logic.IToolWrapperContribution*Tasksstatic facade for third-party tool wrappers.Fallout.Common.Tools.*.ITargetLifecycleListenerIOnTargetRunning,IOnTargetSucceeded, etc. (theIBuildExtensionhooks).IOutputSinkWhy 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.Questions for discussion
IOutputSinkthe right shape, or should logging run through Serilog's existing sinks? Default: shipIOutputSinkas a thin, easy-to-register wrapper, but also let plugins register Serilog sinks directly viabuilder.Services. Disagree?IPlugin-level catch-all (like VS'sIVsPackage) for things we forgot? Default: no — a back-door defeats a closed catalogue. Add a real extension point when the use case shows up.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: