Locked design for 4-Augen-Prüfung on Fristen + Termine. m-confirmed
decisions on all 11 open questions:
- Qualification gate reuses paliad.project_teams.role per-project
(no new firm-wide axis). Adds new value `senior_pa` to the enum.
- Strict ladder: lead > of_counsel > associate > senior_pa > pa.
Default required_role = associate. Per-project override allows pa-
approves-pa or senior_pa-tier escalation.
- Per-(project, entity_type, lifecycle_event) policy grammar — up to
8 settable rows per project in paliad.approval_policies.
- Edit-trigger allowlist = date-bearing fields only (Frist due_date /
original_due_date / warning_date; Termin start_at / end_at).
- Write-then-approve: row mutates immediately, approval_status flips
between approved/pending/legacy. Delete is the one stage-then-write
exception (hard-delete on approve, restore on reject).
- Refuse + global_admin override on single-qualified-approver deadlock.
- Pending state visualised everywhere — list views, agenda, dashboard
traffic-light, project detail, CalDAV-synced calendars (`[PENDING] `
title prefix), email reminders.
- Bell + /inbox page with two tabs (zur Genehmigung / meine Anfragen).
- Operational paliad.approval_requests + audit lifecycle written to
existing paliad.project_events (4 new event_types per entity).
- RLS = same can_see_project predicate; service layer enforces the
approve/reject action gate. CHECK constraint blocks self-approval.
- Mark-legacy backfill: approval_status='legacy' on existing rows;
next mutation flows through the gate.
Implementation phasing: single migration 054 + 8-commit PR plan
covering schema, service, wiring, policy authoring page, inbox,
pending pills, CalDAV/email integration, Verlauf rendering.
Inventor parked. Awaiting m go/no-go before any coder shift.