# Research — Governance-as-a-Service Packaging v1 **Date**: 2026-05-01 **Spec**: [spec.md](spec.md) This document resolves the planning decisions for the smallest safe management-ready package over one released review context. ## Decision 1 — Keep the existing customer review workspace and released-review detail flow as the only primary and secondary surfaces **Decision**: Reuse [../../apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php](../../apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php) as the primary decision surface and [../../apps/platform/app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php](../../apps/platform/app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php) in customer-workspace mode as the only secondary context surface. **Rationale**: - The repo already has the admin-plane route, tenant-safe prefilter behavior, package-readiness-adjacent columns, and bounded feature and browser coverage for these surfaces. - The missing product contract is management-ready packaging over existing truth, not new routing, a new panel, or a customer portal shell. - Reusing these surfaces keeps the package anchored to one released review context and prevents a second package registry or dashboard. **Alternatives considered**: - Add a dedicated package page or customer-only package portal. - Rejected: duplicates the current review-consumption path and widens scope into shell-level IA and identity concerns. - Put all management-ready content on the workspace only. - Rejected: would overload the list surface and weaken the existing released-review drilldown as the package-owning context. ## Decision 2 — Prefer current review-pack reuse and signed download over creating a new exported artifact or generation path **Decision**: Treat the current export review pack and its signed download route as the default package-delivery seam for v1. The management-ready path should reuse `downloadCurrentReviewPackAction()` and current review-pack truth before considering any new artifact concept. **Rationale**: - In customer-workspace mode [../../apps/platform/app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php](../../apps/platform/app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php) already exposes `downloadCurrentReviewPackAction()` and suppresses operator lifecycle actions. - [../../apps/platform/app/Services/ReviewPackService.php](../../apps/platform/app/Services/ReviewPackService.php) already provides signed download URLs, while `generateFromReview()` is tied to the existing export workflow and `OperationRun` lifecycle. - The feature spec explicitly forbids package generation runs and a new package artifact family. Reusing current review-pack truth is therefore the narrowest correct path. **Alternatives considered**: - Add a new `GovernancePackage` artifact or export namespace. - Rejected: creates parallel persistence and new lifecycle semantics the spec explicitly forbids. - Start `generateFromReview()` from the management-ready package action when no pack exists. - Rejected: introduces a queued generation path and breaks the explicit no-`OperationRun` scope boundary. ## Decision 3 — Derive package meaning from current review summary and section truth, not from a parallel package record **Decision**: Compose package meaning from existing released-review summary and section payloads, especially `summary.control_interpretation`, `summary.highlights`, and the current section family created by [../../apps/platform/app/Services/TenantReviews/TenantReviewComposer.php](../../apps/platform/app/Services/TenantReviews/TenantReviewComposer.php) and [../../apps/platform/app/Services/TenantReviews/TenantReviewSectionFactory.php](../../apps/platform/app/Services/TenantReviews/TenantReviewSectionFactory.php). **Rationale**: - The repo already persists the management-relevant building blocks needed for this slice inside the released review artifact. - Existing sections already cover executive summary, control interpretation, open risks, accepted risks, permission posture, baseline drift, and operations health. - Reusing those payloads keeps workspace, detail, and package access on one truth path and avoids a second semantic layer. **Alternatives considered**: - Persist a package-specific JSON blob or summary projection. - Rejected: adds a new source of truth for content already represented by the released review. - Compose package content directly from raw findings, evidence payloads, and stored reports in page code. - Rejected: bypasses the shared interpretation path and increases drift risk. ## Decision 4 — Keep Spec 259’s shared interpretation layer mandatory and keep “open decisions” narrowed to risk-acceptance / exception truth **Decision**: Package content must remain dependent on [../../apps/platform/app/Support/Governance/Controls/ComplianceEvidenceMappingV1.php](../../apps/platform/app/Support/Governance/Controls/ComplianceEvidenceMappingV1.php) and on the review’s existing `control_interpretation` payload. The roadmap phrase `open decisions` remains narrowed to accepted-risk and exception decision truth only. **Rationale**: - The spec requires the package to stay on the shared customer-safe interpretation path and explicitly forbids raw finding or report language as the package’s meaning layer. - `ComplianceEvidenceMappingV1` already includes accepted-risk follow-up wording and limitation semantics that fit the package’s calm disclosure goal. - Narrowing `open decisions` to existing exception and risk-acceptance truth keeps scope out of queue or workflow-engine territory. **Alternatives considered**: - Invent a package-local management summary mapper. - Rejected: would fork the current interpretation contract and create inconsistent wording across workspace, detail, and package access. - Generalize `open decisions` into a broader governance inbox or approval board. - Rejected: imports a new workflow engine and wider product semantics beyond the current slice. ## Decision 5 — Reuse artifact-truth seams for availability, expiry, and truth separation **Decision**: Reuse [../../apps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php](../../apps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php) for current review, evidence snapshot, and review-pack availability or expiry semantics, and keep artifact/result truth separation explicit in the package contract. **Rationale**: - `ArtifactTruthPresenter` already resolves envelopes for `TenantReview`, `EvidenceSnapshot`, and `ReviewPack` and already carries compressed truth about artifact existence, readiness, and reasons. - The package spec explicitly requires artifact/result truth separation: the package summary must not redefine review, pack, evidence, or report truth. - Reusing the presenter keeps package availability semantics aligned with adjacent governance artifact surfaces. **Alternatives considered**: - Add a new package availability enum or presenter family. - Rejected: redundant with current artifact-truth seams and disproportionate for this slice. - Collapse review truth, review-pack truth, and evidence truth into one package status. - Rejected: violates the repo’s operator-surface guidance around distinct truth dimensions. ## Decision 6 — Keep stored reports subordinate source truth and do not invent a new viewer shell during v1 planning **Decision**: Treat stored reports as existing evidence inputs and secondary drilldown only where the repo already exposes them through current seams. Do not introduce a new stored-report viewer route or shell during v1 planning. **Rationale**: - The repo clearly has stored-report-backed evidence inputs through 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). - A shared stored-report viewer resource is not obvious in the current operator plane, so inventing one here would exceed the slice and introduce a new surface family. - The package can still remain truthful by summarizing stored-report-backed evidence basis and marking supporting detail unavailable when no existing entitled viewer seam exists. **Alternatives considered**: - Create a new stored-report detail surface as part of packaging. - Rejected: adds a new viewer family not required to ship one management-ready package. - Ignore stored-report-backed evidence entirely. - Rejected: would understate the evidence basis and make the package less faithful to the existing review truth. ## Decision 7 — Reuse current audit events and metadata instead of introducing a new audit family **Decision**: Keep package auditability on the existing `customer_review_workspace.opened`, `tenant_review.opened`, `review_pack.downloaded`, and `evidence_snapshot.opened` events, enriching metadata before introducing any new audit concept. **Rationale**: - [../../apps/platform/app/Support/Audit/AuditActionId.php](../../apps/platform/app/Support/Audit/AuditActionId.php) already defines the relevant action IDs for the package path. - Workspace and released-review entry points already record interpretation-version and source-surface context, and review-pack downloads already flow through a shared signed route. - The spec requires auditability, not a new audit store or family. **Alternatives considered**: - Create a new `governance_package.opened` event family up front. - Rejected: not justified until the feature proves it needs an explicit open event beyond current review-open and pack-download moments. - Rely on passive render without audit coverage. - Rejected: weakens attributable access semantics for a stakeholder-ready deliverable. ## Decision 8 — Defer branding and profile variants from v1 and keep neutral localization-ready package framing **Decision**: V1 does not introduce MSP branding, profile variants, or client-specific layouts. `Download governance package` remains neutral governance-package framing over the current export review pack for the released review, and new labels stay in the existing DE/EN localization posture. **Rationale**: - Repo exploration did not reveal a clear existing branding source-of-truth that this slice could safely reuse without hidden configuration or persistence work. - The spec only needs one repeatable management-ready package path; it does not need brand customization to prove product fit. - Deferring branding avoids accidental profile-variant, layout, or package-template framework growth. **Alternatives considered**: - Add bounded package branding now. - Rejected: no clear repo-real branding source-of-truth was confirmed, so this would import hidden scope. - Hardcode package wording inline on page classes. - Rejected: weakens localization-readiness and makes cross-surface wording drift more likely. ## Decision 9 — Keep validation in existing review, review-pack, evidence, and smoke test families **Decision**: Expand the existing unit, feature, and single browser smoke files that already cover the review, pack, evidence, and audit seams touched by this feature. **Rationale**: - The repo already has focused tests for workspace behavior, released-review explanation, review-pack download, entitlement enforcement, evidence audit logging, and the bounded workspace smoke path. - Those files are the cheapest honest proof for package reuse, scope isolation, calm unavailable states, and truth separation. - Reusing them honors the spec’s test-governance requirement to avoid a broader heavy family. **Alternatives considered**: - Add a new package-specific browser suite. - Rejected: too expensive for the bounded value of this slice. - Rely only on unit tests around new helpers. - Rejected: the feature’s core contract lives on rendered Filament surfaces and needs surface-level proof.