42 KiB
42 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 preservedpartial: host-owned types or views exist, but the legacy plugin path is still the active writercompat-only: old surface still exists only to preserve callers while the host boundary takes overnot 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 alias-wired module loader creation | src/plugins/loader.ts |
src/extension-host/loader-module-loader.ts |
partial |
Lazy Jiti creation and SDK-alias-wired module loading now delegate through a host-owned loader-module-loader helper. |
| 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 lazy runtime proxy creation | src/plugins/loader.ts |
src/extension-host/loader-runtime-proxy.ts |
partial |
Lazy plugin runtime creation now delegates through a host-owned loader-runtime-proxy helper instead of remaining inline in the orchestrator. |
| Loader provenance and duplicate-order policy | src/plugins/loader.ts |
src/extension-host/loader-policy.ts |
partial |
Plugin-record creation, duplicate precedence, and provenance indexing now live in host-owned loader-policy helpers. |
| Loader discovery policy results | mixed inside src/extension-host/loader-policy.ts and src/extension-host/loader-orchestrator.ts |
src/extension-host/loader-discovery-policy.ts |
partial |
Open-allowlist discovery warnings now resolve through explicit host-owned discovery-policy results before the orchestrator logs them. |
| 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 |
High-level load entry and compatibility facade behavior now route through a host-owned loader orchestrator while src/plugins/loader.ts remains the external compatibility surface. |
| Loader host process state | mixed inside src/plugins/loader.ts and src/extension-host/loader-orchestrator.ts |
src/extension-host/loader-host-state.ts |
partial |
Shared discovery warning-cache state and loader reset behavior now delegate through a host-owned loader-host-state helper. |
| Loader preflight and cache-hit setup | mixed inside src/plugins/loader.ts and src/extension-host/loader-orchestrator.ts |
src/extension-host/loader-preflight.ts |
partial |
Test-default application, config normalization, cache-key construction, cache-hit activation, and command-clear preflight now delegate through a host-owned loader-preflight helper. |
| Loader post-preflight pipeline composition | mixed inside src/plugins/loader.ts and src/extension-host/loader-orchestrator.ts |
src/extension-host/loader-pipeline.ts |
partial |
Post-preflight execution setup and session-run composition now delegate through a host-owned loader-pipeline helper. |
| Loader execution setup composition | mixed inside src/plugins/loader.ts and src/extension-host/loader-orchestrator.ts |
src/extension-host/loader-execution.ts |
partial |
Runtime creation, registry creation, bootstrap setup, module-loader creation, and session creation now delegate through a host-owned loader-execution helper. |
| Loader discovery and manifest bootstrap | mixed inside src/plugins/loader.ts and src/extension-host/loader-orchestrator.ts |
src/extension-host/loader-bootstrap.ts |
partial |
Discovery, manifest loading, manifest diagnostics, discovery-policy logging, provenance building, and candidate ordering now delegate through a host-owned loader-bootstrap helper. |
| Loader mutable activation state session | local variables in 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 session run and finalization composition | mixed inside src/extension-host/loader-orchestrator.ts and src/extension-host/loader-session.ts |
src/extension-host/loader-run.ts |
partial |
Candidate iteration, manifest lookup, per-candidate session processing, and finalization handoff now delegate through a host-owned loader-run helper. |
| Loader activation policy outcomes | open-coded in 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/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, readiness, and activation finalization | src/plugins/loader.ts |
src/extension-host/loader-finalize.ts |
partial |
Cache writes, 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. |
| Plugin API compatibility facade | src/plugins/registry.ts |
src/extension-host/plugin-api.ts |
partial |
Compatibility OpenClawPluginApi composition and logger shaping now delegate through a host-owned helper; concrete registration callbacks now come from src/extension-host/plugin-registry.ts while src/plugins/registry.ts remains the external wrapper. |
| Plugin registry compatibility facade | src/plugins/registry.ts |
src/extension-host/plugin-registry.ts |
partial |
The compatibility plugin-registry facade now delegates through a host-owned helper; src/plugins/registry.ts mainly defines shared types and forwards to the host-owned facade. |
| Plugin registry compatibility policy | mixed inside src/extension-host/plugin-registry.ts |
src/extension-host/plugin-registry-compat.ts |
partial |
Provider normalization, command duplicate enforcement, and registry-local diagnostic shaping now delegate through a host-owned compatibility helper; the underlying provider-validation and plugin-command subsystems still remain legacy-owned. |
| Plugin registry registration actions | mixed inside src/extension-host/plugin-registry.ts |
src/extension-host/plugin-registry-registrations.ts |
partial |
Low-risk registration actions for tools, hooks, gateway methods, HTTP routes, channels, CLI, services, typed hooks, and context engines now delegate through a host-owned helper; the compatibility facade still composes those actions with provider and command compatibility policy. |
| Channel registration writes | src/plugins/registry.ts |
host-owned channel registry | partial |
Validation and normalization now delegate to src/extension-host/runtime-registrations.ts, and compatibility writes now route through src/extension-host/registry-writes.ts; the legacy plugin API still remains the call surface. |
| Provider registration writes | src/plugins/registry.ts |
host-owned provider registry | partial |
Provider normalization and compatibility diagnostics now delegate through src/extension-host/plugin-registry-compat.ts, duplicate detection and normalized registration shape still delegate to src/extension-host/runtime-registrations.ts, and compatibility writes route through src/extension-host/registry-writes.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, and compatibility append or replace writes now route through src/extension-host/registry-writes.ts. |
| 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, and compatibility writes now route through src/extension-host/registry-writes.ts. |
| Tool registration writes | src/plugins/registry.ts |
host-owned tool registry | partial |
Tool-name normalization and tool-factory shaping delegate through src/extension-host/runtime-registrations.ts, and low-risk compatibility writes now route through src/extension-host/registry-writes.ts; duplicate handling still follows the legacy tool path. |
| CLI registration writes | src/plugins/registry.ts |
host-owned CLI registry | partial |
CLI command-name normalization delegates through src/extension-host/runtime-registrations.ts, and compatibility writes now route through src/extension-host/registry-writes.ts; the legacy plugin API still remains the call surface. |
| Service registration writes | src/plugins/registry.ts |
host-owned service registry | partial |
Service-id normalization delegates through src/extension-host/runtime-registrations.ts, compatibility writes now route through src/extension-host/registry-writes.ts, and broader lifecycle ownership now starts in src/extension-host/service-lifecycle.ts. |
| Command registration writes | src/plugins/registry.ts |
host-owned command registry | partial |
Command-name normalization, duplicate-enforcement diagnostics, and legacy plugin-command registry bridging now delegate through src/extension-host/plugin-registry-compat.ts; the final compatibility write still routes through src/extension-host/registry-writes.ts. |
| 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, and the compatibility write now routes through src/extension-host/registry-writes.ts; 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, and the compatibility write now routes through src/extension-host/registry-writes.ts; 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, and the compatibility write now routes through src/extension-host/registry-writes.ts; prompt-injection policy and execution semantics remain legacy-owned. |
| Hook compatibility policy and bridging | src/plugins/registry.ts |
src/extension-host/hook-compat.ts |
partial |
Legacy internal-hook bridging and typed prompt-injection compatibility policy now delegate through a host-owned helper; actual hook execution ownership remains 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 |
src/extension-host/service-lifecycle.ts |
partial |
Service startup, stop ordering, service-context creation, and failure logging now delegate through a host-owned service-lifecycle helper while src/plugins/services.ts remains the compatibility entry point. |
| CLI registration | plugin CLI registration in src/plugins/registry.ts and CLI loaders |
src/extension-host/cli-lifecycle.ts plus static descriptors where possible |
partial |
CLI duplicate detection, registrar invocation, and async failure logging now delegate through a host-owned CLI-lifecycle helper while src/plugins/cli.ts remains the compatibility entry point. |
| 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:
- Extract a host-owned boundary module.
- Keep the old plugin-era entry point as a compatibility facade.
- Move static or lookup-heavy readers first.
- Add focused seam tests where the dependency graph allows it.
- 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 discovery-policy outcomes, 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
- service startup, stop ordering, and failure logging
- CLI duplicate detection, registrar invocation, and async failure logging
Immediate Next Targets
These are the next lowest-risk cutover steps:
- Replace remaining static-only manifest-registry injections with resolved-extension registry inputs where practical.
- Extend the new loader lifecycle state machine, session-owned activation state, discovery-policy outcomes, activation-policy outcomes, and finalization-policy results into broader activation-state and policy ownership in
src/extension-host/*. - Introduce explicit host-owned registration surfaces for runtime writes, starting with the least-coupled registries.
- Move minimal SDK compatibility and loader normalization into
src/extension-host/*without breaking currentopenclaw/plugin-sdk/*loading. - Start the first pilot on
extensions/thread-ownershiponly 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
- gateway/server method registration
- slot arbitration
- ACP backend registration
- channel runtime compatibility bridges
- pilot parity tracking