diff --git a/Codex-Project-Index.md b/Codex-Project-Index.md index 4c25355..633b1b3 100644 --- a/Codex-Project-Index.md +++ b/Codex-Project-Index.md @@ -7,7 +7,6 @@ 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` - [Repo-README](Repo-README) - `/mnt/DATA/git/govoplan-core/README.md` - [Repo-docs-ACCESS-RBAC-MODEL](Repo-docs-ACCESS-RBAC-MODEL) - `/mnt/DATA/git/govoplan-core/docs/ACCESS_RBAC_MODEL.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-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` @@ -15,11 +14,9 @@ This page is generated from repository and product-directory project files. - [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-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-GOVOPLAN-MASTER-ROADMAP](Repo-docs-GOVOPLAN-MASTER-ROADMAP) - `/mnt/DATA/git/govoplan-core/docs/GOVOPLAN_MASTER_ROADMAP.md` - [Repo-docs-MODULE-ARCHITECTURE](Repo-docs-MODULE-ARCHITECTURE) - `/mnt/DATA/git/govoplan-core/docs/MODULE_ARCHITECTURE.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-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-REMOTE-WEBUI-BUNDLES](Repo-docs-REMOTE-WEBUI-BUNDLES) - `/mnt/DATA/git/govoplan-core/docs/REMOTE_WEBUI_BUNDLES.md` diff --git a/Repo-docs-CATALOG-TRUST-AND-LICENSING.md b/Repo-docs-CATALOG-TRUST-AND-LICENSING.md deleted file mode 100644 index 7ebc49e..0000000 --- a/Repo-docs-CATALOG-TRUST-AND-LICENSING.md +++ /dev/null @@ -1,271 +0,0 @@ - - -> Mirrored from `/mnt/DATA/git/govoplan-core/docs/CATALOG_TRUST_AND_LICENSING.md`. -> Origin: `repository`. -> Active tasks and changing state belong in Gitea issues; this wiki page is durable project context. - ---- -# Module Catalog Trust And Licensing - -GovOPlaN module install and uninstall must remain operator-controlled. The -running server may plan and validate package changes, but package mutation is -performed by the separate installer daemon or an operator shell during -maintenance mode. - -## Roles - -`govoplan-web` is the public static distribution surface for official catalog -resources: - -- signed module package catalogs, grouped by release channel -- public catalog keyrings -- public license verification keyrings -- examples and operator-facing download paths - -`govoplan-core` is the verifier and orchestrator: - -- fetches a local or remote module catalog -- verifies catalog signatures against configured trusted keys -- enforces approved release channels -- rejects expired or not-yet-valid catalogs -- records accepted catalog sequence numbers for replay protection -- checks catalog entry license feature requirements before planning installs -- writes installer plans and request records - -Feature and platform modules own their package artifacts, manifests, migration -metadata, retirement providers, and optional lifecycle behavior. - -## Catalog Source - -Core accepts either a local catalog file or a remote URL: - -```bash -GOVOPLAN_MODULE_PACKAGE_CATALOG=/srv/govoplan/catalogs/stable.json -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 -``` - -If both file and URL are set, the URL wins. The cache is used when a remote -fetch fails, so an operator can still inspect the last known catalog. A cached -catalog must still pass signature, freshness, channel, and replay validation. - -## Catalog Shape - -An official catalog is a JSON object with: - -- `catalog_version` -- `channel` -- `sequence` -- `generated_at` -- `not_before` when delayed activation is needed -- `expires_at` -- `modules` -- `signatures` - -Each module entry can declare: - -- backend package name and pinned install reference -- WebUI package name and pinned install reference -- display metadata and tags -- `license_features`, the feature entitlements required to plan that install - -The signature is Ed25519 over canonical JSON with both `signature` and -`signatures` removed. Core accepts the legacy single `signature` field and the -new `signatures` array. - -## Keyrings And Rotation - -Trusted catalog keys are configured locally: - -```bash -GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS_FILE=/srv/govoplan/trust/catalog-keyring.json -GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS='{"release-key-1":""}' -``` - -For development or tightly controlled deployments, a keyring can be read from a -URL and cached: - -```bash -GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS_URL=https://govoplan.example/catalogs/v1/keyring.json -GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS_CACHE=/srv/govoplan/runtime/catalog-cache/keyring.json -``` - -Production installations should pin the trusted keyring locally or ship it -through deployment configuration. Fetching trusted keys from the same public -origin as the catalog is convenient, but that origin must not become the only -trust root. - -Keyring entries support: - -- `key_id` -- `public_key` or `public_key_base64` -- `status`: `active`, `next`, `retired`, `revoked`, or `disabled` -- `not_before` -- `not_after` - -Rotation process: - -1. Add the next public key to the local trusted keyring with status `next`. -2. Publish catalogs signed by both current and next keys. -3. Upgrade installations so the next key is locally trusted. -4. Promote the next key to `active`. -5. Retire the old key only after every supported installation trusts the new - key. -6. Mark a compromised key `revoked` and publish a higher sequence catalog - signed by an uncompromised key. - -## Replay And Freshness - -Use replay state in production: - -```bash -GOVOPLAN_MODULE_PACKAGE_CATALOG_SEQUENCE_STATE=/srv/govoplan/runtime/catalog-sequences.json -GOVOPLAN_MODULE_PACKAGE_CATALOG_ENFORCE_SEQUENCE=true -``` - -Core records the accepted sequence per channel after a catalog entry is planned -from the admin interface. With strict sequence enforcement, a previously -accepted sequence is rejected; without strict enforcement, only older sequences -are rejected. - -Catalogs should always expire. Long-lived catalogs make rollback and key -compromise harder to reason about. - -### Sequence-State Recovery - -The sequence state file is operational state, not a trust root. Keep it on -persistent storage and include it in normal backups: - -```json -{ - "channels": { - "stable": { - "last_sequence": 42, - "accepted_at": "2026-07-07T12:00:00Z", - "key_id": "release-key-1", - "source": "https://govoplan.example/catalogs/v1/channels/stable.json" - } - } -} -``` - -If the file is lost, restore it from backup. If no backup exists, reconstruct -each channel from the highest sequence already accepted in installer run -records, release records, or the currently deployed module package set. Do not -lower `last_sequence` to make an older catalog pass; publish a new higher -sequence catalog when the accepted point is uncertain. - -If the file is corrupted, copy it aside for incident review, validate the -current signed catalog with channel and freshness enforcement, then rewrite the -state with the known accepted sequence. Keep -`GOVOPLAN_MODULE_PACKAGE_CATALOG_REQUIRE_SIGNATURE=true` and approved-channel -checks enabled during recovery. Temporarily disabling -`GOVOPLAN_MODULE_PACKAGE_CATALOG_ENFORCE_SEQUENCE` allows revalidating the same -sequence, but older sequences remain rejected once the reconstructed -`last_sequence` is in place. - -## Release Channels - -Approved channels are deployment policy: - -```bash -GOVOPLAN_MODULE_PACKAGE_CATALOG_APPROVED_CHANNELS=stable,lts -GOVOPLAN_MODULE_PACKAGE_CATALOG_REQUIRE_SIGNATURE=true -``` - -The admin UI can display other catalog metadata, but core rejects catalogs from -unapproved channels when validation is configured. - -## Licensing - -Catalog entries can require license features: - -```json -"license_features": ["module.mail", "support.standard"] -``` - -Core checks those requirements against an offline license file before allowing -the entry into the install plan. - -```bash -GOVOPLAN_LICENSE_FILE=/srv/govoplan/license.json -GOVOPLAN_LICENSE_ENFORCEMENT=true -GOVOPLAN_LICENSE_TRUSTED_KEYS_FILE=/srv/govoplan/trust/license-keyring.json -``` - -License files are JSON objects with: - -- `license_id` -- `subject` -- `features` -- `valid_from` -- `valid_until` -- `signature` - -Issue or renew a license from an operator/release shell that has the Ed25519 -private key: - -```bash -govoplan-module-installer \ - --issue-license /srv/govoplan/license.json \ - --license-id customer-2026-07 \ - --license-subject "Example Municipality" \ - --license-feature module.mail \ - --license-feature support.standard \ - --license-valid-until 2027-07-31T23:59:59Z \ - --license-signing-key-id license-issuer-1 \ - --license-signing-private-key /srv/govoplan/secrets/license-issuer-1.pem \ - --format json -``` - -Validate an imported license without exposing secrets: - -```bash -govoplan-module-installer \ - --validate-license /srv/govoplan/license.json \ - --license-trusted-key license-issuer-1="" \ - --require-trusted-license \ - --license-required-feature module.mail \ - --format json -``` - -The CLI and admin module catalog panel report the license id, subject, -validity window, signing key id, signed/trusted state, available features, and -missing entitlements for the configured package catalog. They do not expose -private signing material. - -License enforcement can run in observe-only mode by leaving -`GOVOPLAN_LICENSE_ENFORCEMENT` unset. In that mode, missing or invalid license -data is surfaced as a warning but does not block planning. - -Renewal is an ordinary re-issuance with a new `license_id`, extended -`valid_until`, and the full intended feature set. Import the renewed JSON to -`GOVOPLAN_LICENSE_FILE`, keep the previous file for audit, and validate it -before setting enforcement. - -Revocation is handled through the trusted license keyring. Mark a compromised -or invalid issuer key as `revoked` or `disabled`, publish or deploy the updated -keyring, then reissue affected licenses with an active key. Installations that -run with `GOVOPLAN_LICENSE_ENFORCEMENT=true` reject licenses signed only by a -revoked key after the local keyring is updated. - -Emergency fallback is deliberately explicit. Operators can temporarily unset -`GOVOPLAN_LICENSE_ENFORCEMENT` to keep package planning observable while a -license or keyring is recovered. Record the change in the operational incident -log, keep catalog signature and channel enforcement enabled, and restore -license enforcement after a trusted renewal validates successfully. - -Licensing is intentionally separate from open-source code licensing. The -catalog/license mechanism can govern support channels, official release -eligibility, hosted update access, professional support, or commercial -entitlements without changing the source license of the repositories. - -## Production Gaps - -The current implementation validates signed catalog metadata, offline license -entitlements, and local artifact SHA-256 when artifact paths are supplied in an -install plan. Production-grade distribution still needs: - -- remote registry/git artifact resolution before package-manager apply -- hardened catalog publishing pipeline in `govoplan-web` -- automated key rotation runbook and emergency revocation procedure diff --git a/Repo-docs-CONFIGURATION-PACKAGES.md b/Repo-docs-CONFIGURATION-PACKAGES.md index 0046f75..8278be5 100644 --- a/Repo-docs-CONFIGURATION-PACKAGES.md +++ b/Repo-docs-CONFIGURATION-PACKAGES.md @@ -1,4 +1,4 @@ - + > Mirrored from `/mnt/DATA/git/govoplan-core/docs/CONFIGURATION_PACKAGES.md`. > Origin: `repository`. @@ -17,7 +17,7 @@ a case workflow, task creation, a mail template, payment processing, access roles, audit evidence, and the interface bindings between those modules. The guiding reference scenario is the government-operations permit journey in -`docs/GOVERNMENT_OPERATIONS_VISION.md`: a person applies through the portal, +`docs/GOVOPLAN_MASTER_ROADMAP.md`: a person applies through the portal, uploads files, receives workflow-driven messages and appointment proposals, has a case opened, gets a permit generated from a template, and completes payment. Configuration packages are the mechanism that should make such processes diff --git a/Repo-docs-DEPLOYMENT-OPERATOR-GUIDE.md b/Repo-docs-DEPLOYMENT-OPERATOR-GUIDE.md index 88eb76a..b48b388 100644 --- a/Repo-docs-DEPLOYMENT-OPERATOR-GUIDE.md +++ b/Repo-docs-DEPLOYMENT-OPERATOR-GUIDE.md @@ -1,4 +1,4 @@ - + > Mirrored from `/mnt/DATA/git/govoplan-core/docs/DEPLOYMENT_OPERATOR_GUIDE.md`. > Origin: `repository`. @@ -380,10 +380,8 @@ does not install or uninstall real packages. It exercises: - 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. +See `RELEASE_DEPENDENCIES.md` for release package refs, migration baseline +checks, catalog trust, signing, keyring, replay, and license operation. ## Operator Checklist diff --git a/Repo-docs-DOCUMENTATION-MAP.md b/Repo-docs-DOCUMENTATION-MAP.md index 69f5b24..d8e6551 100644 --- a/Repo-docs-DOCUMENTATION-MAP.md +++ b/Repo-docs-DOCUMENTATION-MAP.md @@ -1,4 +1,4 @@ - + > Mirrored from `/mnt/DATA/git/govoplan-core/docs/DOCUMENTATION_MAP.md`. > Origin: `repository`. @@ -26,9 +26,7 @@ operator, and roadmap pages. | 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. | +| Release dependencies and catalogs | `RELEASE_DEPENDENCIES.md` | Release package refs, migration baselines, release lockfiles, catalog trust/licensing, catalog publishing, and release checklist. | | Remote WebUI bundle design | `REMOTE_WEBUI_BUNDLES.md` | Experimental controlled-deployment design; normal releases still use package builds. | ## Product And Module Planning @@ -38,7 +36,6 @@ operator, and roadmap pages. | Product roadmap and module routing | `GOVOPLAN_MASTER_ROADMAP.md` | Product-level sequencing, implementation gates, issue routing, and missing-module decisions. | | 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 diff --git a/Repo-docs-GOVERNMENT-OPERATIONS-VISION.md b/Repo-docs-GOVERNMENT-OPERATIONS-VISION.md deleted file mode 100644 index ff54877..0000000 --- a/Repo-docs-GOVERNMENT-OPERATIONS-VISION.md +++ /dev/null @@ -1,256 +0,0 @@ - - -> Mirrored from `/mnt/DATA/git/govoplan-core/docs/GOVERNMENT_OPERATIONS_VISION.md`. -> Origin: `repository`. -> Active tasks and changing state belong in Gitea issues; this wiki page is durable project context. - ---- -# GovOPlaN Government Operations Vision - -This document is the durable product north star for GovOPlaN as a modular -platform for administrative operations. It should be mirrored to the Gitea wiki. -Active implementation belongs in Gitea issues and module-specific follow-ups. - -The goal is not to replace every existing system. GovOPlaN should connect -existing systems, provide better workflows where the current landscape is weak, -and make administrative processes configurable, auditable, and reusable. - -## Guiding Reference Journey - -A useful reference process is a permit application that crosses public portal, -back-office workflow, documents, appointments, templates, notifications, and -payments: - -1. A person applies for a permit through the public portal. -2. The applicant uploads required files and submits structured form data. -3. Submission creates a case, a workflow instance, and an internal task. -4. Completing the task creates a postbox message, a notification, and an email - notification with an appointment proposal. -5. The applicant accepts an appointment, which updates the calendar and the - workflow state. -6. During the appointment, the case is opened and the permit is generated from a - governed template. -7. The payment is processed and linked to the case. -8. The permit, payment evidence, communication history, and audit trail remain - available according to policy and retention rules. - -This journey should be possible to model as a configuration package once the -participating modules exist. The package should wire module-owned fragments -together without core knowing module internals. - -## Design Principles - -- Modules must stay independently installable, enableable, and disableable. -- Cross-module behavior should use core-mediated capabilities, commands, events, - DTOs, and UI contribution points rather than direct imports. -- Configuration packages should turn installed modules into concrete, reusable - administrative processes. -- Operators should be able to configure the platform through the UI. -- Every powerful configuration path needs preflight, preview, audit, rollback, - RBAC, and policy checks. -- Integration should be a first-class product path: connect to existing systems, - consume their data, and publish governed outputs back to them. -- GovOPlaN should scale from a small local installation to a larger deployment - with separately scalable web, API, worker, storage, and database components. - -## Capability Map - -| Capability | Likely owner | -| --- | --- | -| Public application entry point | `govoplan-portal` | -| Structured forms and validation | `govoplan-forms` | -| Uploaded files and managed storage | `govoplan-files` | -| Case record and lifecycle | `govoplan-cases` | -| Workflow transitions and automation | `govoplan-workflow` | -| Internal work queues and tasks | `govoplan-tasks` | -| Appointment proposals and booking | `govoplan-appointments`, `govoplan-calendar` | -| Postbox, email, and notifications | `govoplan-mail`, `govoplan-notifications` | -| Permit/document generation | `govoplan-templates`, `govoplan-dms` | -| Payment capture and accounting handoff | `govoplan-payments`, `govoplan-ledger` | -| Roles, permissions, tenants, policy, audit | `govoplan-access`, `govoplan-tenancy`, `govoplan-policy`, `govoplan-audit` | -| External software integration | `govoplan-connectors` | -| Recurring extraction and transformation | proposed `govoplan-datasources`, proposed `govoplan-dataflow` | -| Reports, BI, and management visibility | `govoplan-reporting` | - -## Integration Landscape - -The integration strategy should start with research and connector catalogues. -The product needs a structured view of common public-sector systems and -recurring integration patterns before deciding where native modules are worth -building. - -Research should cover: - -- citizen portals and service portals -- DMS/e-file systems and archive systems -- case-management and workflow platforms -- ERP, finance, accounting, payment, and cash-register systems -- identity providers, LDAP/Active Directory, SAML, OIDC, OpenDesk, and IAM tools -- groupware, mail, calendar, postbox, and notification systems -- document collaboration, chat, video conferencing, and project-management tools -- FIT-Connect, XTA/OSCI, XRechnung, XOE/V, ePayment, and other public-sector - protocol families -- file shares, Nextcloud, Seafile, WebDAV, SMB/NFS, and object storage -- reporting, BI, open-data, RSS/API publication, and data-exchange endpoints - -The output should be a ranked connector backlog with owners, protocols, -authentication models, data shapes, operational risks, and minimum viable -integration tests. - -The core classification index lives in -`docs/PUBLIC_SECTOR_INTEGRATION_STRATEGY.md`; the detailed connector catalogue -and executable target inventory live in -`govoplan-connectors/docs/PUBLIC_SECTOR_INTEGRATION_CATALOGUE.md`. - -## Recurring Data Extraction And Transformation - -A concrete recurring use case is monthly extraction and transformation of data -received from one or more sources, preparing files for several downstream -systems by applying transformation rules. - -This should become a datasource-plus-workflow-plus-dataflow capability: - -- register datasources for uploads, file locations, APIs, databases, and - external systems -- discover or declare schemas -- define transformation rules, mapping versions, validation rules, and output - formats -- schedule monthly runs and allow manual reruns -- produce previewable diffs and validation diagnostics before publication -- write output files to configured destinations -- keep provenance, lineage, input hashes, generated outputs, operator actions, - and audit evidence -- let workflows react to success, warning, failure, or manual approval - -`govoplan-datasources` and `govoplan-dataflow` are proposed module boundaries -for this area if the scope grows beyond connectors and reporting. - -## Full UI Configuration - -The long-term target is that operators configure the platform through the UI -instead of editing files for normal operation. - -UI-managed configuration should include: - -- module installation, enablement, lifecycle state, and health -- tenants, users, groups, roles, policies, and permissions -- connectors, credentials, secret references, and external service tests -- workflows, forms, templates, task queues, schedules, and notifications -- configuration package import/export and environment-specific data collection -- retention, audit, privacy, maintenance mode, and safety controls -- deployment-visible settings such as public URLs, mail senders, storage - profiles, queues, and worker capabilities - -Safety controls should include dry-run plans, field-level validation, policy -explanations, two-person approval for destructive changes, versioned -configuration history, rollback paths, audit events, and maintenance-mode -guards. - -The initial safety metadata contract lives in -`govoplan_core.core.configuration_safety`. It classifies known configuration -fields as UI-managed or deployment-managed, assigns risk levels, marks secret -handling as reference-only or env-only, and declares dry-run, policy -explanation, audit, approval, rollback-history, maintenance-mode, and RBAC -requirements. Admin UI editors should consume this metadata before exposing -powerful settings. - -The initial executable guardrail path is `plan_configuration_change(...)`, -exposed through: - -- `GET /api/v1/admin/configuration-safety` -- `POST /api/v1/admin/configuration-safety/plan` - -The planner reports missing scopes, dry-run requirements, maintenance-mode -requirements, two-person approval status, secret-reference violations, -rollback-history requirements, policy explanations, and audit event names before -an editor applies a high-impact configuration change. - -## Scalability - -GovOPlaN should be manually scalable first and automatically scalable where the -deployment platform supports it. - -The architecture should support: - -- stateless web/API processes behind a reverse proxy or load balancer -- separate background workers for mail, workflow jobs, imports, exports, - transformations, notifications, and scheduled tasks -- PostgreSQL as the production database path -- object/file storage that can grow independently from the API process -- queue-backed job dispatch with retry, deduplication, and observability -- cache and lock services only where they are optional or operationally - documented -- health checks, readiness checks, metrics, and clear degraded-mode behavior - -The product needs realistic sizing profiles instead of guessed requirements. -Sizing should account for tenants, concurrent users, cases, files, storage -volume, upload/download rates, campaign volume, workflow jobs, transformation -runs, reporting load, and retention/audit growth. - -See `govoplan-ops/docs/SCALABILITY_PROFILES.md` for the first deployment -topology, readiness/degraded-mode model, worker scaling assumptions, PostgreSQL -production path, and sizing matrix. - -## Hardware Requirements - -Hardware guidance should be empirical and deployment-shaped. The first sizing -matrix should distinguish: - -- local development -- single-office pilot -- small production tenant -- medium municipal deployment -- larger shared deployment with separate workers and PostgreSQL - -Each profile should document CPU, memory, disk, database, storage, queue/cache, -backup, and monitoring requirements, plus the assumptions behind the numbers. -A later calculator can turn operator inputs into recommended profiles. - -The initial matrix lives in `govoplan-ops/docs/SCALABILITY_PROFILES.md`; the -calculator is kept as a follow-up once real deployment measurements are -available. - -## Collaboration - -Collaboration should be integration-first. GovOPlaN should connect with strong -existing tools and provide native behavior only where the administrative process -needs tighter governance than an external tool can provide. - -Target areas: - -- collaborative document editing and versioning through DMS integrations -- comments, internal notes, and task discussions attached to cases and workflow - items -- chat and messaging connectors -- video conferencing connectors with appointment/workflow handoff -- project-management connectors, with OpenProject as the first likely target -- presence, notifications, and activity streams where they improve operational - handoff - -Native modules are justified when GovOPlaN must own the domain semantics, -permissions, audit trail, retention behavior, or configuration package fragments. - -## Relationship To Configuration Packages - -The permit-to-payment journey should become a reference configuration package. -The package imports module-owned fragments, binds interfaces between modules, -asks the operator for deployment-specific data, and validates everything before -applying it. - -See `docs/CONFIGURATION_PACKAGES.md` for the concrete package model. - -## Tracking Issues - -The cross-cutting backlog starts with these core tracking issues. Split -module-specific child issues from them when implementation begins. - -| Topic | Tracking | -| --- | --- | -| Government operations backbone reference model | `add-ideas/govoplan-core#213` | -| Permit-to-payment configuration package | `add-ideas/govoplan-core#214` | -| Public-sector integration landscape catalogue | `add-ideas/govoplan-core#215` | -| Recurring datasource and data-transformation workflows | `add-ideas/govoplan-core#216` | -| Scalability profiles and autoscaling readiness | `add-ideas/govoplan-core#217` | -| Fully UI-managed configuration with safety controls | `add-ideas/govoplan-core#218` | -| Hardware sizing matrix and requirements calculator | `add-ideas/govoplan-core#219` | -| Collaboration suite integration strategy | `add-ideas/govoplan-core#220` | diff --git a/Repo-docs-GOVOPLAN-MASTER-ROADMAP.md b/Repo-docs-GOVOPLAN-MASTER-ROADMAP.md index aedd434..d962b99 100644 --- a/Repo-docs-GOVOPLAN-MASTER-ROADMAP.md +++ b/Repo-docs-GOVOPLAN-MASTER-ROADMAP.md @@ -1,4 +1,4 @@ - + > Mirrored from `/mnt/DATA/git/govoplan-core/docs/GOVOPLAN_MASTER_ROADMAP.md`. > Origin: `repository`. @@ -7,14 +7,14 @@ --- # GovOPlaN Master Roadmap -This roadmap orders GovOPlaN work so the product moves toward the government -operations vision without turning every possible public-sector need into an +This roadmap is the durable product north star and sequencing guide for +GovOPlaN as a modular platform for administrative operations. It keeps the +product moving without turning every possible public-sector need into an immediate implementation track. -Use this document for sequencing and module routing. Use -`GOVERNMENT_OPERATIONS_VISION.md` for the north star. Issues are the active -backlog; this document is durable planning context and should be mirrored to the -Gitea wiki. +Use this document for product direction, sequencing, and module routing. Issues +are the active backlog; this document is durable planning context and should be +mirrored to the Gitea wiki. ## Product Thesis @@ -23,8 +23,11 @@ institutions. It should help an institution model real administrative procedures, connect existing systems, keep durable evidence, and explain the configured system to users. -The product should not start by replacing every specialist system. It should -first provide a reliable administrative spine: +The goal is not to replace every existing system. GovOPlaN should connect +existing systems, provide better workflows where the current landscape is weak, +and make administrative processes configurable, auditable, and reusable. + +The product should first provide a reliable administrative spine: - identities, roles, tenants, policy, audit, and governance - forms, files, cases, workflow, tasks, templates, and records @@ -35,6 +38,21 @@ first provide a reliable administrative spine: Domain modules should come after the spine can run a reference procedure end to end. +## Design Principles + +- Modules must stay independently installable, enableable, and disableable. +- Cross-module behavior should use core-mediated capabilities, commands, + events, DTOs, and UI contribution points rather than direct imports. +- Configuration packages should turn installed modules into concrete, reusable + administrative processes. +- Operators should be able to configure the platform through the UI. +- Every powerful configuration path needs preflight, preview, audit, rollback, + RBAC, and policy checks. +- Integration should be a first-class product path: connect to existing + systems, consume their data, and publish governed outputs back to them. +- GovOPlaN should scale from a small local installation to a larger deployment + with separately scalable web, API, worker, storage, and database components. + ## Focus Rules 1. Build one reference journey per wave. @@ -49,6 +67,65 @@ end. 7. A module moves from scaffold to implementation only when it has an owner, reference journey, boundary notes, capability contracts, and testable MVP. +## Capability Map + +| Capability | Likely owner | +| --- | --- | +| Public application entry point | `govoplan-portal` | +| Structured forms and validation | `govoplan-forms` | +| Uploaded files and managed storage | `govoplan-files` | +| Case record and lifecycle | `govoplan-cases` | +| Workflow transitions and automation | `govoplan-workflow` | +| Internal work queues and tasks | `govoplan-tasks` | +| Appointment proposals and booking | `govoplan-appointments`, `govoplan-calendar` | +| Postbox, email, and notifications | `govoplan-mail`, `govoplan-notifications` | +| Permit/document generation | `govoplan-templates`, `govoplan-dms` | +| Payment capture and accounting handoff | `govoplan-payments`, `govoplan-ledger` | +| Roles, permissions, tenants, policy, audit | `govoplan-access`, `govoplan-tenancy`, `govoplan-policy`, `govoplan-audit` | +| External software integration | `govoplan-connectors` | +| Recurring extraction and transformation | possible future `govoplan-datasources`, possible future `govoplan-dataflow` | +| Reports, BI, and management visibility | `govoplan-reporting` | + +## Configuration And Safety Target + +The long-term target is that operators configure the platform through the UI +instead of editing files for normal operation. + +UI-managed configuration should include: + +- module installation, enablement, lifecycle state, and health +- tenants, users, groups, roles, policies, and permissions +- connectors, credentials, secret references, and external service tests +- workflows, forms, templates, task queues, schedules, and notifications +- configuration package import/export and environment-specific data collection +- retention, audit, privacy, maintenance mode, and safety controls +- deployment-visible settings such as public URLs, mail senders, storage + profiles, queues, and worker capabilities + +Safety controls should include dry-run plans, field-level validation, policy +explanations, two-person approval for destructive changes, versioned +configuration history, rollback paths, audit events, and maintenance-mode +guards. + +The initial safety metadata contract lives in +`govoplan_core.core.configuration_safety`. It classifies known configuration +fields as UI-managed or deployment-managed, assigns risk levels, marks secret +handling as reference-only or env-only, and declares dry-run, policy +explanation, audit, approval, rollback-history, maintenance-mode, and RBAC +requirements. Admin UI editors should consume this metadata before exposing +powerful settings. + +The initial executable guardrail path is `plan_configuration_change(...)`, +exposed through: + +- `GET /api/v1/admin/configuration-safety` +- `POST /api/v1/admin/configuration-safety/plan` + +The planner reports missing scopes, dry-run requirements, maintenance-mode +requirements, two-person approval status, secret-reference violations, +rollback-history requirements, policy explanations, and audit event names before +an editor applies a high-impact configuration change. + ## Reference Journeys The roadmap should be driven by three journeys. @@ -57,14 +134,18 @@ The roadmap should be driven by three journeys. This is the primary public-administration journey. -1. Public portal submission. -2. Structured form and file upload. -3. Case and workflow creation. -4. Internal task queue. -5. Appointment or booking. -6. Template-generated permit or decision document. -7. Payment and accounting handoff. -8. Postbox, notification, audit, retention, and records evidence. +1. A person applies for a permit through the public portal. +2. The applicant uploads required files and submits structured form data. +3. Submission creates a case, a workflow instance, and an internal task. +4. Completing the task creates a postbox message, a notification, and an email + notification with an appointment proposal. +5. The applicant accepts an appointment, which updates the calendar and the + workflow state. +6. During the appointment, the case is opened and the permit is generated from + a governed template. +7. The payment is processed and linked to the case and accounting handoff. +8. The permit, payment evidence, communication history, audit trail, retention + state, and records evidence remain available according to policy. This journey proves the platform can coordinate modules without core knowing module internals. @@ -342,6 +423,14 @@ Create only when justified: Reference journey: monthly data extraction, transformation, validation, approval, publication, and reporting. +Recurring extraction/transformation should start as a configuration package +across connectors, files, workflow, reporting, and templates. The package should +register sources, declare schemas, define mapping/validation versions, schedule +runs, produce previewable diffs, write governed outputs, and preserve lineage, +hashes, operator actions, and audit evidence. Create `govoplan-datasources` or +`govoplan-dataflow` only after this work exposes repeated contracts that do not +belong to existing modules. + Exit criteria: - connector catalog exists before building many adapters diff --git a/Repo-docs-MODULE-ARCHITECTURE.md b/Repo-docs-MODULE-ARCHITECTURE.md index 9c1d5f0..33798fe 100644 --- a/Repo-docs-MODULE-ARCHITECTURE.md +++ b/Repo-docs-MODULE-ARCHITECTURE.md @@ -1,4 +1,4 @@ - + > Mirrored from `/mnt/DATA/git/govoplan-core/docs/MODULE_ARCHITECTURE.md`. > Origin: `repository`. @@ -272,6 +272,10 @@ Concrete consumers: snapshot first, then changed campaign/version metadata and optional summary refreshes when version, job, issue, or delivery-attempt changes invalidate the workspace view. +- `GET /api/v1/campaigns/{campaign_id}/jobs/delta`: returns a paginated job + table snapshot first, then stable row deltas for unfiltered job status + updates. Filtered, created, deleted, or stale-watermark requests fall back to + a full page snapshot so pagination remains correct. ## Module Responsibilities diff --git a/Repo-docs-RELEASE-CATALOG-WORKFLOW.md b/Repo-docs-RELEASE-CATALOG-WORKFLOW.md deleted file mode 100644 index 51a86b2..0000000 --- a/Repo-docs-RELEASE-CATALOG-WORKFLOW.md +++ /dev/null @@ -1,144 +0,0 @@ - - -> Mirrored from `/mnt/DATA/git/govoplan-core/docs/RELEASE_CATALOG_WORKFLOW.md`. -> Origin: `repository`. -> Active tasks and changing state belong in Gitea issues; this wiki page is durable project context. - ---- -# Release Catalog Workflow - -GovOPlaN release catalogs are published by `govoplan-web` as static JSON and -verified by `govoplan-core` before installer plans are accepted. - -Private signing keys must stay outside all git repositories. Public keyrings -are published with the website. - -## One-Time Key Setup - -Create the first catalog signing key on the release machine: - -```bash -cd /mnt/DATA/git/govoplan-core -KEY_DIR="$HOME/.config/govoplan/release-keys" -mkdir -p "$KEY_DIR" -./.venv/bin/python scripts/generate-catalog-keypair.py \ - --key-id release-key-1 \ - --private-key "$KEY_DIR/release-key-1.pem" \ - --public-key "$KEY_DIR/release-key-1.pub" \ - --keyring "$KEY_DIR/catalog-keyring.json" -``` - -Keep `release-key-1.pem` private. The generated keyring contains only public -material. - -## Publish Current Release Catalog - -Generate the signed catalog into `govoplan-web`: - -```bash -cd /mnt/DATA/git/govoplan-core -KEY_DIR="$HOME/.config/govoplan/release-keys" -scripts/publish-release-catalog.sh \ - --version \ - --sequence 202607071340 \ - --catalog-signing-key "release-key-1=$KEY_DIR/release-key-1.pem" \ - --build-web -``` - -This writes: - -- `/mnt/DATA/git/govoplan-web/public/catalogs/v1/channels/stable.json` -- `/mnt/DATA/git/govoplan-web/public/catalogs/v1/keyring.json` - -The wrapper validates the catalog with core using the generated public keyring. - -## Publish After A New Release - -For normal module/core releases, first audit and record migration baselines, -then tag and push the module/core repos. Finally publish the website catalog: - -```bash -cd /mnt/DATA/git/govoplan-core -./.venv/bin/python scripts/release-migration-audit.py --strict -``` - -```bash -cd /mnt/DATA/git/govoplan-core -KEY_DIR="$HOME/.config/govoplan/release-keys" -scripts/publish-release-catalog.sh \ - --version \ - --catalog-signing-key "release-key-1=$KEY_DIR/release-key-1.pem" \ - --build-web \ - --commit \ - --tag \ - --push -``` - -The website tag is `catalog-v`. The public URL is: - -```text -https://govoplan.add-ideas.de/catalogs/v1/channels/stable.json -``` - -The public keyring URL is: - -```text -https://govoplan.add-ideas.de/catalogs/v1/keyring.json -``` - -## Integrated Release Script - -`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 automatic mode: -warning-only before the first recorded migration baseline, strict after a -baseline exists. Add `--strict-migration-audit` when you want to force strict -mode explicitly: - -```bash -cd /mnt/DATA/git/govoplan-core -KEY_DIR="$HOME/.config/govoplan/release-keys" -scripts/push-release-tag.sh \ - --bump subversion \ - --strict-migration-audit \ - --publish-web-catalog \ - --catalog-signing-key "release-key-1=$KEY_DIR/release-key-1.pem" \ - --build-web-catalog -``` - -Use `--catalog-signing-key` more than once during a key rotation window. The -catalog will contain multiple signatures and the public keyring will include the -corresponding public keys. - -## Consumer Configuration - -On a GovOPlaN installation that should consume the official stable catalog: - -```bash -GOVOPLAN_MODULE_PACKAGE_CATALOG_URL=https://govoplan.add-ideas.de/catalogs/v1/channels/stable.json -GOVOPLAN_MODULE_PACKAGE_CATALOG_CACHE=/srv/govoplan/runtime/catalog-cache/stable.json -GOVOPLAN_MODULE_PACKAGE_CATALOG_REQUIRE_SIGNATURE=true -GOVOPLAN_MODULE_PACKAGE_CATALOG_APPROVED_CHANNELS=stable -GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS_FILE=/srv/govoplan/trust/catalog-keyring.json -GOVOPLAN_MODULE_PACKAGE_CATALOG_SEQUENCE_STATE=/srv/govoplan/runtime/catalog-sequences.json -GOVOPLAN_MODULE_PACKAGE_CATALOG_ENFORCE_SEQUENCE=true -``` - -For production, copy the public keyring into deployment configuration and pin it -locally. Do not rely on a URL-fetched keyring as the only trust root. - -## Core Updates - -`stable.json` includes a top-level `core_release` section for operator/update -tooling. Core is intentionally not listed as a normal module entry, because it -must not be added to saved enabled-module state. Core upgrades should remain an -operator-supervised package update with restart and health checks. - -## Key Rotation - -1. Generate the next private key outside git. -2. Run `publish-release-catalog.sh` with both signing keys. -3. Publish the web catalog/keyring. -4. Roll the new public keyring into installations. -5. Stop signing with the old key after the supported fleet trusts the new key. -6. Mark compromised keys as revoked in the public keyring and publish a higher - sequence catalog signed by a trusted uncompromised key. diff --git a/Repo-docs-RELEASE-DEPENDENCIES.md b/Repo-docs-RELEASE-DEPENDENCIES.md index 88735d9..929acb6 100644 --- a/Repo-docs-RELEASE-DEPENDENCIES.md +++ b/Repo-docs-RELEASE-DEPENDENCIES.md @@ -1,4 +1,4 @@ - + > Mirrored from `/mnt/DATA/git/govoplan-core/docs/RELEASE_DEPENDENCIES.md`. > Origin: `repository`. @@ -7,14 +7,12 @@ --- # GovOPlaN Release Dependencies -This document owns release package composition: Python package refs, WebUI -release package refs, release lockfiles, migration baselines, and the final -release checklist. +This document owns release package composition, signed package catalogs, +license checks, catalog publishing, migration baselines, and the final release +checklist. 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`. +`DEPLOYMENT_OPERATOR_GUIDE.md`. ## Backend Packages @@ -146,6 +144,371 @@ Current tag-only module repositories: - `govoplan-xrechnung` - `govoplan-xta-osci` +## Catalog Trust And Licensing + +GovOPlaN module install and uninstall must remain operator-controlled. The +running server may plan and validate package changes, but package mutation is +performed by the separate installer daemon or an operator shell during +maintenance mode. + +`govoplan-web` is the public static distribution surface for official catalog +resources: + +- signed module package catalogs, grouped by release channel +- public catalog keyrings +- public license verification keyrings +- examples and operator-facing download paths + +`govoplan-core` is the verifier and orchestrator: + +- fetches a local or remote module catalog +- verifies catalog signatures against configured trusted keys +- enforces approved release channels +- rejects expired or not-yet-valid catalogs +- records accepted catalog sequence numbers for replay protection +- checks catalog entry license feature requirements before planning installs +- writes installer plans and request records + +Feature and platform modules own their package artifacts, manifests, migration +metadata, retirement providers, and optional lifecycle behavior. + +Core accepts either a local catalog file or a remote URL: + +```bash +GOVOPLAN_MODULE_PACKAGE_CATALOG=/srv/govoplan/catalogs/stable.json +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 +``` + +If both file and URL are set, the URL wins. The cache is used when a remote +fetch fails, so an operator can still inspect the last known catalog. A cached +catalog must still pass signature, freshness, channel, and replay validation. + +An official catalog is a JSON object with: + +- `catalog_version` +- `channel` +- `sequence` +- `generated_at` +- `not_before` when delayed activation is needed +- `expires_at` +- `modules` +- `signatures` + +Each module entry can declare: + +- backend package name and pinned install reference +- WebUI package name and pinned install reference +- display metadata and tags +- `license_features`, the feature entitlements required to plan that install + +The signature is Ed25519 over canonical JSON with both `signature` and +`signatures` removed. Core accepts the legacy single `signature` field and the +new `signatures` array. + +Trusted catalog keys are configured locally: + +```bash +GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS_FILE=/srv/govoplan/trust/catalog-keyring.json +GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS='{"release-key-1":""}' +``` + +For development or tightly controlled deployments, a keyring can be read from a +URL and cached: + +```bash +GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS_URL=https://govoplan.example/catalogs/v1/keyring.json +GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS_CACHE=/srv/govoplan/runtime/catalog-cache/keyring.json +``` + +Production installations should pin the trusted keyring locally or ship it +through deployment configuration. Fetching trusted keys from the same public +origin as the catalog is convenient, but that origin must not become the only +trust root. + +Keyring entries support: + +- `key_id` +- `public_key` or `public_key_base64` +- `status`: `active`, `next`, `retired`, `revoked`, or `disabled` +- `not_before` +- `not_after` + +Rotation process: + +1. Add the next public key to the local trusted keyring with status `next`. +2. Publish catalogs signed by both current and next keys. +3. Upgrade installations so the next key is locally trusted. +4. Promote the next key to `active`. +5. Retire the old key only after every supported installation trusts the new + key. +6. Mark a compromised key `revoked` and publish a higher sequence catalog + signed by an uncompromised key. + +Use replay state in production: + +```bash +GOVOPLAN_MODULE_PACKAGE_CATALOG_SEQUENCE_STATE=/srv/govoplan/runtime/catalog-sequences.json +GOVOPLAN_MODULE_PACKAGE_CATALOG_ENFORCE_SEQUENCE=true +``` + +Core records the accepted sequence per channel after a catalog entry is planned +from the admin interface. With strict sequence enforcement, a previously +accepted sequence is rejected; without strict enforcement, only older sequences +are rejected. Catalogs should always expire. + +The sequence state file is operational state, not a trust root. Keep it on +persistent storage and include it in normal backups: + +```json +{ + "channels": { + "stable": { + "last_sequence": 42, + "accepted_at": "2026-07-07T12:00:00Z", + "key_id": "release-key-1", + "source": "https://govoplan.example/catalogs/v1/channels/stable.json" + } + } +} +``` + +If the file is lost, restore it from backup. If no backup exists, reconstruct +each channel from the highest sequence already accepted in installer run +records, release records, or the currently deployed module package set. Do not +lower `last_sequence` to make an older catalog pass; publish a new higher +sequence catalog when the accepted point is uncertain. + +If the file is corrupted, copy it aside for incident review, validate the +current signed catalog with channel and freshness enforcement, then rewrite the +state with the known accepted sequence. Keep +`GOVOPLAN_MODULE_PACKAGE_CATALOG_REQUIRE_SIGNATURE=true` and approved-channel +checks enabled during recovery. Temporarily disabling +`GOVOPLAN_MODULE_PACKAGE_CATALOG_ENFORCE_SEQUENCE` allows revalidating the same +sequence, but older sequences remain rejected once the reconstructed +`last_sequence` is in place. + +Approved channels are deployment policy: + +```bash +GOVOPLAN_MODULE_PACKAGE_CATALOG_APPROVED_CHANNELS=stable,lts +GOVOPLAN_MODULE_PACKAGE_CATALOG_REQUIRE_SIGNATURE=true +``` + +The admin UI can display other catalog metadata, but core rejects catalogs from +unapproved channels when validation is configured. + +Catalog entries can require license features: + +```json +"license_features": ["module.mail", "support.standard"] +``` + +Core checks those requirements against an offline license file before allowing +the entry into the install plan. + +```bash +GOVOPLAN_LICENSE_FILE=/srv/govoplan/license.json +GOVOPLAN_LICENSE_ENFORCEMENT=true +GOVOPLAN_LICENSE_TRUSTED_KEYS_FILE=/srv/govoplan/trust/license-keyring.json +``` + +License files are JSON objects with: + +- `license_id` +- `subject` +- `features` +- `valid_from` +- `valid_until` +- `signature` + +Issue or renew a license from an operator/release shell that has the Ed25519 +private key: + +```bash +govoplan-module-installer \ + --issue-license /srv/govoplan/license.json \ + --license-id customer-2026-07 \ + --license-subject "Example Municipality" \ + --license-feature module.mail \ + --license-feature support.standard \ + --license-valid-until 2027-07-31T23:59:59Z \ + --license-signing-key-id license-issuer-1 \ + --license-signing-private-key /srv/govoplan/secrets/license-issuer-1.pem \ + --format json +``` + +Validate an imported license without exposing secrets: + +```bash +govoplan-module-installer \ + --validate-license /srv/govoplan/license.json \ + --license-trusted-key license-issuer-1="" \ + --require-trusted-license \ + --license-required-feature module.mail \ + --format json +``` + +The CLI and admin module catalog panel report the license id, subject, +validity window, signing key id, signed/trusted state, available features, and +missing entitlements for the configured package catalog. They do not expose +private signing material. + +License enforcement can run in observe-only mode by leaving +`GOVOPLAN_LICENSE_ENFORCEMENT` unset. In that mode, missing or invalid license +data is surfaced as a warning but does not block planning. + +Renewal is an ordinary re-issuance with a new `license_id`, extended +`valid_until`, and the full intended feature set. Import the renewed JSON to +`GOVOPLAN_LICENSE_FILE`, keep the previous file for audit, and validate it +before setting enforcement. + +Revocation is handled through the trusted license keyring. Mark a compromised +or invalid issuer key as `revoked` or `disabled`, publish or deploy the updated +keyring, then reissue affected licenses with an active key. Installations that +run with `GOVOPLAN_LICENSE_ENFORCEMENT=true` reject licenses signed only by a +revoked key after the local keyring is updated. + +Emergency fallback is deliberately explicit. Operators can temporarily unset +`GOVOPLAN_LICENSE_ENFORCEMENT` to keep package planning observable while a +license or keyring is recovered. Record the change in the operational incident +log, keep catalog signature and channel enforcement enabled, and restore +license enforcement after a trusted renewal validates successfully. + +Licensing is intentionally separate from open-source code licensing. The +catalog/license mechanism can govern support channels, official release +eligibility, hosted update access, professional support, or commercial +entitlements without changing the source license of the repositories. + +Production-grade distribution still needs remote registry/git artifact +resolution before package-manager apply, a hardened catalog publishing pipeline +in `govoplan-web`, and automated key rotation and emergency revocation drills. + +## Release Catalog Publishing + +GovOPlaN release catalogs are published by `govoplan-web` as static JSON and +verified by `govoplan-core` before installer plans are accepted. Private signing +keys must stay outside all git repositories. Public keyrings are published with +the website. + +Create the first catalog signing key on the release machine: + +```bash +cd /mnt/DATA/git/govoplan-core +KEY_DIR="$HOME/.config/govoplan/release-keys" +mkdir -p "$KEY_DIR" +./.venv/bin/python scripts/generate-catalog-keypair.py \ + --key-id release-key-1 \ + --private-key "$KEY_DIR/release-key-1.pem" \ + --public-key "$KEY_DIR/release-key-1.pub" \ + --keyring "$KEY_DIR/catalog-keyring.json" +``` + +Keep `release-key-1.pem` private. The generated keyring contains only public +material. + +Generate the signed catalog into `govoplan-web`: + +```bash +cd /mnt/DATA/git/govoplan-core +KEY_DIR="$HOME/.config/govoplan/release-keys" +scripts/publish-release-catalog.sh \ + --version \ + --sequence 202607071340 \ + --catalog-signing-key "release-key-1=$KEY_DIR/release-key-1.pem" \ + --build-web +``` + +This writes: + +- `/mnt/DATA/git/govoplan-web/public/catalogs/v1/channels/stable.json` +- `/mnt/DATA/git/govoplan-web/public/catalogs/v1/keyring.json` + +The wrapper validates the catalog with core using the generated public keyring. + +For normal module/core releases, first audit and record migration baselines, +then tag and push the module/core repos. Finally publish the website catalog: + +```bash +cd /mnt/DATA/git/govoplan-core +./.venv/bin/python scripts/release-migration-audit.py --strict +``` + +```bash +cd /mnt/DATA/git/govoplan-core +KEY_DIR="$HOME/.config/govoplan/release-keys" +scripts/publish-release-catalog.sh \ + --version \ + --catalog-signing-key "release-key-1=$KEY_DIR/release-key-1.pem" \ + --build-web \ + --commit \ + --tag \ + --push +``` + +The website tag is `catalog-v`. The public URL is: + +```text +https://govoplan.add-ideas.de/catalogs/v1/channels/stable.json +``` + +The public keyring URL is: + +```text +https://govoplan.add-ideas.de/catalogs/v1/keyring.json +``` + +`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 automatic mode: +warning-only before the first recorded migration baseline, strict after a +baseline exists. Add `--strict-migration-audit` when you want to force strict +mode explicitly: + +```bash +cd /mnt/DATA/git/govoplan-core +KEY_DIR="$HOME/.config/govoplan/release-keys" +scripts/push-release-tag.sh \ + --bump subversion \ + --strict-migration-audit \ + --publish-web-catalog \ + --catalog-signing-key "release-key-1=$KEY_DIR/release-key-1.pem" \ + --build-web-catalog +``` + +Use `--catalog-signing-key` more than once during a key rotation window. The +catalog will contain multiple signatures and the public keyring will include the +corresponding public keys. + +On a GovOPlaN installation that should consume the official stable catalog: + +```bash +GOVOPLAN_MODULE_PACKAGE_CATALOG_URL=https://govoplan.add-ideas.de/catalogs/v1/channels/stable.json +GOVOPLAN_MODULE_PACKAGE_CATALOG_CACHE=/srv/govoplan/runtime/catalog-cache/stable.json +GOVOPLAN_MODULE_PACKAGE_CATALOG_REQUIRE_SIGNATURE=true +GOVOPLAN_MODULE_PACKAGE_CATALOG_APPROVED_CHANNELS=stable +GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS_FILE=/srv/govoplan/trust/catalog-keyring.json +GOVOPLAN_MODULE_PACKAGE_CATALOG_SEQUENCE_STATE=/srv/govoplan/runtime/catalog-sequences.json +GOVOPLAN_MODULE_PACKAGE_CATALOG_ENFORCE_SEQUENCE=true +``` + +For production, copy the public keyring into deployment configuration and pin it +locally. Do not rely on a URL-fetched keyring as the only trust root. + +`stable.json` includes a top-level `core_release` section for operator/update +tooling. Core is intentionally not listed as a normal module entry because it +must not be added to saved enabled-module state. Core upgrades should remain an +operator-supervised package update with restart and health checks. + +Key rotation for published catalogs: + +1. Generate the next private key outside git. +2. Run `publish-release-catalog.sh` with both signing keys. +3. Publish the web catalog/keyring. +4. Roll the new public keyring into installations. +5. Stop signing with the old key after the supported fleet trusts the new key. +6. Mark compromised keys as revoked in the public keyring and publish a higher + sequence catalog signed by a trusted uncompromised key. + ## PostgreSQL Release Check Release candidates should pass a disposable PostgreSQL migration and startup @@ -231,11 +594,6 @@ first public baseline and record that baseline in - `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. @@ -251,7 +609,7 @@ first public baseline and record that baseline in - 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`. +- Publish the signed catalog through the release catalog publishing flow above. - 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.