Fallout-build / Fallout-build/Fallout

[RFC #4] Plugin discovery and load model

Open
#100 1 comment 0 reactions 0 assignees View on GitHub
RFC target/vNext
Dominant language
C#
Stars
154
Forks
19
Avg merge
1d 22h
Merged PRs (30d)
15

Description

**RFC #4 — Plugin discovery and load model**

Self-RFC. Pins the runtime mechanics: how plugins get found, when they load, and what trust posture the host assumes.

## Context
RFC #97 fixes the contract (assembly attribute + `IFalloutPlugin`). This RFC fixes the mechanics — when the host looks for plugins, what happens if one is broken, and whether plugins run isolated or full-trust.

## Proposed model

### Discovery: opt-in via assembly attribute
At startup the host enumerates loaded assemblies and reads `[assembly: FalloutPlugin(typeof(...))]` from each. Only assemblies declaring the attribute incur scanning cost. No type-walking, no `GetAssemblies().SelectMany(a => a.GetTypes())` — the attribute is a single read.

### Load timing: before phase 1 (Initializing)
Discovery and `IFalloutPlugin.Configure(builder)` run **before** the orchestrator starts Initializing. The composition root is built and frozen before any middleware runs:
- Plugins can register middleware, hosts, parameter sources — anything the phases consume.
- Plugins cannot alter the composition root mid-build. (If runtime reconfiguration is ever needed, ship a new extension point; don't unfreeze the container.)

### Caching
Discovery results (assembly hash → plugin types) cache at `/.build/plugin-cache.json`. Cache key is the hash of every referenced assembly. Hits skip the attribute read; misses re-scan and update. Saves ~20–100ms on later builds.

### Trust model: same as Roslyn analyzers
Plugins run **in-process, full trust**. A malicious or buggy plugin can call `Environment.Exit(0)`, touch the filesystem, read env vars, make network calls — same as Roslyn analyzers, MSBuild SDKs, source generators. The right tradeoff:
- The user already added the plugin via `PackageReference` — a trust decision.
- In-process .NET sandboxing is hard and incomplete (`AppDomain`s deprecated; collectible `AssemblyLoadContext`s isolate lifetime, not capability).
- Out-of-process (subprocess per plugin) adds 10–100ms per call and breaks debugging.

The host documents this in the author guide and consumer FAQ. **No engineering around it.**

### Optional: collectible AssemblyLoadContext
If hot-reloading plugins in a long-running daemon ever matters, load each into a collectible `AssemblyLoadContext`. **Defer to a future RFC** unless someone surfaces the use case here.

### Error handling
- Attribute points at a type that doesn't implement `IFalloutPlugin` → throw at startup with the assembly + offending type name.
- `Configure` throws → throw, wrapping the inner exception with "plugin {name} failed to configure". Build stops.
- Plugin requires a newer `PluginApiVersion` than the host → throw with the version mismatch.

**Fail-fast rationale:** silently skipping a broken plugin produces "why doesn't my plugin work" tickets that are hard to debug. Loud, clear failure is kinder.

## Questions for discussion
1. Deterministic load order? Default: yes — alphabetical by package ID. Predictable beats clever. Disagree?
2. Load-order dependencies between plugins (`[FalloutPlugin(LoadAfter = "...")]`)? Default: no — extension points are unordered within a phase; cross-phase order is fixed. Need another plugin's services? Resolve via DI like any consumer.
3. Ship `dotnet fallout plugins list`? Default: yes, useful for debugging. Belongs in `Fallout.GlobalTool`.

## Out of scope (other RFCs)
- Plugin contract — RFC #97.
- Extension points — RFC #98.
- SDK versioning — RFC #99.
- Conflicts between plugins — RFC #101.

## How to engage
Use cases that *don't* fit this load model are most valuable. "I want plugin X to register a new tool wrapper at minute 3 of the build" tells us the freeze-after-Configure decision is wrong.

## Decision lands in
When this RFC locks (2026-08-31), its shape becomes the spec for:
- #148 — [SDK-3] Plugin discovery & load pipeline

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.