You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A lightweight harness build of the core today still carries everything: workflows/flows, skills, MCP, meet, webviews/channels, web3/wallet, voice, media generation, and ~130 other domains. Two costs:
Runtime bloat — build_registered_controllers() in src/core/all.rs unconditionally registers every domain's controllers; the agent tool surface, store init, and bus subscribers follow. Even ServiceSet::none() (from feat(core): add pluggable core runtime and fleet host #4791) only skips background services — the full RPC/tool surface still initializes. A harness that wants "agent loop + memory + threads" pays for all of it: startup time, memory, tool-surface/prompt bloat, attack surface.
Compile-time bloat — every domain compiles into every binary. Cargo [features] today only cover leaf concerns (tokenjuice-treesitter, sandbox-*, whatsapp-web, e2e-test-support), not subsystem families. Embedders (examples/embed_headless.rs, openhuman-fleet, stdio-MCP hosts) can't build a slim core.
Approach
Group subsystems behind per-family feature gates, one tracked issue per gate (linked below). Each gate spans two layers:
Cargo feature (compile-time): sheds the domain's crates/deps from the build. Default-on — the Tauri desktop app always builds with all gates enabled; shipped product is unchanged.
DomainSet flag (runtime): a selector on CoreBuilder (src/core/runtime/builder.rs) next to ServiceSet, so embedders can further narrow at runtime what was compiled in. DomainSet::full() is the default; DomainSet::harness() = agent + memory + threads + config + security only.
Effects of a disabled gate: controllers not registered (unknown-method over RPC), agent tools absent, stores not initialized, bus subscribers not registered, /schema reflects the actual surface.
The clean seam is the phase-2 DomainRegistration collapse already planned in docs/plans/pluggable-core/README.md — once each domain registers via a single DomainRegistration entry (controllers + tools + stores + subscribers), gating is one filter over that list instead of scattered ifs.
Per-gate definition of done (applies to every child issue)
Cargo feature added to root Cargo.toml, in default; Tauri shell builds unchanged with all gates on.
DomainSet flag wired through registration, store init, and subscriber registration.
E2E with gate enabled: full existing suites pass unchanged.
E2E with gate disabled: build compiles, core boots and serves /rpc, /schema omits the gated namespaces, gated RPC methods return unknown-method, agent tool list omits gated tools.
CI smoke covering the disabled combination (e.g. matrix cargo check/boot-test with the gate off).
docs/plans/pluggable-core/phase-2-corecontext.md — the DomainRegistration collapse is the prerequisite seam; this effort is a strong argument for prioritizing it.
Problem
A lightweight harness build of the core today still carries everything: workflows/flows, skills, MCP, meet, webviews/channels, web3/wallet, voice, media generation, and ~130 other domains. Two costs:
build_registered_controllers()insrc/core/all.rsunconditionally registers every domain's controllers; the agent tool surface, store init, and bus subscribers follow. EvenServiceSet::none()(from feat(core): add pluggable core runtime and fleet host #4791) only skips background services — the full RPC/tool surface still initializes. A harness that wants "agent loop + memory + threads" pays for all of it: startup time, memory, tool-surface/prompt bloat, attack surface.[features]today only cover leaf concerns (tokenjuice-treesitter,sandbox-*,whatsapp-web,e2e-test-support), not subsystem families. Embedders (examples/embed_headless.rs,openhuman-fleet, stdio-MCP hosts) can't build a slim core.Approach
Group subsystems behind per-family feature gates, one tracked issue per gate (linked below). Each gate spans two layers:
DomainSetflag (runtime): a selector onCoreBuilder(src/core/runtime/builder.rs) next toServiceSet, so embedders can further narrow at runtime what was compiled in.DomainSet::full()is the default;DomainSet::harness()= agent + memory + threads + config + security only.Effects of a disabled gate: controllers not registered (unknown-method over RPC), agent tools absent, stores not initialized, bus subscribers not registered,
/schemareflects the actual surface.The clean seam is the phase-2
DomainRegistrationcollapse already planned indocs/plans/pluggable-core/README.md— once each domain registers via a singleDomainRegistrationentry (controllers + tools + stores + subscribers), gating is one filter over that list instead of scatteredifs.Per-gate definition of done (applies to every child issue)
Cargo.toml, indefault; Tauri shell builds unchanged with all gates on.DomainSetflag wired through registration, store init, and subscriber registration./rpc,/schemaomits the gated namespaces, gated RPC methods return unknown-method, agent tool list omits gated tools.cargo check/boot-test with the gate off).Child issues
DomainSetonCoreBuilder+DomainRegistrationfilter seam (prerequisite) — PR feat(core): runtime DomainSet composition axis — group-tagged registry + ambient filter (#4796) #4808 (merged)Non-goals
SecurityPolicyremain the per-user control).ServiceSet— orthogonal axes:ServiceSet= what runs in the background;DomainSet= what exists at all.Relationship to existing work
CoreBuilder/CoreRuntime/ServiceSet, fleet host) — this is the missing second axis of that composition story.docs/plans/pluggable-core/phase-2-corecontext.md— theDomainRegistrationcollapse is the prerequisite seam; this effort is a strong argument for prioritizing it.