Sync wiki after docs cleanup
@@ -7,13 +7,16 @@ This page is generated from repository and product-directory project files.
|
|||||||
- [Product govoplan-split-concept-action-plan](Product govoplan-split-concept-action-plan) - `/mnt/DATA/Nextcloud/ADD ideas UG/Products/govoplan/split-concept-action-plan.md`
|
- [Product govoplan-split-concept-action-plan](Product govoplan-split-concept-action-plan) - `/mnt/DATA/Nextcloud/ADD ideas UG/Products/govoplan/split-concept-action-plan.md`
|
||||||
- [Repo-README](Repo-README) - `/mnt/DATA/git/govoplan-core/README.md`
|
- [Repo-README](Repo-README) - `/mnt/DATA/git/govoplan-core/README.md`
|
||||||
- [Repo-docs-ACCESS-EXTRACTION-PLAN](Repo-docs-ACCESS-EXTRACTION-PLAN) - `/mnt/DATA/git/govoplan-core/docs/ACCESS_EXTRACTION_PLAN.md`
|
- [Repo-docs-ACCESS-EXTRACTION-PLAN](Repo-docs-ACCESS-EXTRACTION-PLAN) - `/mnt/DATA/git/govoplan-core/docs/ACCESS_EXTRACTION_PLAN.md`
|
||||||
|
- [Repo-docs-ACCESS-RBAC-MODEL](Repo-docs-ACCESS-RBAC-MODEL) - `/mnt/DATA/git/govoplan-core/docs/ACCESS_RBAC_MODEL.md`
|
||||||
- [Repo-docs-API-CONDITIONAL-DELTA](Repo-docs-API-CONDITIONAL-DELTA) - `/mnt/DATA/git/govoplan-core/docs/API_CONDITIONAL_DELTA.md`
|
- [Repo-docs-API-CONDITIONAL-DELTA](Repo-docs-API-CONDITIONAL-DELTA) - `/mnt/DATA/git/govoplan-core/docs/API_CONDITIONAL_DELTA.md`
|
||||||
- [Repo-docs-CATALOG-TRUST-AND-LICENSING](Repo-docs-CATALOG-TRUST-AND-LICENSING) - `/mnt/DATA/git/govoplan-core/docs/CATALOG_TRUST_AND_LICENSING.md`
|
- [Repo-docs-CATALOG-TRUST-AND-LICENSING](Repo-docs-CATALOG-TRUST-AND-LICENSING) - `/mnt/DATA/git/govoplan-core/docs/CATALOG_TRUST_AND_LICENSING.md`
|
||||||
- [Repo-docs-CODEX-WORKFLOW](Repo-docs-CODEX-WORKFLOW) - `/mnt/DATA/git/govoplan-core/docs/CODEX_WORKFLOW.md`
|
- [Repo-docs-CODEX-WORKFLOW](Repo-docs-CODEX-WORKFLOW) - `/mnt/DATA/git/govoplan-core/docs/CODEX_WORKFLOW.md`
|
||||||
- [Repo-docs-CONFIGURATION-PACKAGES](Repo-docs-CONFIGURATION-PACKAGES) - `/mnt/DATA/git/govoplan-core/docs/CONFIGURATION_PACKAGES.md`
|
- [Repo-docs-CONFIGURATION-PACKAGES](Repo-docs-CONFIGURATION-PACKAGES) - `/mnt/DATA/git/govoplan-core/docs/CONFIGURATION_PACKAGES.md`
|
||||||
- [Repo-docs-DEPLOYMENT-OPERATOR-GUIDE](Repo-docs-DEPLOYMENT-OPERATOR-GUIDE) - `/mnt/DATA/git/govoplan-core/docs/DEPLOYMENT_OPERATOR_GUIDE.md`
|
- [Repo-docs-DEPLOYMENT-OPERATOR-GUIDE](Repo-docs-DEPLOYMENT-OPERATOR-GUIDE) - `/mnt/DATA/git/govoplan-core/docs/DEPLOYMENT_OPERATOR_GUIDE.md`
|
||||||
|
- [Repo-docs-DOCUMENTATION-MAP](Repo-docs-DOCUMENTATION-MAP) - `/mnt/DATA/git/govoplan-core/docs/DOCUMENTATION_MAP.md`
|
||||||
- [Repo-docs-EVENTS-AND-AUDIT](Repo-docs-EVENTS-AND-AUDIT) - `/mnt/DATA/git/govoplan-core/docs/EVENTS_AND_AUDIT.md`
|
- [Repo-docs-EVENTS-AND-AUDIT](Repo-docs-EVENTS-AND-AUDIT) - `/mnt/DATA/git/govoplan-core/docs/EVENTS_AND_AUDIT.md`
|
||||||
- [Repo-docs-GITEA-ISSUES](Repo-docs-GITEA-ISSUES) - `/mnt/DATA/git/govoplan-core/docs/GITEA_ISSUES.md`
|
- [Repo-docs-GITEA-ISSUES](Repo-docs-GITEA-ISSUES) - `/mnt/DATA/git/govoplan-core/docs/GITEA_ISSUES.md`
|
||||||
|
- [Repo-docs-GOVERNANCE-MODEL](Repo-docs-GOVERNANCE-MODEL) - `/mnt/DATA/git/govoplan-core/docs/GOVERNANCE_MODEL.md`
|
||||||
- [Repo-docs-GOVERNMENT-OPERATIONS-VISION](Repo-docs-GOVERNMENT-OPERATIONS-VISION) - `/mnt/DATA/git/govoplan-core/docs/GOVERNMENT_OPERATIONS_VISION.md`
|
- [Repo-docs-GOVERNMENT-OPERATIONS-VISION](Repo-docs-GOVERNMENT-OPERATIONS-VISION) - `/mnt/DATA/git/govoplan-core/docs/GOVERNMENT_OPERATIONS_VISION.md`
|
||||||
- [Repo-docs-GOVOPLAN-MASTER-ROADMAP](Repo-docs-GOVOPLAN-MASTER-ROADMAP) - `/mnt/DATA/git/govoplan-core/docs/GOVOPLAN_MASTER_ROADMAP.md`
|
- [Repo-docs-GOVOPLAN-MASTER-ROADMAP](Repo-docs-GOVOPLAN-MASTER-ROADMAP) - `/mnt/DATA/git/govoplan-core/docs/GOVOPLAN_MASTER_ROADMAP.md`
|
||||||
- [Repo-docs-GOVOPLAN-MODULE-ROADMAP](Repo-docs-GOVOPLAN-MODULE-ROADMAP) - `/mnt/DATA/git/govoplan-core/docs/GOVOPLAN_MODULE_ROADMAP.md`
|
- [Repo-docs-GOVOPLAN-MODULE-ROADMAP](Repo-docs-GOVOPLAN-MODULE-ROADMAP) - `/mnt/DATA/git/govoplan-core/docs/GOVOPLAN_MODULE_ROADMAP.md`
|
||||||
@@ -21,9 +24,7 @@ This page is generated from repository and product-directory project files.
|
|||||||
- [Repo-docs-MODULE-BOUNDARY-DECISIONS](Repo-docs-MODULE-BOUNDARY-DECISIONS) - `/mnt/DATA/git/govoplan-core/docs/MODULE_BOUNDARY_DECISIONS.md`
|
- [Repo-docs-MODULE-BOUNDARY-DECISIONS](Repo-docs-MODULE-BOUNDARY-DECISIONS) - `/mnt/DATA/git/govoplan-core/docs/MODULE_BOUNDARY_DECISIONS.md`
|
||||||
- [Repo-docs-POLICY-CONTRACTS](Repo-docs-POLICY-CONTRACTS) - `/mnt/DATA/git/govoplan-core/docs/POLICY_CONTRACTS.md`
|
- [Repo-docs-POLICY-CONTRACTS](Repo-docs-POLICY-CONTRACTS) - `/mnt/DATA/git/govoplan-core/docs/POLICY_CONTRACTS.md`
|
||||||
- [Repo-docs-PUBLIC-SECTOR-INTEGRATION-STRATEGY](Repo-docs-PUBLIC-SECTOR-INTEGRATION-STRATEGY) - `/mnt/DATA/git/govoplan-core/docs/PUBLIC_SECTOR_INTEGRATION_STRATEGY.md`
|
- [Repo-docs-PUBLIC-SECTOR-INTEGRATION-STRATEGY](Repo-docs-PUBLIC-SECTOR-INTEGRATION-STRATEGY) - `/mnt/DATA/git/govoplan-core/docs/PUBLIC_SECTOR_INTEGRATION_STRATEGY.md`
|
||||||
- [Repo-docs-RBAC-MANIFEST](Repo-docs-RBAC-MANIFEST) - `/mnt/DATA/git/govoplan-core/docs/RBAC_MANIFEST.md`
|
|
||||||
- [Repo-docs-RELEASE-CATALOG-WORKFLOW](Repo-docs-RELEASE-CATALOG-WORKFLOW) - `/mnt/DATA/git/govoplan-core/docs/RELEASE_CATALOG_WORKFLOW.md`
|
- [Repo-docs-RELEASE-CATALOG-WORKFLOW](Repo-docs-RELEASE-CATALOG-WORKFLOW) - `/mnt/DATA/git/govoplan-core/docs/RELEASE_CATALOG_WORKFLOW.md`
|
||||||
- [Repo-docs-RELEASE-DEPENDENCIES](Repo-docs-RELEASE-DEPENDENCIES) - `/mnt/DATA/git/govoplan-core/docs/RELEASE_DEPENDENCIES.md`
|
- [Repo-docs-RELEASE-DEPENDENCIES](Repo-docs-RELEASE-DEPENDENCIES) - `/mnt/DATA/git/govoplan-core/docs/RELEASE_DEPENDENCIES.md`
|
||||||
- [Repo-docs-REMOTE-WEBUI-BUNDLES](Repo-docs-REMOTE-WEBUI-BUNDLES) - `/mnt/DATA/git/govoplan-core/docs/REMOTE_WEBUI_BUNDLES.md`
|
- [Repo-docs-REMOTE-WEBUI-BUNDLES](Repo-docs-REMOTE-WEBUI-BUNDLES) - `/mnt/DATA/git/govoplan-core/docs/REMOTE_WEBUI_BUNDLES.md`
|
||||||
- [Repo-docs-SCALABILITY-AND-SIZING](Repo-docs-SCALABILITY-AND-SIZING) - `/mnt/DATA/git/govoplan-core/docs/SCALABILITY_AND_SIZING.md`
|
- [Repo-docs-SCALABILITY-AND-SIZING](Repo-docs-SCALABILITY-AND-SIZING) - `/mnt/DATA/git/govoplan-core/docs/SCALABILITY_AND_SIZING.md`
|
||||||
- [Repo-docs-SYSTEM-GOVERNANCE-MANIFEST](Repo-docs-SYSTEM-GOVERNANCE-MANIFEST) - `/mnt/DATA/git/govoplan-core/docs/SYSTEM_GOVERNANCE_MANIFEST.md`
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!-- codex-wiki-sync:f744da05674d7f1c94f7b85f -->
|
<!-- codex-wiki-sync:e4c303086f9134064a521fb1 -->
|
||||||
|
|
||||||
> Mirrored from `/mnt/DATA/git/govoplan-core/README.md`.
|
> Mirrored from `/mnt/DATA/git/govoplan-core/README.md`.
|
||||||
> Origin: `repository`.
|
> Origin: `repository`.
|
||||||
@@ -26,8 +26,9 @@ Feature modules own their backend routers, models, migrations, permissions, fron
|
|||||||
|
|
||||||
Canonical policy documents live in `docs/`:
|
Canonical policy documents live in `docs/`:
|
||||||
|
|
||||||
- [RBAC_MANIFEST.md](docs/RBAC_MANIFEST.md)
|
- [DOCUMENTATION_MAP.md](docs/DOCUMENTATION_MAP.md)
|
||||||
- [SYSTEM_GOVERNANCE_MANIFEST.md](docs/SYSTEM_GOVERNANCE_MANIFEST.md)
|
- [ACCESS_RBAC_MODEL.md](docs/ACCESS_RBAC_MODEL.md)
|
||||||
|
- [GOVERNANCE_MODEL.md](docs/GOVERNANCE_MODEL.md)
|
||||||
- [MODULE_ARCHITECTURE.md](docs/MODULE_ARCHITECTURE.md)
|
- [MODULE_ARCHITECTURE.md](docs/MODULE_ARCHITECTURE.md)
|
||||||
- [DEPLOYMENT_OPERATOR_GUIDE.md](docs/DEPLOYMENT_OPERATOR_GUIDE.md)
|
- [DEPLOYMENT_OPERATOR_GUIDE.md](docs/DEPLOYMENT_OPERATOR_GUIDE.md)
|
||||||
- [CODEX_WORKFLOW.md](docs/CODEX_WORKFLOW.md)
|
- [CODEX_WORKFLOW.md](docs/CODEX_WORKFLOW.md)
|
||||||
@@ -63,7 +64,7 @@ ENABLED_MODULES=access,campaigns ./.venv/bin/python -m govoplan_core.devserver \
|
|||||||
|
|
||||||
The runner loads the same `GovoplanServerConfig` as `govoplan_core.server.app:app`, builds the platform registry, and passes core plus enabled module source roots to uvicorn as reload directories. After reinstalling the editable package, the same command is also available as `govoplan-devserver`.
|
The runner loads the same `GovoplanServerConfig` as `govoplan_core.server.app:app`, builds the platform registry, and passes core plus enabled module source roots to uvicorn as reload directories. After reinstalling the editable package, the same command is also available as `govoplan-devserver`.
|
||||||
|
|
||||||
The default development database is PostgreSQL at `postgresql+psycopg://govoplan_dev@127.0.0.1:5432/govoplan_dev`. Store the password in `~/.pgpass`. To force the old disposable SQLite fallback, run with `GOVOPLAN_DEV_DATABASE_BACKEND=sqlite`; that database lives at `runtime/multimailer-dev.db`.
|
The default development database is PostgreSQL at `postgresql+psycopg://govoplan_dev@127.0.0.1:5432/govoplan_dev`. Store the password in `~/.pgpass`. To force the disposable SQLite fallback, run with `GOVOPLAN_DEV_DATABASE_BACKEND=sqlite`; that database lives below `runtime/`.
|
||||||
|
|
||||||
Local devserver runs do not require Redis. `CELERY_ENABLED` defaults to `false`, so campaign queue actions update database state without publishing Celery tasks. Use the synchronous send flow for local send tests, or set `CELERY_ENABLED=true` only when a Redis broker and worker are running.
|
Local devserver runs do not require Redis. `CELERY_ENABLED` defaults to `false`, so campaign queue actions update database state without publishing Celery tasks. Use the synchronous send flow for local send tests, or set `CELERY_ENABLED=true` only when a Redis broker and worker are running.
|
||||||
|
|
||||||
|
|||||||
295
Repo-docs-ACCESS-RBAC-MODEL.md
Normal file
295
Repo-docs-ACCESS-RBAC-MODEL.md
Normal file
@@ -0,0 +1,295 @@
|
|||||||
|
<!-- codex-wiki-sync:5cc4f586f61b0996b6e973b1 -->
|
||||||
|
|
||||||
|
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/ACCESS_RBAC_MODEL.md`.
|
||||||
|
> Origin: `repository`.
|
||||||
|
> Active tasks and changing state belong in Gitea issues; this wiki page is durable project context.
|
||||||
|
|
||||||
|
---
|
||||||
|
# GovOPlaN RBAC And Resource-Access Model
|
||||||
|
|
||||||
|
**Updated:** 2026-07-09
|
||||||
|
|
||||||
|
## Authorization Equation
|
||||||
|
|
||||||
|
An operation is permitted only when every applicable layer allows it:
|
||||||
|
|
||||||
|
```text
|
||||||
|
effective role/API-key capability
|
||||||
|
AND resource ownership/share access
|
||||||
|
AND workflow state
|
||||||
|
AND active governance/policy constraints
|
||||||
|
```
|
||||||
|
|
||||||
|
RBAC answers what an actor may do. ACLs answer which resource the actor may do
|
||||||
|
it to. Workflow state and policy decide whether the operation is currently
|
||||||
|
valid.
|
||||||
|
|
||||||
|
## Identity And Scope
|
||||||
|
|
||||||
|
```text
|
||||||
|
Account global login identity
|
||||||
|
+- User membership tenant-local identity
|
||||||
|
+- direct tenant roles
|
||||||
|
+- active group memberships
|
||||||
|
| +- inherited tenant roles
|
||||||
|
+- tenant-local API keys
|
||||||
|
|
||||||
|
Account
|
||||||
|
+- direct system-role assignments
|
||||||
|
```
|
||||||
|
|
||||||
|
A browser session has one active tenant membership. System privileges do not
|
||||||
|
silently grant tenant data access. API keys remain tenant-local and receive the
|
||||||
|
intersection of their configured scopes and their owner's live tenant scopes on
|
||||||
|
every request.
|
||||||
|
|
||||||
|
## Wildcards
|
||||||
|
|
||||||
|
```text
|
||||||
|
tenant:* every canonical tenant permission
|
||||||
|
system:* every canonical system permission
|
||||||
|
* legacy alias interpreted as tenant:* only
|
||||||
|
```
|
||||||
|
|
||||||
|
Tenant wildcards never grant system permissions.
|
||||||
|
|
||||||
|
## Canonical Tenant Permissions
|
||||||
|
|
||||||
|
Campaigns:
|
||||||
|
|
||||||
|
```text
|
||||||
|
campaign:read
|
||||||
|
campaign:create
|
||||||
|
campaign:update
|
||||||
|
campaign:copy
|
||||||
|
campaign:archive
|
||||||
|
campaign:delete
|
||||||
|
campaign:share
|
||||||
|
campaign:validate
|
||||||
|
campaign:build
|
||||||
|
campaign:review
|
||||||
|
campaign:send_test
|
||||||
|
campaign:queue
|
||||||
|
campaign:control
|
||||||
|
campaign:send
|
||||||
|
campaign:retry
|
||||||
|
campaign:reconcile
|
||||||
|
```
|
||||||
|
|
||||||
|
Recipients:
|
||||||
|
|
||||||
|
```text
|
||||||
|
recipients:read
|
||||||
|
recipients:write
|
||||||
|
recipients:import
|
||||||
|
recipients:export
|
||||||
|
```
|
||||||
|
|
||||||
|
Files:
|
||||||
|
|
||||||
|
```text
|
||||||
|
files:read
|
||||||
|
files:download
|
||||||
|
files:upload
|
||||||
|
files:organize
|
||||||
|
files:share
|
||||||
|
files:delete
|
||||||
|
files:admin
|
||||||
|
```
|
||||||
|
|
||||||
|
Reports and audit:
|
||||||
|
|
||||||
|
```text
|
||||||
|
reports:read
|
||||||
|
reports:export
|
||||||
|
reports:send
|
||||||
|
audit:read
|
||||||
|
```
|
||||||
|
|
||||||
|
Mail servers:
|
||||||
|
|
||||||
|
```text
|
||||||
|
mail_servers:read
|
||||||
|
mail_servers:use
|
||||||
|
mail_servers:test
|
||||||
|
mail_servers:write
|
||||||
|
mail_servers:manage_credentials
|
||||||
|
```
|
||||||
|
|
||||||
|
Tenant administration:
|
||||||
|
|
||||||
|
```text
|
||||||
|
admin:users:read
|
||||||
|
admin:users:create
|
||||||
|
admin:users:update
|
||||||
|
admin:users:suspend
|
||||||
|
|
||||||
|
admin:groups:read
|
||||||
|
admin:groups:write
|
||||||
|
admin:groups:manage_members
|
||||||
|
|
||||||
|
admin:roles:read
|
||||||
|
admin:roles:write
|
||||||
|
admin:roles:assign
|
||||||
|
|
||||||
|
admin:api_keys:read
|
||||||
|
admin:api_keys:create
|
||||||
|
admin:api_keys:revoke
|
||||||
|
|
||||||
|
admin:settings:read
|
||||||
|
admin:settings:write
|
||||||
|
admin:policies:read
|
||||||
|
admin:policies:write
|
||||||
|
```
|
||||||
|
|
||||||
|
## Canonical System Permissions
|
||||||
|
|
||||||
|
```text
|
||||||
|
system:tenants:read
|
||||||
|
system:tenants:create
|
||||||
|
system:tenants:update
|
||||||
|
system:tenants:suspend
|
||||||
|
|
||||||
|
system:accounts:read
|
||||||
|
system:accounts:create
|
||||||
|
system:accounts:update
|
||||||
|
system:accounts:suspend
|
||||||
|
|
||||||
|
system:roles:read
|
||||||
|
system:roles:write
|
||||||
|
system:roles:assign
|
||||||
|
|
||||||
|
system:access:read
|
||||||
|
system:access:assign
|
||||||
|
|
||||||
|
system:audit:read
|
||||||
|
system:settings:read
|
||||||
|
system:settings:write
|
||||||
|
system:governance:read
|
||||||
|
system:governance:write
|
||||||
|
```
|
||||||
|
|
||||||
|
`system:access:*` remains a read/assignment boundary for cross-tenant and
|
||||||
|
system access handling. It is not a separate primary UI area.
|
||||||
|
|
||||||
|
## Default Tenant Roles
|
||||||
|
|
||||||
|
- **Owner:** `tenant:*`. At least one active operational owner must remain.
|
||||||
|
- **Tenant administrator:** settings, policies, users, groups, roles, API keys,
|
||||||
|
and read access to campaigns/files/reports/audit. Real delivery remains
|
||||||
|
separately delegable.
|
||||||
|
- **Administrator:** all tenant permissions for upgraded installations.
|
||||||
|
- **Access administrator:** membership and assignment management within
|
||||||
|
delegation limits.
|
||||||
|
- **Campaign manager:** prepare, validate, and build campaigns; no review
|
||||||
|
approval or real delivery by default.
|
||||||
|
- **Reviewer:** inspect and approve prepared campaign messages.
|
||||||
|
- **Sender:** mock-test, queue, control, send, retry, and reconcile prepared
|
||||||
|
campaigns; can use/test approved mail profiles.
|
||||||
|
- **File manager:** managed file operations without campaign delivery rights.
|
||||||
|
- **Viewer:** read campaigns, recipients, files, and reports.
|
||||||
|
- **Auditor:** read campaigns, recipient evidence, reports, and audit records;
|
||||||
|
export detailed evidence.
|
||||||
|
|
||||||
|
## Default System Roles
|
||||||
|
|
||||||
|
- **System owner:** `system:*`, protected. At least one active account must
|
||||||
|
retain it.
|
||||||
|
- **System administrator:** all specific system permissions, editable and not
|
||||||
|
protected.
|
||||||
|
- **System auditor:** read-only system registry/settings/governance/audit role,
|
||||||
|
editable.
|
||||||
|
|
||||||
|
## Delegation Ceiling
|
||||||
|
|
||||||
|
For role definition, assignment, and API-key creation:
|
||||||
|
|
||||||
|
```text
|
||||||
|
requested scopes subset of actor delegateable scopes
|
||||||
|
```
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
|
||||||
|
1. Tenant roles may contain tenant scopes only.
|
||||||
|
2. System roles may contain system scopes only.
|
||||||
|
3. Definition rights and assignment rights are separate.
|
||||||
|
4. Group definition and group membership management are separate.
|
||||||
|
5. API-key scopes are intersected with the owner's current effective scopes on
|
||||||
|
every request.
|
||||||
|
6. Suspended accounts, users, tenants, or groups stop contributing access
|
||||||
|
immediately.
|
||||||
|
7. Administrative updates are field-sensitive; a user with only status
|
||||||
|
authority cannot change role assignments.
|
||||||
|
|
||||||
|
## Campaign Ownership And ACLs
|
||||||
|
|
||||||
|
A campaign has exactly one owner:
|
||||||
|
|
||||||
|
```text
|
||||||
|
owner user OR owner group
|
||||||
|
```
|
||||||
|
|
||||||
|
Additional active shares may target users or groups with `read` or `write`.
|
||||||
|
|
||||||
|
Resolution:
|
||||||
|
|
||||||
|
- owner user: read and write;
|
||||||
|
- member of owner group: read and write;
|
||||||
|
- explicit read share: read;
|
||||||
|
- explicit write share: read and write;
|
||||||
|
- `tenant:*`: tenant-wide ACL bypass;
|
||||||
|
- ordinary campaign permission without ownership/share: no object access.
|
||||||
|
|
||||||
|
ACLs do not add capabilities. A write share still needs the specific permission
|
||||||
|
for update, validation, review, send, report, retry, or reconciliation.
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
The current file access model distinguishes tenant-level file capabilities from
|
||||||
|
space/folder/file ownership:
|
||||||
|
|
||||||
|
| Scope | Meaning |
|
||||||
|
| --- | --- |
|
||||||
|
| `files:read` | browse/read visible file spaces and metadata |
|
||||||
|
| `files:download` | download file content when ACL permits |
|
||||||
|
| `files:upload` | create files in writable spaces |
|
||||||
|
| `files:organize` | create folders, move files, and update metadata where ACL permits |
|
||||||
|
| `files:share` | share files/spaces according to owner and policy rules |
|
||||||
|
| `files:delete` | delete or retire files where ACL permits |
|
||||||
|
| `files:admin` | tenant-wide administration of user/group file spaces |
|
||||||
|
|
||||||
|
External file connections and spaces are additionally constrained by connector
|
||||||
|
policy and owner/group assignment in the files module.
|
||||||
|
|
||||||
|
## Mail Servers
|
||||||
|
|
||||||
|
| Scope | Meaning |
|
||||||
|
| --- | --- |
|
||||||
|
| `mail_servers:read` | profile metadata and effective policy visibility |
|
||||||
|
| `mail_servers:use` | use an allowed profile for a campaign or message flow |
|
||||||
|
| `mail_servers:test` | run connectivity tests without revealing secrets |
|
||||||
|
| `mail_servers:write` | create/update profile metadata where policy allows |
|
||||||
|
| `mail_servers:manage_credentials` | create/replace SMTP/IMAP secrets or lower-level credentials where policy allows |
|
||||||
|
|
||||||
|
Reusable encrypted profiles exist. Effective usability is also constrained by
|
||||||
|
hierarchical mail-profile policy, ownership, allowed/forced profile sets,
|
||||||
|
credential inheritance mode, lower-level override switches, and allow/deny
|
||||||
|
patterns.
|
||||||
|
|
||||||
|
## Compatibility Aliases
|
||||||
|
|
||||||
|
Compatibility aliases may exist in backend code for upgraded installations, but
|
||||||
|
new UI and docs should use canonical scopes.
|
||||||
|
|
||||||
|
Current alias direction:
|
||||||
|
|
||||||
|
```text
|
||||||
|
* -> tenant:*
|
||||||
|
system:tenants:write -> create/update/suspend tenant scopes
|
||||||
|
system:access:write -> system access assignment/write scopes
|
||||||
|
```
|
||||||
|
|
||||||
|
A separate `retention:*` family is not currently canonical because retention is
|
||||||
|
managed through system settings and tenant policy scopes. Add it only if
|
||||||
|
retention operation duties need separation from general policy/settings
|
||||||
|
administration.
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<!-- codex-wiki-sync:ff49eae099d66fa2cc85476a -->
|
<!-- codex-wiki-sync:c50d21c9bc23d7e4d8722b2d -->
|
||||||
|
|
||||||
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/API_CONDITIONAL_DELTA.md`.
|
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/API_CONDITIONAL_DELTA.md`.
|
||||||
> Origin: `repository`.
|
> Origin: `repository`.
|
||||||
@@ -36,6 +36,11 @@ changed inside a collection.
|
|||||||
Collection endpoints that can expose row-level changes should use the shared
|
Collection endpoints that can expose row-level changes should use the shared
|
||||||
delta contract instead of inventing module-specific formats.
|
delta contract instead of inventing module-specific formats.
|
||||||
|
|
||||||
|
Core provides `core_change_sequence` as the shared monotonic change sequence.
|
||||||
|
Modules record append-only entries in the same database transaction as the
|
||||||
|
resource write. Watermarks are encoded as `seq:<number>` and should be treated
|
||||||
|
as opaque by clients.
|
||||||
|
|
||||||
Backend shape:
|
Backend shape:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
@@ -51,8 +56,8 @@ Backend shape:
|
|||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
- `items`: changed or current items since the requested watermark.
|
- `items`: changed or current items since the requested watermark.
|
||||||
- `deleted`: deleted item markers with at least `id`, and optionally `revision`
|
- `deleted`: deleted item markers with at least `id`, and optionally
|
||||||
and `deleted_at`.
|
`resource_type`, `revision`, and `deleted_at`.
|
||||||
- `watermark`: opaque value the client sends as `since` on the next request.
|
- `watermark`: opaque value the client sends as `since` on the next request.
|
||||||
- `has_more`: true when the client should request the next page with the
|
- `has_more`: true when the client should request the next page with the
|
||||||
returned watermark.
|
returned watermark.
|
||||||
@@ -66,6 +71,18 @@ Recommended query parameters:
|
|||||||
- `limit`: maximum number of changed items plus deleted markers.
|
- `limit`: maximum number of changed items plus deleted markers.
|
||||||
- `include_deleted`: whether deleted markers should be returned.
|
- `include_deleted`: whether deleted markers should be returned.
|
||||||
|
|
||||||
Modules should base watermarks on a monotonic revision, audit/event sequence, or
|
Modules should record changes with:
|
||||||
updated/deleted timestamp that is scoped to the same tenant and authorization
|
|
||||||
rules as the endpoint response.
|
- `module_id`: the owning module, for example `files`.
|
||||||
|
- `collection`: the delta collection, for example `files.assets`.
|
||||||
|
- `resource_type`: stable row kind, for example `file` or `folder`.
|
||||||
|
- `resource_id`: stable resource identifier.
|
||||||
|
- `operation`: `created`, `updated`, or `deleted`.
|
||||||
|
- `tenant_id`: tenant scope when the change is tenant-owned.
|
||||||
|
- `payload`: small, non-secret routing metadata that helps determine whether a
|
||||||
|
tombstone belongs to the requested view.
|
||||||
|
|
||||||
|
The first concrete consumer is `GET /api/v1/files/delta`. Without `since`, it
|
||||||
|
returns the current files/folders snapshot for the requested owner/campaign
|
||||||
|
scope. With `since=seq:<number>`, it returns changed files, changed folders,
|
||||||
|
and tombstones for resources that left the current view.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!-- codex-wiki-sync:acb892c7bff57bb32a283613 -->
|
<!-- codex-wiki-sync:697692fe9fef40e247e27cb5 -->
|
||||||
|
|
||||||
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/DEPLOYMENT_OPERATOR_GUIDE.md`.
|
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/DEPLOYMENT_OPERATOR_GUIDE.md`.
|
||||||
> Origin: `repository`.
|
> Origin: `repository`.
|
||||||
@@ -165,8 +165,8 @@ prefer `FILE_STORAGE_*`.
|
|||||||
| Setting | Default | Notes |
|
| Setting | Default | Notes |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `CORS_ORIGINS` | local dev origins | Set to the exact WebUI origins in staging/production. |
|
| `CORS_ORIGINS` | local dev origins | Set to the exact WebUI origins in staging/production. |
|
||||||
| `AUTH_SESSION_COOKIE_NAME` | `msm_session` | Change only through a controlled rollout because it logs users out. |
|
| `AUTH_SESSION_COOKIE_NAME` | configured default | Change only through a controlled rollout because it logs users out. |
|
||||||
| `AUTH_CSRF_COOKIE_NAME` | `msm_csrf` | Must match WebUI/API deployment. |
|
| `AUTH_CSRF_COOKIE_NAME` | configured default | Must match WebUI/API deployment. |
|
||||||
| `AUTH_COOKIE_SECURE` | `false` | Set `true` behind HTTPS. |
|
| `AUTH_COOKIE_SECURE` | `false` | Set `true` behind HTTPS. |
|
||||||
| `AUTH_COOKIE_SAMESITE` | `lax` | Use a stricter value only after testing login and CSRF flows. |
|
| `AUTH_COOKIE_SAMESITE` | `lax` | Use a stricter value only after testing login and CSRF flows. |
|
||||||
| `AUTH_COOKIE_DOMAIN` | empty | Set only when the API and WebUI intentionally share a parent domain. |
|
| `AUTH_COOKIE_DOMAIN` | empty | Set only when the API and WebUI intentionally share a parent domain. |
|
||||||
@@ -264,15 +264,25 @@ GOVOPLAN_STOP_PROFILE_DEPENDENCIES_ON_EXIT=1 scripts/launch-production-like-dev.
|
|||||||
|
|
||||||
## Module Install/Uninstall Operations
|
## Module Install/Uninstall Operations
|
||||||
|
|
||||||
Use Admin > System > Modules for planning. Use the operator shell for package
|
Use Admin > System > Modules for planning. The running API server validates and
|
||||||
changes:
|
queues install plans; it does not run pip/npm or restart itself from an HTTP
|
||||||
|
request. Package mutation belongs to the trusted installer CLI/daemon in an
|
||||||
|
operator shell while maintenance mode is active.
|
||||||
|
|
||||||
|
Preflight from the server shell:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
govoplan-module-installer --format shell
|
govoplan-module-installer --format shell
|
||||||
|
```
|
||||||
|
|
||||||
|
Apply a prepared plan directly from a controlled shell:
|
||||||
|
|
||||||
|
```bash
|
||||||
govoplan-module-installer --apply --build-webui
|
govoplan-module-installer --apply --build-webui
|
||||||
```
|
```
|
||||||
|
|
||||||
For production-like runs, prefer supervised mode with restart and health checks:
|
For production-like runs, prefer supervised mode with migrations, database
|
||||||
|
backup/restore hooks, restart commands, and health checks:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
govoplan-module-installer \
|
govoplan-module-installer \
|
||||||
@@ -286,6 +296,71 @@ govoplan-module-installer \
|
|||||||
--database-restore-command 'pg_restore --clean --if-exists --dbname "$GOVOPLAN_DATABASE_URL_PGTOOLS" "$GOVOPLAN_DATABASE_BACKUP_PATH"'
|
--database-restore-command 'pg_restore --clean --if-exists --dbname "$GOVOPLAN_DATABASE_URL_PGTOOLS" "$GOVOPLAN_DATABASE_BACKUP_PATH"'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To let the admin UI submit work without executing package managers inside the
|
||||||
|
API process, run the daemon in a separate operator shell:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
govoplan-module-installer \
|
||||||
|
--daemon \
|
||||||
|
--migrate \
|
||||||
|
--build-webui \
|
||||||
|
--database-backup-command 'pg_dump --format=custom "$GOVOPLAN_DATABASE_URL_PGTOOLS" > "$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_PGTOOLS" "$GOVOPLAN_DATABASE_BACKUP_PATH"' \
|
||||||
|
--health-url http://127.0.0.1:8000/health \
|
||||||
|
--restart-command '<restart govoplan server>'
|
||||||
|
```
|
||||||
|
|
||||||
|
The daemon claims one queued request at a time and writes request/run records
|
||||||
|
below `runtime/module-installer`. For process-manager one-shot usage or tests,
|
||||||
|
use `--daemon-once`. Check daemon status with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
govoplan-module-installer --daemon-status --format json
|
||||||
|
```
|
||||||
|
|
||||||
|
The installer uses a runtime lock, snapshots `pip freeze` plus WebUI package
|
||||||
|
files, writes a run record, and marks planned rows as applied only after all
|
||||||
|
commands succeed. With `--migrate`, SQLite databases are backed up through
|
||||||
|
SQLite's backup API; non-SQLite databases require
|
||||||
|
`--database-backup-command`, `--database-restore-check-command`, and
|
||||||
|
`--database-restore-command`.
|
||||||
|
|
||||||
|
Database hook commands receive:
|
||||||
|
|
||||||
|
- `GOVOPLAN_INSTALLER_RUN_DIR`
|
||||||
|
- `GOVOPLAN_DATABASE_URL`
|
||||||
|
- `GOVOPLAN_DATABASE_URL_PGTOOLS` for PostgreSQL tools
|
||||||
|
- `GOVOPLAN_DATABASE_BACKUP_PATH`
|
||||||
|
- `GOVOPLAN_DATABASE_BACKUP_METADATA`
|
||||||
|
|
||||||
|
Avoid embedding secrets directly in commands; prefer environment variables,
|
||||||
|
service credentials, or deployment-local secret injection.
|
||||||
|
|
||||||
|
Inspect installer history and lock state from the operator shell:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
govoplan-module-installer --list-runs --format json
|
||||||
|
govoplan-module-installer --show-run <run-id> --format json
|
||||||
|
govoplan-module-installer --lock-status --format json
|
||||||
|
govoplan-module-installer --list-requests --format json
|
||||||
|
govoplan-module-installer --show-request <request-id> --format json
|
||||||
|
govoplan-module-installer --cancel-request <request-id> --format json
|
||||||
|
govoplan-module-installer --retry-request <request-id> --format json
|
||||||
|
```
|
||||||
|
|
||||||
|
Rollback uses the saved run snapshot:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
govoplan-module-installer --rollback <run-id>
|
||||||
|
govoplan-module-installer --rollback <run-id> --database-restore-command '<override restore command>'
|
||||||
|
```
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
Run the rollback drill before relying on installer automation in a new
|
Run the rollback drill before relying on installer automation in a new
|
||||||
environment:
|
environment:
|
||||||
|
|
||||||
@@ -293,8 +368,22 @@ environment:
|
|||||||
./.venv/bin/python scripts/module-installer-rollback-drill.py --format json
|
./.venv/bin/python scripts/module-installer-rollback-drill.py --format json
|
||||||
```
|
```
|
||||||
|
|
||||||
See `RELEASE_DEPENDENCIES.md` for release package refs, catalog trust,
|
The drill uses temporary SQLite databases and simulated package commands. It
|
||||||
installer daemon operation, rollback records, and destructive module retirement.
|
does not install or uninstall real packages. It exercises:
|
||||||
|
|
||||||
|
- package command failure followed by supervised rollback;
|
||||||
|
- migration failure with a SQLite database snapshot;
|
||||||
|
- restart-command failure;
|
||||||
|
- health timeout after restart;
|
||||||
|
- destructive retirement executor failure with database rollback;
|
||||||
|
- PostgreSQL-style backup, restore-check, and restore hooks;
|
||||||
|
- daemon heartbeat, request queue claim/update, retry/cancel, and stale lock
|
||||||
|
detection/removal.
|
||||||
|
|
||||||
|
See `RELEASE_DEPENDENCIES.md` for release package refs and migration baseline
|
||||||
|
checks. See `CATALOG_TRUST_AND_LICENSING.md` and
|
||||||
|
`RELEASE_CATALOG_WORKFLOW.md` for catalog trust, signing, keyring, replay, and
|
||||||
|
license operation.
|
||||||
|
|
||||||
## Operator Checklist
|
## Operator Checklist
|
||||||
|
|
||||||
|
|||||||
60
Repo-docs-DOCUMENTATION-MAP.md
Normal file
60
Repo-docs-DOCUMENTATION-MAP.md
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
<!-- codex-wiki-sync:ce7ebc0e58d89829724fe8ae -->
|
||||||
|
|
||||||
|
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/DOCUMENTATION_MAP.md`.
|
||||||
|
> Origin: `repository`.
|
||||||
|
> Active tasks and changing state belong in Gitea issues; this wiki page is durable project context.
|
||||||
|
|
||||||
|
---
|
||||||
|
# GovOPlaN Documentation Map
|
||||||
|
|
||||||
|
This map defines the source-of-truth documents for the current repository docs.
|
||||||
|
Use it to avoid duplicating long procedures across architecture, release,
|
||||||
|
operator, and roadmap pages.
|
||||||
|
|
||||||
|
## Core Platform
|
||||||
|
|
||||||
|
| Topic | Canonical document | Notes |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Module architecture and kernel contracts | `MODULE_ARCHITECTURE.md` | Stable module contracts, boundaries, lifecycle, and WebUI contribution rules. |
|
||||||
|
| Access extraction history | `ACCESS_EXTRACTION_PLAN.md` | Historical extraction plan and remaining ownership context only. |
|
||||||
|
| RBAC and resource access | `ACCESS_RBAC_MODEL.md` | Current permission, role, API-key, and resource-access model. |
|
||||||
|
| Governance hierarchy | `GOVERNANCE_MODEL.md` | System, tenant, user/group, campaign policy inheritance and admin UI structure. |
|
||||||
|
| Policy decision DTOs and provenance | `POLICY_CONTRACTS.md` | Shared explain/provenance shape; module-specific policy docs should link here. |
|
||||||
|
| Events and audit trace context | `EVENTS_AND_AUDIT.md` | Event dispatch semantics and audit payload conventions. |
|
||||||
|
|
||||||
|
## Release And Operations
|
||||||
|
|
||||||
|
| Topic | Canonical document | Notes |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Runtime configuration and operator flow | `DEPLOYMENT_OPERATOR_GUIDE.md` | Production/staging configuration, migrations, backups, installer operation, and rollback drill. |
|
||||||
|
| Release package dependencies | `RELEASE_DEPENDENCIES.md` | Release package refs, migration baselines, release lockfiles, and release checklist. |
|
||||||
|
| Catalog publishing workflow | `RELEASE_CATALOG_WORKFLOW.md` | Release-machine steps for signed catalog/keyring publication through `govoplan-web`. |
|
||||||
|
| Catalog trust and licensing rules | `CATALOG_TRUST_AND_LICENSING.md` | Catalog shape, signatures, keyrings, replay protection, and offline licenses. |
|
||||||
|
| Remote WebUI bundle design | `REMOTE_WEBUI_BUNDLES.md` | Experimental controlled-deployment design; normal releases still use package builds. |
|
||||||
|
| Scalability and sizing | `SCALABILITY_AND_SIZING.md` | Core sizing profiles until `govoplan-ops` owns executable operations tooling. |
|
||||||
|
|
||||||
|
## Product And Module Planning
|
||||||
|
|
||||||
|
| Topic | Canonical document | Notes |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Product roadmap waves | `GOVOPLAN_MASTER_ROADMAP.md` | Product-level sequencing and implementation gates. |
|
||||||
|
| Module and issue routing | `GOVOPLAN_MODULE_ROADMAP.md` | Quick map from ideas to owning repositories and issues. |
|
||||||
|
| Durable boundary decisions | `MODULE_BOUNDARY_DECISIONS.md` | Native-vs-connector decisions and missing-module criteria. |
|
||||||
|
| Public-sector integration posture | `PUBLIC_SECTOR_INTEGRATION_STRATEGY.md` | Strategy index; executable target inventory lives in `govoplan-connectors`. |
|
||||||
|
| Configuration packages | `CONFIGURATION_PACKAGES.md` | Package model, provider contract, import/export flow, and tracking slices. |
|
||||||
|
| Government operations vision | `GOVERNMENT_OPERATIONS_VISION.md` | Product vision and reference journeys; active work belongs in issues. |
|
||||||
|
|
||||||
|
## Workflow Docs
|
||||||
|
|
||||||
|
| Topic | Canonical document | Notes |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Gitea issues and wiki sync | `GITEA_ISSUES.md` | Issue labels, imports, wiki mirroring, and Codex state updates. |
|
||||||
|
| Codex local workflow | `CODEX_WORKFLOW.md` | Local agent setup and focused verification commands. |
|
||||||
|
|
||||||
|
## Cross-Repo Rule
|
||||||
|
|
||||||
|
Core docs may keep strategy, kernel contracts, and routing decisions. Module
|
||||||
|
repositories should own executable module behavior, concrete API/UI contracts,
|
||||||
|
and operator notes for their own module. When content spans both, keep the
|
||||||
|
durable decision in core and link to the module document for implementation
|
||||||
|
details.
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<!-- codex-wiki-sync:594603fc964c35213662c309 -->
|
<!-- codex-wiki-sync:140f86b93e1b868e4b7970c1 -->
|
||||||
|
|
||||||
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/GITEA_ISSUES.md`.
|
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/GITEA_ISSUES.md`.
|
||||||
> Origin: `repository`.
|
> Origin: `repository`.
|
||||||
@@ -215,6 +215,13 @@ Apply the wiki mirror:
|
|||||||
./scripts/gitea-sync-wiki.py --env-file /home/zemion/.config/gitea/gitea.env --apply
|
./scripts/gitea-sync-wiki.py --env-file /home/zemion/.config/gitea/gitea.env --apply
|
||||||
```
|
```
|
||||||
|
|
||||||
|
After renaming or deleting repository docs, prune previously managed wiki pages
|
||||||
|
that no longer have a source file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/gitea-sync-wiki.py --env-file /home/zemion/.config/gitea/gitea.env --repo govoplan-core --prune-managed --apply
|
||||||
|
```
|
||||||
|
|
||||||
The default apply path uses the Gitea wiki git repository, not one REST API
|
The default apply path uses the Gitea wiki git repository, not one REST API
|
||||||
request per page. It keeps a local checkout cache below
|
request per page. It keeps a local checkout cache below
|
||||||
`/tmp/codex-gitea-wiki-sync`, commits changed pages once per repository, and
|
`/tmp/codex-gitea-wiki-sync`, commits changed pages once per repository, and
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
<!-- codex-wiki-sync:52df55abecef39b15ef93822 -->
|
<!-- codex-wiki-sync:41153300a1e89969d44135dd -->
|
||||||
|
|
||||||
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/SYSTEM_GOVERNANCE_MANIFEST.md`.
|
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/GOVERNANCE_MODEL.md`.
|
||||||
> Origin: `repository`.
|
> Origin: `repository`.
|
||||||
> Active tasks and changing state belong in Gitea issues; this wiki page is durable project context.
|
> Active tasks and changing state belong in Gitea issues; this wiki page is durable project context.
|
||||||
|
|
||||||
---
|
---
|
||||||
# Multi Seal Mail - Current System and Tenant Governance Model
|
# GovOPlaN Governance Model
|
||||||
|
|
||||||
**Updated:** 2026-06-16
|
**Updated:** 2026-07-09
|
||||||
**Current migration head:** `f5a6b7c8d9e0`
|
|
||||||
|
|
||||||
## Governance Rule
|
## Governance Rule
|
||||||
|
|
||||||
System policy is authoritative for tenants and all lower levels. Each lower level may only narrow what it inherits:
|
System policy is authoritative for tenants and all lower levels. Each lower
|
||||||
|
level may only narrow what it inherits:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
system
|
system
|
||||||
@@ -21,52 +21,65 @@ system
|
|||||||
-> campaign
|
-> campaign
|
||||||
```
|
```
|
||||||
|
|
||||||
Lower levels do not widen privileges, allowed profiles, retention durations or credential rights granted by a higher level.
|
Lower levels do not widen privileges, allowed profiles, retention durations, or
|
||||||
|
credential rights granted by a higher level.
|
||||||
|
|
||||||
## Administration Structure
|
## Administration Structure
|
||||||
|
|
||||||
|
GovOPlaN separates system administration from scoped configuration:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
SYSTEM
|
ADMINISTRATION
|
||||||
- Settings
|
- Modules
|
||||||
- Retention
|
- Packages
|
||||||
- Mail servers
|
- Maintenance
|
||||||
|
- Changes
|
||||||
|
|
||||||
|
GLOBAL
|
||||||
- Tenants
|
- Tenants
|
||||||
- Users
|
- Roles
|
||||||
- Groups
|
- Groups and users
|
||||||
- System roles
|
- File connectors
|
||||||
- Tenant roles
|
- Mail servers
|
||||||
- Audit
|
- API keys
|
||||||
|
- Retention
|
||||||
|
|
||||||
TENANT
|
TENANT
|
||||||
- Settings boundary
|
|
||||||
- Users
|
|
||||||
- Groups
|
|
||||||
- Roles
|
- Roles
|
||||||
- API keys
|
- Groups and users
|
||||||
|
- File connectors
|
||||||
- Mail servers
|
- Mail servers
|
||||||
|
- API keys
|
||||||
- Retention
|
- Retention
|
||||||
- Audit
|
|
||||||
|
|
||||||
USER
|
|
||||||
- User mail
|
|
||||||
- User retention
|
|
||||||
|
|
||||||
GROUP
|
GROUP
|
||||||
- Group mail
|
- File connectors
|
||||||
- Group retention
|
- Mail servers
|
||||||
|
- API keys
|
||||||
|
- Retention
|
||||||
|
|
||||||
|
USER
|
||||||
|
- File connectors
|
||||||
|
- Mail servers
|
||||||
|
- API keys
|
||||||
|
- Retention
|
||||||
```
|
```
|
||||||
|
|
||||||
There is no separate System access page. Compatibility access scopes remain in the backend for assignment/read boundaries.
|
System access scopes remain in the backend for assignment/read boundaries, but
|
||||||
|
the UI should present the configuration hierarchy rather than a separate
|
||||||
|
"system access" concept.
|
||||||
|
|
||||||
## Tenant Governance
|
## Tenant Governance
|
||||||
|
|
||||||
System settings define tenant defaults and whether tenants may narrow selected options. Tenant overrides can only restrict:
|
System settings define tenant defaults and whether tenants may narrow selected
|
||||||
|
options. Tenant overrides can only restrict:
|
||||||
|
|
||||||
- custom groups;
|
- custom groups;
|
||||||
- custom roles;
|
- custom roles;
|
||||||
- tenant API keys.
|
- tenant API keys.
|
||||||
|
|
||||||
The backend enforces that tenant governance cannot widen system-denied privileges.
|
The backend enforces that tenant governance cannot widen system-denied
|
||||||
|
privileges.
|
||||||
|
|
||||||
## Mail-Profile Governance
|
## Mail-Profile Governance
|
||||||
|
|
||||||
@@ -80,7 +93,10 @@ group
|
|||||||
campaign
|
campaign
|
||||||
```
|
```
|
||||||
|
|
||||||
Effective campaign profile availability follows campaign ownership. A campaign owned by a user resolves through system, tenant, that user and campaign policy. A group-owned campaign resolves through system, tenant, that group and campaign policy.
|
Effective campaign profile availability follows campaign ownership. A campaign
|
||||||
|
owned by a user resolves through system, tenant, that user, and campaign
|
||||||
|
policy. A group-owned campaign resolves through system, tenant, that group, and
|
||||||
|
campaign policy.
|
||||||
|
|
||||||
Policy semantics:
|
Policy semantics:
|
||||||
|
|
||||||
@@ -88,12 +104,18 @@ Policy semantics:
|
|||||||
- lower levels can further restrict the set;
|
- lower levels can further restrict the set;
|
||||||
- forced profiles mean the lower level must choose from the forced set;
|
- forced profiles mean the lower level must choose from the forced set;
|
||||||
- a forced set with one profile effectively enforces that profile;
|
- a forced set with one profile effectively enforces that profile;
|
||||||
- campaign-level profile creation is allowed only if the effective policy permits it;
|
- campaign-level profile creation is allowed only if the effective policy
|
||||||
- SMTP/IMAP credentials use one inheritance decision per protocol: lower levels must inherit profile credentials, may inherit profile credentials, or must provide local credentials;
|
permits it;
|
||||||
- the lower-level override switch for `smtp_credentials.inherit` and `imap_credentials.inherit` controls whether descendants may change that inheritance decision;
|
- SMTP/IMAP credentials use one inheritance decision per protocol: lower levels
|
||||||
|
must inherit profile credentials, may inherit profile credentials, or must
|
||||||
|
provide local credentials;
|
||||||
|
- the lower-level override switch for `smtp_credentials.inherit` and
|
||||||
|
`imap_credentials.inherit` controls whether descendants may change that
|
||||||
|
inheritance decision;
|
||||||
- deny patterns always win over allow patterns;
|
- deny patterns always win over allow patterns;
|
||||||
- empty or `*` allowlist means allow all except denied;
|
- empty or `*` allowlist means allow all except denied;
|
||||||
- non-empty allowlist means at least one allow rule must match and no deny rule may match.
|
- non-empty allowlist means at least one allow rule must match and no deny rule
|
||||||
|
may match.
|
||||||
|
|
||||||
Pattern targets:
|
Pattern targets:
|
||||||
|
|
||||||
@@ -105,7 +127,23 @@ From header
|
|||||||
recipient domains
|
recipient domains
|
||||||
```
|
```
|
||||||
|
|
||||||
Ownership transfer is intentionally deferred as a two-step workflow: original owner initiates, new owner accepts and reselects/repairs the mail profile if their effective policy requires it.
|
Ownership transfer is intentionally deferred as a two-step workflow: original
|
||||||
|
owner initiates, new owner accepts and reselects/repairs the mail profile if
|
||||||
|
their effective policy requires it.
|
||||||
|
|
||||||
|
## File-Connector Governance
|
||||||
|
|
||||||
|
File connector profiles and credentials are separated. Profiles describe
|
||||||
|
external endpoints; credentials bind authentication material and policy to a
|
||||||
|
scope. Concrete linked folders appear as file spaces in the files module.
|
||||||
|
|
||||||
|
Governance follows the same inheritance shape as mail:
|
||||||
|
|
||||||
|
- system and tenant policy can permit, require, or forbid lower-level
|
||||||
|
connections/credentials;
|
||||||
|
- user or group ownership controls which spaces appear to principals;
|
||||||
|
- spaces inherit endpoint and credential policy from their connector profile;
|
||||||
|
- connector health and credential tests must not reveal plaintext secrets.
|
||||||
|
|
||||||
## Retention Governance
|
## Retention Governance
|
||||||
|
|
||||||
@@ -127,20 +165,27 @@ Rules:
|
|||||||
|
|
||||||
- system may set concrete defaults or unlimited retention;
|
- system may set concrete defaults or unlimited retention;
|
||||||
- system exposes allow-limiting toggles per field;
|
- system exposes allow-limiting toggles per field;
|
||||||
- tenants, users/groups and campaigns may only shorten inherited retention where the parent allows limiting;
|
- tenants, users/groups, and campaigns may only shorten inherited retention
|
||||||
|
where the parent allows limiting;
|
||||||
- blank lower-level values inherit;
|
- blank lower-level values inherit;
|
||||||
- mock mailbox retention is currently system-level because mock mailbox records do not yet carry tenant/campaign ownership metadata;
|
- mock mailbox retention is currently system-level because mock mailbox records
|
||||||
- dry-run/apply retention actions report affected classes before destructive cleanup.
|
do not yet carry tenant/campaign ownership metadata;
|
||||||
|
- dry-run/apply retention actions report affected classes before destructive
|
||||||
|
cleanup.
|
||||||
|
|
||||||
## Role Definitions and Assignments
|
## Role Definitions And Assignments
|
||||||
|
|
||||||
### System roles
|
### System Roles
|
||||||
|
|
||||||
System roles define instance-wide permissions. `system:*` is stored as one wildcard and displayed as granting the full system catalogue. System owner is protected.
|
System roles define instance-wide permissions. `system:*` is stored as one
|
||||||
|
wildcard and displayed as granting the full system catalogue. System owner is
|
||||||
|
protected.
|
||||||
|
|
||||||
### Tenant roles
|
### Tenant Roles
|
||||||
|
|
||||||
Tenant roles can be system-governed templates or tenant-local definitions, subject to system tenant-governance settings and actor delegation ceilings. Wildcard counts are expanded against the canonical tenant catalogue.
|
Tenant roles can be system-governed templates or tenant-local definitions,
|
||||||
|
subject to system tenant-governance settings and actor delegation ceilings.
|
||||||
|
Wildcard counts are expanded against the canonical tenant catalogue.
|
||||||
|
|
||||||
## Audit Access
|
## Audit Access
|
||||||
|
|
||||||
@@ -151,15 +196,17 @@ system audit -> system:audit:read
|
|||||||
tenant audit -> active tenant + audit:read
|
tenant audit -> active tenant + audit:read
|
||||||
```
|
```
|
||||||
|
|
||||||
Audit pages use server pagination, filtering and bounded grids.
|
Audit pages use server pagination, filtering, and bounded grids.
|
||||||
|
|
||||||
## Tenant Switching
|
## Tenant Switching
|
||||||
|
|
||||||
Tenant switching preserves the current URL when possible and falls back when a route/resource is not accessible in the new tenant context.
|
Tenant switching preserves the current URL when possible and falls back when a
|
||||||
|
route/resource is not accessible in the new tenant context.
|
||||||
|
|
||||||
The tenant selector is hidden for ordinary single-tenant accounts and visible for multi-tenant or system tenant-management contexts.
|
The tenant selector is hidden for ordinary single-tenant accounts and visible
|
||||||
|
for multi-tenant or system tenant-management contexts.
|
||||||
|
|
||||||
## DataGrid Contract in Administration
|
## Administration DataGrid Contract
|
||||||
|
|
||||||
Admin lists use bounded container grids:
|
Admin lists use bounded container grids:
|
||||||
|
|
||||||
@@ -171,14 +218,12 @@ Admin lists use bounded container grids:
|
|||||||
- sticky headers where needed;
|
- sticky headers where needed;
|
||||||
- server pagination for audit.
|
- server pagination for audit.
|
||||||
|
|
||||||
## Still Deferred
|
## Deferred Work
|
||||||
|
|
||||||
- real SMTP/IMAP test-bed verification and operator runbook;
|
- real SMTP/IMAP test-bed verification and operator runbook;
|
||||||
- recipient import with column mapping;
|
- recipient import with column mapping;
|
||||||
- Seafile/external connector governance;
|
|
||||||
- system/tenant/group/user file-space hierarchy and external storage hierarchy;
|
|
||||||
- session/device revocation UI;
|
- session/device revocation UI;
|
||||||
- backup/restore, monitoring and update procedures;
|
- backup/restore, monitoring, and update procedures;
|
||||||
- DSAR workflows and evidence bundle verifier;
|
- DSAR workflows and evidence bundle verifier;
|
||||||
- campaign ownership transfer workflow;
|
- campaign ownership transfer workflow;
|
||||||
- policy impact analysis before delete/disable/unshare/change;
|
- policy impact analysis before delete/disable/unshare/change;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<!-- codex-wiki-sync:2ad17e6a9dae70657f3db355 -->
|
<!-- codex-wiki-sync:2309280bdcc08466992f87bf -->
|
||||||
|
|
||||||
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/GOVOPLAN_MODULE_ROADMAP.md`.
|
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/GOVOPLAN_MODULE_ROADMAP.md`.
|
||||||
> Origin: `repository`.
|
> Origin: `repository`.
|
||||||
@@ -53,12 +53,13 @@ Gitea wiki. Boundary decisions are recorded in
|
|||||||
| Installer/deployment operator flow | `govoplan-core`, later `govoplan-ops` | `add-ideas/govoplan-core#26` |
|
| Installer/deployment operator flow | `govoplan-core`, later `govoplan-ops` | `add-ideas/govoplan-core#26` |
|
||||||
| Production-like deployment documentation | `govoplan-core`, later `govoplan-ops` | `add-ideas/govoplan-core#28` |
|
| Production-like deployment documentation | `govoplan-core`, later `govoplan-ops` | `add-ideas/govoplan-core#28` |
|
||||||
|
|
||||||
## Proposed Missing Modules
|
|
||||||
|
|
||||||
## Boundary Decision Register
|
## Boundary Decision Register
|
||||||
|
|
||||||
`docs/MODULE_BOUNDARY_DECISIONS.md` is the durable decision register for older
|
`docs/MODULE_BOUNDARY_DECISIONS.md` is the durable decision register for older
|
||||||
roadmap and boundary issues. Current decisions:
|
roadmap and boundary issues. Keep decision rationale there; keep this page as a
|
||||||
|
quick routing map from ideas to repositories and tracking issues.
|
||||||
|
|
||||||
|
Current decisions:
|
||||||
|
|
||||||
- templates and reporting are separate modules
|
- templates and reporting are separate modules
|
||||||
- RSS/source consume-publish starts in connectors; datasources/dataflow are not
|
- RSS/source consume-publish starts in connectors; datasources/dataflow are not
|
||||||
@@ -72,41 +73,15 @@ roadmap and boundary issues. Current decisions:
|
|||||||
|
|
||||||
## Proposed Missing Modules
|
## Proposed Missing Modules
|
||||||
|
|
||||||
`govoplan-datasources` is not created yet. It should exist only if source
|
The following modules are intentionally not created yet. Their candidate
|
||||||
catalog ownership becomes broad enough to justify a module separate from
|
responsibilities and creation criteria live in `MODULE_BOUNDARY_DECISIONS.md`:
|
||||||
connectors, files, and reporting. Candidate responsibilities:
|
|
||||||
|
|
||||||
- source catalogue for SQL databases, CSV/Excel files, uploaded files, APIs, RSS feeds, and governed file locations
|
- `govoplan-datasources`
|
||||||
- credentials and connection profiles
|
- `govoplan-dataflow`
|
||||||
- schema discovery and refresh cadence
|
- `govoplan-projects`
|
||||||
- provenance, freshness, permission boundaries, and audit events
|
|
||||||
|
|
||||||
`govoplan-dataflow` is not created yet. It should exist only if pipelines and
|
Create a repository only after a concrete implementation package proves that
|
||||||
publication become first-class product behavior beyond workflow, connectors,
|
existing connector, files, reporting, workflow, or task ownership is too narrow.
|
||||||
and reporting. Candidate responsibilities:
|
|
||||||
|
|
||||||
- ingestion, transformation, validation, scheduling, and lineage
|
|
||||||
- connecting datasources to reports, APIs, RSS, exports, and downstream systems
|
|
||||||
- the "consume sources, become source" lifecycle
|
|
||||||
- publication-state and audit integration
|
|
||||||
|
|
||||||
`govoplan-projects` is intentionally not created yet. The decision is
|
|
||||||
connector-first through OpenProject. A native module is justified only if
|
|
||||||
GovOPlaN must own project semantics beyond cases, tasks, workflow,
|
|
||||||
appointments, documents, and reporting.
|
|
||||||
|
|
||||||
## Boundary Notes
|
|
||||||
|
|
||||||
- `govoplan-connectors` owns protocol and external-system integration strategy. It should not own business semantics once a domain module exists.
|
|
||||||
- `govoplan-files` owns file storage semantics and file-provider contracts. Remote provider implementations must stay optional.
|
|
||||||
- `govoplan-dms` owns document lifecycle, collaboration, versions, approvals, locks, retention, and legal hold.
|
|
||||||
- `govoplan-addresses` owns persons, organizations, postal/email addresses, distribution lists, and recipient import/export.
|
|
||||||
- `govoplan-calendar` owns events, availability, resources, recurrence, and groupware calendar adapters.
|
|
||||||
- `govoplan-scheduling` owns meeting scheduling polls, participant availability collection, candidate-slot ranking, and decision handoff.
|
|
||||||
- `govoplan-appointments` owns public/internal appointment-booking workflows.
|
|
||||||
- `govoplan-idm` owns directory, provisioning, and identity-provider integration; `govoplan-access` consumes resolved principals and permissions.
|
|
||||||
- `govoplan-reporting` owns report definitions, BI views, scheduled outputs, and export targets.
|
|
||||||
- `govoplan-templates` owns reusable renderable templates, not data selection or persistence.
|
|
||||||
|
|
||||||
## Integration Catalogue Routing
|
## Integration Catalogue Routing
|
||||||
|
|
||||||
@@ -120,23 +95,5 @@ When a target needs executable behavior, create the implementation issue in the
|
|||||||
owning module repository and keep only the cross-module routing or architecture
|
owning module repository and keep only the cross-module routing or architecture
|
||||||
decision in core.
|
decision in core.
|
||||||
|
|
||||||
## Release Tooling Note
|
Release composition and tag-only repository handling are documented in
|
||||||
|
`RELEASE_DEPENDENCIES.md`.
|
||||||
`scripts/push-release-tag.sh` covers the released full-product package set:
|
|
||||||
|
|
||||||
- `govoplan-access`
|
|
||||||
- `govoplan-admin`
|
|
||||||
- `govoplan-tenancy`
|
|
||||||
- `govoplan-policy`
|
|
||||||
- `govoplan-audit`
|
|
||||||
- `govoplan-files`
|
|
||||||
- `govoplan-mail`
|
|
||||||
- `govoplan-campaign`
|
|
||||||
- `govoplan-calendar`
|
|
||||||
- `govoplan-core`
|
|
||||||
|
|
||||||
It also includes existing roadmap/scaffold module repositories such as addresses, appointments, connectors, DMS, forms, IDM, reporting, scheduling, templates, workflow, XOE/V, and XRechnung as tag-only repositories. Tag-only repositories are committed, tagged, and pushed with the same release tag, but they are not added to `requirements-release.txt` or `webui/package.release.json` until they contain installable package metadata.
|
|
||||||
|
|
||||||
Proposed modules without repositories, such as `govoplan-datasources`,
|
|
||||||
`govoplan-dataflow`, and `govoplan-projects`, cannot be included until a later
|
|
||||||
decision creates their repositories.
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!-- codex-wiki-sync:17655e955d797a78fafc4a99 -->
|
<!-- codex-wiki-sync:91c58fb1c95354b9b6f10f5a -->
|
||||||
|
|
||||||
> 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`.
|
||||||
@@ -50,9 +50,9 @@ The kernel must not own product semantics such as users, tenants, RBAC decisions
|
|||||||
During the staged split, `govoplan-core` still contains compatibility surfaces
|
During the staged split, `govoplan-core` still contains compatibility surfaces
|
||||||
for tenancy settings, governance/policy contracts, audit helpers, CSRF/API
|
for tenancy settings, governance/policy contracts, audit helpers, CSRF/API
|
||||||
helpers, and secret helpers. The extracted access implementation lives in
|
helpers, and secret helpers. The extracted access implementation lives in
|
||||||
`govoplan-access`; live legacy ORM table definitions have been split across
|
`govoplan-access`; live ORM table definitions have been split across their
|
||||||
their platform owners while retaining historical table names. The old core
|
platform owners using module-prefixed table names. The old core route,
|
||||||
route, admin-service, and access-security re-export modules have been removed.
|
admin-service, and access-security re-export modules have been removed.
|
||||||
Callers must use module-owned imports, the public `govoplan_access.auth` request
|
Callers must use module-owned imports, the public `govoplan_access.auth` request
|
||||||
dependency API, or kernel capabilities.
|
dependency API, or kernel capabilities.
|
||||||
The remaining platform compatibility surfaces are temporary until the matching
|
The remaining platform compatibility surfaces are temporary until the matching
|
||||||
|
|||||||
@@ -1,298 +0,0 @@
|
|||||||
<!-- codex-wiki-sync:40f840a9dc93adaef56c7dc1 -->
|
|
||||||
|
|
||||||
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/RBAC_MANIFEST.md`.
|
|
||||||
> Origin: `repository`.
|
|
||||||
> Active tasks and changing state belong in Gitea issues; this wiki page is durable project context.
|
|
||||||
|
|
||||||
---
|
|
||||||
# Multi Seal Mail - Current RBAC and Resource-Access Model
|
|
||||||
|
|
||||||
**Updated:** 2026-06-16
|
|
||||||
**Current migration head:** `f5a6b7c8d9e0`
|
|
||||||
|
|
||||||
## Authorization Equation
|
|
||||||
|
|
||||||
An operation is permitted only when every applicable layer allows it:
|
|
||||||
|
|
||||||
```text
|
|
||||||
effective role/API-key capability
|
|
||||||
AND resource ownership/share access
|
|
||||||
AND workflow state
|
|
||||||
AND active governance/policy constraints
|
|
||||||
```
|
|
||||||
|
|
||||||
RBAC answers what an actor may do. ACLs answer which resource the actor may do it to. Workflow state and policy decide whether the operation is currently valid.
|
|
||||||
|
|
||||||
## Identity and Scope
|
|
||||||
|
|
||||||
```text
|
|
||||||
Account global login identity
|
|
||||||
+- User membership tenant-local identity
|
|
||||||
+- direct tenant roles
|
|
||||||
+- active group memberships
|
|
||||||
| +- inherited tenant roles
|
|
||||||
+- tenant-local API keys
|
|
||||||
|
|
||||||
Account
|
|
||||||
+- direct system-role assignments
|
|
||||||
```
|
|
||||||
|
|
||||||
A browser session has one active tenant membership. System privileges do not silently grant tenant data access. API keys remain tenant-local and receive the intersection of their configured scopes and their owner's live tenant scopes on every request.
|
|
||||||
|
|
||||||
## Wildcards
|
|
||||||
|
|
||||||
```text
|
|
||||||
tenant:* every canonical tenant permission
|
|
||||||
system:* every canonical system permission
|
|
||||||
* legacy alias interpreted as tenant:* only
|
|
||||||
```
|
|
||||||
|
|
||||||
Tenant wildcards never grant system permissions.
|
|
||||||
|
|
||||||
## Canonical Tenant Permissions - 53
|
|
||||||
|
|
||||||
### Campaigns
|
|
||||||
|
|
||||||
```text
|
|
||||||
campaign:read
|
|
||||||
campaign:create
|
|
||||||
campaign:update
|
|
||||||
campaign:copy
|
|
||||||
campaign:archive
|
|
||||||
campaign:delete
|
|
||||||
campaign:share
|
|
||||||
campaign:validate
|
|
||||||
campaign:build
|
|
||||||
campaign:review
|
|
||||||
campaign:send_test
|
|
||||||
campaign:queue
|
|
||||||
campaign:control
|
|
||||||
campaign:send
|
|
||||||
campaign:retry
|
|
||||||
campaign:reconcile
|
|
||||||
```
|
|
||||||
|
|
||||||
### Recipients
|
|
||||||
|
|
||||||
```text
|
|
||||||
recipients:read
|
|
||||||
recipients:write
|
|
||||||
recipients:import
|
|
||||||
recipients:export
|
|
||||||
```
|
|
||||||
|
|
||||||
### Files
|
|
||||||
|
|
||||||
```text
|
|
||||||
files:read
|
|
||||||
files:download
|
|
||||||
files:upload
|
|
||||||
files:organize
|
|
||||||
files:share
|
|
||||||
files:delete
|
|
||||||
files:admin
|
|
||||||
```
|
|
||||||
|
|
||||||
### Reports and Audit
|
|
||||||
|
|
||||||
```text
|
|
||||||
reports:read
|
|
||||||
reports:export
|
|
||||||
reports:send
|
|
||||||
audit:read
|
|
||||||
```
|
|
||||||
|
|
||||||
### Mail Servers
|
|
||||||
|
|
||||||
```text
|
|
||||||
mail_servers:read
|
|
||||||
mail_servers:use
|
|
||||||
mail_servers:test
|
|
||||||
mail_servers:write
|
|
||||||
mail_servers:manage_credentials
|
|
||||||
```
|
|
||||||
|
|
||||||
### Tenant Administration
|
|
||||||
|
|
||||||
```text
|
|
||||||
admin:users:read
|
|
||||||
admin:users:create
|
|
||||||
admin:users:update
|
|
||||||
admin:users:suspend
|
|
||||||
|
|
||||||
admin:groups:read
|
|
||||||
admin:groups:write
|
|
||||||
admin:groups:manage_members
|
|
||||||
|
|
||||||
admin:roles:read
|
|
||||||
admin:roles:write
|
|
||||||
admin:roles:assign
|
|
||||||
|
|
||||||
admin:api_keys:read
|
|
||||||
admin:api_keys:create
|
|
||||||
admin:api_keys:revoke
|
|
||||||
|
|
||||||
admin:settings:read
|
|
||||||
admin:settings:write
|
|
||||||
admin:policies:read
|
|
||||||
admin:policies:write
|
|
||||||
```
|
|
||||||
|
|
||||||
## Canonical System Permissions - 18
|
|
||||||
|
|
||||||
```text
|
|
||||||
system:tenants:read
|
|
||||||
system:tenants:create
|
|
||||||
system:tenants:update
|
|
||||||
system:tenants:suspend
|
|
||||||
|
|
||||||
system:accounts:read
|
|
||||||
system:accounts:create
|
|
||||||
system:accounts:update
|
|
||||||
system:accounts:suspend
|
|
||||||
|
|
||||||
system:roles:read
|
|
||||||
system:roles:write
|
|
||||||
system:roles:assign
|
|
||||||
|
|
||||||
system:access:read
|
|
||||||
system:access:assign
|
|
||||||
|
|
||||||
system:audit:read
|
|
||||||
system:settings:read
|
|
||||||
system:settings:write
|
|
||||||
system:governance:read
|
|
||||||
system:governance:write
|
|
||||||
```
|
|
||||||
|
|
||||||
`system:access:*` remains as a compatibility/read and assignment boundary for cross-tenant/system access handling. It is not a separate primary UI area.
|
|
||||||
|
|
||||||
## Default Tenant Roles
|
|
||||||
|
|
||||||
- **Owner:** `tenant:*`. At least one active operational owner must remain.
|
|
||||||
- **Tenant administrator:** settings, policies, users, groups, roles and API keys plus read access to campaigns/files/reports/audit. Real delivery remains separately delegable.
|
|
||||||
- **Administrator (legacy):** all tenant permissions for upgraded installations.
|
|
||||||
- **Access administrator:** membership and assignment management within delegation limits.
|
|
||||||
- **Campaign manager:** prepare, validate and build campaigns; no review approval or real delivery by default.
|
|
||||||
- **Reviewer:** inspect and approve prepared campaign messages.
|
|
||||||
- **Sender:** mock-test, queue, control, send, retry and reconcile prepared campaigns; can use/test approved mail profiles.
|
|
||||||
- **File manager:** managed file operations without campaign delivery rights.
|
|
||||||
- **Viewer:** read campaigns, recipients, files and reports.
|
|
||||||
- **Auditor:** read campaigns, recipient evidence, reports and audit records; export detailed evidence.
|
|
||||||
|
|
||||||
## Default System Roles
|
|
||||||
|
|
||||||
- **System owner:** `system:*`, protected. At least one active account must retain it.
|
|
||||||
- **System administrator:** all specific system permissions, editable and not protected.
|
|
||||||
- **System auditor:** read-only system registry/settings/governance/audit role, editable.
|
|
||||||
|
|
||||||
## Delegation Ceiling
|
|
||||||
|
|
||||||
For role definition, assignment and API-key creation:
|
|
||||||
|
|
||||||
```text
|
|
||||||
requested scopes subset of actor delegateable scopes
|
|
||||||
```
|
|
||||||
|
|
||||||
Rules:
|
|
||||||
|
|
||||||
1. Tenant roles may contain tenant scopes only.
|
|
||||||
2. System roles may contain system scopes only.
|
|
||||||
3. Definition rights and assignment rights are separate.
|
|
||||||
4. Group definition and group membership management are separate.
|
|
||||||
5. API-key scopes are intersected with the owner's current effective scopes on every request.
|
|
||||||
6. Suspended accounts, users, tenants or groups stop contributing access immediately.
|
|
||||||
7. Administrative updates are field-sensitive; a user with only status authority cannot change role assignments.
|
|
||||||
|
|
||||||
## Campaign Ownership and ACLs
|
|
||||||
|
|
||||||
A campaign has exactly one owner:
|
|
||||||
|
|
||||||
```text
|
|
||||||
owner user OR owner group
|
|
||||||
```
|
|
||||||
|
|
||||||
Additional active shares may target users or groups with `read` or `write`.
|
|
||||||
|
|
||||||
Resolution:
|
|
||||||
|
|
||||||
- owner user: read and write;
|
|
||||||
- member of owner group: read and write;
|
|
||||||
- explicit read share: read;
|
|
||||||
- explicit write share: read and write;
|
|
||||||
- `tenant:*`: tenant-wide ACL bypass;
|
|
||||||
- ordinary campaign permission without ownership/share: no object access.
|
|
||||||
|
|
||||||
ACLs do not add capabilities. A write share still needs the specific permission for update, validation, review, send, report, retry or reconciliation.
|
|
||||||
|
|
||||||
## Sensitive Recipient Boundary
|
|
||||||
|
|
||||||
Recipient-complete campaign JSON, message data and job detail require `recipients:read`. Recipient edits require `recipients:write`; exports require `recipients:export`; import is reserved for the dedicated recipient import/list workflow.
|
|
||||||
|
|
||||||
## Files
|
|
||||||
|
|
||||||
| Permission | Operations |
|
|
||||||
|---|---|
|
|
||||||
| `files:read` | list, search, inspect, resolve metadata |
|
|
||||||
| `files:download` | download file bytes and generated ZIP archives |
|
|
||||||
| `files:upload` | upload files and ZIP contents |
|
|
||||||
| `files:organize` | create folders, rename, move, copy and bulk rename |
|
|
||||||
| `files:share` | create/revoke file shares |
|
|
||||||
| `files:delete` | delete/hide files and folders subject to retention |
|
|
||||||
| `files:admin` | tenant-wide administration of user/group file spaces |
|
|
||||||
|
|
||||||
## Mail Servers
|
|
||||||
|
|
||||||
| Permission | Boundary |
|
|
||||||
|---|---|
|
|
||||||
| `mail_servers:read` | profile metadata and effective policy visibility |
|
|
||||||
| `mail_servers:use` | select an approved profile without reading secrets |
|
|
||||||
| `mail_servers:test` | run server-side connection tests |
|
|
||||||
| `mail_servers:write` | define/edit profiles in allowed scopes |
|
|
||||||
| `mail_servers:manage_credentials` | create/replace SMTP/IMAP secrets or campaign-level credentials where policy allows |
|
|
||||||
|
|
||||||
Reusable encrypted profiles now exist. Effective usability is also constrained by hierarchical mail-profile policy, ownership, allowed/forced profile sets, credential inheritance mode, the lower-level override switch for that mode, and allow/deny patterns.
|
|
||||||
|
|
||||||
## Sessions, API Keys and CSRF
|
|
||||||
|
|
||||||
- Browser login creates an HttpOnly session cookie and a separate readable CSRF cookie.
|
|
||||||
- Unsafe cookie-authenticated requests require matching CSRF cookie/header and stored CSRF hash.
|
|
||||||
- API keys remain supported for CLI/automation and do not use browser CSRF.
|
|
||||||
- Login responses still expose a compatibility session token in the response body; the WebUI does not persist it.
|
|
||||||
|
|
||||||
## Legacy Compatibility
|
|
||||||
|
|
||||||
Runtime aliases remain only for names that are no longer canonical, including:
|
|
||||||
|
|
||||||
```text
|
|
||||||
campaign:write
|
|
||||||
attachments:read
|
|
||||||
attachments:write
|
|
||||||
admin:users
|
|
||||||
admin:users:write
|
|
||||||
admin:api_keys:write
|
|
||||||
admin:settings
|
|
||||||
system:tenants:write
|
|
||||||
system:access:write
|
|
||||||
```
|
|
||||||
|
|
||||||
Canonical scopes are not widened by runtime alias expansion after migration.
|
|
||||||
|
|
||||||
## Deferred Permission Families
|
|
||||||
|
|
||||||
Add these only with their corresponding implemented features:
|
|
||||||
|
|
||||||
```text
|
|
||||||
templates:*
|
|
||||||
address_books:*
|
|
||||||
recipient_lists:*
|
|
||||||
connectors:*
|
|
||||||
dsar:*
|
|
||||||
system:monitoring:read
|
|
||||||
system:backups:run
|
|
||||||
system:backups:restore
|
|
||||||
system:updates:apply
|
|
||||||
system:updates:rollback
|
|
||||||
```
|
|
||||||
|
|
||||||
A separate `retention:*` family is not currently canonical because retention is managed through system settings and tenant policy scopes. Add it only if retention operation duties need separation from general policy/settings administration.
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<!-- codex-wiki-sync:6527293c59e25e64f6553a58 -->
|
<!-- codex-wiki-sync:7b2a17802d161c1f7bb900e6 -->
|
||||||
|
|
||||||
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/RELEASE_CATALOG_WORKFLOW.md`.
|
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/RELEASE_CATALOG_WORKFLOW.md`.
|
||||||
> Origin: `repository`.
|
> Origin: `repository`.
|
||||||
@@ -39,7 +39,7 @@ Generate the signed catalog into `govoplan-web`:
|
|||||||
cd /mnt/DATA/git/govoplan-core
|
cd /mnt/DATA/git/govoplan-core
|
||||||
KEY_DIR="$HOME/.config/govoplan/release-keys"
|
KEY_DIR="$HOME/.config/govoplan/release-keys"
|
||||||
scripts/publish-release-catalog.sh \
|
scripts/publish-release-catalog.sh \
|
||||||
--version 0.1.4 \
|
--version <x.y.z> \
|
||||||
--sequence 202607071340 \
|
--sequence 202607071340 \
|
||||||
--catalog-signing-key "release-key-1=$KEY_DIR/release-key-1.pem" \
|
--catalog-signing-key "release-key-1=$KEY_DIR/release-key-1.pem" \
|
||||||
--build-web
|
--build-web
|
||||||
@@ -89,9 +89,10 @@ https://govoplan.add-ideas.de/catalogs/v1/keyring.json
|
|||||||
## Integrated Release Script
|
## Integrated Release Script
|
||||||
|
|
||||||
`scripts/push-release-tag.sh` can publish the web catalog after module and core
|
`scripts/push-release-tag.sh` can publish the web catalog after module and core
|
||||||
tags have been pushed. It runs the migration release audit in non-strict mode
|
tags have been pushed. It runs the migration release audit in automatic mode:
|
||||||
by default; add `--strict-migration-audit` for stable releases after
|
warning-only before the first recorded migration baseline, strict after a
|
||||||
`docs/migration-release-baselines.json` has been updated:
|
baseline exists. Add `--strict-migration-audit` when you want to force strict
|
||||||
|
mode explicitly:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /mnt/DATA/git/govoplan-core
|
cd /mnt/DATA/git/govoplan-core
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!-- codex-wiki-sync:61ed52f82af2f6866512f2cf -->
|
<!-- codex-wiki-sync:46958666bd160e10691e4273 -->
|
||||||
|
|
||||||
> 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`.
|
||||||
@@ -7,9 +7,20 @@
|
|||||||
---
|
---
|
||||||
# GovOPlaN Release Dependencies
|
# GovOPlaN Release Dependencies
|
||||||
|
|
||||||
Release installs must not depend on sibling checkout paths. Local development can keep editable installs and `file:` WebUI links, but release packaging should resolve modules from tagged git refs or from a package registry.
|
This document owns release package composition: Python package refs, WebUI
|
||||||
|
release package refs, release lockfiles, migration baselines, and the final
|
||||||
|
release checklist.
|
||||||
|
|
||||||
## Backend
|
Operator runtime configuration and module install/uninstall execution live in
|
||||||
|
`DEPLOYMENT_OPERATOR_GUIDE.md`. Catalog signatures, keyrings, replay
|
||||||
|
protection, and licensing live in `CATALOG_TRUST_AND_LICENSING.md`. Publishing
|
||||||
|
the public catalog through `govoplan-web` lives in `RELEASE_CATALOG_WORKFLOW.md`.
|
||||||
|
|
||||||
|
## Backend Packages
|
||||||
|
|
||||||
|
Release installs must not depend on sibling checkout paths. Local development
|
||||||
|
can keep editable installs and `file:` WebUI links, but release packaging must
|
||||||
|
resolve modules from tagged git refs or from a package registry.
|
||||||
|
|
||||||
Local development:
|
Local development:
|
||||||
|
|
||||||
@@ -25,14 +36,17 @@ cd /mnt/DATA/git/govoplan-core
|
|||||||
./.venv/bin/python -m pip install -r requirements-release.txt
|
./.venv/bin/python -m pip install -r requirements-release.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
`.[server]` is resolved relative to the current working directory. If you create the virtualenv elsewhere, still run the install command from the core checkout:
|
`.[server]` is resolved relative to the current working directory. If you
|
||||||
|
create the virtualenv elsewhere, still run the install command from the core
|
||||||
|
checkout:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /mnt/DATA/git/govoplan-core
|
cd /mnt/DATA/git/govoplan-core
|
||||||
/tmp/govoplan-release-test/bin/python -m pip install -r requirements-release.txt
|
/tmp/govoplan-release-test/bin/python -m pip install -r requirements-release.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
`requirements-release.txt` pins the module repositories to the release tag. Update those refs when cutting a release:
|
`requirements-release.txt` pins the module repositories to the release tag.
|
||||||
|
Update those refs when cutting a release:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
govoplan-access git@git.add-ideas.de:add-ideas/govoplan-access.git v0.1.6
|
govoplan-access git@git.add-ideas.de:add-ideas/govoplan-access.git v0.1.6
|
||||||
@@ -46,452 +60,15 @@ govoplan-campaign git@git.add-ideas.de:add-ideas/govoplan-campaign.git v0.1.6
|
|||||||
govoplan-calendar git@git.add-ideas.de:add-ideas/govoplan-calendar.git v0.1.6
|
govoplan-calendar git@git.add-ideas.de:add-ideas/govoplan-calendar.git v0.1.6
|
||||||
```
|
```
|
||||||
|
|
||||||
### PostgreSQL Release Check
|
## WebUI Packages
|
||||||
|
|
||||||
Release candidates should pass a disposable PostgreSQL migration and startup
|
Local development uses `webui/package.json`, which may point at sibling module
|
||||||
smoke check before tagging or publishing catalogs. Start the local testbed, then
|
checkouts while active development is happening.
|
||||||
run the permutation check from the core checkout:
|
|
||||||
|
|
||||||
```bash
|
Release WebUI installs should use `webui/package.release.json`. It points
|
||||||
cd /mnt/DATA/git/govoplan-core/dev/postgres
|
module dependencies at the same tagged git repositories. After the module tags
|
||||||
cp .env.example .env
|
referenced there exist, generate the committed release lockfile without
|
||||||
docker compose --env-file .env up -d
|
touching the development package files:
|
||||||
|
|
||||||
cd /mnt/DATA/git/govoplan-core
|
|
||||||
set -a
|
|
||||||
. dev/postgres/.env
|
|
||||||
set +a
|
|
||||||
./.venv/bin/python scripts/postgres-integration-check.py \
|
|
||||||
--database-url "$GOVOPLAN_POSTGRES_DATABASE_URL" \
|
|
||||||
--reset-schema
|
|
||||||
```
|
|
||||||
|
|
||||||
The script checks migrations and `/health` startup for core-only, files-only,
|
|
||||||
mail-only, campaign-only, campaign+files, campaign+mail, and full-product
|
|
||||||
module sets. `--reset-schema` is destructive and must only be used against a
|
|
||||||
throwaway database.
|
|
||||||
|
|
||||||
### Migration Baselines
|
|
||||||
|
|
||||||
Development migrations may be small and numerous while a feature is moving.
|
|
||||||
Before a stable release, unreleased migrations may be rewritten or squashed into
|
|
||||||
a release-level baseline or release-to-release upgrade migration. After a
|
|
||||||
release tag has shipped, released migration revision IDs are immutable.
|
|
||||||
|
|
||||||
The release policy is:
|
|
||||||
|
|
||||||
- unreleased migrations may be folded before release;
|
|
||||||
- released migrations are never rewritten or deleted;
|
|
||||||
- each stable release records the public migration head revisions in
|
|
||||||
`docs/migration-release-baselines.json`;
|
|
||||||
- fresh installations should apply release-level baselines/upgrades, not
|
|
||||||
unreleased create-then-rename churn;
|
|
||||||
- release-to-release schema changes should be folded into one reviewed
|
|
||||||
migration per migration owner where practical.
|
|
||||||
|
|
||||||
Audit the current graph during release preparation:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd /mnt/DATA/git/govoplan-core
|
|
||||||
./.venv/bin/python scripts/release-migration-audit.py
|
|
||||||
```
|
|
||||||
|
|
||||||
Use strict mode after the baseline file has been updated for the release:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./.venv/bin/python scripts/release-migration-audit.py --strict
|
|
||||||
```
|
|
||||||
|
|
||||||
`scripts/push-release-tag.sh` runs the audit in non-strict mode by default so
|
|
||||||
release operators see the current migration heads before tagging. Pass
|
|
||||||
`--strict-migration-audit` when cutting a release whose migration baselines have
|
|
||||||
already been recorded, or `--skip-migration-audit` only for emergency/manual
|
|
||||||
release work.
|
|
||||||
|
|
||||||
Before the first stable release, fold the current development chain into the
|
|
||||||
first public baseline and record that baseline in
|
|
||||||
`docs/migration-release-baselines.json`. The tracking issue is
|
|
||||||
`add-ideas/govoplan-core#223`.
|
|
||||||
|
|
||||||
## Runtime Module Package Changes
|
|
||||||
|
|
||||||
The admin module manager can hot-enable and hot-disable packages that are
|
|
||||||
already installed. It does not install or uninstall Python/npm packages from
|
|
||||||
inside the running server.
|
|
||||||
|
|
||||||
For runtime package changes, create an operator install plan in Admin > System >
|
|
||||||
Modules. The module manager shows the trusted installer preflight status and
|
|
||||||
blocks unsafe uninstalls before the operator touches packages.
|
|
||||||
|
|
||||||
Preflight from the server shell:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
govoplan-module-installer --format shell
|
|
||||||
```
|
|
||||||
|
|
||||||
Apply from a controlled operator shell while maintenance mode is active:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
govoplan-module-installer --apply --build-webui
|
|
||||||
```
|
|
||||||
|
|
||||||
For real install/uninstall work, prefer supervised mode with the deployment's
|
|
||||||
restart command and health endpoint:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
govoplan-module-installer \
|
|
||||||
--supervise \
|
|
||||||
--migrate \
|
|
||||||
--build-webui \
|
|
||||||
--health-url http://127.0.0.1:8000/health \
|
|
||||||
--restart-command '<restart govoplan server>'
|
|
||||||
```
|
|
||||||
|
|
||||||
To let the admin UI trigger package work without executing pip/npm inside a
|
|
||||||
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_PGTOOLS" > "$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_PGTOOLS" "$GOVOPLAN_DATABASE_BACKUP_PATH"' \
|
|
||||||
--health-url http://127.0.0.1:8000/health \
|
|
||||||
--restart-command '<restart govoplan server>'
|
|
||||||
```
|
|
||||||
|
|
||||||
Admin > System > Modules can then queue the saved install plan as a supervised
|
|
||||||
request. Install rows can be planned directly from the approved package catalog;
|
|
||||||
uninstall rows are generated from installed, disabled modules so the Python
|
|
||||||
distribution and WebUI package names do not need to be typed by hand. The
|
|
||||||
daemon claims one queued request at a time and writes request/run records below
|
|
||||||
`runtime/module-installer`. For process-manager one-shot usage or tests, use
|
|
||||||
`--daemon-once`. The daemon also writes
|
|
||||||
`runtime/module-installer/daemon.status.json`; check it with:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
govoplan-module-installer --daemon-status --format json
|
|
||||||
```
|
|
||||||
|
|
||||||
The installer uses a runtime lock, snapshots `pip freeze` plus WebUI
|
|
||||||
`package.json`/`package-lock.json`, writes a run record below
|
|
||||||
`runtime/module-installer/runs`, and marks planned rows as applied only after
|
|
||||||
all commands succeed. When `--migrate` is used with a `sqlite:///` database URL,
|
|
||||||
the installer also snapshots the SQLite database with SQLite's backup API before
|
|
||||||
running migrations. For other database engines, pass external backup/restore
|
|
||||||
hooks:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
govoplan-module-installer \
|
|
||||||
--supervise \
|
|
||||||
--migrate \
|
|
||||||
--database-backup-command 'pg_dump --format=custom "$GOVOPLAN_DATABASE_URL_PGTOOLS" > "$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_PGTOOLS" "$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-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
|
|
||||||
package snapshots, re-runs the restart command when supplied, and restores the
|
|
||||||
saved install plan state so the operator can correct it. The supervisor must
|
|
||||||
run outside the FastAPI server process; the admin UI saves and validates plans
|
|
||||||
but does not mutate packages from an HTTP request.
|
|
||||||
|
|
||||||
After a successful install plan, the installer adds installed modules to saved
|
|
||||||
startup state by default so the restarted server can discover and enable them.
|
|
||||||
After a successful uninstall plan, the installer removes uninstalled modules
|
|
||||||
from saved startup state by default. Use
|
|
||||||
`--no-activate-installed-modules` or
|
|
||||||
`--keep-uninstalled-modules-in-desired` only for staged rollout workflows that
|
|
||||||
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
|
|
||||||
installer runs that used `--migrate` and captured a database snapshot.
|
|
||||||
Non-SQLite rollback is automatic when the run used
|
|
||||||
`--database-backup-command` and `--database-restore-command`; otherwise migrated
|
|
||||||
non-SQLite runs are blocked before package changes are applied.
|
|
||||||
|
|
||||||
Rollback uses the saved run snapshot:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
govoplan-module-installer --rollback <run-id>
|
|
||||||
govoplan-module-installer --rollback <run-id> --database-restore-command '<override restore command>'
|
|
||||||
```
|
|
||||||
|
|
||||||
Database hook commands run with these environment variables:
|
|
||||||
|
|
||||||
- `GOVOPLAN_INSTALLER_RUN_DIR`: the run snapshot directory
|
|
||||||
- `GOVOPLAN_DATABASE_URL`: the configured database URL
|
|
||||||
- `GOVOPLAN_DATABASE_URL_PGTOOLS`: the same PostgreSQL URL converted from
|
|
||||||
`postgresql+driver://` to `postgresql://` for `pg_dump`, `pg_restore`, and
|
|
||||||
`psql`; set only for PostgreSQL URLs
|
|
||||||
- `GOVOPLAN_DATABASE_BACKUP_PATH`: a suggested backup artifact path inside the
|
|
||||||
run directory
|
|
||||||
- `GOVOPLAN_DATABASE_BACKUP_METADATA`: optional JSON metadata path that backup
|
|
||||||
commands may write for operator diagnostics
|
|
||||||
|
|
||||||
Avoid embedding secrets directly in commands; prefer environment variables,
|
|
||||||
service credentials, or deployment-local secret injection.
|
|
||||||
|
|
||||||
Inspect installer history and lock state from the operator shell:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
govoplan-module-installer --list-runs --format json
|
|
||||||
govoplan-module-installer --show-run <run-id> --format json
|
|
||||||
govoplan-module-installer --lock-status --format json
|
|
||||||
govoplan-module-installer --list-requests --format json
|
|
||||||
govoplan-module-installer --show-request <request-id> --format json
|
|
||||||
govoplan-module-installer --cancel-request <request-id> --format json
|
|
||||||
govoplan-module-installer --retry-request <request-id> --format json
|
|
||||||
```
|
|
||||||
|
|
||||||
### Rollback Drill
|
|
||||||
|
|
||||||
Before using the installer daemon in production, run the rollback drill in a
|
|
||||||
controlled shell from the core checkout:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./.venv/bin/python scripts/module-installer-rollback-drill.py --format json
|
|
||||||
```
|
|
||||||
|
|
||||||
The drill uses temporary SQLite databases and simulated package commands. It
|
|
||||||
does not install or uninstall real packages. It exercises:
|
|
||||||
|
|
||||||
- package command failure followed by supervised rollback
|
|
||||||
- migration failure with a SQLite database snapshot
|
|
||||||
- restart-command failure
|
|
||||||
- health timeout after restart
|
|
||||||
- destructive retirement executor failure with database rollback
|
|
||||||
- PostgreSQL-style backup, restore-check, and restore hooks
|
|
||||||
- daemon heartbeat, request queue claim/update, retry/cancel, and stale lock
|
|
||||||
detection/removal
|
|
||||||
|
|
||||||
Keep the drill runtime for inspection with:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./.venv/bin/python scripts/module-installer-rollback-drill.py \
|
|
||||||
--keep-runtime \
|
|
||||||
--runtime-root /srv/govoplan/drills/installer-rollback-$(date +%Y%m%d)
|
|
||||||
```
|
|
||||||
|
|
||||||
Each scenario writes an installer run record below
|
|
||||||
`<runtime-root>/<scenario>/installer/runs/<run-id>/record.json`. For a successful
|
|
||||||
rollback drill, check:
|
|
||||||
|
|
||||||
- `status` is `applied` only for the original package phase when rollback later
|
|
||||||
happens in the supervisor
|
|
||||||
- `rollback_status` is `rolled-back` when package/database snapshots were
|
|
||||||
restored
|
|
||||||
- `supervisor.status` is `rolled-back` for supervised package, migration,
|
|
||||||
restart, and health failures
|
|
||||||
- `supervisor.failure_reason` names the failing restart or health target
|
|
||||||
- `snapshot.database_backup` exists for migrated SQLite runs and destructive
|
|
||||||
retirement runs
|
|
||||||
- PostgreSQL hook drills write `database.external.backup`,
|
|
||||||
`restore-check.marker`, and `restore.marker`
|
|
||||||
|
|
||||||
The PostgreSQL drill validates the hook interface without connecting to a live
|
|
||||||
database. In production, replace the documented example hooks with deployment
|
|
||||||
commands that target a disposable staging database first:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
--database-backup-command 'pg_dump --format=custom "$GOVOPLAN_DATABASE_URL_PGTOOLS" > "$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_PGTOOLS" "$GOVOPLAN_DATABASE_BACKUP_PATH"'
|
|
||||||
```
|
|
||||||
|
|
||||||
If a daemon request fails, inspect it and retry only after the underlying cause
|
|
||||||
is corrected:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
govoplan-module-installer --show-request <request-id> --format json
|
|
||||||
govoplan-module-installer --show-run <run-id> --format json
|
|
||||||
govoplan-module-installer --retry-request <request-id> --format json
|
|
||||||
```
|
|
||||||
|
|
||||||
Cancel queued duplicate work before retrying:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
govoplan-module-installer --list-requests --format json
|
|
||||||
govoplan-module-installer --cancel-request <request-id> --format json
|
|
||||||
```
|
|
||||||
|
|
||||||
For stale locks, first check the lock payload and confirm the recorded process
|
|
||||||
is no longer running on the host that owns the runtime directory:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
govoplan-module-installer --lock-status --format json
|
|
||||||
```
|
|
||||||
|
|
||||||
Only remove `runtime/module-installer/install.lock` after confirming there is
|
|
||||||
no active installer process and no package manager command still running. Then
|
|
||||||
rerun preflight before applying or retrying the request.
|
|
||||||
|
|
||||||
Package catalogs can be local files or remote static resources, for example
|
|
||||||
served by `govoplan-web`. Set `GOVOPLAN_MODULE_PACKAGE_CATALOG` for a local file
|
|
||||||
or `GOVOPLAN_MODULE_PACKAGE_CATALOG_URL` for a remote catalog matching
|
|
||||||
`docs/module-package-catalog.example.json`; the admin UI will show those entries
|
|
||||||
and can save them into the install plan. This keeps the release approval
|
|
||||||
decision outside the running server while avoiding hand-typed package refs.
|
|
||||||
Remote catalogs can be cached for offline inspection:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
GOVOPLAN_MODULE_PACKAGE_CATALOG_URL=https://govoplan.example/catalogs/v1/channels/stable.json
|
|
||||||
GOVOPLAN_MODULE_PACKAGE_CATALOG_CACHE=/srv/govoplan/runtime/catalog-cache/stable.json
|
|
||||||
```
|
|
||||||
|
|
||||||
Validate the catalog before handing it to operators:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
govoplan-module-installer --validate-package-catalog docs/module-package-catalog.example.json --format json
|
|
||||||
```
|
|
||||||
|
|
||||||
Release catalogs should be signed, channel-gated, expiring, and sequence
|
|
||||||
tracked. The supported signing format is an Ed25519 signature over the
|
|
||||||
canonical catalog JSON object with the `signature` and `signatures` fields
|
|
||||||
removed. Core accepts the legacy single `signature` field and the newer
|
|
||||||
`signatures` array used during key rotation. 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>"}'
|
|
||||||
GOVOPLAN_MODULE_PACKAGE_CATALOG_SEQUENCE_STATE=/srv/govoplan/runtime/catalog-sequences.json
|
|
||||||
GOVOPLAN_MODULE_PACKAGE_CATALOG_ENFORCE_SEQUENCE=true
|
|
||||||
```
|
|
||||||
|
|
||||||
Back up the sequence state with other runtime metadata. If it is lost or
|
|
||||||
corrupted, reconstruct the highest accepted sequence per channel from installer
|
|
||||||
run records or release records, never by lowering the sequence to admit an
|
|
||||||
older catalog. `docs/CATALOG_TRUST_AND_LICENSING.md` includes the recovery JSON
|
|
||||||
shape and reset procedure.
|
|
||||||
|
|
||||||
Catalog module entries may include `artifact_integrity.python` and
|
|
||||||
`artifact_integrity.webui` metadata. Each artifact entry can declare:
|
|
||||||
|
|
||||||
- `ref`: the exact Python or WebUI install ref expected in the plan
|
|
||||||
- `sha256`: the expected SHA-256 digest of the resolved artifact
|
|
||||||
- `path` or `artifact_path`: a local artifact path that the installer can hash
|
|
||||||
before applying the plan
|
|
||||||
- `sbom_url`: the published SBOM for the artifact
|
|
||||||
- `provenance_url`: the published provenance or attestation for the artifact
|
|
||||||
- `registry_identity` or `git_ref`: the expected registry or source identity
|
|
||||||
|
|
||||||
When a saved install plan includes this metadata, installer preflight records
|
|
||||||
verification results in the run record under `preflight.artifact_integrity`.
|
|
||||||
Set `GOVOPLAN_MODULE_INSTALLER_REQUIRE_ARTIFACT_INTEGRITY=true` in production
|
|
||||||
to block package changes whose Python/WebUI artifacts are missing integrity
|
|
||||||
metadata or cannot be locally verified.
|
|
||||||
|
|
||||||
Trusted keys can also be loaded from
|
|
||||||
`GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS_FILE`. A URL-backed keyring is
|
|
||||||
supported for development and tightly controlled deployments through
|
|
||||||
`GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS_URL` plus
|
|
||||||
`GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS_CACHE`, but production systems
|
|
||||||
should pin trusted keys locally.
|
|
||||||
|
|
||||||
Catalog entries can declare `license_features`. If
|
|
||||||
`GOVOPLAN_LICENSE_ENFORCEMENT=true`, core blocks planning catalog installs
|
|
||||||
whose required features are not present in the configured offline license:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
GOVOPLAN_LICENSE_FILE=/srv/govoplan/license.json
|
|
||||||
GOVOPLAN_LICENSE_TRUSTED_KEYS_FILE=/srv/govoplan/trust/license-keyring.json
|
|
||||||
GOVOPLAN_LICENSE_ENFORCEMENT=true
|
|
||||||
```
|
|
||||||
|
|
||||||
Operators can validate the imported license and required catalog entitlements:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
govoplan-module-installer \
|
|
||||||
--validate-license /srv/govoplan/license.json \
|
|
||||||
--license-trusted-key license-issuer-1="<base64 public key>" \
|
|
||||||
--require-trusted-license \
|
|
||||||
--license-required-feature module.mail \
|
|
||||||
--format json
|
|
||||||
```
|
|
||||||
|
|
||||||
Release or support operators can issue/renew signed offline licenses with
|
|
||||||
`govoplan-module-installer --issue-license`. Keep the signing private key off
|
|
||||||
the application server; the admin UI only displays public diagnostics such as
|
|
||||||
license id, subject, validity window, trusted key id, features, and missing
|
|
||||||
entitlements.
|
|
||||||
|
|
||||||
See `docs/CATALOG_TRUST_AND_LICENSING.md` for key rotation, replay protection,
|
|
||||||
and licensing details. See `docs/RELEASE_CATALOG_WORKFLOW.md` for the concrete
|
|
||||||
release-machine workflow that generates signing keys and publishes signed
|
|
||||||
catalogs through `govoplan-web`. 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. 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. The target
|
|
||||||
design and follow-up slices are in `docs/REMOTE_WEBUI_BUNDLES.md`.
|
|
||||||
|
|
||||||
Module manifests can declare core compatibility bounds and uninstall guard
|
|
||||||
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. When `destroy_data` is set on
|
|
||||||
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
|
|
||||||
|
|
||||||
Local development uses `webui/package.json`, which may point at sibling module checkouts while active development is happening.
|
|
||||||
|
|
||||||
Release WebUI installs should use `webui/package.release.json`. It points module dependencies at the same tagged git repositories. After the module tags referenced there exist, generate the committed release lockfile without touching the development package files:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /mnt/DATA/git/govoplan-core
|
cd /mnt/DATA/git/govoplan-core
|
||||||
@@ -500,16 +77,47 @@ cd webui
|
|||||||
PATH=/home/zemion/.nvm/versions/node/v22.22.3/bin:$PATH /home/zemion/.nvm/versions/node/v22.22.3/bin/npm run build
|
PATH=/home/zemion/.nvm/versions/node/v22.22.3/bin:$PATH /home/zemion/.nvm/versions/node/v22.22.3/bin/npm run build
|
||||||
```
|
```
|
||||||
|
|
||||||
The module repositories include root-level npm package manifests so git installs can resolve `@govoplan/access-webui`, `@govoplan/admin-webui`, `@govoplan/files-webui`, `@govoplan/mail-webui`, `@govoplan/campaign-webui`, and `@govoplan/calendar-webui` from repository roots even though their source lives below `webui/src`.
|
The module repositories include root-level npm package manifests so git
|
||||||
|
installs can resolve `@govoplan/access-webui`, `@govoplan/admin-webui`,
|
||||||
|
`@govoplan/files-webui`, `@govoplan/mail-webui`,
|
||||||
|
`@govoplan/campaign-webui`, and `@govoplan/calendar-webui` from repository
|
||||||
|
roots even though their source lives below `webui/src`.
|
||||||
|
|
||||||
The normal release path is automated by `scripts/push-release-tag.sh`: it bumps or accepts the target version, updates Python/WebUI/module manifest versions, commits/tags/pushes the module repositories first, regenerates `webui/package-lock.release.json`, and then commits/tags/pushes core. If the working tree has already been bumped, pass the current version explicitly:
|
### Release Lockfile Strategy
|
||||||
|
|
||||||
|
The supported release composition currently is the full GovOPlaN product: core
|
||||||
|
plus access, admin, tenancy, policy, audit, files, mail, campaign, and
|
||||||
|
calendar. Keep one committed full-product release lockfile at
|
||||||
|
`webui/package-lock.release.json`, generated from
|
||||||
|
`webui/package.release.json` in a clean release workspace. Development
|
||||||
|
`package-lock.json` may continue to point at local `file:` dependencies.
|
||||||
|
|
||||||
|
Frontend module permutations are regression-tested through
|
||||||
|
`GOVOPLAN_WEBUI_MODULE_PACKAGES` and temporary build output, not through
|
||||||
|
committed lockfiles for every possible combination. If a smaller composition
|
||||||
|
becomes a separately shipped product, add an explicit release manifest and
|
||||||
|
lockfile pair for that product, for example
|
||||||
|
`package.release.files-mail.json` and `package-lock.release.files-mail.json`,
|
||||||
|
generated in a clean release workspace from tagged git dependencies.
|
||||||
|
|
||||||
|
## Release Tag Script
|
||||||
|
|
||||||
|
The normal release path is automated by `scripts/push-release-tag.sh`: it bumps
|
||||||
|
or accepts the target version, updates Python/WebUI/module manifest versions,
|
||||||
|
commits/tags/pushes the module repositories first, regenerates
|
||||||
|
`webui/package-lock.release.json`, and then commits/tags/pushes core. If the
|
||||||
|
working tree has already been bumped, pass the current version explicitly:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /mnt/DATA/git/govoplan-core
|
cd /mnt/DATA/git/govoplan-core
|
||||||
scripts/push-release-tag.sh --version 0.1.6
|
scripts/push-release-tag.sh --version 0.1.6
|
||||||
```
|
```
|
||||||
|
|
||||||
The script also includes GovOPlaN roadmap/scaffold module repositories that do not yet have package metadata. Those repositories are committed, tagged, and pushed with the same release tag, but they are tag-only until they contain `pyproject.toml`, module manifests, or WebUI packages. Tag-only repositories are not listed in `requirements-release.txt` or `webui/package.release.json`.
|
The script also includes GovOPlaN roadmap/scaffold module repositories that do
|
||||||
|
not yet have package metadata. Those repositories are committed, tagged, and
|
||||||
|
pushed with the same release tag, but they are tag-only until they contain
|
||||||
|
`pyproject.toml`, module manifests, or WebUI packages. Tag-only repositories
|
||||||
|
are not listed in `requirements-release.txt` or `webui/package.release.json`.
|
||||||
|
|
||||||
Current tag-only module repositories:
|
Current tag-only module repositories:
|
||||||
|
|
||||||
@@ -538,17 +146,112 @@ Current tag-only module repositories:
|
|||||||
- `govoplan-xrechnung`
|
- `govoplan-xrechnung`
|
||||||
- `govoplan-xta-osci`
|
- `govoplan-xta-osci`
|
||||||
|
|
||||||
### Release lockfile strategy
|
## PostgreSQL Release Check
|
||||||
|
|
||||||
The supported release composition currently is the full Multi Seal Mail product: core plus access, admin, tenancy, policy, audit, files, mail, campaign, and calendar. Keep one committed full-product release lockfile at `webui/package-lock.release.json`, generated from `webui/package.release.json` in a clean release workspace. Development `package-lock.json` may continue to point at local `file:` dependencies.
|
Release candidates should pass a disposable PostgreSQL migration and startup
|
||||||
|
smoke check before tagging or publishing catalogs. Start the local testbed,
|
||||||
|
then run the permutation check from the core checkout:
|
||||||
|
|
||||||
Frontend module permutations are regression-tested through `GOVOPLAN_WEBUI_MODULE_PACKAGES` and temporary build output, not through committed lockfiles for every possible combination. If a smaller composition becomes a separately shipped product, add an explicit release manifest and lockfile pair for that product, for example `package.release.files-mail.json` and `package-lock.release.files-mail.json`, generated in a clean release workspace from tagged git dependencies.
|
```bash
|
||||||
|
cd /mnt/DATA/git/govoplan-core/dev/postgres
|
||||||
|
cp .env.example .env
|
||||||
|
docker compose --env-file .env up -d
|
||||||
|
|
||||||
|
cd /mnt/DATA/git/govoplan-core
|
||||||
|
set -a
|
||||||
|
. dev/postgres/.env
|
||||||
|
set +a
|
||||||
|
./.venv/bin/python scripts/postgres-integration-check.py \
|
||||||
|
--database-url "$GOVOPLAN_POSTGRES_DATABASE_URL" \
|
||||||
|
--reset-schema
|
||||||
|
```
|
||||||
|
|
||||||
|
The script checks migrations and `/health` startup for core-only, files-only,
|
||||||
|
mail-only, campaign-only, campaign+files, campaign+mail, and full-product
|
||||||
|
module sets. `--reset-schema` is destructive and must only be used against a
|
||||||
|
throwaway database.
|
||||||
|
|
||||||
|
## Migration Baselines
|
||||||
|
|
||||||
|
Development migrations may be small and numerous while a feature is moving.
|
||||||
|
Before a stable release, unreleased migrations may be rewritten or squashed into
|
||||||
|
a release-level baseline or release-to-release upgrade migration. After a
|
||||||
|
release tag has shipped, released migration revision IDs are immutable.
|
||||||
|
|
||||||
|
The release policy is:
|
||||||
|
|
||||||
|
- unreleased migrations may be folded before release;
|
||||||
|
- released migrations are never rewritten or deleted;
|
||||||
|
- each stable release records the public migration head revisions in
|
||||||
|
`docs/migration-release-baselines.json`;
|
||||||
|
- fresh installations should apply release-level baselines/upgrades, not
|
||||||
|
unreleased create-then-rename churn;
|
||||||
|
- release-to-release schema changes should be folded into one reviewed
|
||||||
|
migration per migration owner where practical.
|
||||||
|
|
||||||
|
Audit the current graph during release preparation:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /mnt/DATA/git/govoplan-core
|
||||||
|
./.venv/bin/python scripts/release-migration-audit.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Generate the reviewed/manual squash checklist:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./.venv/bin/python scripts/release-migration-audit.py --squash-plan
|
||||||
|
```
|
||||||
|
|
||||||
|
After the release migrations have been reviewed and the graph is final, record
|
||||||
|
the release baseline:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./.venv/bin/python scripts/release-migration-audit.py --record-release <x.y.z>
|
||||||
|
```
|
||||||
|
|
||||||
|
Use strict mode to verify that the current heads are recorded:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./.venv/bin/python scripts/release-migration-audit.py --strict
|
||||||
|
```
|
||||||
|
|
||||||
|
`scripts/push-release-tag.sh` runs the audit by default in automatic mode:
|
||||||
|
non-strict while no release baseline exists, strict after the first baseline is
|
||||||
|
recorded. Pass `--warn-migration-audit` for an explicit non-strict audit,
|
||||||
|
`--strict-migration-audit` to force strict mode, or `--skip-migration-audit`
|
||||||
|
only for emergency/manual release work.
|
||||||
|
|
||||||
|
Before the first stable release, fold the current development chain into the
|
||||||
|
first public baseline and record that baseline in
|
||||||
|
`docs/migration-release-baselines.json`. The tracking issue is
|
||||||
|
`add-ideas/govoplan-core#223`.
|
||||||
|
|
||||||
|
## Related Operator Documents
|
||||||
|
|
||||||
|
- `DEPLOYMENT_OPERATOR_GUIDE.md`: runtime environment, explicit migrations,
|
||||||
|
backup/restore commands, module installer daemon/supervisor operation, and
|
||||||
|
rollback drills.
|
||||||
|
- `CATALOG_TRUST_AND_LICENSING.md`: catalog JSON shape, signature validation,
|
||||||
|
key rotation, sequence-state recovery, artifact integrity, and license
|
||||||
|
enforcement.
|
||||||
|
- `RELEASE_CATALOG_WORKFLOW.md`: release-machine steps for signing and
|
||||||
|
publishing `govoplan-web` catalog/keyring artifacts.
|
||||||
|
- `REMOTE_WEBUI_BUNDLES.md`: experimental browser-loaded module bundles for
|
||||||
|
controlled deployments; normal releases use package builds.
|
||||||
|
|
||||||
## Release Checklist
|
## Release Checklist
|
||||||
|
|
||||||
- Keep Python package versions, WebUI package versions, and git tags aligned.
|
- Keep Python package versions, WebUI package versions, and git tags aligned.
|
||||||
- Tag core, access, admin, tenancy, policy, audit, files, mail, campaign, calendar, and scaffold module repositories together.
|
- Tag core, access, admin, tenancy, policy, audit, files, mail, campaign,
|
||||||
- Update `requirements-release.txt` and `webui/package.release.json` when the release tag changes.
|
calendar, and scaffold module repositories together.
|
||||||
- Generate the committed full-product release lockfile from `package.release.json` with `scripts/generate-release-lock.sh`.
|
- Update `requirements-release.txt` and `webui/package.release.json` when the
|
||||||
- Add separate release manifest/lockfile pairs only for module compositions that are shipped as their own products.
|
release tag changes.
|
||||||
|
- Generate the committed full-product release lockfile from
|
||||||
|
`package.release.json` with `scripts/generate-release-lock.sh`.
|
||||||
|
- Run `scripts/release-migration-audit.py --strict` after recording a release
|
||||||
|
baseline.
|
||||||
|
- Run the PostgreSQL release check against a disposable database.
|
||||||
|
- Publish the signed catalog through `RELEASE_CATALOG_WORKFLOW.md`.
|
||||||
|
- Add separate release manifest/lockfile pairs only for module compositions
|
||||||
|
that are shipped as their own products.
|
||||||
- Do not commit local sibling paths into release manifests.
|
- Do not commit local sibling paths into release manifests.
|
||||||
|
|||||||
Reference in New Issue
Block a user