Automatisch erstellt: Commit aller Änderungen in Branch 260-governance-service-packaging-session-1777640889. Bitte prüfen und mergen. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #315
317 lines
15 KiB
Markdown
317 lines
15 KiB
Markdown
# Data Model — Governance-as-a-Service Packaging v1
|
|
|
|
**Spec**: [spec.md](spec.md)
|
|
|
|
No new persisted table, artifact family, or package projection store is required for this feature. The package remains a derived management-ready view over current review, section, review-pack, evidence, stored-report, governance-decision, entitlement, and audit truth.
|
|
|
|
## Source Truth Reused
|
|
|
|
### Workspace / Tenant Entitlement Context
|
|
|
|
**Purpose**: Establish the active workspace boundary and entitled tenant set before workspace rows, released-review detail, package download, or supporting artifact links resolve.
|
|
|
|
**Persisted carriers**:
|
|
- existing workspace membership rows
|
|
- existing tenant membership pivot rows and role assignments
|
|
- existing capability registry and role-capability map
|
|
|
|
**Relevant fields / contracts**:
|
|
- `workspace_id`
|
|
- `tenant_id`
|
|
- workspace membership existence
|
|
- tenant membership role
|
|
- capability grants derived from [../../apps/platform/app/Support/Auth/Capabilities.php](../../apps/platform/app/Support/Auth/Capabilities.php)
|
|
- remembered tenant context from the current workspace session model
|
|
|
|
**Validation rules**:
|
|
- actors outside the current workspace or tenant scope resolve as not found
|
|
- package readiness is only aggregated for entitled tenants with eligible released reviews
|
|
- supporting artifact availability must not leak inaccessible tenant or review presence
|
|
|
|
### ReleasedReviewContext
|
|
|
|
**Purpose**: Existing tenant review that anchors all package content and package-access semantics.
|
|
|
|
**Persisted carrier**: existing `tenant_reviews` rows via [../../apps/platform/app/Models/TenantReview.php](../../apps/platform/app/Models/TenantReview.php)
|
|
|
|
**Relevant fields / relationships**:
|
|
- `id`
|
|
- `workspace_id`
|
|
- `tenant_id`
|
|
- `status`
|
|
- `generated_at`
|
|
- `published_at`
|
|
- `summary`
|
|
- `evidence_snapshot_id`
|
|
- `current_export_review_pack_id`
|
|
- `tenant`
|
|
- `evidenceSnapshot`
|
|
- `sections`
|
|
|
|
**Validation / usage rules**:
|
|
- only released reviews feed the management-ready package path
|
|
- the review remains the canonical package-owning context; package output must not become independent truth about review state
|
|
- existing `summary.control_interpretation`, `summary.highlights`, and related summary data remain the first reuse path for package meaning
|
|
|
|
### TenantReviewSection Family
|
|
|
|
**Purpose**: Existing released-review section set that already captures the management-relevant content needed for packaging.
|
|
|
|
**Persisted carrier**: existing `tenant_review_sections` rows via [../../apps/platform/app/Models/TenantReviewSection.php](../../apps/platform/app/Models/TenantReviewSection.php)
|
|
|
|
**Current section keys already relevant to packaging**:
|
|
- `executive_summary`
|
|
- `control_interpretation`
|
|
- `open_risks`
|
|
- `accepted_risks`
|
|
- `permission_posture`
|
|
- `baseline_drift_posture`
|
|
- `operations_health`
|
|
|
|
**Relevant fields**:
|
|
- `section_key`
|
|
- `title`
|
|
- `sort_order`
|
|
- `completeness_state`
|
|
- `summary_payload`
|
|
- `render_payload`
|
|
- `measured_at`
|
|
|
|
**Validation / usage rules**:
|
|
- package sections should be rendered from this current section family before any new payload is considered
|
|
- accepted-risk and governance-decision follow-up stays anchored to the current `accepted_risks` section and related persisted decision truth
|
|
- if implementation later needs a small additional helper field, it must stay embedded inside existing review payloads rather than creating a new package entity
|
|
|
|
### Shared Interpretation Summary
|
|
|
|
**Purpose**: Existing management-meaning layer from Spec 259 that translates technical review truth into calm customer-safe language.
|
|
|
|
**Primary producer**: [../../apps/platform/app/Support/Governance/Controls/ComplianceEvidenceMappingV1.php](../../apps/platform/app/Support/Governance/Controls/ComplianceEvidenceMappingV1.php) via [../../apps/platform/app/Services/TenantReviews/TenantReviewSectionFactory.php](../../apps/platform/app/Services/TenantReviews/TenantReviewSectionFactory.php) and [../../apps/platform/app/Services/TenantReviews/TenantReviewComposer.php](../../apps/platform/app/Services/TenantReviews/TenantReviewComposer.php)
|
|
|
|
**Current carriers**:
|
|
- `TenantReview.summary['control_interpretation']`
|
|
- `TenantReviewSection` with `section_key = control_interpretation`
|
|
|
|
**Relevant fields / payload**:
|
|
- interpretation version
|
|
- control readiness summaries
|
|
- evidence-basis summaries
|
|
- limitation and follow-up wording
|
|
- per-control entries rendered for deeper detail
|
|
|
|
**Validation / usage rules**:
|
|
- package meaning must remain dependent on this shared interpretation layer
|
|
- if the interpretation layer or version is unavailable, the package must show explicit partial or unavailable state and must not infer management meaning directly from raw findings or stored reports
|
|
|
|
### ReviewPack
|
|
|
|
**Purpose**: Existing packaged export artifact reused as the default package-delivery seam for stakeholder download.
|
|
|
|
**Persisted carrier**: existing `review_packs` rows via [../../apps/platform/app/Models/ReviewPack.php](../../apps/platform/app/Models/ReviewPack.php)
|
|
|
|
**Relevant fields / relationships**:
|
|
- `id`
|
|
- `workspace_id`
|
|
- `tenant_id`
|
|
- `tenant_review_id`
|
|
- `status`
|
|
- `expires_at`
|
|
- `summary`
|
|
- `options`
|
|
- `tenantReview`
|
|
- `evidenceSnapshot`
|
|
|
|
**Validation / usage rules**:
|
|
- the package path should prefer reusing `currentExportReviewPack` and its signed download route
|
|
- management-ready package access must not create a new review-pack generation run or a new package artifact family
|
|
- review-pack readiness, expiry, missing-input, and blocked states remain review-pack truth, not new package lifecycle state
|
|
|
|
### EvidenceSnapshot
|
|
|
|
**Purpose**: Existing supporting proof artifact that informs evidence-basis summaries and explicit deeper drilldown.
|
|
|
|
**Persisted carrier**: existing `evidence_snapshots` rows via [../../apps/platform/app/Models/EvidenceSnapshot.php](../../apps/platform/app/Models/EvidenceSnapshot.php)
|
|
|
|
**Relevant fields / relationships**:
|
|
- `id`
|
|
- `workspace_id`
|
|
- `tenant_id`
|
|
- `status`
|
|
- `completeness_state`
|
|
- `generated_at`
|
|
- `expires_at`
|
|
- `summary`
|
|
- `items`
|
|
|
|
**Validation / usage rules**:
|
|
- evidence remains supporting truth and must stay distinct from package summary truth
|
|
- default-visible package content may summarize the evidence basis, but raw evidence payloads remain secondary and capability-gated
|
|
- supporting proof access should reuse existing evidence routes and audit events
|
|
|
|
### StoredReport-backed Evidence Inputs
|
|
|
|
**Purpose**: Existing report artifacts that feed evidence dimensions and therefore indirectly support the package evidence basis.
|
|
|
|
**Persisted carriers**:
|
|
- existing `stored_reports` rows via [../../apps/platform/app/Models/StoredReport.php](../../apps/platform/app/Models/StoredReport.php)
|
|
- existing evidence-source seams such as [../../apps/platform/app/Services/Evidence/Sources/PermissionPostureSource.php](../../apps/platform/app/Services/Evidence/Sources/PermissionPostureSource.php) and [../../apps/platform/app/Services/Evidence/Sources/EntraAdminRolesSource.php](../../apps/platform/app/Services/Evidence/Sources/EntraAdminRolesSource.php)
|
|
|
|
**Relevant fields / contracts**:
|
|
- `StoredReport.id`
|
|
- `workspace_id`
|
|
- `tenant_id`
|
|
- `report_type`
|
|
- `fingerprint`
|
|
- current evidence-source `source_kind = stored_report`
|
|
- current evidence-source `source_record_id`
|
|
|
|
**Validation / usage rules**:
|
|
- stored reports remain subordinate source artifacts behind evidence and review truth
|
|
- the package may mention stored-report-backed evidence basis, but it must not default to raw report payloads or invent a new viewer shell in v1
|
|
- if no current entitled viewer seam exists, the package should prefer explicit unavailable or secondary context messaging over a new route
|
|
|
|
### GovernanceDecisionTruth
|
|
|
|
**Purpose**: Existing accepted-risk and exception decision truth that qualifies management-ready package claims and powers the narrowed `open decisions` meaning.
|
|
|
|
**Persisted carriers**:
|
|
- existing `finding_exceptions` rows via [../../apps/platform/app/Models/FindingException.php](../../apps/platform/app/Models/FindingException.php)
|
|
- existing `finding_exception_decisions` truth referenced by the current exception relationships
|
|
|
|
**Relevant fields / relationships**:
|
|
- exception `status`
|
|
- `current_validity_state`
|
|
- `owner_user_id`
|
|
- `approved_by_user_id`
|
|
- `request_reason`
|
|
- `review_due_at`
|
|
- `effective_from`
|
|
- `expires_at`
|
|
- `owner`
|
|
- `approver`
|
|
- `currentDecision`
|
|
|
|
**Validation / usage rules**:
|
|
- `open decisions` remains narrowed to this existing accepted-risk / exception decision truth only
|
|
- package wording may summarize accountable role or person, decision reason, follow-up, and validity timing where current product truth exists
|
|
- missing owner, approval, or timing truth must surface as explicit partial disclosure instead of invented certainty
|
|
|
|
### Audit Log Event Family
|
|
|
|
**Purpose**: Existing audit trail used to keep package access and supporting artifact consumption attributable.
|
|
|
|
**Persisted carrier**: existing `audit_logs` rows via [../../apps/platform/app/Services/Audit/WorkspaceAuditLogger.php](../../apps/platform/app/Services/Audit/WorkspaceAuditLogger.php)
|
|
|
|
**Relevant current action IDs**:
|
|
- `customer_review_workspace.opened`
|
|
- `tenant_review.opened`
|
|
- `review_pack.downloaded`
|
|
- `evidence_snapshot.opened`
|
|
|
|
**Validation / usage rules**:
|
|
- no new audit store or audit family is justified by default
|
|
- package access and supporting artifact access should reuse these events with shared metadata before introducing a new event concept
|
|
|
|
## Derived Contracts
|
|
|
|
### GovernancePackageSummaryProjection
|
|
|
|
**Purpose**: Conceptual derived package contract rendered from the released review and supporting artifacts.
|
|
|
|
**Persistence**: not persisted independently; derived from `TenantReview.summary`, existing section payloads, current review-pack truth, evidence truth, and governance-decision truth
|
|
|
|
**Fields**:
|
|
- `review_id`
|
|
- `tenant_id`
|
|
- `interpretation_version`
|
|
- `delivery_artifact_family = review_pack`
|
|
- `package_availability`
|
|
- `executive_summary`
|
|
- `top_findings[]`
|
|
- `accepted_risks[]`
|
|
- `governance_decisions[]`
|
|
- `evidence_basis_summary`
|
|
- `supporting_artifact_links[]`
|
|
- `calm_disclosure`
|
|
|
|
**Field boundary rules**:
|
|
- `accepted_risks[]` contains currently valid tolerated-risk positions that explain why a material issue is presently accepted and does not need immediate stakeholder follow-up beyond awareness.
|
|
- `governance_decisions[]` contains accepted-risk or exception decision entries that still require stakeholder awareness because they are expiring, expired, revoked, missing basis, or otherwise need follow-up.
|
|
- the same underlying accepted-risk or exception decision must not appear in both arrays for the same released review; if an entry qualifies for both, prefer `governance_decisions[]`.
|
|
|
|
**Validation rules**:
|
|
- the projection must not become independent product truth about review, evidence, pack, or governance state
|
|
- the downloadable artifact for v1 remains the current export review pack for the released review; the governance package summary is derived framing over that existing artifact, not a second export family
|
|
- package meaning must stay consistent between workspace summary, released-review detail, and package delivery for the same released review
|
|
- if implementation later needs a tiny helper shape, it must stay embedded inside current review/resource helpers rather than new persistence
|
|
|
|
### PackageAvailabilityState
|
|
|
|
**Purpose**: Derived explanation of whether the current released review can deliver the management-ready package now.
|
|
|
|
**Persistence**: derived from current review-pack truth, evidence basis completeness, interpretation availability, and entitlement state
|
|
|
|
**Planned values**:
|
|
- `available`
|
|
- `partial`
|
|
- `unavailable`
|
|
- `expired`
|
|
- `blocked`
|
|
|
|
**Validation rules**:
|
|
- these are presentation semantics only and must not become a new persisted lifecycle family
|
|
- stale or incomplete basis resolves through `partial` or `unavailable` reasons such as `stale_basis` or `evidence_basis_partial`, not a separate top-level state
|
|
- entitlement-restricted package access resolves through `blocked` or per-artifact `forbidden` semantics, not a separate top-level availability state
|
|
- reasons should remain attributable to the underlying review-pack, evidence, entitlement, or interpretation truth
|
|
|
|
**Canonical mapping from current artifact-truth seam**:
|
|
|
|
| Current repo truth | Package state | Reason-code guidance | Notes |
|
|
|---|---|---|---|
|
|
| `publicationReadiness = publishable` and current pack truth | `available` | `null` unless a secondary artifact has its own issue | The current export review pack is ready for stakeholder delivery. |
|
|
| `publicationReadiness = internal_only` or freshness `stale` while the summary is still readable | `partial` | `stale_basis` or `evidence_basis_partial` | Keep the management summary readable, but be explicit that the delivery basis is incomplete or stale. |
|
|
| `publicationReadiness = blocked`, `artifactExistence = not_created`, `contentState = missing_input`, or interpretation/source truth is not publishable | `unavailable` | `current_review_pack_missing`, `interpretation_missing`, or `source_not_publishable` | The package cannot be truthfully delivered now, so do not imply download readiness. |
|
|
| `artifactExistence = historical_only` or current pack expiry is the governing truth | `expired` | `current_review_pack_expired` | Historical exports stay attributable, but they are not the current stakeholder package. |
|
|
| In-scope actor lacks package entitlement to the released-review package path | `blocked` | `entitlement_restricted` | The package path itself is gated and must not render as deliverable. |
|
|
| Package summary is readable, but one supporting proof or artifact link is restricted | package state stays `available` or `partial` according to review-pack truth; affected secondary link becomes `forbidden` or `unavailable` | `supporting_access_limited` belongs on the supporting link message, not on the top-level package state | Keep package-level access and per-artifact access distinct. |
|
|
|
|
**Additional mapping notes**:
|
|
- repo directions such as `usable` stay inside `SupportingArtifactLink.state` and do not create a sixth package state
|
|
- repo directions such as `follow_up_needed` affect governance-follow-up wording and calm disclosure, not top-level package availability on their own
|
|
|
|
### GovernanceDecisionFollowUp
|
|
|
|
**Purpose**: Derived management-readable summary of accepted-risk / exception decisions that still need stakeholder awareness.
|
|
|
|
**Persistence**: derived from current exception and decision truth only
|
|
|
|
**Fields**:
|
|
- `decision_source`
|
|
- `decision_state`
|
|
- `decision_summary`
|
|
- `accountable_label` (nullable)
|
|
- `review_due_at` (nullable)
|
|
- `expires_at` (nullable)
|
|
- `follow_up_message`
|
|
|
|
**Validation rules**:
|
|
- follow-up entries must not imply a broader queue or workflow board
|
|
- only currently valid accepted-risk / exception decision truth may feed this projection
|
|
|
|
### SupportingArtifactLink
|
|
|
|
**Purpose**: Derived representation of optional proof and artifact drilldowns from the package.
|
|
|
|
**Persistence**: derived from current evidence, review-pack, and existing viewer availability
|
|
|
|
**Fields**:
|
|
- `artifact_family`
|
|
- `state`
|
|
- `label`
|
|
- `message`
|
|
- `url` (nullable)
|
|
|
|
**Validation rules**:
|
|
- links must point only to existing entitled surfaces
|
|
- if no current viewer seam exists for a stored-report-backed detail, the link stays unavailable rather than introducing a new route
|
|
- the package must not duplicate raw payloads when a secondary artifact link is unavailable |