# 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.