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`. > Mirrored from `/mnt/DATA/git/govoplan-core/docs/MODULE_ARCHITECTURE.md`.
> Origin: `repository`. > 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 subscriptions, or irreversible migration state must expose uninstall guard
providers through their manifest. Guards return `blocker`, `warning`, or providers through their manifest. Guards return `blocker`, `warning`, or
`info` results and may inspect live state through the core-owned DB session. `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 - Core refreshes the active registry before frontend metadata is returned from
`/api/v1/platform/modules`; the WebUI shell refetches this metadata after `/api/v1/platform/modules`; the WebUI shell refetches this metadata after
module changes so navigation, routes, and UI capabilities update without a 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 - `GET /api/v1/admin/system/modules/package-catalog` reads approved package
references from `GOVOPLAN_MODULE_PACKAGE_CATALOG` so operators can add known references from `GOVOPLAN_MODULE_PACKAGE_CATALOG` so operators can add known
module refs to the install plan without typing them manually. The endpoint 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 - `PUT /api/v1/admin/system/modules/install-plan` saves planned install or
uninstall rows. Install rows must use tagged package or git references, not uninstall rows. Install rows must use tagged package or git references, not
local `file:`/workspace paths. Python install rows must also include the 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` - `govoplan-module-installer --validate-package-catalog [path] --format json`
validates a catalog file or the catalog configured through validates a catalog file or the catalog configured through
`GOVOPLAN_MODULE_PACKAGE_CATALOG`. `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 - `govoplan-module-installer --rollback <run-id>` restores the saved package
snapshots, restores the captured SQLite or external database snapshot when snapshots, restores the captured SQLite or external database snapshot when
present, and reruns package installation from the previous freeze file. 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 an active module is blocked;
- uninstalling a module still present in desired startup state 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 with active/desired dependents is blocked;
- uninstalling a module that owns migrations is blocked until that module - uninstalling a module that owns migrations is non-destructive by default:
explicitly supports migration retirement; schema/data remain dormant and preflight emits a warning;
- modules that declare migration retirement support should also register a - modules that declare explicit migration retirement support should also
retirement provider. Without a provider, preflight emits a manual-review register a retirement provider. Without a provider, preflight emits a
warning. Providers may return blockers, warnings, and an explanatory summary, manual-review warning. Providers may return blockers, warnings, and an
but core does not drop schema or data on behalf of modules. 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 - module-owned uninstall guard providers can veto data/migration/worker unsafe
removals; removals;
- install refs must be exact versions or tagged git refs; - 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 currently executing the request. The admin UI therefore remains an operator
planning and request-submission surface; the trusted daemon/CLI is the executor. planning and request-submission surface; the trusted daemon/CLI is the executor.
Automatic rollback covers Python and WebUI package state. For `sqlite:///` Automatic rollback covers Python and WebUI package state. The manual/shell
database URLs, `--migrate` also captures a SQLite backup and rollback restores daemon can run `npm install` and `npm run build`; this remains the supported
it before the supervisor restarts the server. For non-SQLite database URLs, WebUI package path. Browser-loaded remote module bundles are experimental and
`--migrate` requires deployment-specific backup and restore commands. Hook reserved for controlled deployments with integrity/signature policy.
commands run in the installer run directory with:
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_INSTALLER_RUN_DIR`
- `GOVOPLAN_DATABASE_URL` - `GOVOPLAN_DATABASE_URL`
- `GOVOPLAN_DATABASE_BACKUP_PATH` - `GOVOPLAN_DATABASE_BACKUP_PATH`
- `GOVOPLAN_DATABASE_BACKUP_METADATA` - `GOVOPLAN_DATABASE_BACKUP_METADATA`
Module uninstall remains blocked until data and migration-state retirement rules Module uninstall does not retire data by default. Package removal leaves
are satisfied. 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` The running FastAPI server still reports `package_mutation_supported=false`
because dependency-manager operations are not executed inside request handlers. 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`. > Mirrored from `/mnt/DATA/git/govoplan-core/docs/RELEASE_DEPENDENCIES.md`.
> Origin: `repository`. > Origin: `repository`.
@@ -81,13 +81,19 @@ govoplan-module-installer \
``` ```
To let the admin UI trigger package work without executing pip/npm inside a 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 ```bash
govoplan-module-installer \ govoplan-module-installer \
--daemon \ --daemon \
--migrate \ --migrate \
--build-webui \ --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 \ --health-url http://127.0.0.1:8000/health \
--restart-command '<restart govoplan server>' --restart-command '<restart govoplan server>'
``` ```
@@ -115,14 +121,16 @@ govoplan-module-installer \
--supervise \ --supervise \
--migrate \ --migrate \
--database-backup-command 'pg_dump --format=custom "$GOVOPLAN_DATABASE_URL" > "$GOVOPLAN_DATABASE_BACKUP_PATH"' \ --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"' \ --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 \ --health-url http://127.0.0.1:8000/health \
--restart-command '<restart govoplan server>' --restart-command '<restart govoplan server>'
``` ```
The backup command runs before migrations. The restore command is stored in the The backup command runs before migrations. The restore-check command validates
run record and runs during rollback unless an override is passed to the produced backup artifact before migrations proceed, without restoring over
`--rollback`. 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 Supervised mode treats package command failure, migration failure, restart
failure, and health timeout as rollback triggers. It restores the Python/WebUI 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 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 Install rows must use tagged package/git refs or registry packages, not local
`file:` or workspace links. WebUI package changes still require `npm install` `file:` or workspace links. The installer daemon can run `npm install` and
and a WebUI rebuild/reload because the current shell resolves WebUI modules from `npm run build` for WebUI package changes; that is the supported path. Browser
the build-time package graph. After backend package changes, run migrations and remote bundles are still experimental and should be treated as a controlled
restart or reload the affected server/worker processes according to the deployment option, not the normal install/uninstall mechanism.
deployment model.
Module manifests can declare core compatibility bounds and uninstall guard Module manifests can declare core compatibility bounds and uninstall guard
providers. Preflight blocks incompatible manifest contracts/core versions and providers. Preflight blocks incompatible manifest contracts/core versions,
lets module-owned guards veto package removal when data, migrations, workers, or active modules, desired startup state, protected modules, and active dependents.
schedulers would make uninstall unsafe. Modules that own migrations are treated Default uninstall is non-destructive: module data and schema remain dormant if
as non-retirable by default, so package uninstall is blocked unless the manifest the package is removed. Persistent-data guards therefore warn by default instead
explicitly declares migration retirement support. A migration-owning module that of requiring export/delete. A module that supports explicit data/schema
does declare retirement support should register a retirement provider; otherwise retirement should register a retirement provider; that provider may block when
preflight emits a manual-review warning instead of pretending schema/data its retirement preconditions are not met.
retirement is automated.
## WebUI ## WebUI