Mirrored from
/mnt/DATA/git/govoplan-core/docs/REMOTE_WEBUI_BUNDLES.md. Origin:repository. Active tasks and changing state belong in Gitea issues; this wiki page is durable project context.
Remote WebUI Bundle Loading
GovOPlaN WebUI modules normally ship through the core WebUI package graph:
install a tagged npm/git dependency, run npm install, rebuild the shell, and
restart or reload the served assets. Remote WebUI bundles are an experimental
future path for controlled deployments where a backend-enabled module is not in
the local WebUI package graph and the operator wants the shell to load its
frontend without rebuilding core.
This design defines the target guardrails. The current rebuild/reload path remains the default production path.
Current Rebuild Path
The supported release path is:
- Install or remove backend and WebUI package dependencies through the trusted installer CLI/daemon.
- Snapshot package state before mutation.
- Run
npm installand optionallynpm run build. - Restart or reload the served WebUI assets.
- Use installer rollback if package apply, restart, or health checks fail.
Strengths:
- package manager and lockfile semantics stay conventional
- CSP can stay strict because all code is served as built assets
- rollback restores package files and lockfiles
- local development uses sibling workspace dependencies naturally
Costs:
- frontend changes require a rebuild/reload
- hot enabling a module with frontend code is not possible in the running shell
- failed rebuilds happen at install time, not at lazy module-load time
Remote Bundle Path
Remote loading is only for modules that are enabled by the backend and absent
from virtual:govoplan-installed-modules. The backend manifest exposes:
FrontendModule.asset_manifestasset_manifest_integrityasset_manifest_signatureasset_manifest_public_key_idasset_manifest_contract_version
The WebUI shell fetches the asset manifest, verifies manifest integrity and/or
signature, validates the manifest contract, fetches the entry bundle, verifies
the entry integrity, imports the bundle, validates the exported
PlatformWebModule, and applies backend metadata before registering routes,
navigation, and UI capabilities.
Unsigned and unhashed manifests are skipped. Entries without integrity are skipped. A module id mismatch is skipped.
Asset Manifest Contract
Contract version 1:
{
"contractVersion": "1",
"moduleId": "files",
"entry": "./files-webui.remote.js",
"entryIntegrity": "SHA-256-<base64-or-hex-digest>",
"moduleExport": "default"
}
The backend manifest carries the manifest-level trust metadata. The remote asset manifest carries the concrete entry URL and entry digest.
Compatibility Checks
Before a remote bundle is accepted:
- backend module must be enabled
- local WebUI module with the same id must be absent
- manifest contract must be supported by the shell
- manifest
moduleId, exported moduleid, and backend module id must match - backend metadata remains authoritative for label, version, dependencies, nav, and runtime UI capability exposure
- future contract versions must declare required shell capabilities so old shells fail closed
Remote bundles must not broaden backend permissions. They can only contribute routes/nav/capabilities that the backend metadata and existing permission checks allow.
CSP
The current implementation imports verified entry bytes through a blob URL. A production CSP for this mode must explicitly allow:
connect-srcfor the approved asset-manifest and bundle originsscript-srcforblob:only when remote loading is enabled- no
unsafe-inlinerequirement for remote modules
If an installation cannot allow blob: scripts, the follow-up implementation
should use signed same-origin module assets with static URLs instead of blob
imports. Remote loading must be disableable by configuration so strict-CSP
deployments can keep the rebuild path only.
Cache Invalidation
The shell cache key is:
<module-id>:<asset-manifest-url>:<backend-module-version>
Release catalogs should publish immutable manifest and entry URLs or change at least one cache-key component on every release. Emergency rollback can point the backend manifest at a previous immutable manifest URL or lower the enabled module version after the backend package rollback.
Browsers may still cache remote responses. Approved asset servers should use:
- long cache lifetimes only for content-addressed immutable assets
- short cache lifetimes or explicit revalidation for channel/latest manifest aliases
Cache-Control: no-storefor emergency override manifests
Rollback
Remote WebUI rollback is metadata rollback, not package-manager rollback:
- if the backend package install rolls back, the previous backend frontend metadata returns
- if only remote assets are bad, publish a new manifest URL or revert the backend/frontend metadata to the last known good manifest
- failed remote loading must degrade by omitting the remote module frontend, not by breaking the shell
Installer run records should eventually include remote asset manifest URLs, integrity, signature key ids, and load-test results when a plan enables a remote frontend.
Local And Development Behavior
Local development should keep using workspace/file dependencies and Vite. Remote loading is useful for integration testing release artifacts, not for day-to-day module UI development.
Development deployments may use unsigned catalogs and local asset servers only when signature/integrity enforcement is intentionally disabled. The remote loader itself still requires an integrity hash or a verifiable signature.
Follow-Up Slices
- Add a server-side remote-bundle policy flag and surface whether remote loading is enabled in platform metadata.
- Add CSP documentation/config generation for strict rebuild-only mode versus controlled remote-bundle mode.
- Add an installer/catalog preflight that validates remote WebUI asset manifests and records verified identity in installer run records.
- Add Playwright coverage for a signed test remote bundle, failed digest, bad module id, cache-key refresh, and fallback when the module is unavailable.
- Add release tooling to emit immutable remote asset manifests with digest, signature, key id, and rollback metadata.