Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m4s
Implements platform feature branch `259-compliance-evidence-mapping`. Target branch: `platform-dev`. Follow-up integration path after merge: `platform-dev` -> `dev`. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #312
341 lines
14 KiB
Markdown
341 lines
14 KiB
Markdown
# Data Model — Compliance Evidence Mapping v1
|
|
|
|
**Spec**: [spec.md](spec.md)
|
|
|
|
No new persisted table, report artifact family, or projection store is required for this feature. The implementation reuses current review, section, evidence, finding, accepted-risk, membership, and audit truth, then embeds one bounded interpretation contract inside the existing review payloads.
|
|
|
|
## Source Truth Reused
|
|
|
|
### Workspace / Tenant Entitlement Context
|
|
|
|
**Purpose**: Establish the active workspace boundary and entitled tenant set before any workspace row, released-review detail, or supporting evidence route is resolved.
|
|
|
|
**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 existing workspace session model
|
|
|
|
**Validation rules**:
|
|
- the actor must be a member of the current workspace or the request resolves as not found
|
|
- workspace rows and explicit tenant filters may only resolve for entitled tenants in that workspace
|
|
- out-of-scope tenant targets remain `404` and must not leak review or evidence presence
|
|
|
|
### CanonicalControlDefinition
|
|
|
|
**Purpose**: Existing provider-neutral control identity used as the anchor for every mapped customer-safe control summary.
|
|
|
|
**Carrier**: existing [../../apps/platform/config/canonical_controls.php](../../apps/platform/config/canonical_controls.php) loaded through [../../apps/platform/app/Support/Governance/Controls/CanonicalControlCatalog.php](../../apps/platform/app/Support/Governance/Controls/CanonicalControlCatalog.php)
|
|
|
|
**Relevant fields**:
|
|
- `control_key`
|
|
- `name`
|
|
- `domain_key`
|
|
- `subdomain_key`
|
|
- `summary`
|
|
- `control_class`
|
|
- `evaluation_strategy`
|
|
- `evidence_archetypes`
|
|
- `historical_status`
|
|
|
|
**Validation / usage rules**:
|
|
- canonical controls remain provider-neutral and customer-facing labels must continue to use the catalog's neutral names
|
|
- provider-specific Microsoft bindings stay internal resolution inputs only
|
|
- the interpretation overlay may add customer-safe readiness meaning, but it must not create a second control taxonomy
|
|
|
|
### Findings Summary Evidence Input
|
|
|
|
**Purpose**: Existing per-finding evidence basis that already resolves canonical control references and accepted-risk governance state.
|
|
|
|
**Persisted carriers**:
|
|
- existing `evidence_snapshots`
|
|
- existing `evidence_snapshot_items`
|
|
- existing `findings`
|
|
|
|
**Primary producer**: [../../apps/platform/app/Services/Evidence/Sources/FindingsSummarySource.php](../../apps/platform/app/Services/Evidence/Sources/FindingsSummarySource.php)
|
|
|
|
**Relevant fields / payload**:
|
|
- `EvidenceSnapshot.id`
|
|
- `EvidenceSnapshot.generated_at`
|
|
- `EvidenceSnapshot.expires_at`
|
|
- `EvidenceSnapshotItem.dimension_key = findings_summary`
|
|
- `summary_payload.entries[].id`
|
|
- `summary_payload.entries[].status`
|
|
- `summary_payload.entries[].severity`
|
|
- `summary_payload.entries[].terminal_outcome`
|
|
- `summary_payload.entries[].canonical_control_resolution`
|
|
- `summary_payload.entries[].governance_state`
|
|
- `summary_payload.entries[].governance_warning`
|
|
- `summary_payload.canonical_controls[]`
|
|
- `summary_payload.risk_acceptance`
|
|
|
|
**Validation / usage rules**:
|
|
- canonical control identity continues to come from the current upstream resolution path only
|
|
- the interpretation overlay should consume current governance-state and terminal-outcome values rather than inventing a second status source
|
|
- if the current payload is sufficient, upstream evidence collection remains unchanged
|
|
|
|
### FindingException / Accepted Risk Decision
|
|
|
|
**Purpose**: Existing accepted-risk and accountability truth that can weaken or qualify a customer-safe control interpretation.
|
|
|
|
**Persisted carrier**: existing `finding_exceptions` rows via [../../apps/platform/app/Models/FindingException.php](../../apps/platform/app/Models/FindingException.php)
|
|
|
|
**Relevant fields / relationships**:
|
|
- `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**:
|
|
- accepted-risk truth may qualify a control interpretation but must not collapse into a fully positive readiness claim
|
|
- missing owner, approver, or review-due truth must surface as explicit partial disclosure rather than fabricated certainty
|
|
- this slice remains read-only and does not introduce approval, renewal, or revocation actions
|
|
|
|
### TenantReview
|
|
|
|
**Purpose**: Existing released review artifact that anchors the shared interpretation contract for both workspace and detail surfaces.
|
|
|
|
**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`
|
|
- `operation_run_id`
|
|
- `tenant`
|
|
- `evidenceSnapshot`
|
|
- `sections`
|
|
|
|
**Planned embedded summary additions inside the existing `summary` JSON**:
|
|
- `control_interpretation.version`
|
|
- `control_interpretation.display_label`
|
|
- `control_interpretation.non_certification_disclosure`
|
|
- `control_interpretation.controls[]`
|
|
- `control_interpretation.limitations[]`
|
|
|
|
**Validation / usage rules**:
|
|
- only released reviews feed the default customer-safe workspace path
|
|
- the shared interpretation version must be carried at compose time so older released reviews preserve the meaning shown at publication time
|
|
- the workspace must read the embedded summary contract instead of recomputing the interpretation locally
|
|
|
|
### TenantReviewSection
|
|
|
|
**Purpose**: Existing detailed review section carrier used for the per-control explanation surface on the released review detail page.
|
|
|
|
**Persisted carrier**: existing `tenant_review_sections` rows via [../../apps/platform/app/Models/TenantReviewSection.php](../../apps/platform/app/Models/TenantReviewSection.php)
|
|
|
|
**Relevant fields**:
|
|
- `section_key`
|
|
- `title`
|
|
- `sort_order`
|
|
- `completeness_state`
|
|
- `summary_payload`
|
|
- `render_payload`
|
|
- `measured_at`
|
|
|
|
**Planned usage**:
|
|
- add one new v1 interpretation section inside the existing section family with the canonical `control_interpretation` section key
|
|
- keep the section near the top of the customer-workspace detail disclosure so mapped-control explanation precedes rawer supporting sections
|
|
|
|
**Planned embedded payload shape**:
|
|
- `summary_payload.version`
|
|
- `summary_payload.mapped_control_count`
|
|
- `summary_payload.follow_up_required_count`
|
|
- `summary_payload.limitation_counts`
|
|
- `render_payload.entries[]` containing detailed per-control explanations
|
|
|
|
**Validation / usage rules**:
|
|
- exactly one interpretation section should exist per review for v1
|
|
- the detail surface should read this section instead of deriving a second explanation contract in-page
|
|
- this remains part of the existing review artifact and does not create a new section table or entity family
|
|
|
|
### 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**:
|
|
- supporting proof remains optional, lower-priority, and capability-gated
|
|
- the overlay may summarize the evidence basis, but raw payloads and unrestricted diagnostics remain outside the default customer-safe path
|
|
- supporting evidence access should reuse the existing evidence route and audit action
|
|
|
|
### Audit Log Event Family
|
|
|
|
**Purpose**: Existing audit trail used to keep the displayed interpretation and access path traceable.
|
|
|
|
**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`
|
|
- `evidence_snapshot.opened`
|
|
|
|
**Planned shared metadata additions**:
|
|
- `source_surface`
|
|
- `interpretation_version`
|
|
- `review_id` when a released review is opened from the workspace
|
|
- `tenant_filter_id` when the workspace is entered with a safe prefilter
|
|
|
|
**Validation / usage rules**:
|
|
- no new audit store or audit event family is justified
|
|
- interpretation-version traceability should be added to shared metadata before introducing any new event concept
|
|
|
|
## Embedded Interpretation Contracts
|
|
|
|
### ControlInterpretationOverlayVersion
|
|
|
|
**Purpose**: The explicit version label that states which customer-safe interpretation rules produced the displayed control/readiness summaries.
|
|
|
|
**Persistence**: embedded in existing `TenantReview.summary` and the existing interpretation section payload; echoed in shared audit metadata when relevant
|
|
|
|
**Fields**:
|
|
- `version_key` (planned baseline: `compliance_evidence_mapping.v1`)
|
|
- `display_label`
|
|
- `non_certification_disclosure`
|
|
|
|
**Validation rules**:
|
|
- exactly one version key is carried for a given released review
|
|
- the version must be visible on workspace and detail surfaces whenever mapped control summaries are shown
|
|
|
|
### CustomerControlSummary
|
|
|
|
**Purpose**: Compact per-control summary reused by the workspace and as the top-level contract for the detail surface.
|
|
|
|
**Persistence**: embedded inside `TenantReview.summary['control_interpretation']['controls']`
|
|
|
|
**Fields**:
|
|
- `control_key`
|
|
- `control_name`
|
|
- `domain_key`
|
|
- `readiness_bucket`
|
|
- `limitation_flags[]`
|
|
- `customer_summary`
|
|
- `evidence_basis_summary`
|
|
- `accepted_risk_summary` (nullable)
|
|
- `recommended_next_action`
|
|
- `detail_anchor` (nullable)
|
|
- `supporting_finding_ids[]`
|
|
|
|
**Validation rules**:
|
|
- one summary exists per mapped canonical control for the released review
|
|
- the summary must stay customer-safe and must not expose provider IDs, raw JSON, or support-only diagnostics
|
|
- the same summary meaning must appear on the workspace and detail surfaces for the same released review
|
|
|
|
### CustomerControlExplanation
|
|
|
|
**Purpose**: Detailed per-control explanation rendered on the released-review detail surface.
|
|
|
|
**Persistence**: embedded inside the interpretation `TenantReviewSection.render_payload.entries[]`
|
|
|
|
**Fields**:
|
|
- `control_key`
|
|
- `control_name`
|
|
- `readiness_bucket`
|
|
- `limitation_flags[]`
|
|
- `explanation_text`
|
|
- `evidence_basis_items[]`
|
|
- `accepted_risk_context` (nullable)
|
|
- `recommended_next_action`
|
|
- `proof_access_state`
|
|
|
|
**Validation rules**:
|
|
- the detail explanation must be a denser expansion of the compact summary, not a second source of truth
|
|
- supporting evidence remains explicit drilldown, not default-visible raw detail
|
|
- the explanation must keep non-certification language visible and must not claim legal or framework attestation
|
|
|
|
### CustomerReviewWorkspaceEntry
|
|
|
|
**Purpose**: Derived row-level presentation contract for one entitled tenant with a released review on the workspace page.
|
|
|
|
**Persistence**: none; derived at request time from the latest released `TenantReview` and its embedded interpretation contract
|
|
|
|
**Fields**:
|
|
- `workspace_id`
|
|
- `tenant_id`
|
|
- `tenant_name`
|
|
- `latest_published_review_id`
|
|
- `latest_review_published_at`
|
|
- `interpretation_version`
|
|
- `control_summaries[]`
|
|
- `follow_up_summary`
|
|
|
|
**Validation rules**:
|
|
- exactly one derived entry exists per entitled tenant with a released review visible in the current workspace scope
|
|
- when no entitled tenant has a released review, the workspace falls back to a page-level empty state rather than emitting partial row contracts without a review
|
|
- the one dominant row action remains opening the released review; supporting proof stays secondary and is not a peer primary action on the row
|
|
|
|
### CustomerReviewDetailContext
|
|
|
|
**Purpose**: Derived detail-page contract for the existing released-review surface when launched from the workspace.
|
|
|
|
**Persistence**: none; derived from the released `TenantReview`, its interpretation section, and the current `customer_workspace` query flag
|
|
|
|
**Fields**:
|
|
- `review_id`
|
|
- `tenant_id`
|
|
- `customer_workspace_context` (boolean)
|
|
- `interpretation_version`
|
|
- `controls[]`
|
|
- `non_certification_disclosure`
|
|
- `operator_actions_hidden` (boolean)
|
|
- `supporting_evidence_collapsed_by_default` (boolean)
|
|
|
|
**Validation rules**:
|
|
- the detail page must stay read-only in customer-workspace context
|
|
- the same interpretation version and control meaning shown on the workspace must be visible here
|
|
- supporting evidence should remain explicit in-body drilldown rather than a new dominant header action
|
|
|
|
## Derived Disclosure States
|
|
|
|
This feature introduces no new platform-wide lifecycle family. It does require one bounded overlay-local readiness contract and explicit limitation flags.
|
|
|
|
### Primary readiness buckets
|
|
|
|
- `follow_up_required`
|
|
- `review_recommended`
|
|
- `evidence_on_record`
|
|
|
|
### Limitation flags
|
|
|
|
- `accepted_risk_influenced`
|
|
- `partial_mapping`
|
|
- `stale_evidence`
|
|
- `supporting_evidence_unavailable`
|
|
- `unmapped`
|
|
|
|
**Validation rules**:
|
|
- limitation flags qualify the customer-safe interpretation and must never be silently collapsed into `evidence_on_record`
|
|
- accepted risk remains a qualifier, not a passing state
|
|
- these values stay embedded in the interpretation contract only and do not become a broader platform taxonomy or standalone persistence family |