feat(cases): enforce purpose-bound case governance
Module Package Release / publish-packages (push) Successful in 12s

This commit is contained in:
2026-08-24 20:05:31 +02:00
parent 9435116299
commit 17415d8831
28 changed files with 786 additions and 142 deletions
+39 -14
View File
@@ -88,19 +88,21 @@ The persistent backend provides:
- replay-safe case timeline events carrying the institutional context and a
stable event/audit reference
- tenant-level resource ACL and tenant summary providers
- tenant-wide or restricted object access with explicit, revisioned grants
- tenant-wide or restricted object access with purpose-bound, revisioned grant snapshots
- deterministic, replay-safe case launch from an exact Service binding
- deterministic, replay-safe Case escalation from an authorized Ticket handoff
The `/cases` list and `/cases/:caseId` detail workspace provide server-side
search/status filtering, case facts, typed references, history, timeline, and
OCC-guarded title/status/access revisions with an explicit change reason.
Restricted cases are visible to their creator, case administrators, explicit
user/group grants, and matching function, function-assignment, or
organization-unit assignments. The same decision filters list, detail,
history, timeline, and update operations so an inaccessible identifier does
not disclose case existence. API reads and writes are tenant-bound, and
create/update/assign/close/share/catalog operations have separate permissions.
Restricted cases require a current custodian, explicit subject, or matching
function, function-assignment, or organization-unit grant. The grant must imply
the requested permission and contain the exact declared purpose. The same
decision filters list, detail, history, timeline, update, evidence, Decision,
Search, and Records-source operations so an inaccessible identifier does not
disclose case existence. Current grants govern historical revisions. API reads
and writes are tenant-bound, and create/update/assign/close/share/catalog
operations have separate permissions.
## Permissions
@@ -114,9 +116,14 @@ Implemented scopes:
- `cases:case:share`
- `cases:case:admin`
Access decisions combine tenant permissions, creator/administrative authority,
case assignments, and explicit case shares. Restricted access is versioned
with the case record so its history remains reconstructable.
Access decisions combine tenant permissions with current purpose-bound
custodian, assignment-derived, and explicit subject grants. Creating or newly
restricting a case establishes a custodian grant for the attributable actor.
`cases.casework` is the stable interactive default; Search rechecks use only
`cases.search`; Records filing supplies its declared purpose. Assignment-derived
grants admit `cases.casework`, `cases.search`, and `cases.records`. Each accepted
timeline event stores the evaluated purpose. Restricted access snapshots remain
versioned with the case record while current grant state governs disclosure.
## Data Model Sketch
@@ -187,7 +194,7 @@ metadata snapshots. The owning module remains responsible for the real object.
When Records is enabled, `records.source.cases` resolves one exact immutable
case revision for eAkte filing. Cases rechecks current tenant, scope, and
object-level access, then returns the case number, lifecycle state, represented
object-level access for the caller-declared purpose, then returns the case number, lifecycle state, represented
valid interval, recorded time, canonical snapshot digest, and launch link.
Records owns the filing decision and chronology; Cases remains authoritative
for the case and its revision history.
@@ -196,7 +203,25 @@ When Search is enabled, `cases.cases` indexes current Case titles, numbers,
types, states, and the existing bounded search projection. It includes no
provider-owned evidence content or protected Decision reasoning. Restricted
Case candidates carry bounded ACL tokens and every result is checked again
against the current Case object-access decision before disclosure.
against the current Case object-access decision using the fixed `cases.search`
purpose before disclosure. Search links preserve that purpose in the Case URL.
## Information governance adoption
Cases enforces temporal browsing for immutable case revisions while always
using current authorization for historical reads. It enforces exact-purpose
access for restricted cases and records the evaluated purpose in lifecycle
evidence. Governed context validates and persists tenant, service, party,
organization, function, acting assignment/delegation, mandate, jurisdiction,
legal-basis, evidence, Decision, and record references at their owning
boundaries.
Retention remains contract-only. Cases preserves immutable revisions and
timeline evidence and publishes DSAR retention/manual-review consequences, but
does not yet apply configurable schedules, legal holds, appraisal, or
disposition gates. Those controls must be implemented through the Records
boundary or a future explicit Cases retention policy before retention can be
claimed as enforced.
## WebUI
@@ -230,8 +255,8 @@ The focused suite covers:
## Data-subject requests
Cases publishes `privacy.dsar.cases`. Canonical account, identity, and
membership selectors cover Cases-owned operator attribution; account and
identity selectors also cover explicit case-access grants. Exact
membership selectors cover Cases-owned operator attribution and matching
account, identity, or membership access grants. Exact
`cases.case`, `cases.revision`, `cases.access_grant`, and `cases.timeline`
references select lifecycle data. When a canonical and direct selector are
combined, a Cases-owned relationship must corroborate them and all supplied