Runtime model
Meteorack is organized around four runtime layers:
runtime-corePortable contracts, registries, client/runtime APIs, and runtime-agnostic test helpers.runtime-wpThe current WordPress host runtime used by the Hub plugin.runtime-testbedA neutral proving host used to validate contracts and module boot outside WordPress.runtime-meteorackThe first-party non-WordPress host runtime for the long-term platform.
Adapters live inside runtimes. Modules consume contracts from runtime-core and should not import WordPress or infrastructure primitives directly.
Because the platform is not live yet, avoidable compatibility duplication should be minimized:
- prefer hard cutover over long-lived aliases when there are no external consumers
- keep PHP host/runtime bridges only where WordPress actually needs them
- treat re-export shims and compatibility barrels as short-lived migration aids, not permanent architecture
Boot sequence today
At a high level, the current WordPress host runtime works like this:
- The plugin entrypoint loads the SDK/runtime autoloaders.
- The Hub constructs a hub-scoped compatibility context through
SdkContextFactory. ModuleRuntimeLoaderdiscoversmodule.jsonfiles fromwp-content/meteorack/modules.- Each module boots inside crash isolation.
- The host injects parsed module metadata and host-owned services.
- The module receives a slug-scoped compatibility context through
onSdkReady(). - The Hub registers routes, assets, and admin surfaces after boot.
This is the current compatibility path, not the final permanent architecture.
Context scoping
SdkContextFactory currently splits services into two categories:
- shared singletons such as auth, http, license, design tokens, and channels
- slug-scoped services such as logger, cache, settings, events, scheduler, storage, and secrets
That shape remains useful for the WordPress host runtime, but the long-term portable contract surface lives in runtime-core, not in SdkContext itself.
Module discovery
The current WordPress host runtime supports both flat and categorized discovery paths:
wp-content/meteorack/modules/{slug}wp-content/meteorack/modules/core/{slug}wp-content/meteorack/modules/adapters/{slug}wp-content/meteorack/modules/dev/{slug}
Modules are sorted by priority before boot.
Package and workspace boundaries
meteorack-sdk is responsible for:
- durable
@meteorack/modules-sdk-*packages runtime-testbed- SDK docs, schemas, examples, conformance tests, and the standalone module-author workflow
meteorack-suite remains responsible for:
runtime-wp- Hub plugin packaging and install surface
- current WordPress scaffold/bootstrap glue
- WordPress-host runtime code and scaffold/bootstrap glue that still belongs to the host
meteorack-platform remains responsible for:
runtime-meteorack- shared platform infra packages such as
auth,db,logger, andui - first-party modules under
meteorack-platform/modules/ - product apps and platform runtime consumers
Module and integration boundaries
- domain products such as
cmsandcommerceare modules, not runtimes - integration modules may live next to other first-party modules
- low-level host connectors stay inside the relevant runtime
- for example, WooCommerce business logic can live in a module, while direct WordPress/WooCommerce glue stays inside
runtime-wp
Shell system
The UI shell should be treated as one system, not as a long list of unrelated shell names.
The public model is:
AppShellis the main shell API- shells are configured by
surface, regions, slots, and tokens - modules usually render inside the shell, not define a brand-new shell for every feature
Simple example:
- admin area uses
AppShellwith anadminsurface - customer account area uses
AppShellwith anaccountsurface - storefront uses
AppShellwith astorefrontsurface
So the outside API stays simple, while the inside implementation can still stay clean.
Why this matters
If every surface gets a separate public shell name, the system becomes noisy very quickly:
AdminShellAccountShellStorefrontShellCartShellMobileShell
That is not the direction we want.
Instead, we want:
- one shell system
- reusable shell parts
- surface-specific presets behind the scenes
Public rule
Public SDK docs should describe:
- one public
AppShell - shared shell regions
- shared shell tokens
- shared shell composition rules
Not a long public catalog of shell variants.
Internal rule
Internally, runtimes or themes may still compose surface-specific presets.
Simple example:
runtime-wpmay compose an admin-flavored shell preset- a customer portal may compose an account-flavored shell preset
But that should remain an implementation detail, not the main public mental model.
Shell regions and slots
The shell should be extensible through stable regions.
The initial region model is:
headersidebarcontentrightRailbottomNavoverlayfooter
Simple example:
- a storefront can use
rightRailfor a cart rail - mobile can use
bottomNavfor app-style navigation - admin can use
overlayfor command palette or search drawer
This lets the shell grow without inventing a brand-new shell name every time we add one more rail, bar, or overlay.
What modules should depend on
Most modules should not own the shell.
Most modules should depend on:
- shared UI primitives such as
Button,Card,Input,Table - page-level composition pieces such as
PageHeader - shell slots/regions exposed by the host
- design tokens
Simple example:
- the
searchmodule should render its page and controls - the host shell decides whether that page appears inside an admin shell, account shell, or another surface
This keeps modules portable.
Themes and shell styling
Themes should change:
- tokens
- spacing
- colors
- typography
- shell presentation
Themes should not need to rewrite module internals just to restyle the experience.
Simple example:
- one admin theme can feel minimal and flat
- another can feel darker and more layered
- the same module page should still work in both because it consumes shared tokens and shared UI primitives
Developer-surface rules
The portable SDK surface should optimize for both human developers and AI-assisted workflows:
- public boundaries are schema-first on the TypeScript side and should emit machine-readable artifacts such as JSON Schema or OpenAPI for the durable public contracts
- transport and runtime results use discriminated unions instead of
ok: boolean - public errors use a typed hierarchy rooted in
SdkErrorand carrycode,message,requestId,param,docUrl,suggestions,retryable, anddetailswhen relevant - branded identifier types are used selectively for easy-to-mix values such as module slugs, event names, route paths, capability keys, and session/user identifiers
- public functions with multiple inputs prefer a single options object
- module-author APIs should offer builders such as
defineRoute()anddefineModuleManifest()rather than forcing raw object assembly everywhere - every public export should ship with TSDoc and runnable
@exampleblocks - SDK docs should also publish AI-friendly indexes such as
llms.txtandllms-full.txt - the primary standalone developer workflow should come through the module-author CLI plus
runtime-testbed, not through WordPress scaffold templates
Current execution status
runtime-wpis the active production host todayruntime-testbedexists to prove portability outside WordPressruntime-meteorackis the long-term host runtime target- legacy
@meteorack/sdk-*barrels are gone; new work should use the durable@meteorack/modules-sdk-*package family directly