18 Commits
Author SHA1 Message Date
zemion 85caa8d337 chore(release): integrate structured documentation localization
Dependency Audit / dependency-audit (push) Successful in 1m45s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Failing after 12m2s
Developer Meta-package Release / publish-package (push) Successful in 10s
2026-08-22 20:45:41 +02:00
zemion 64640327ae chore(release): pin datasource lifecycle governance
Dependency Audit / dependency-audit (push) Successful in 1m47s
Security Audit / security-audit (push) Failing after 11m49s
Deployment Installer / deployment-installer (push) Successful in 6s
Developer Meta-package Release / publish-package (push) Successful in 9s
2026-08-22 19:37:54 +02:00
zemion cc7c2a91ee chore(release): pin Records 0.1.20
Deployment Installer / deployment-installer (push) Successful in 5s
Dependency Audit / dependency-audit (push) Successful in 1m44s
Security Audit / security-audit (push) Failing after 11m51s
2026-08-22 18:42:15 +02:00
zemion 7c92565d9d Compose v0.1.35 resident permit configuration package
Dependency Audit / dependency-audit (push) Successful in 1m44s
Developer Meta-package Release / publish-package (push) Successful in 9s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Failing after 11m59s
2026-08-22 18:05:58 +02:00
zemion 23bfe5e2f8 Compose Core v0.1.34 and Mail v0.1.22
Dependency Audit / dependency-audit (push) Successful in 1m46s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Failing after 11m54s
Developer Meta-package Release / publish-package (push) Successful in 9s
2026-08-22 17:30:27 +02:00
zemion cf2f7f6890 Compose Core v0.1.33 and Connectors v0.1.22
Dependency Audit / dependency-audit (push) Successful in 1m44s
Deployment Installer / deployment-installer (push) Successful in 7s
Security Audit / security-audit (push) Failing after 12m8s
2026-08-22 16:31:58 +02:00
zemion 23b601bc0d build: compose external knowledge connector slice
Security Audit / security-audit (push) Failing after 12m23s
Dependency Audit / dependency-audit (push) Successful in 1m45s
Deployment Installer / deployment-installer (push) Successful in 6s
2026-08-22 14:44:55 +02:00
zemion 99c52c2153 build: compose governed Wiki vertical slice
Dependency Audit / dependency-audit (push) Successful in 1m44s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Failing after 12m20s
2026-08-22 13:33:31 +02:00
zemion ca68d98806 build: release ticket operations vertical slice
Dependency Audit / dependency-audit (push) Successful in 1m40s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Failing after 11m44s
2026-08-22 12:24:55 +02:00
zemion 79c4cb067a build: release localized documentation batch
Dependency Audit / dependency-audit (push) Successful in 1m39s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Failing after 11m41s
2026-08-22 08:45:51 +02:00
zemion cd498dc1d8 build: release seed documentation coverage batch
Dependency Audit / dependency-audit (push) Successful in 1m40s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Failing after 11m35s
2026-08-22 08:12:04 +02:00
zemion e07b3487e3 build: release documentation coverage batch
Dependency Audit / dependency-audit (push) Successful in 1m41s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Failing after 11m23s
2026-08-22 07:40:10 +02:00
zemion 72279de2c0 chore: sync Tasks and Postbox documentation releases
Dependency Audit / dependency-audit (push) Successful in 1m42s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Failing after 11m43s
2026-08-22 07:07:49 +02:00
zemion 88543ab115 chore: sync REST and SOAP reference releases
Dependency Audit / dependency-audit (push) Successful in 1m40s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Failing after 11m18s
2026-08-22 06:38:20 +02:00
zemion 81fe0f4680 chore: sync Docs German reference release
Dependency Audit / dependency-audit (push) Successful in 1m36s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Failing after 11m3s
2026-08-22 06:12:49 +02:00
zemion fe784cc562 chore: sync Mail German help release
Dependency Audit / dependency-audit (push) Successful in 1m36s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Failing after 11m0s
2026-08-22 05:45:12 +02:00
zemion 9fe7ad2cb4 chore: sync Mail POP3 legacy import release
Dependency Audit / dependency-audit (push) Successful in 1m31s
Deployment Installer / deployment-installer (push) Successful in 5s
Security Audit / security-audit (push) Failing after 11m3s
2026-08-22 05:09:01 +02:00
zemion f1eebd849c chore: sync Campaign portable transfer release
Dependency Audit / dependency-audit (push) Successful in 1m35s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Failing after 10m52s
2026-08-22 03:58:31 +02:00
11 changed files with 716 additions and 70 deletions
@@ -6,8 +6,8 @@ Every other active module requires a reviewed explanation of why it owns no
persistent subject-data store. Adding a migration invalidates that explanation.
- Active modules: 68
- Registered and documented DSAR providers: 45
- Reviewed no-store rationales: 23
- Registered and documented DSAR providers: 48
- Reviewed no-store rationales: 20
- Unexplained coverage gaps: 0
| Module | Repository | Persistence | Coverage | Rationale |
@@ -40,7 +40,7 @@ persistent subject-data store. Adding a migration invalidates that explanation.
| `forms` | `govoplan-forms` | Migration-owned | Provider | Provider `privacy.dsar.forms` is registered and documented. |
| `forms_runtime` | `govoplan-forms-runtime` | Migration-owned | Provider | Provider `privacy.dsar.forms_runtime` is registered and documented. |
| `grants` | `govoplan-grants` | No module migration | Reviewed no-store rationale | Contract-only module: grant applications, awards, and monitoring are not persisted; reassess before adding a migration-owned store. |
| `helpdesk` | `govoplan-helpdesk` | No module migration | Reviewed no-store rationale | Contract-only module: helpdesk requests, queues, and resolutions are not persisted; reassess before adding a migration-owned store. |
| `helpdesk` | `govoplan-helpdesk` | Migration-owned | Provider | Provider `privacy.dsar.helpdesk` is registered and documented. |
| `identity` | `govoplan-identity` | Migration-owned | Provider | Provider `privacy.dsar.identity` is registered and documented. |
| `identity_trust` | `govoplan-identity-trust` | Migration-owned | Provider | Provider `privacy.dsar.identity_trust` is registered and documented. |
| `idm` | `govoplan-idm` | Migration-owned | Provider | Provider `privacy.dsar.idm` is registered and documented. |
@@ -73,11 +73,11 @@ persistent subject-data store. Adding a migration invalidates that explanation.
| `tasks` | `govoplan-tasks` | Migration-owned | Provider | Provider `privacy.dsar.tasks` is registered and documented. |
| `templates` | `govoplan-templates` | Migration-owned | Provider | Provider `privacy.dsar.templates` is registered and documented. |
| `tenancy` | `govoplan-tenancy` | No module migration | Reviewed no-store rationale | Orchestration module: tenant lifecycle and settings use Core-owned storage; Access covers account and membership subject data. |
| `tickets` | `govoplan-tickets` | No module migration | Reviewed no-store rationale | Contract-only module: ticket, queue, SLA, and adapter persistence are not implemented; reassess before adding a migration-owned store. |
| `tickets` | `govoplan-tickets` | Migration-owned | Provider | Provider `privacy.dsar.tickets` is registered and documented. |
| `transparency` | `govoplan-transparency` | No module migration | Reviewed no-store rationale | Contract-only module: requests, disclosure reviews, and publications are not persisted; reassess before adding a migration-owned store. |
| `views` | `govoplan-views` | Migration-owned | Provider | Provider `privacy.dsar.views` is registered and documented. |
| `voting` | `govoplan-voting` | Migration-owned | Provider | Provider `privacy.dsar.voting` is registered and documented. |
| `wiki` | `govoplan-wiki` | No module migration | Reviewed no-store rationale | Contract-only module: wiki spaces, pages, and revisions are not persisted; reassess before adding a migration-owned store. |
| `wiki` | `govoplan-wiki` | Migration-owned | Provider | Provider `privacy.dsar.wiki` is registered and documented. |
| `workflow` | `govoplan-workflow` | No module migration | Reviewed no-store rationale | Presentation-only module: Workflow edits and projects Workflow Engine state; Workflow Engine owns persistence and DSAR coverage. |
| `workflow_engine` | `govoplan-workflow-engine` | Migration-owned | Provider | Provider `privacy.dsar.workflow_engine` is registered and documented. |
@@ -109,7 +109,9 @@ semantics as authenticated navigation routes.
| `/scheduling/public/:requestId/:token` | Scheduling | Public signed token | Public participation | Scheduling #8 complete in `c17cbda` |
| `/search` | Search | `search:result:read` | Keyboard-first global/context overlay and full results fallback | Search pattern migration complete in [Search #4](https://git.add-ideas.de/GovOPlaN/govoplan-search/issues/4); durable evidence in `govoplan-search/docs/INTERFACE_PATTERN_MIGRATION.md` |
| `/templates` | Templates | Template read/write/publish/render/admin | Governed library, immutable-revision editor, compatibility preview, and render evidence | Templates pattern migration complete in [Templates #5](https://git.add-ideas.de/GovOPlaN/govoplan-templates/issues/5), commit `72fafa2` |
| `/tickets` | Tickets | `tickets:ticket:read` | Governed operational queue/detail workspace with distinct report, triage, assignment, resolution, comment, reference and removal boundaries | Tickets vertical slice and pattern migration complete in [Tickets #1](https://git.add-ideas.de/GovOPlaN/govoplan-tickets/issues/1), release `v0.1.20` |
| `/voting` | Voting | `voting:ballot:read` | Governed ballot workspace | Voting pattern migration complete in [Voting #1](https://git.add-ideas.de/GovOPlaN/govoplan-voting/issues/1), commit `2625990` |
| `/wiki` | Wiki | `wiki:page:read` | Governed space-tree/page workspace with draft editing, immutable revision comparison, publication, comments, typed references and archival | Native Wiki vertical slice and pattern migration implemented in [Wiki #1](https://git.add-ideas.de/GovOPlaN/govoplan-wiki/issues/1), release `v0.1.20` |
| `/workflow` | Workflow | Definition read or instance admin | Native BPMN editor, governed revision actions and execution evidence | Workflow pattern migration complete in [Workflow #15](https://git.add-ideas.de/GovOPlaN/govoplan-workflow/issues/15); durable evidence in `govoplan-workflow/docs/INTERFACE_PATTERN_MIGRATION.md` |
## Final Module Closure Evidence
@@ -323,8 +325,8 @@ The generated manifest snapshot reports no WebUI package for:
`govoplan-learning`, `govoplan-mandates`, `govoplan-parties`,
`govoplan-permits`, `govoplan-poll`, `govoplan-procurement`,
`govoplan-records`, `govoplan-resources`, `govoplan-rest`,
`govoplan-services`, `govoplan-soap`, `govoplan-tickets`,
`govoplan-transparency`, `govoplan-wiki`, and `govoplan-workflow-engine`.
`govoplan-services`, `govoplan-soap`, `govoplan-transparency`, and
`govoplan-workflow-engine`.
Tenancy does provide composed administration surfaces despite having no direct
route. This section is only negative package evidence; connector-only,
+44 -44
View File
@@ -4,84 +4,84 @@ build-backend = "setuptools.build_meta"
[project]
name = "govoplan"
version = "0.1.29"
version = "0.1.37"
description = "Developer convenience package for a versioned GovOPlaN composition"
readme = "README.md"
requires-python = ">=3.12"
license = { text = "AGPL-3.0-or-later" }
dependencies = [
"govoplan-core[server]==0.1.29",
"govoplan-core[server]==0.1.37",
"govoplan-tenancy==0.1.18",
"govoplan-organizations==0.1.18",
"govoplan-identity==0.1.18",
"govoplan-idm==0.1.20",
"govoplan-access==0.1.19",
"govoplan-admin==0.1.18",
"govoplan-access==0.1.20",
"govoplan-admin==0.1.19",
"govoplan-policy==0.1.20",
"govoplan-audit==0.1.18",
"govoplan-audit==0.1.19",
"govoplan-dashboard==0.1.18",
"govoplan-files==0.1.20",
"govoplan-mail==0.1.18",
"govoplan-campaign==0.1.23",
"govoplan-mail==0.1.22",
"govoplan-campaign==0.1.24",
"govoplan-calendar==0.1.18",
"govoplan-docs==0.1.18",
"govoplan-ops==0.1.18",
"govoplan-docs==0.1.21",
"govoplan-ops==0.1.19",
]
[project.optional-dependencies]
full = [
"govoplan-addresses==0.1.18",
"govoplan-approvals==0.1.18",
"govoplan-assets==0.1.18",
"govoplan-booking==0.1.18",
"govoplan-cases==0.1.19",
"govoplan-certificates==0.1.18",
"govoplan-assets==0.1.19",
"govoplan-booking==0.1.19",
"govoplan-cases==0.1.20",
"govoplan-certificates==0.1.19",
"govoplan-committee==0.1.18",
"govoplan-connectors==0.1.20",
"govoplan-consultation==0.1.18",
"govoplan-contracts==0.1.18",
"govoplan-connectors==0.1.22",
"govoplan-consultation==0.1.19",
"govoplan-contracts==0.1.19",
"govoplan-dataflow==0.1.20",
"govoplan-datasources==0.1.20",
"govoplan-decisions==0.1.18",
"govoplan-datasources==0.1.21",
"govoplan-decisions==0.1.19",
"govoplan-dist-lists==0.1.18",
"govoplan-encryption==0.1.18",
"govoplan-evaluation==0.1.18",
"govoplan-facilities==0.1.18",
"govoplan-forms==0.1.19",
"govoplan-evaluation==0.1.19",
"govoplan-facilities==0.1.19",
"govoplan-forms==0.1.20",
"govoplan-forms-runtime==0.1.18",
"govoplan-grants==0.1.18",
"govoplan-helpdesk==0.1.18",
"govoplan-grants==0.1.19",
"govoplan-helpdesk==0.1.20",
"govoplan-identity-trust==0.1.18",
"govoplan-inspections==0.1.18",
"govoplan-learning==0.1.18",
"govoplan-mandates==0.1.18",
"govoplan-inspections==0.1.19",
"govoplan-learning==0.1.19",
"govoplan-mandates==0.1.19",
"govoplan-notifications==0.1.18",
"govoplan-parties==0.1.18",
"govoplan-parties==0.1.19",
"govoplan-payments==0.1.20",
"govoplan-permits==0.1.18",
"govoplan-poll==0.1.18",
"govoplan-portal==0.1.18",
"govoplan-postbox==0.1.18",
"govoplan-procurement==0.1.18",
"govoplan-permits==0.1.19",
"govoplan-poll==0.1.19",
"govoplan-portal==0.1.19",
"govoplan-postbox==0.1.19",
"govoplan-procurement==0.1.19",
"govoplan-projects==0.1.18",
"govoplan-quick-access==0.1.18",
"govoplan-records==0.1.19",
"govoplan-quick-access==0.1.19",
"govoplan-records==0.1.20",
"govoplan-reporting==0.1.18",
"govoplan-resources==0.1.18",
"govoplan-rest==0.1.18",
"govoplan-resources==0.1.19",
"govoplan-rest==0.1.19",
"govoplan-risk-compliance==0.1.18",
"govoplan-scheduling==0.1.18",
"govoplan-search==0.1.18",
"govoplan-services==0.1.18",
"govoplan-soap==0.1.18",
"govoplan-tasks==0.1.19",
"govoplan-services==0.1.19",
"govoplan-soap==0.1.19",
"govoplan-tasks==0.1.20",
"govoplan-templates==0.1.18",
"govoplan-tickets==0.1.18",
"govoplan-transparency==0.1.18",
"govoplan-views==0.1.18",
"govoplan-tickets==0.1.20",
"govoplan-transparency==0.1.19",
"govoplan-views==0.1.19",
"govoplan-voting==0.1.18",
"govoplan-wiki==0.1.18",
"govoplan-workflow==0.1.20",
"govoplan-wiki==0.1.20",
"govoplan-workflow==0.1.21",
"govoplan-workflow-engine==0.1.19",
]
@@ -17,6 +17,26 @@ human review handoff, formal outcome, Postbox delivery channel, and Records
filing/retention target. Generic permit wording is no longer acceptance
evidence for this package.
The package is now executable rather than metadata-only. Its Access fragments
create the bounded resident-permit clerk role, collect only the tenant-local
responsibility group key and name, create that group, and bind the role. The
Forms-owned fragment carries a digest-bound German-reference application schema
and imports it as a tenant-local draft with source provenance. Reapplying the
same source digest is a no-op; replacing an unrelated local definition remains
blocked unless the reviewed package explicitly selects a new revision. Normal
Forms review and publication are still required before the definition can serve
new applications. The Workflow Engine-owned fragment materializes and activates
the tenant review baseline, resolves the chosen responsibility group into each
human handoff, and preserves the evidence, decision, and EUR 30 payment-review
steps as a replay-safe contributed definition.
Services, Cases, Payments, Tasks, and the optional delivery and Records modules
already execute the pinned journey through their runtime
contracts, but their reusable configuration fragments are not yet claimed by
this package. Until those module-owned configuration providers are added, the
package preflight deliberately distinguishes the installed runtime composition
from the Access, Forms, and Workflow configurations it can currently materialize.
An installed Forms and Forms Runtime pair adds an alternative governed entry
path before case/workflow handoff:
@@ -76,3 +96,11 @@ and Decision revision filing. Target-environment browser accessibility,
production identity and delivery, a named archive profile, and recovery evidence
are still required before this product package may claim `reference_ready`
maturity.
The generic package orchestrator stops at the first provider apply or health
blocker. Access and Forms may commit in separate provider transactions, so the
operator must retain the reviewed pre-apply database snapshot until verification
is complete. The Admin result reports no-op, snapshot-required, or partial-apply
recovery state and never describes this as atomic cross-module undo. Exported
fragments carry source/module/operator/scope provenance; supplied values and
credentials are not serialized into that provenance.
@@ -8,36 +8,366 @@
"category": "institutional-governance",
"license": "AGPL-3.0-or-later",
"required_modules": [
{"module_id": "access"},
{"module_id": "audit"},
{"module_id": "cases"},
{"module_id": "decisions"},
{"module_id": "forms"},
{"module_id": "forms_runtime"},
{"module_id": "mandates"},
{"module_id": "parties"},
{"module_id": "payments"},
{"module_id": "policy"},
{"module_id": "portal"},
{"module_id": "services"}
{"module_id": "services"},
{"module_id": "tasks"},
{"module_id": "workflow_engine"}
],
"required_capabilities": [
"access.configuration",
"cases.party_context",
"cases.service_intake",
"decisions.registry",
"forms.configuration",
"forms.definitions",
"mandates.resolver",
"parties.resolver",
"payments.requests",
"portal.service_directory",
"services.availability",
"services.definitions"
"services.definitions",
"workflow.configuration"
],
"optional_modules": [
{"module_id": "approvals"},
{"module_id": "committee"},
{"module_id": "files"},
{"module_id": "forms"},
{"module_id": "forms_runtime"},
{"module_id": "postbox"},
{"module_id": "records"},
{"module_id": "search"},
{"module_id": "tasks"},
{"module_id": "workflow_engine"}
{"module_id": "search"}
],
"data_requirements": [
{
"key": "responsible_group_slug",
"label": "Responsible permit group key",
"data_type": "string",
"required": true,
"secret": false,
"description": "Tenant-local stable key for the group that reviews resident parking permit applications."
},
{
"key": "responsible_group_name",
"label": "Responsible permit group name",
"data_type": "string",
"required": true,
"secret": false,
"description": "Human-readable tenant-local name shown for the responsible permit group."
}
],
"fragments": [
{
"module_id": "access",
"fragment_type": "roles",
"fragment_id": "resident-parking-permit-clerk",
"payload": {
"items": [
{
"slug": "resident-parking-permit-clerk",
"name": "Resident parking permit clerk",
"description": "Reviews resident parking permit submissions, workflow handoffs, cases, decisions, and payment evidence.",
"permissions": [
"cases:case:read",
"cases:case:create",
"cases:case:update",
"decisions:decision:read",
"decisions:decision:write",
"forms:definition:read",
"forms_runtime:workspace:read",
"forms_runtime:workspace:write",
"payments:payment:read",
"payments:payment:write",
"tasks:item:read",
"tasks:item:write",
"workflow:definition:read",
"workflow:instance:read",
"workflow:instance:start",
"workflow:instance:transition"
]
}
]
}
},
{
"module_id": "access",
"fragment_type": "groups",
"fragment_id": "resident-parking-permit-responsibility",
"payload": {
"items": [
{
"slug": {"$data": "responsible_group_slug"},
"name": {"$data": "responsible_group_name"},
"description": "Tenant-local responsibility group for the resident parking permit reference journey."
}
]
}
},
{
"module_id": "access",
"fragment_type": "group_role_assignments",
"fragment_id": "resident-parking-permit-clerk-assignment",
"payload": {
"items": [
{
"group": {"$data": "responsible_group_slug"},
"role": "resident-parking-permit-clerk"
}
]
}
},
{
"module_id": "forms",
"fragment_type": "definition",
"fragment_id": "resident-parking-permit-application",
"payload": {
"on_conflict": "new_revision",
"change_reason": "Install the reviewed resident parking permit reference form.",
"fragment": {
"kind": "govoplan.forms.definition",
"contract_version": "0.1.0",
"definition": {
"reference": {
"kind": "form",
"owner_module": "forms",
"object_id": "resident-parking-permit-application",
"tenant_id": "reference-package",
"version": "3",
"valid_at": null,
"label": null
},
"key": "resident-parking-permit-application",
"temporal": {
"revision": "3",
"valid_from": null,
"valid_to": null,
"recorded_at": "2026-08-22T00:00:00+00:00",
"superseded_at": null,
"change_reason": "Reference package revision."
},
"title": "Resident parking permit",
"description": "Apply for a resident parking permit through a digital or assisted channel.",
"fields": [
{
"key": "applicant_name",
"label": "Name",
"value_type": "text",
"required": true,
"help_text": null,
"options": [],
"constraints": {"min_length": 2, "max_length": 200},
"default_value": null
},
{
"key": "applicant_email",
"label": "Email",
"value_type": "text",
"required": true,
"help_text": null,
"options": [],
"constraints": {"format": "email"},
"default_value": null
},
{
"key": "residence_address",
"label": "Primary residence",
"value_type": "text",
"required": true,
"help_text": null,
"options": [],
"constraints": {"max_length": 500},
"default_value": null
},
{
"key": "licence_plate",
"label": "Licence plate",
"value_type": "text",
"required": true,
"help_text": null,
"options": [],
"constraints": {"max_length": 20},
"default_value": null
}
],
"publication_state": "published",
"allow_drafts": true,
"max_attachments": 4,
"signature_requirement": "none",
"policy_refs": [
"law:resident-parking-permit",
"records:resident-parking-permit"
],
"handoff_kinds": ["case", "workflow"],
"metadata": {},
"pages": [
{
"key": "application",
"title": "Application",
"description": null,
"sections": [
{
"key": "applicant-and-vehicle",
"title": "Applicant and vehicle",
"description": null,
"field_keys": [
"applicant_name",
"applicant_email",
"residence_address",
"licence_plate"
]
}
]
}
],
"localizations": [
{
"locale": "de",
"title": "Anwohnerparkausweis beantragen",
"description": "Einen Anwohnerparkausweis digital oder mit Unterstützung beantragen.",
"field_labels": {
"applicant_name": "Name",
"applicant_email": "E-Mail-Adresse",
"residence_address": "Hauptwohnsitz",
"licence_plate": "Kennzeichen"
},
"field_help_texts": {},
"option_labels": {},
"page_titles": {"application": "Antrag"},
"section_titles": {
"applicant-and-vehicle": "Antragstellende Person und Fahrzeug"
}
}
],
"fallback_locale": "de"
},
"definition_sha256": "7dc108002d532c07e5e7f3b14029a9d4deb3836ebb65d97fb6b51166a70e0ed4",
"provenance": {
"owner_module": "forms",
"tenant_id": "reference-package",
"form_id": "resident-parking-permit-application",
"revision": "3",
"exported_at": "2026-08-22T12:00:00+00:00",
"exported_by": "GovOPlaN reference package"
}
}
}
},
{
"module_id": "workflow_engine",
"fragment_type": "workflow_definitions",
"fragment_id": "resident-parking-permit-workflow",
"payload": {
"schema_version": 1,
"origin_module_id": "configuration_package.service_to_decision",
"origin_module_version": "0.1.0",
"items": [
{
"definition_key": "resident-parking-permit-review",
"name": "Resident parking permit review",
"description": "Review evidence, record the formal decision, and verify payment evidence for the resident parking permit reference journey.",
"scope_type": "tenant",
"allow_start": true,
"allow_reuse": true,
"allow_automation": false,
"execution_mode": "guided",
"activate_on_install": true,
"graph": {
"schema_version": 1,
"nodes": [
{
"id": "start",
"type": "workflow.start.manual",
"label": "Application received",
"config": {"input_schema_ref": "form:resident-parking-permit-application"}
},
{
"id": "review-evidence",
"type": "workflow.review",
"label": "Review application evidence",
"config": {
"title": "Review resident parking permit evidence",
"reviewer": {
"kind": "group",
"id": {"$data": "responsible_group_slug"},
"label": {"$data": "responsible_group_name"}
},
"due_after": "P14D",
"required_evidence": [
"identity",
"primary_residence",
"vehicle_registration"
],
"view_surface_ids": []
}
},
{
"id": "record-decision",
"type": "workflow.activity",
"label": "Record formal decision",
"config": {
"title": "Record the resident parking permit decision",
"instructions": "Record the operative result, reasoning, legal basis, remedy, and exact evidence references through the Decisions capability.",
"assignee": {
"kind": "group",
"id": {"$data": "responsible_group_slug"},
"label": {"$data": "responsible_group_name"}
},
"due_after": "P7D",
"view_surface_ids": []
}
},
{
"id": "verify-payment",
"type": "workflow.activity",
"label": "Verify payment evidence",
"config": {
"title": "Verify the resident parking permit fee",
"instructions": "Verify the EUR 30.00 obligation, immutable receipt evidence, currency, amount, and transaction reference before completion.",
"assignee": {
"kind": "group",
"id": {"$data": "responsible_group_slug"},
"label": {"$data": "responsible_group_name"}
},
"due_after": "P14D",
"view_surface_ids": []
}
},
{
"id": "completed",
"type": "workflow.end.completed",
"label": "Permit journey complete",
"config": {"output_mapping": {}}
}
],
"edges": [
{"id": "start-review", "source": "start", "target": "review-evidence"},
{"id": "review-decision", "source": "review-evidence", "source_port": "approved", "target": "record-decision"},
{"id": "decision-payment", "source": "record-decision", "target": "verify-payment"},
{"id": "payment-completed", "source": "verify-payment", "target": "completed"}
],
"metadata": {
"reference_journey": "resident-parking-permit",
"locale": "de-DE",
"payment_amount_minor": 3000,
"payment_currency": "EUR"
}
},
"metadata": {
"reference_package": "product.service-to-decision",
"form_id": "resident-parking-permit-application"
}
}
]
}
}
],
"evidence": [
{
+7 -7
View File
@@ -5,14 +5,14 @@ govoplan-tenancy @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-tenancy.git@
govoplan-organizations @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-organizations.git@v0.1.18
govoplan-identity @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-identity.git@v0.1.18
govoplan-idm @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-idm.git@v0.1.20
govoplan-access @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-access.git@v0.1.19
govoplan-admin @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-admin.git@v0.1.18
govoplan-access @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-access.git@v0.1.20
govoplan-admin @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-admin.git@v0.1.19
govoplan-policy @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-policy.git@v0.1.20
govoplan-audit @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-audit.git@v0.1.18
govoplan-audit @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-audit.git@v0.1.19
govoplan-dashboard @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-dashboard.git@v0.1.18
govoplan-files @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-files.git@v0.1.20
govoplan-mail @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-mail.git@v0.1.18
govoplan-campaign @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-campaign.git@v0.1.23
govoplan-mail @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-mail.git@v0.1.22
govoplan-campaign @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-campaign.git@v0.1.24
govoplan-calendar @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-calendar.git@v0.1.18
govoplan-docs @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-docs.git@v0.1.18
govoplan-ops @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-ops.git@v0.1.18
govoplan-docs @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-docs.git@v0.1.21
govoplan-ops @ git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-ops.git@v0.1.19
+167 -1
View File
@@ -5,9 +5,17 @@ import json
from pathlib import Path
import unittest
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
from govoplan_core.core.configuration_packages import (
ConfigurationApplyResult,
ConfigurationExportResult,
ConfigurationPackageManifest,
ConfigurationPlanItem,
ConfigurationPreflightContext,
ConfigurationPreflightResult,
ConfigurationProviderDescription,
configuration_package_claim_issues,
dry_run_configuration_package,
)
@@ -54,10 +62,19 @@ class ConfigurationPackageArtifactTests(unittest.TestCase):
f"Missing repository for {requirement.module_id}",
)
provider_module_ids = tuple(
sorted({fragment.module_id for fragment in manifest.fragments})
)
providers = tuple(_ArtifactProvider(module_id) for module_id in provider_module_ids)
supplied_data = {
str(item["key"]): _sample_value(item)
for item in manifest.data_requirements
}
result = dry_run_configuration_package(
manifest,
(),
providers,
ConfigurationPreflightContext(
supplied_data=supplied_data,
installed_modules={
item.module_id: item.version or "workspace"
for item in manifest.required_modules
@@ -74,6 +91,155 @@ class ConfigurationPackageArtifactTests(unittest.TestCase):
self.assertIn("product.governed-data-assurance", package_ids)
self.assertIn("product.service-to-decision", package_ids)
def test_service_to_decision_package_imports_its_form_as_an_idempotent_local_draft(self) -> None:
from govoplan_forms.backend.configuration_provider import (
_apply_definition,
_preflight_definition,
)
from govoplan_forms.backend.db.models import FormDefinitionRevision
from govoplan_forms.backend.service import get_form_definition
package = ConfigurationPackageManifest.from_mapping(json.loads(
(PACKAGE_ROOT / "product/service-to-decision/package.json").read_text(
encoding="utf-8"
)
))
fragment = next(
item
for item in package.fragments
if item.module_id == "forms" and item.fragment_type == "definition"
)
context = ConfigurationPreflightContext(
tenant_id="tenant-reference-test",
operator_user_id="operator-1",
operator_scopes=frozenset({"system:governance:write"}),
)
engine = create_engine("sqlite+pysqlite:///:memory:")
FormDefinitionRevision.__table__.create(engine)
session = Session(engine)
try:
preflight = _preflight_definition(session, fragment, context)
applied = _apply_definition(session, fragment, context)
session.commit()
replay = _apply_definition(session, fragment, context)
imported = get_form_definition(
session,
type("Principal", (), {"tenant_id": "tenant-reference-test"})(),
form_id="resident-parking-permit-application",
)
finally:
session.close()
engine.dispose()
self.assertFalse(any(item.severity == "blocker" for item in preflight.diagnostics))
self.assertEqual("create", preflight.plan[0].action)
self.assertEqual(1, len(applied.created_refs))
self.assertEqual({}, replay.created_refs)
self.assertIsNotNone(imported)
assert imported is not None
self.assertEqual("tenant-reference-test", imported.reference.tenant_id)
self.assertEqual("draft", imported.publication_state)
self.assertEqual("de", imported.fallback_locale)
def test_service_to_decision_package_materializes_its_tenant_workflow_idempotently(self) -> None:
from govoplan_core.core.configuration_packages import _resolve_fragment_data_references
from govoplan_workflow_engine.backend.configuration_provider import (
apply_workflow_definitions,
preflight_workflow_definitions,
)
from govoplan_workflow_engine.backend.db.models import (
WorkflowDefinition,
WorkflowDefinitionRevision,
)
package = ConfigurationPackageManifest.from_mapping(json.loads(
(PACKAGE_ROOT / "product/service-to-decision/package.json").read_text(
encoding="utf-8"
)
))
fragment = next(
item
for item in package.fragments
if item.module_id == "workflow_engine"
)
context = ConfigurationPreflightContext(
tenant_id="tenant-reference-test",
supplied_data={
"responsible_group_slug": "traffic-permits",
"responsible_group_name": "Traffic permits",
},
)
resolved = _resolve_fragment_data_references(
fragment,
context.supplied_data,
)
engine = create_engine("sqlite+pysqlite:///:memory:")
WorkflowDefinition.__table__.create(engine)
WorkflowDefinitionRevision.__table__.create(engine)
session = Session(engine)
try:
preflight = preflight_workflow_definitions(session, resolved, context)
applied = apply_workflow_definitions(
session,
resolved,
context,
registry=None,
)
replay = apply_workflow_definitions(
session,
resolved,
context,
registry=None,
)
session.commit()
finally:
session.close()
engine.dispose()
self.assertFalse(any(item.severity == "blocker" for item in preflight.diagnostics))
self.assertEqual("create", preflight.plan[0].action)
self.assertIn("resident-parking-permit-review", applied.created_refs)
self.assertEqual({}, replay.created_refs)
self.assertEqual({}, replay.updated_refs)
class _ArtifactProvider:
def __init__(self, module_id: str) -> None:
self.module_id = module_id
def describe(self) -> ConfigurationProviderDescription:
return ConfigurationProviderDescription(module_id=self.module_id)
def preflight(self, fragment, context) -> ConfigurationPreflightResult:
del context
return ConfigurationPreflightResult(plan=(ConfigurationPlanItem(
action="create",
module_id=fragment.module_id,
fragment_type=fragment.fragment_type,
fragment_id=fragment.fragment_id,
),))
def apply(self, fragment, supplied_data, context) -> ConfigurationApplyResult:
del fragment, supplied_data, context
return ConfigurationApplyResult()
def export(self, selection, context) -> ConfigurationExportResult:
del selection, context
return ConfigurationExportResult()
def health(self, import_result, context):
del import_result, context
return ()
def _sample_value(requirement: dict[str, object]) -> object:
data_type = str(requirement.get("data_type") or requirement.get("type") or "string")
if data_type == "boolean":
return False
if data_type in {"integer", "number"}:
return 1
return f"fixture-{requirement['key']}"
if __name__ == "__main__":
unittest.main()
+1 -1
View File
@@ -70,7 +70,7 @@ class PackageRegistryReleaseTests(unittest.TestCase):
by_name = {item["name"]: item for item in selected}
self.assertIn("govoplan-core", by_name)
self.assertIn("govoplan-records", by_name)
self.assertEqual("0.1.19", by_name["govoplan-tasks"]["version"])
self.assertEqual("0.1.20", by_name["govoplan-tasks"]["version"])
payload = PACKAGE_SET.generate_package_set(
core_version=core_version,
+4
View File
@@ -115,6 +115,7 @@ PY
"$PYTHON" -m unittest discover -s /mnt/DATA/git/govoplan-approvals/tests
"$PYTHON" -m unittest discover -s /mnt/DATA/git/govoplan-identity-trust/tests
"$PYTHON" -m unittest discover -s /mnt/DATA/git/govoplan-encryption/tests
"$PYTHON" -m pytest -q /mnt/DATA/git/govoplan-wiki/tests
"$PYTHON" -m pytest -q /mnt/DATA/git/govoplan-campaign/tests/test_approval_gate.py
"$PYTHON" "$META_ROOT/tools/checks/check-datasource-composition.py"
"$PYTHON" "$META_ROOT/tools/checks/check-sanctions-screening-composition.py"
@@ -160,3 +161,6 @@ cd /mnt/DATA/git/govoplan-campaign/webui
"$NPM" run test:accessibility-contract
"$NPM" run test:campaign-collaboration
"$NPM" run test:campaign-work
cd /mnt/DATA/git/govoplan-wiki/webui
"$NPM" run test:interface-pattern
@@ -7,7 +7,6 @@
"evaluation": "Contract-only module: evaluation runs, responses, and scores are not persisted; reassess before adding a migration-owned store.",
"facilities": "Contract-only module: facility and maintenance persistence are not implemented; reassess before adding a migration-owned store.",
"grants": "Contract-only module: grant applications, awards, and monitoring are not persisted; reassess before adding a migration-owned store.",
"helpdesk": "Contract-only module: helpdesk requests, queues, and resolutions are not persisted; reassess before adding a migration-owned store.",
"inspections": "Contract-only module: inspections, findings, and measures are not persisted; reassess before adding a migration-owned store.",
"learning": "Contract-only module: learning offers, enrollment, and completion are not persisted; reassess before adding a migration-owned store.",
"ops": "Projection-only module: Ops reads bounded platform and provider status; durable recovery evidence remains owned by Core and domain modules.",
@@ -18,8 +17,6 @@
"rest": "Transport-only module: REST binds explicitly published functions and owns no domain or subject-data store.",
"soap": "Transport-only module: SOAP binds explicitly published operations and owns no domain or subject-data store.",
"tenancy": "Orchestration module: tenant lifecycle and settings use Core-owned storage; Access covers account and membership subject data.",
"tickets": "Contract-only module: ticket, queue, SLA, and adapter persistence are not implemented; reassess before adding a migration-owned store.",
"transparency": "Contract-only module: requests, disclosure reviews, and publications are not persisted; reassess before adding a migration-owned store.",
"wiki": "Contract-only module: wiki spaces, pages, and revisions are not persisted; reassess before adding a migration-owned store.",
"workflow": "Presentation-only module: Workflow edits and projects Workflow Engine state; Workflow Engine owns persistence and DSAR coverage."
}
@@ -539,6 +539,125 @@
"rationale": "The Connector governance administration page constructs this review-decision URL from the selected run identifier.",
"repository": "govoplan-connectors"
},
{
"category": "ui_reachable",
"method": "GET",
"path": "/connectors/knowledge/profiles",
"rationale": "The External knowledge administration page lists MediaWiki and BlueSpice profiles through this endpoint.",
"repository": "govoplan-connectors"
},
{
"category": "ui_reachable",
"method": "POST",
"path": "/connectors/knowledge/profiles",
"rationale": "The External knowledge administration page creates a mapped, ACL-governed knowledge profile through this endpoint.",
"repository": "govoplan-connectors"
},
{
"category": "ui_reachable",
"method": "PUT",
"path": "/connectors/knowledge/profiles/{}",
"rationale": "The External knowledge administration page constructs this revision-guarded profile URL from the selected profile identifier.",
"repository": "govoplan-connectors"
},
{
"category": "ui_reachable",
"method": "POST",
"path": "/connectors/knowledge/profiles/{}/discover",
"rationale": "The External knowledge administration page discovers product, version, capabilities, namespaces, and diagnostics through this endpoint.",
"repository": "govoplan-connectors"
},
{
"category": "ui_reachable",
"method": "POST",
"path": "/connectors/knowledge/profiles/{}/migration-dry-runs",
"rationale": "The External knowledge administration page runs a bounded, non-writing native-Wiki migration preview through this endpoint.",
"repository": "govoplan-connectors"
},
{
"category": "ui_reachable",
"method": "GET",
"path": "/connectors/knowledge/profiles/{}/objects",
"rationale": "The External knowledge administration page lists synchronized, identity-stable knowledge snapshots through this endpoint.",
"repository": "govoplan-connectors"
},
{
"category": "ui_reachable",
"method": "POST",
"path": "/connectors/knowledge/profiles/{}/pages/{}/publish",
"rationale": "The External knowledge administration page constructs this revision-checked external publication URL from the selected profile and page identifiers.",
"repository": "govoplan-connectors"
},
{
"category": "ui_reachable",
"method": "POST",
"path": "/connectors/knowledge/profiles/{}/sync",
"rationale": "The External knowledge administration page runs keyed full backfills and recent-change deltas through this endpoint.",
"repository": "govoplan-connectors"
},
{
"category": "ui_reachable",
"method": "GET",
"path": "/connectors/knowledge/runs",
"rationale": "The External knowledge administration page lists synchronization, migration-preview, and publication evidence through this endpoint.",
"repository": "govoplan-connectors"
},
{
"category": "ui_reachable",
"method": "GET",
"path": "/connectors/service-desk/profiles",
"rationale": "The External service desk administration page lists Znuny/OTRS profiles through this endpoint.",
"repository": "govoplan-connectors"
},
{
"category": "ui_reachable",
"method": "POST",
"path": "/connectors/service-desk/profiles",
"rationale": "The External service desk administration page creates route-, queue-, field-, authority-, and ACL-governed profiles through this endpoint.",
"repository": "govoplan-connectors"
},
{
"category": "ui_reachable",
"method": "PUT",
"path": "/connectors/service-desk/profiles/{}",
"rationale": "The External service desk administration page constructs this revision-guarded profile URL from the selected profile identifier.",
"repository": "govoplan-connectors"
},
{
"category": "ui_reachable",
"method": "POST",
"path": "/connectors/service-desk/profiles/{}/discover",
"rationale": "The External service desk administration page discovers product, version, maturity, capabilities, route health, and diagnostics through this endpoint.",
"repository": "govoplan-connectors"
},
{
"category": "ui_reachable",
"method": "GET",
"path": "/connectors/service-desk/profiles/{}/objects",
"rationale": "The External service desk administration page lists synchronized identity-stable, ACL-governed external ticket projections through this endpoint.",
"repository": "govoplan-connectors"
},
{
"category": "ui_reachable",
"method": "POST",
"path": "/connectors/service-desk/profiles/{}/sync",
"rationale": "The External service desk administration page runs keyed bounded full and delta synchronization through this endpoint.",
"repository": "govoplan-connectors"
},
{
"category": "ui_reachable",
"method": "POST",
"path": "/connectors/service-desk/profiles/{}/tickets/{}/update",
"rationale": "The External service desk ticket list opens a separated revision-checked governed update dialog and constructs this URL from stable profile and provider ticket identifiers.",
"repository": "govoplan-connectors"
},
{
"category": "ui_reachable",
"method": "GET",
"path": "/connectors/service-desk/runs",
"rationale": "The External service desk administration page lists synchronization and external-mutation recovery evidence through this endpoint.",
"repository": "govoplan-connectors"
},
{
"category": "intentionally_headless",
"method": "GET",