12 KiB
Research — Governance-as-a-Service Packaging v1
Date: 2026-05-01
Spec: 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 as the primary decision surface and ../../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 already exposes
downloadCurrentReviewPackAction()and suppresses operator lifecycle actions. - ../../apps/platform/app/Services/ReviewPackService.php already provides signed download URLs, while
generateFromReview()is tied to the existing export workflow andOperationRunlifecycle. - 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
GovernancePackageartifact 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-
OperationRunscope boundary.
- Rejected: introduces a queued generation path and breaks the explicit no-
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 and ../../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 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.
ComplianceEvidenceMappingV1already includes accepted-risk follow-up wording and limitation semantics that fit the package’s calm disclosure goal.- Narrowing
open decisionsto 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 decisionsinto 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 for current review, evidence snapshot, and review-pack availability or expiry semantics, and keep artifact/result truth separation explicit in the package contract.
Rationale:
ArtifactTruthPresenteralready resolves envelopes forTenantReview,EvidenceSnapshot, andReviewPackand 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 and ../../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 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.openedevent 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.