Document destructive module retirement

2026-07-07 14:44:48 +02:00
parent b2cb9f7e97
commit e250799fe2
2 changed files with 27 additions and 5 deletions

@@ -1,4 +1,4 @@
<!-- codex-wiki-sync:e7726f6b85ca46308a5ff1cf --> <!-- codex-wiki-sync:97f252ae80996d8ee236fd44 -->
> 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`.
@@ -386,6 +386,13 @@ Hot enable/disable is a core design principle for every module:
should warn that data will remain dormant. Guards should block only when should warn that data will remain dormant. Guards should block only when
removing the package would corrupt other active modules, workers, external removing the package would corrupt other active modules, workers, external
subscriptions, or deployment state. A guard failure is treated as a blocker. subscriptions, or deployment state. A guard failure is treated as a blocker.
- Modules that can destroy their own data must also expose a migration
retirement provider. Destructive retirement is opt-in per uninstall plan row
through `destroy_data: true`; the installer then snapshots the database,
invokes the module-owned retirement executor while the package is still
installed, and only then removes Python/WebUI packages. Without that flag,
the same provider is used for preflight reporting only and module tables/data
remain dormant.
- 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
@@ -428,7 +435,9 @@ The package install-plan API records operator intent only:
planned non-destructive uninstall row for an installed module after it has planned non-destructive uninstall row for an installed module after it has
been disabled. The Python distribution name is resolved from the installed been disabled. The Python distribution name is resolved from the installed
`govoplan.modules` entry point; the WebUI package name comes from the module `govoplan.modules` entry point; the WebUI package name comes from the module
manifest. manifest. Operators can then edit the saved plan row and set `destroy_data`
when they explicitly want module-owned tables/data retired before package
removal.
- `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

@@ -1,4 +1,4 @@
<!-- codex-wiki-sync:a1540bf59b3f4a01db0416e4 --> <!-- codex-wiki-sync:874f18ab843f9c893d212d76 -->
> 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`.
@@ -150,6 +150,17 @@ from saved startup state by default. Use
`--keep-uninstalled-modules-in-desired` only for staged rollout workflows that `--keep-uninstalled-modules-in-desired` only for staged rollout workflows that
will update module state separately. will update module state separately.
Uninstall is non-destructive by default. A planned uninstall row can set
`destroy_data: true` to request destructive module retirement. The module must
provide an automated retirement provider, and the installer snapshots the
database before dropping module-owned tables. For SQLite this uses the built-in
snapshot path; for PostgreSQL or another non-SQLite database, provide
`--database-backup-command`, `--database-restore-check-command`, and
`--database-restore-command`. If a destructive run fails during package removal,
the installer restores the database snapshot before returning the failed run
result; supervised restart/health failures also roll back through the normal
supervisor path.
Package rollback is automatic. SQLite database rollback is automatic for Package rollback is automatic. SQLite database rollback is automatic for
installer runs that used `--migrate` and captured a database snapshot. installer runs that used `--migrate` and captured a database snapshot.
Non-SQLite rollback is automatic when the run used Non-SQLite rollback is automatic when the run used
@@ -244,8 +255,10 @@ active modules, desired startup state, protected modules, and active dependents.
Default uninstall is non-destructive: module data and schema remain dormant if Default uninstall is non-destructive: module data and schema remain dormant if
the package is removed. Persistent-data guards therefore warn by default instead the package is removed. Persistent-data guards therefore warn by default instead
of requiring export/delete. A module that supports explicit data/schema of requiring export/delete. A module that supports explicit data/schema
retirement should register a retirement provider; that provider may block when retirement should register a retirement provider. When `destroy_data` is set on
its retirement preconditions are not met. an uninstall plan row, that provider is allowed to destroy module-owned data
after the installer has captured a database snapshot; otherwise it is used only
for preflight reporting.
## WebUI ## WebUI