Skip to content

runtime: let a preset carry extensions and pre-built backends#444

Open
mfw78 wants to merge 1 commit into
feat/m2-registry-servicefrom
feat/m2-preset-launch-surface
Open

runtime: let a preset carry extensions and pre-built backends#444
mfw78 wants to merge 1 commit into
feat/m2-registry-servicefrom
feat/m2-preset-launch-surface

Conversation

@mfw78

@mfw78 mfw78 commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

What

Widens the Runtime preset trait: components/add_ons take self/&self instead of being static, and a new extensions() hook (default empty) lets a preset supply linker extensions. RuntimeBuilder::with_runtime binds a preset by value; runtime::<R>() stays as sugar over it for R: Default. PresetBuilder::launch gathers the presets extensions ahead of any appended via with_extensions, then builds components from the (now consuming) preset.

Why

The preset trait could not express a domain preset that also needs a linker Extension, or hand back an already-built instance (e.g. mock backends), so both paths bypassed runtime::<R>() and wired assembly by hand. This closes the trait-surface gap without a marker-vs-value split beyond runtime/with_runtime.

Testing

  • preset_extensions_and_appended_extensions_both_link: a value-bound preset extension and an appended extension both reach the linker exactly once.
  • preset_hands_over_a_prebuilt_backend: components(self) carries a pre-built LogPipeline through unchanged.

AI Assistance

Implemented with Claude Code assistance.

Closes #273

@lgahdl lgahdl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked whether this closes the preset-unreachability gap flagged on #442 (with_logs/with_chain/with_store unreachable through preset-based callers). It's only half-closed:

  • A preset author can now pre-load a Prebuilt backend inside their own Runtime::components(self) impl (the new PrebuiltLogsPreset test demonstrates this well). But an external caller holding a stock preset (e.g. CoreRuntime) still has no hook to override that preset's chain/store/logs before .launch()PresetBuilder::launch (builder.rs:109) still does self.preset.components().build(...) inline with nothing exposed in between to intercept. The test harness still bypasses PresetBuilder entirely via the manual TypedBuilder chain, for exactly this reason, and this PR doesn't change that. Might be worth scoping the PR body to "preset-authored pre-built backends" so it doesn't read as fully closing #442's gap.

  • builder.rs:98 — the doc comment promises the preset's extensions are gathered with appended ones "after," but there's no test for the case where the preset and an appended extension register the same namespace (only distinct namespaces alpha/beta are tested). If a caller appends an extension meaning to override a preset's built-in one for the same namespace, the resulting behavior (silent double-link, last-wins, or error) is undefined and untested.

Everything else — ownership of self.preset.components()/extensions()/add_ons(), the runtime::<R>() sugar over with_runtime — looks clean, no bugs found there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants