From 9ef79928b33d7d77421bd69a54b35fe16375a6d8 Mon Sep 17 00:00:00 2001 From: Albrecht Degering Date: Wed, 5 Aug 2026 19:52:13 +0200 Subject: [PATCH] Release v0.1.16 --- docs/EAKTE_ARCHITECTURE.md | 191 +++++++++++++++++++++++ docs/RECORDS_DOMAIN_BOUNDARY.md | 4 + package.json | 2 +- pyproject.toml | 6 +- src/govoplan_records/backend/manifest.py | 43 ++++- 5 files changed, 237 insertions(+), 9 deletions(-) create mode 100644 docs/EAKTE_ARCHITECTURE.md diff --git a/docs/EAKTE_ARCHITECTURE.md b/docs/EAKTE_ARCHITECTURE.md new file mode 100644 index 0000000..6501ff3 --- /dev/null +++ b/docs/EAKTE_ARCHITECTURE.md @@ -0,0 +1,191 @@ +# eAkte Architecture + +## Purpose + +The eAkte is the authoritative institutional record context for a matter, +procedure, subject, project, or responsibility. It answers what belongs to the +record, how it is structured, why an item was filed, which version was known, +who may use it for which purpose, when it closes, what must be retained, and +how it is offered, transferred, preserved, or disposed. + +GovOPlaN Records should provide this governance lifecycle natively while being +able to place it over an external DMS, records system, long-term archive, or +specialist procedure. It must not duplicate all document editing or storage. + +Implementation is tracked in +[Records #1](https://git.add-ideas.de/GovOPlaN/govoplan-records/issues/1). + +## Ownership Boundary + +Records owns: + +- file plans and record classes; +- record, volume, process/file, and record-item identity; +- classification, filing decision, ordering, and relationship to a case or + other institutional context; +- effective retention rule application, closure, hold, appraisal, + disposition proposal, approval, transfer, and destruction evidence; +- authoritative record metadata and exact content/reference manifests; +- external records-system mappings and source-authority mode; +- export, transfer, archive-offer, and custody receipts. + +Records does not own: + +- file bytes, versions, previews, or malware handling (Files); +- collaborative document editing, check-in/check-out, document review, or DMS + provider behavior (DMS and connector owner); +- generated document definitions (Templates); +- case lifecycle (Cases), work coordination (Workflow Engine/Tasks), formal + outcomes (Decisions), or general audit events (Audit); +- generic retention and access policy authoring (Policy); +- archive preservation implementation or evidence-renewal cryptography + (external archive/TR-ESOR provider and Encryption/Identity Trust). + +## Core Object Model + +| Object | Meaning | +| --- | --- | +| File plan | Versioned hierarchy derived from institutional responsibilities | +| Record class | Rules for required metadata, allowed content, access, retention, closure, and disposition | +| Record | Stable legal/institutional record identity and context | +| Volume/part | Bounded subdivision for size, period, classification, or custody | +| Process/file | Optional business transaction grouping inside a record | +| Record item | Immutable filing event linking exact content or an external object revision | +| Filing note | Reason, source, relationship, ordering, actor/capacity, and evidence for inclusion | +| Hold | Effective-dated suspension of disposition with authority and scope | +| Appraisal | Archive value/offer decision and responsible archive interaction | +| Disposition case | Proposed retain, transfer, destroy, or reclassify action with review and evidence | +| Transfer package | Exact metadata/content manifest, profile, digest, encryption, and receipts | +| Custody event | Handoff, acceptance, rejection, correction, return, or destruction observation | + +Every object carries tenant/institution, valid and recorded time, revision, +source authority, classification, purpose constraints, retention/hold state, +institutional context, provenance, and optimistic-concurrency token. + +## Record Lifecycle + +```text +planned -> open -> closed -> retention_running -> appraisal_due + | | + v v + held offered_to_archive + | + +-----------------------------+------------------+ + v v v + accepted rejected retained + | | | + v v v + transferred disposal_due reappraise + | + v + destroyed +``` + +Reopening creates a governed transition and does not reset elapsed retention +without an explicit rule. A hold preserves the reason and affected scope. A +destruction action requires exact manifest, current authority, policy, +approval, preflight, idempotency, outcome-unknown recovery, and evidence. + +## Filing Semantics + +- Filing links an exact immutable document/file/object revision; a later source + revision is a new record item unless the record class permits an explicitly + tracked living reference. +- The item records valid time of the represented fact and recorded time of + filing independently. +- The current security context always controls browsing, including historical + views. +- Purpose-aware access may be narrower than ordinary read permission and can + require case assignment, represented function, mandate, legal basis, or + reason-for-access capture. +- A record item can reference a message, decision, form submission, report, + dataset materialization, external DMS object, physical item, or paper scan; + it is not limited to Files. +- Corrections and replacements link items and retain what was previously part + of the record. + +## Native, External, And Hybrid Operation + +| Mode | GovOPlaN behavior | +| --- | --- | +| Native authoritative | Records owns lifecycle and manifests; Files or object storage owns bytes | +| External authoritative | External eAkte/DMS owns structure and lifecycle; GovOPlaN keeps governed references and provider state | +| External mirror | GovOPlaN keeps a read/search projection and immutable evidence snapshots | +| Governed sync | Explicit metadata/filing fields can change on both sides with revision and conflict rules | +| Governance overlay | GovOPlaN owns case/workflow/policy/evidence around records held externally | +| Linked reference | Only stable identity, display metadata, authority, and launch link are retained | + +The mode is configurable by tenant, record class, provider binding, and where +safe by field group. A migration assesses exact objects and receipts; enabling +a connector never silently copies all records. + +## Standards And Provider Profiles + +The domain contract remains neutral, while German public-sector deployments +can add profiles for: + +- `xdomea` exchange of files, processes, documents, file plans, and + disposition messages. The IT-Planungsrat decision defines xdomea for + inter-authority exchange and disposition scenarios: + +- archive offering and transfer guidance from the Bundesarchiv, including + xdomea and XAIP/LXAIP packages: + +- BSI TR-03125/TR-ESOR evidence preservation and archive information packages + where cryptographic evidentiary value must be maintained: + +- provider-specific DMS/VBS, archive, and specialist-procedure adapters through + the standard external-provider declaration and recovery gate. + +A profile declares supported operations, conformance version, metadata +mapping, content formats, evidence behavior, size limits, retries, conflicts, +and target-tested provider. Naming a standard is not a conformance claim. + +## UI Model + +The normal record workspace contains: + +- file-plan tree and saved institutional contexts; +- record list with class, subject, responsibility, state, retention, holds, + source, and access explanation; +- one record surface with metadata, chronology, structured contents, related + case/service/decision/work, access reason, and evidence; +- filing action available from owner modules without exposing Records internals; +- close, reopen, hold, appraisal, transfer, and disposition workflows with + consequence preview; +- temporal current/at/all browsing, while clearly separating valid and recorded + time; +- search and export that honor current access, purpose, sealed content, and + minimization. + +Technical provider IDs, hashes, package schemas, and source mappings remain +available in an evidence/details view. + +## Recovery And Scale + +- PostgreSQL is the durable record-state authority; content uses shared object + storage or an external provider, never node-local paths. +- Every external filing, transfer, or destruction uses intent-before-effect, + idempotency, durable receipts, outcome-unknown state, and reconciliation. +- Backup evidence binds record rows, object manifests, provider mappings, + policy/configuration versions, and key references. +- Restore verifies content digests, missing keys/objects, provider reachability, + and disposition holds before reopening effects. +- Search indexes are rebuildable projections and cannot become record + authority. + +## Delivery Order + +1. Persist file plans, record classes, records, record items, exact references, + chronology, permissions, temporal reads, institutional context, and search. +2. Integrate filing from Cases, Forms Runtime, Decisions, Campaign/Postbox, + Files, and Reporting. +3. Add closure, retention calculation, holds, appraisal, and reviewed + disposition without destructive provider effects. +4. Add native transfer packages and one target-tested xdomea/archive provider. +5. Add destruction/recovery, TR-ESOR provider integration, migration, and + signed reference-journey evidence. + +The first reference package should file the digital and assisted variants of +the same service-to-decision journey into equivalent records and prove search, +historical reconstruction, hold, transfer, restore, and access explanation. diff --git a/docs/RECORDS_DOMAIN_BOUNDARY.md b/docs/RECORDS_DOMAIN_BOUNDARY.md index bac110e..70b1475 100644 --- a/docs/RECORDS_DOMAIN_BOUNDARY.md +++ b/docs/RECORDS_DOMAIN_BOUNDARY.md @@ -44,3 +44,7 @@ No runtime API, database model, migration, WebUI route, or navigation item is re ## First Implementation Slice Define record class, file plan node, retention schedule, disposal hold, archive transfer, and source document links. + +The complete native/external boundary, temporal and purpose-aware record model, +disposition lifecycle, German public-sector provider profiles, and staged +implementation are specified in [eAkte Architecture](EAKTE_ARCHITECTURE.md). diff --git a/package.json b/package.json index cca0307..31485aa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@govoplan/records", - "version": "0.1.15", + "version": "0.1.16", "private": true, "description": "GovOPlaN Records platform module seed.", "type": "module", diff --git a/pyproject.toml b/pyproject.toml index aaf08b5..3a90198 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,15 +4,15 @@ build-backend = "setuptools.build_meta" [project] name = "govoplan-records" -version = "0.1.15" +version = "0.1.16" description = "GovOPlaN Records platform module seed." readme = "README.md" requires-python = ">=3.12" license = { file = "LICENSE" } authors = [{ name = "GovOPlaN" }] dependencies = [ - "govoplan-core>=0.1.15", - "govoplan-access>=0.1.15", + "govoplan-core>=0.1.16", + "govoplan-access>=0.1.16", ] [tool.setuptools.packages.find] diff --git a/src/govoplan_records/backend/manifest.py b/src/govoplan_records/backend/manifest.py index 2216f2d..ed55e2c 100644 --- a/src/govoplan_records/backend/manifest.py +++ b/src/govoplan_records/backend/manifest.py @@ -6,7 +6,7 @@ from govoplan_core.core.provider_governance import declared_module_architecture MODULE_ID = "records" MODULE_NAME = "Records" -MODULE_VERSION = "0.1.15" +MODULE_VERSION = "0.1.16" READ_SCOPE = "records:workspace:read" WRITE_SCOPE = "records:workspace:write" ADMIN_SCOPE = "records:workspace:admin" @@ -35,8 +35,8 @@ def _permission(scope: str, label: str, description: str) -> PermissionDefinitio PERMISSIONS = ( - _permission(READ_SCOPE, "View records workspace", "Read records records, configuration, and workflow context."), - _permission(WRITE_SCOPE, "Manage records workspace", "Create and update records records and workflow state."), + _permission(READ_SCOPE, "View records workspace", "Read records, configuration, and workflow context."), + _permission(WRITE_SCOPE, "Manage records workspace", "Create and update records and workflow state."), _permission(ADMIN_SCOPE, "Administer records workspace", "Configure records policies, templates, and tenant-level administration."), ) @@ -44,13 +44,13 @@ ROLE_TEMPLATES = ( RoleTemplate( slug="records_manager", name="Records manager", - description="Manage records records and workflow state.", + description="Manage records and workflow state.", permissions=(READ_SCOPE, WRITE_SCOPE), ), RoleTemplate( slug="records_viewer", name="Records viewer", - description="Read records records and workflow context.", + description="Read records and workflow context.", permissions=(READ_SCOPE,), ), ) @@ -76,6 +76,11 @@ DOCUMENTATION = ( href="govoplan-records/docs/RECORDS_DOMAIN_BOUNDARY.md", kind="repository", ), + DocumentationLink( + label="eAkte architecture", + href="govoplan-records/docs/EAKTE_ARCHITECTURE.md", + kind="repository", + ), ), metadata={ "seed": True, @@ -83,6 +88,34 @@ DOCUMENTATION = ( "first_slice": "Define record class, file plan node, retention schedule, disposal hold, archive transfer, and source document links.", }, ), + DocumentationTopic( + id=f"{MODULE_ID}.eakte-architecture", + title="eAkte and digital record lifecycle", + summary="Defines native and external record operation, filing, temporal and purpose-aware access, retention, holds, appraisal, transfer, and disposition.", + body=( + "Records owns the legal and institutional record identity, file plan, filing decisions, " + "retention and disposition lifecycle, and transfer evidence. Files owns bytes, DMS owns " + "document editing, Policy owns reusable rules, and external archives remain supported " + "through explicit source-authority and provider profiles." + ), + layer="available", + documentation_types=("admin", "user"), + audience=("user", "records_manager", "operator", "module_admin", "product_owner"), + order=110, + related_modules=OPTIONAL_DEPENDENCIES, + links=( + DocumentationLink( + label="eAkte architecture", + href="govoplan-records/docs/EAKTE_ARCHITECTURE.md", + kind="repository", + ), + ), + metadata={ + "kind": "concept", + "help_contexts": ["records.page", "records.record", "records.disposition"], + "known_limit": "The architecture is accepted, but persistence and user-visible record workflows remain a scaffold.", + }, + ), ) manifest = ModuleManifest(