Sync wiki from project files

2026-07-28 15:08:46 +02:00
parent 29781c58f0
commit ab0fad0734
3 changed files with 169 additions and 5 deletions

@@ -5,3 +5,4 @@
This page is generated from repository and product-directory project files.
- [Repo-README](Repo-README) - `/mnt/DATA/git/govoplan-policy/README.md`
- [Repo-docs-POLICY-DECISION-PROVENANCE](Repo-docs-POLICY-DECISION-PROVENANCE) - `/mnt/DATA/git/govoplan-policy/docs/POLICY_DECISION_PROVENANCE.md`

@@ -1,4 +1,4 @@
<!-- codex-wiki-sync:fd1768b3785b7658ad6d5c1b -->
<!-- codex-wiki-sync:d526042f0aa1d10a5a4a13aa -->
> Mirrored from `/mnt/DATA/git/govoplan-policy/README.md`.
> Origin: `repository`.
@@ -7,8 +7,39 @@
---
# GovOPlaN Policy
`govoplan-policy` owns policy and retention API route contributions during the
GovOPlaN module split.
<!-- govoplan-repository-type:start -->
**Repository type:** module (platform).
<!-- govoplan-repository-type:end -->
The current package delegates to the legacy access administration
implementation while route ownership is separated before model migration.
`govoplan-policy` owns policy and retention API route contributions and the
retention administration WebUI sections during the GovOPlaN module split.
The `@govoplan/policy-webui` package contributes system, tenant, group, and
user retention sections through the shared `admin.sections` UI capability. The
admin shell does not render retention policy panels unless this module is
installed and enabled.
Policy decision and provenance payloads use the shared kernel DTOs documented
in [docs/POLICY_DECISION_PROVENANCE.md](docs/POLICY_DECISION_PROVENANCE.md)
and `/mnt/DATA/git/govoplan-core/docs/POLICY_CONTRACTS.md`.
Hierarchical policy evaluation, delegation ceilings, and write simulations are
implemented in `govoplan_policy.backend.hierarchy`. Privacy retention uses that
shared helper and exposes `/api/v1/admin/privacy-retention/policies/{scope}/simulate`
for preflight checks before saving lower-level policy changes.
The module also provides the optional
`policy.schedulingParticipantPrivacy` capability. Scheduling owns each
request's participant-visibility setting; Policy can only preserve or narrow
it. The resolver reads an optional `maximum_visibility` ceiling from the
`scheduling_participant_privacy_policy` object in system and tenant settings.
Missing policy is unrestricted, while malformed explicit policy fails closed
to aggregate-only visibility. This resolver slice intentionally has no policy
management endpoint or UI yet.
Policy also provides `policy.definitionGovernance` for Dataflow and Workflow
libraries. It evaluates view, edit, run/start, reuse, derive, and automation
actions across system, tenant, group, and user scopes. Templates cannot run or
be automated. Derived definitions retain ancestor ceilings, and every
decision includes the ordered Policy source path and effective limits so a UI
can explain why an action is available or blocked.

@@ -0,0 +1,132 @@
<!-- codex-wiki-sync:913529d2a534b4eae335338d -->
> Mirrored from `/mnt/DATA/git/govoplan-policy/docs/POLICY_DECISION_PROVENANCE.md`.
> Origin: `repository`.
> Active tasks and changing state belong in Gitea issues; this wiki page is durable project context.
---
# Policy Decision And Provenance Contract
`govoplan-policy` owns policy and retention route contributions. Core keeps the
small shared DTOs that let policy decisions look the same across modules.
Privacy retention implementation lives in this module at
`govoplan_policy.backend.retention`. It is also exposed as the
`policy.privacyRetention` capability so older core compatibility imports can
dispatch to the active policy module without owning policy logic in core. Core
does not import this implementation as a hidden fallback when policy is
disabled.
Reusable hierarchical policy validation lives in
`govoplan_policy.backend.hierarchy`. Policy families should use that helper for
parent locks, lower-level override ceilings, "more restrictive only" checks,
and read-only simulations before destructive or limiting changes are saved.
Domain modules keep their own policy fields and restriction rules, but the
decision shape and simulation payload stay consistent.
When retention needs audit-log storage behavior, it requests the
`audit.retention` capability; it does not import audit module tables or
providers directly.
## Scheduling Participant Privacy
Policy exposes `policy.schedulingParticipantPrivacy` as an optional restriction
hook. Scheduling supplies the request-level visibility choice and remains
responsible for its secure fallback when Policy is absent. The provider never
broadens that choice.
System and tenant settings may contain:
```json
{
"scheduling_participant_privacy_policy": {
"maximum_visibility": "aggregates_only"
}
}
```
`maximum_visibility` is either `aggregates_only` or `names_and_statuses`.
Omitted settings impose no additional restriction. Effective visibility is the
most restrictive of the Scheduling request, the system ceiling, and the tenant
ceiling. Explicit malformed policy fails closed to `aggregates_only` and is
reported in decision details without echoing the invalid stored value. Policy
sources include only explicitly configured or invalid system and tenant steps.
The current slice is resolver-only. A managed write API and administration UI
must add validation, audit, parent-ceiling enforcement, and configuration
safety registration before operators can edit this setting through GovOPlaN.
## Backend DTOs
Use `govoplan_core.core.policy.PolicyDecision` for explainable policy results:
- `allowed`: effective decision for the checked action.
- `reason`: compact operator-readable explanation.
- `source_path`: ordered policy sources that produced the decision.
- `requirements`: machine-readable blockers or prerequisites.
- `details`: domain-specific structured context, redacted when needed.
Use `PolicySourceStep` or `policy_source_step()` for each provenance step:
- `scope_type`: `system`, `tenant`, `user`, `group`, or `campaign`.
- `scope_id`: stable ID for non-system scopes.
- `path`: stable string path generated by `policy_source_path()`.
- `label`: concrete source label such as `System`, `Tenant`, `Owner user`,
`Group`, or `Campaign`.
- `applied_fields`: field names affected by that step.
- `policy`: local policy fragment that explains the applied fields.
Do not build or split provenance paths manually. Use
`policy_source_path()` and `parse_policy_source_path()` so IDs are URL-encoded
consistently.
## Retention Explain Endpoint
Retention policy exposes the shared shape through:
```text
GET /api/v1/admin/privacy-retention/policies/{scope_type}/explain
```
The response contains `decision`, `effective_policy`, `parent_policy`,
`effective_policy_sources`, `parent_policy_sources`, and `blocked_fields`.
Retention policy also exposes a write-preflight endpoint:
```text
POST /api/v1/admin/privacy-retention/policies/{scope}/simulate
```
The request body is the same as the write endpoint. The response contains a
`simulation` object with `allowed`, `changed_fields`, `issues`,
`before_policy`, `requested_policy`, and a shared `PolicyDecision` payload.
The endpoint never writes policy state and is intended for UI validation before
operators attempt destructive or limiting changes.
Clients can use `blocked_fields` to disable controls before a save attempt.
## UI Expectations
Policy UIs should render provenance close to the effective column or field it
explains. The display path should use concrete source labels and local values,
for example:
```text
System: Allow
> Tenant: Deny without override
```
If all lower levels still inherit, continue the path until the effective local
decision:
```text
System: Allow
> Tenant: Inherit
> Group: Inherit
> Campaign: Deny
```
When a parent disallows lower-level limits or changes, the UI should disable
the affected controls and avoid sending those fields in the save payload.
The shared core WebUI helper `PolicySourcePath` renders the source path shape
for module UIs. Modules may use their own field layout, but the data contract
should remain this shape.