chore: consolidate platform split checks
Some checks failed
Dependency Audit / dependency-audit (push) Has been cancelled
Module Matrix / module-matrix (push) Has been cancelled

This commit is contained in:
2026-07-10 12:51:19 +02:00
parent 150b720f12
commit 635d25c74c
216 changed files with 23336 additions and 4077 deletions

View File

@@ -0,0 +1,161 @@
# 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:
1. Install or remove backend and WebUI package dependencies through the trusted
installer CLI/daemon.
2. Snapshot package state before mutation.
3. Run `npm install` and optionally `npm run build`.
4. Restart or reload the served WebUI assets.
5. 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_manifest`
- `asset_manifest_integrity`
- `asset_manifest_signature`
- `asset_manifest_public_key_id`
- `asset_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`:
```json
{
"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 module `id`, 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-src` for the approved asset-manifest and bundle origins
- `script-src` for `blob:` only when remote loading is enabled
- no `unsafe-inline` requirement 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:
```text
<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-store` for 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
1. Add a server-side remote-bundle policy flag and surface whether remote
loading is enabled in platform metadata.
2. Add CSP documentation/config generation for strict rebuild-only mode versus
controlled remote-bundle mode.
3. Add an installer/catalog preflight that validates remote WebUI asset
manifests and records verified identity in installer run records.
4. Add Playwright coverage for a signed test remote bundle, failed digest, bad
module id, cache-key refresh, and fallback when the module is unavailable.
5. Add release tooling to emit immutable remote asset manifests with digest,
signature, key id, and rollback metadata.