Sync wiki from project files

2026-07-07 14:04:37 +02:00
parent bbf1681ff6
commit efebeb32e2
2 changed files with 92 additions and 34 deletions

@@ -1,4 +1,4 @@
<!-- codex-wiki-sync:e92796c6de2292527b4d78a4 -->
<!-- codex-wiki-sync:6ad5365704d5ffc94ea5c9d8 -->
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/MODULE_ARCHITECTURE.md`.
> Origin: `repository`.
@@ -382,7 +382,10 @@ Hot enable/disable is a core design principle for every module:
subscriptions, or irreversible migration state must expose uninstall guard
providers through their manifest. Guards return `blocker`, `warning`, or
`info` results and may inspect live state through the core-owned DB session.
A guard failure is treated as a blocker.
Default package uninstall is non-destructive, so ordinary persistent data
should warn that data will remain dormant. Guards should block only when
removing the package would corrupt other active modules, workers, external
subscriptions, or deployment state. A guard failure is treated as a blocker.
- Core refreshes the active registry before frontend metadata is returned from
`/api/v1/platform/modules`; the WebUI shell refetches this metadata after
module changes so navigation, routes, and UI capabilities update without a
@@ -416,7 +419,8 @@ The package install-plan API records operator intent only:
- `GET /api/v1/admin/system/modules/package-catalog` reads approved package
references from `GOVOPLAN_MODULE_PACKAGE_CATALOG` so operators can add known
module refs to the install plan without typing them manually. The endpoint
also reports catalog validity and the configured path.
also reports catalog validity, channel, signature, trust state, and the
configured path.
- `PUT /api/v1/admin/system/modules/install-plan` saves planned install or
uninstall rows. Install rows must use tagged package or git references, not
local `file:`/workspace paths. Python install rows must also include the
@@ -451,6 +455,11 @@ The package install-plan API records operator intent only:
- `govoplan-module-installer --validate-package-catalog [path] --format json`
validates a catalog file or the catalog configured through
`GOVOPLAN_MODULE_PACKAGE_CATALOG`.
- `--sign-package-catalog <path> --catalog-signing-key-id <key-id> --catalog-signing-private-key <pem>`
signs a catalog with Ed25519. `--require-signed-catalog`,
`--approved-catalog-channel <channel>`, and
`--catalog-trusted-key <key-id>=<base64-public-key>` enforce the approved
release-channel path from an operator shell.
- `govoplan-module-installer --rollback <run-id>` restores the saved package
snapshots, restores the captured SQLite or external database snapshot when
present, and reruns package installation from the previous freeze file.
@@ -479,12 +488,13 @@ The installer preflight is intentionally conservative:
- uninstalling an active module is blocked;
- uninstalling a module still present in desired startup state is blocked;
- uninstalling a module with active/desired dependents is blocked;
- uninstalling a module that owns migrations is blocked until that module
explicitly supports migration retirement;
- modules that declare migration retirement support should also register a
retirement provider. Without a provider, preflight emits a manual-review
warning. Providers may return blockers, warnings, and an explanatory summary,
but core does not drop schema or data on behalf of modules.
- uninstalling a module that owns migrations is non-destructive by default:
schema/data remain dormant and preflight emits a warning;
- modules that declare explicit migration retirement support should also
register a retirement provider. Without a provider, preflight emits a
manual-review warning. Providers may return blockers, warnings, and an
explanatory summary, but core does not drop schema or data on behalf of
modules.
- module-owned uninstall guard providers can veto data/migration/worker unsafe
removals;
- install refs must be exact versions or tagged git refs;
@@ -496,19 +506,26 @@ request handler cannot reliably restart or roll back the process that is
currently executing the request. The admin UI therefore remains an operator
planning and request-submission surface; the trusted daemon/CLI is the executor.
Automatic rollback covers Python and WebUI package state. For `sqlite:///`
database URLs, `--migrate` also captures a SQLite backup and rollback restores
it before the supervisor restarts the server. For non-SQLite database URLs,
`--migrate` requires deployment-specific backup and restore commands. Hook
commands run in the installer run directory with:
Automatic rollback covers Python and WebUI package state. The manual/shell
daemon can run `npm install` and `npm run build`; this remains the supported
WebUI package path. Browser-loaded remote module bundles are experimental and
reserved for controlled deployments with integrity/signature policy.
For `sqlite:///` database URLs, `--migrate` also captures a SQLite backup and
rollback restores it before the supervisor restarts the server. For non-SQLite
database URLs, `--migrate` requires deployment-specific backup and restore
commands. A `--database-restore-check-command` can validate the created backup
artifact before migrations proceed. Hook commands run in the installer run
directory with:
- `GOVOPLAN_INSTALLER_RUN_DIR`
- `GOVOPLAN_DATABASE_URL`
- `GOVOPLAN_DATABASE_BACKUP_PATH`
- `GOVOPLAN_DATABASE_BACKUP_METADATA`
Module uninstall remains blocked until data and migration-state retirement rules
are satisfied.
Module uninstall does not retire data by default. Package removal leaves
module-owned schema/data dormant. Explicit retirement is a later module-owned
operation guarded by retirement providers.
The running FastAPI server still reports `package_mutation_supported=false`
because dependency-manager operations are not executed inside request handlers.

@@ -1,4 +1,4 @@
<!-- codex-wiki-sync:dc16e42ac3a76aeec72851ae -->
<!-- codex-wiki-sync:78c08afa886b630dcc4661ed -->
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/RELEASE_DEPENDENCIES.md`.
> Origin: `repository`.
@@ -81,13 +81,19 @@ govoplan-module-installer \
```
To let the admin UI trigger package work without executing pip/npm inside a
FastAPI request, run the installer daemon under the process supervisor:
FastAPI request, run the installer daemon in a separate operator shell. This is
the preferred development/early-production mode for now because the operator can
watch output, stop before queueing risky changes, and keep restart commands
deployment-specific:
```bash
govoplan-module-installer \
--daemon \
--migrate \
--build-webui \
--database-backup-command 'pg_dump --format=custom "$GOVOPLAN_DATABASE_URL" > "$GOVOPLAN_DATABASE_BACKUP_PATH"' \
--database-restore-check-command 'pg_restore --list "$GOVOPLAN_DATABASE_BACKUP_PATH" >/dev/null' \
--database-restore-command 'pg_restore --clean --if-exists --dbname "$GOVOPLAN_DATABASE_URL" "$GOVOPLAN_DATABASE_BACKUP_PATH"' \
--health-url http://127.0.0.1:8000/health \
--restart-command '<restart govoplan server>'
```
@@ -115,14 +121,16 @@ govoplan-module-installer \
--supervise \
--migrate \
--database-backup-command 'pg_dump --format=custom "$GOVOPLAN_DATABASE_URL" > "$GOVOPLAN_DATABASE_BACKUP_PATH"' \
--database-restore-check-command 'pg_restore --list "$GOVOPLAN_DATABASE_BACKUP_PATH" >/dev/null' \
--database-restore-command 'pg_restore --clean --if-exists --dbname "$GOVOPLAN_DATABASE_URL" "$GOVOPLAN_DATABASE_BACKUP_PATH"' \
--health-url http://127.0.0.1:8000/health \
--restart-command '<restart govoplan server>'
```
The backup command runs before migrations. The restore command is stored in the
run record and runs during rollback unless an override is passed to
`--rollback`.
The backup command runs before migrations. The restore-check command validates
the produced backup artifact before migrations proceed, without restoring over
the live database. The restore command is stored in the run record and runs
during rollback unless an override is passed to `--rollback`.
Supervised mode treats package command failure, migration failure, restart
failure, and health timeout as rollback triggers. It restores the Python/WebUI
@@ -178,22 +186,55 @@ refs. Validate the catalog before handing it to operators:
govoplan-module-installer --validate-package-catalog docs/module-package-catalog.example.json --format json
```
Release catalogs should be signed and channel-gated. The supported signing
format is an Ed25519 signature over the canonical catalog JSON object with the
`signature` field removed. Sign a catalog with:
```bash
govoplan-module-installer \
--sign-package-catalog docs/module-package-catalog.example.json \
--catalog-signing-key-id release-key-1 \
--catalog-signing-private-key /path/to/ed25519-private.pem
```
Validate an approved release catalog with:
```bash
govoplan-module-installer \
--validate-package-catalog docs/module-package-catalog.example.json \
--require-signed-catalog \
--approved-catalog-channel stable \
--catalog-trusted-key release-key-1=<base64-ed25519-public-key> \
--format json
```
For the admin UI/daemon path, configure the same policy through environment
variables:
```bash
GOVOPLAN_MODULE_PACKAGE_CATALOG=/path/to/catalog.json
GOVOPLAN_MODULE_PACKAGE_CATALOG_REQUIRE_SIGNATURE=true
GOVOPLAN_MODULE_PACKAGE_CATALOG_APPROVED_CHANNELS=stable
GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS='{"release-key-1":"<base64-ed25519-public-key>"}'
```
Unsigned catalogs remain usable for local development when signature
enforcement is off, but the admin UI labels them as unsigned.
Install rows must use tagged package/git refs or registry packages, not local
`file:` or workspace links. WebUI package changes still require `npm install`
and a WebUI rebuild/reload because the current shell resolves WebUI modules from
the build-time package graph. After backend package changes, run migrations and
restart or reload the affected server/worker processes according to the
deployment model.
`file:` or workspace links. The installer daemon can run `npm install` and
`npm run build` for WebUI package changes; that is the supported path. Browser
remote bundles are still experimental and should be treated as a controlled
deployment option, not the normal install/uninstall mechanism.
Module manifests can declare core compatibility bounds and uninstall guard
providers. Preflight blocks incompatible manifest contracts/core versions and
lets module-owned guards veto package removal when data, migrations, workers, or
schedulers would make uninstall unsafe. Modules that own migrations are treated
as non-retirable by default, so package uninstall is blocked unless the manifest
explicitly declares migration retirement support. A migration-owning module that
does declare retirement support should register a retirement provider; otherwise
preflight emits a manual-review warning instead of pretending schema/data
retirement is automated.
providers. Preflight blocks incompatible manifest contracts/core versions,
active modules, desired startup state, protected modules, and active dependents.
Default uninstall is non-destructive: module data and schema remain dormant if
the package is removed. Persistent-data guards therefore warn by default instead
of requiring export/delete. A module that supports explicit data/schema
retirement should register a retirement provider; that provider may block when
its retirement preconditions are not met.
## WebUI