openclaw/src/extension-host/cutover-inventory.md
2026-03-15 23:15:26 +00:00

29 KiB

Extension Host Cutover Inventory

Date: 2026-03-15

Purpose

This document is the Phase 0 cutover inventory for the extension-host migration.

It tracks:

  • the current plugin-owned surfaces in the repo
  • where ownership lives today
  • where ownership should move
  • what has already moved
  • what is still blocked on later phases

This is an implementation checklist, not a future-design spec.

Status Legend

  • moved: the host owns the boundary now, with compatibility preserved
  • partial: host-owned types or views exist, but the legacy plugin path is still the active writer
  • compat-only: old surface still exists only to preserve callers while the host boundary takes over
  • not started: no meaningful migration has landed yet

Current Inventory

Surface Current implementation Target owner Status How it has been handled so far
Active runtime registry state src/plugins/runtime.ts plus global plugin runtime state src/extension-host/active-registry.ts moved Host-owned active registry exists; src/plugins/runtime.ts is now a compatibility facade.
Normalized extension descriptor model plugin manifests and package metadata interpreted ad hoc across src/plugins/manifest.ts, src/plugins/discovery.ts, src/plugins/install.ts src/extension-host/schema.ts partial ResolvedExtension, ResolvedContribution, and ContributionPolicy exist; current manifests project into them through compatibility adapters.
Resolved static registry flat rows in src/plugins/manifest-registry.ts src/extension-host/resolved-registry.ts partial Manifest records now carry resolvedExtension; a host-owned resolved registry view exists for static consumers.
Manifest/package metadata loading src/plugins/manifest.ts, src/plugins/discovery.ts, src/plugins/install.ts src/extension-host/schema.ts and src/extension-host/manifest-registry.ts partial Package metadata parsing is routed through host schema helpers; legacy loader flow still supplies the source manifests.
Loader SDK alias compatibility src/plugins/loader.ts src/extension-host/loader-compat.ts partial Plugin-SDK alias candidate ordering, alias-file resolution, and scoped alias-map construction now live in host-owned loader compatibility helpers.
Loader cache key and registry cache control src/plugins/loader.ts src/extension-host/loader-cache.ts partial Cache-key construction, LRU registry cache reads and writes, and cache clearing now delegate through host-owned loader-cache helpers while preserving the current cache shape and cap.
Loader provenance and duplicate-order policy src/plugins/loader.ts src/extension-host/loader-policy.ts partial Plugin-record creation, duplicate precedence, provenance indexing, and allowlist/untracked warnings now live in host-owned loader-policy helpers.
Loader initial candidate planning and record creation src/plugins/loader.ts src/extension-host/loader-records.ts partial Duplicate detection, initial record creation, manifest metadata attachment, and first-pass enable-state planning now delegate through host-owned loader-records helpers.
Loader entry-path opening and module import src/plugins/loader.ts src/extension-host/loader-import.ts partial Boundary-checked entry opening and module import now delegate through host-owned loader-import helpers while preserving the current trusted in-process loading model.
Loader module-export, config-validation, and memory-slot decisions src/plugins/loader.ts src/extension-host/loader-runtime.ts partial Module export resolution, export-metadata application, config validation, and early or final memory-slot decisions now delegate through host-owned loader-runtime helpers.
Loader post-import planning and register execution src/plugins/loader.ts src/extension-host/loader-register.ts partial Definition application, post-import validation planning, and register(...) execution now delegate through host-owned loader-register helpers while preserving current plugin behavior.
Loader per-candidate orchestration src/plugins/loader.ts src/extension-host/loader-flow.ts partial The per-candidate load flow now runs through a host-owned orchestrator that composes planning, import, runtime validation, register execution, and record-state helpers.
Loader top-level load orchestration src/plugins/loader.ts src/extension-host/loader-orchestrator.ts partial Cache hits, runtime creation, discovery, manifest loading, candidate ordering, candidate processing, and finalization now route through a host-owned loader orchestrator while src/plugins/loader.ts remains the compatibility facade.
Loader mutable activation state session local variables in src/plugins/loader.ts and src/extension-host/loader-orchestrator.ts src/extension-host/loader-session.ts partial Seen-id tracking, memory-slot selection state, and finalization inputs now live in a host-owned loader session instead of being spread across top-level loader variables.
Loader activation policy outcomes open-coded in src/plugins/loader.ts and src/extension-host/loader-flow.ts src/extension-host/loader-activation-policy.ts partial Duplicate precedence, config enablement, and early memory-slot gating now resolve through explicit host-owned activation-policy outcomes instead of remaining as inline loader decisions.
Loader record-state transitions src/plugins/loader.ts src/extension-host/loader-state.ts partial The loader now enforces an explicit lifecycle transition model (prepared -> imported -> validated -> registered -> ready, plus terminal disabled and error) while still mapping back to compatibility PluginRecord.status values.
Loader finalization policy results mixed inside src/plugins/loader.ts, src/extension-host/loader-policy.ts, and src/extension-host/loader-finalize.ts src/extension-host/loader-finalization-policy.ts partial Memory-slot finalization warnings and provenance-based untracked-extension warnings now resolve through explicit host-owned finalization-policy results before the finalizer applies them.
Loader final cache, warning, and activation finalization src/plugins/loader.ts src/extension-host/loader-finalize.ts partial Cache writes, untracked-extension warnings, final memory-slot warnings, readiness promotion, and registry activation now delegate through a host-owned loader-finalize helper; broader host lifecycle and policy semantics are still pending.
Channel lookup src/channels/plugins/index.ts, src/channels/plugins/registry-loader.ts, src/channels/registry.ts extension-host-backed registries plus kernel channel contracts partial Readers now consume the host-owned active registry, but writes still originate from plugin registration.
Dock lookup src/channels/dock.ts host-owned static descriptors partial Runtime lookup now uses the host boundary; dock ownership itself has not moved yet.
Message-channel normalization src/utils/message-channel.ts host-owned channel registry view partial Lookup path now reads through the host-owned active registry.
Default plugin HTTP route lookup src/plugins/http-registry.ts host-owned route registry partial Default registry resolution now uses the host boundary; route registration compatibility still flows through the legacy plugin API.
Channel catalog static metadata src/channels/plugins/catalog.ts host-owned static descriptors partial Package metadata parsing now flows through host schema helpers; full canonical catalog migration has not started.
Plugin skill discovery src/agents/skills/plugin-skills.ts host-owned resolved registry moved Static consumer now reads only resolved-extension data for skill paths and enablement filtering.
Plugin auto-enable src/config/plugin-auto-enable.ts host-owned resolved registry partial Primary logic runs on resolved-extension data; old manifest-registry injection remains as a compatibility input for older callers and tests.
Config validation indexing src/config/validation.ts, src/config/resolved-extension-validation.ts host-owned resolved registry moved Validation indexing now builds from resolved-extension records instead of flat manifest rows.
Config doc baseline generation src/config/doc-baseline.ts host-owned resolved registry moved Bundled plugin and channel metadata now load through the resolved-extension registry.
Plugin loader activation src/plugins/loader.ts extension host lifecycle + compatibility loader partial Activation now routes through src/extension-host/activation.ts, but discovery, enablement, provenance, module loading, and policy still live in the legacy plugin loader.
Channel registration writes src/plugins/registry.ts host-owned channel registry partial Validation and normalization now delegate to src/extension-host/runtime-registrations.ts, but the legacy plugin API still performs the write.
Provider registration writes src/plugins/registry.ts host-owned provider registry partial Provider normalization still happens in plugin-era validation, but duplicate detection and normalized registration shape now delegate to src/extension-host/runtime-registrations.ts.
HTTP route registration writes src/plugins/registry.ts host-owned route registry partial Route validation and normalization now delegate to src/extension-host/runtime-registrations.ts, but the legacy plugin API still performs the write.
Gateway method registration writes src/plugins/registry.ts host-owned runtime contribution registry partial Duplicate detection and normalized method registration now delegate to src/extension-host/runtime-registrations.ts, but the legacy plugin API still performs the write.
Tool registration writes src/plugins/registry.ts host-owned tool registry partial Tool-name normalization and tool-factory shaping now delegate to src/extension-host/runtime-registrations.ts, but duplicate handling still follows the legacy tool path.
CLI registration writes src/plugins/registry.ts host-owned CLI registry partial CLI command-name normalization now delegates to src/extension-host/runtime-registrations.ts, but the legacy plugin API still performs the write.
Service registration writes src/plugins/registry.ts host-owned service registry partial Service-id normalization now delegates to src/extension-host/runtime-registrations.ts, but lifecycle remains legacy-owned.
Command registration writes src/plugins/registry.ts host-owned command registry partial Command-name normalization now delegates to src/extension-host/runtime-registrations.ts, but duplicate enforcement still depends on the legacy plugin command registry.
Context-engine registration writes src/plugins/registry.ts host-owned context-engine registry partial Context-engine id normalization now delegates to src/extension-host/runtime-registrations.ts, but the actual context-engine registry remains legacy-owned.
Legacy hook registration writes src/plugins/registry.ts host-owned hook registry partial Hook-entry construction and event normalization now delegate to src/extension-host/runtime-registrations.ts, but internal-hook bridging still remains in the legacy plugin registry.
Typed-hook registration writes src/plugins/registry.ts host-owned typed-hook registry partial Typed-hook record construction and hook-name validation now delegate to src/extension-host/runtime-registrations.ts, but prompt-injection policy and execution semantics remain legacy-owned.
Hook execution and global runner src/plugins/hook-runner-global.ts, src/hooks/internal-hooks.ts, plugin hook registration in src/plugins/registry.ts canonical kernel event stages + host bridges not started No canonical event-stage migration has landed yet.
Service lifecycle src/plugins/services.ts and plugin service registration extension host lifecycle not started Service startup and teardown still depend on legacy plugin registry/service ownership.
CLI registration plugin CLI registration in src/plugins/registry.ts and CLI loaders extension host registry + static descriptors where possible not started No host-owned CLI registry exists yet.
Gateway/server methods src/plugins/registry.ts gateway handler registration host-owned runtime contribution registry not started Still registered directly into the legacy plugin registry.
Slot arbitration src/plugins/slots.ts host-owned arbitration model not started Current slot selection remains plugin-era logic.
ACP backend registry src/acp/runtime/registry.ts host-owned runtime-backend registry not started ACP backends still mutate a global ACP runtime registry directly.
Onboarding/install/setup surfaces src/plugins/install.ts, package manifests, channel catalog, onboarding commands host-owned static descriptors partial Static metadata normalization has started; full setup/install descriptor migration is not done.
Pilot migrations extensions/thread-ownership, extensions/telegram, extensions/acpx extension-host path with parity tracking not started No pilot runs through the host path yet.

Completed Pattern So Far

The migration pattern used so far is intentional:

  1. Extract a host-owned boundary module.
  2. Keep the old plugin-era entry point as a compatibility facade.
  3. Move static or lookup-heavy readers first.
  4. Add focused seam tests where the dependency graph allows it.
  5. Delay loader/lifecycle/event rewrites until more readers already depend on one host-owned boundary.

That pattern has been used for:

  • active registry ownership
  • normalized extension schema and resolved-extension records
  • static consumers such as skills, validation, auto-enable, and config baseline generation
  • loader compatibility, cache control, initial candidate planning, entry-path import, explicit activation-policy outcomes, runtime decisions, post-import register flow, per-candidate orchestration, top-level load orchestration, session-owned activation state, explicit loader lifecycle transitions, explicit finalization-policy results, and final cache plus activation finalization

Immediate Next Targets

These are the next lowest-risk cutover steps:

  1. Replace remaining static-only manifest-registry injections with resolved-extension registry inputs where practical.
  2. Extend the new loader lifecycle state machine, session-owned activation state, activation-policy outcomes, and finalization-policy results into broader activation-state and policy ownership in src/extension-host/*.
  3. Introduce explicit host-owned registration surfaces for runtime writes, starting with the least-coupled registries.
  4. Move minimal SDK compatibility and loader normalization into src/extension-host/* without breaking current openclaw/plugin-sdk/* loading.
  5. Start the first pilot on extensions/thread-ownership only after the host-side registry and lifecycle seams are explicit.

Explicitly Not Done Yet

This inventory should not be read as proof that the extension host is fully in charge already.

The following remain legacy-owned today:

  • activation ordering
  • policy gates
  • typed and legacy hook execution
  • service lifecycle
  • CLI registration
  • gateway/server method registration
  • slot arbitration
  • ACP backend registration
  • channel runtime compatibility bridges
  • pilot parity tracking