# Research — Customer Review Workspace Productization v1 **Date**: 2026-04-30 **Spec**: [spec.md](spec.md) This document resolves the planning decisions for the smallest safe productization follow-up to Spec 249. ## Decision 1 — Keep the existing customer review workspace as the canonical landing surface **Decision**: Productize the existing [../../apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php](../../apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php) page instead of creating a second customer-review page, new Resource, new panel, or customer portal shell. **Rationale**: - The repo already has the canonical admin-plane route, current tenant prefilter behavior, and bounded test family for this page. - The gap is productization of the current disclosure contract, not missing routing or missing persistence. - Reusing the existing page keeps the follow-up aligned with Spec 249 and avoids a second customer-review vocabulary. **Alternatives considered**: - Add a second customer-facing page or shell. - Rejected: duplicates the existing workspace route and widens scope into shell-level IA. - Convert the workspace into a new Resource. - Rejected: this is still a read-only workspace report, not a new persisted object family. ## Decision 2 — Keep the existing released-review detail route as the only secondary context surface **Decision**: Continue to use [../../apps/platform/app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php](../../apps/platform/app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php) as the secondary context surface reached from the workspace by the existing `customer_workspace` query flag. **Rationale**: - The current detail page already suppresses management actions when launched from the customer-workspace flow. - The current route already writes customer-workspace review-open audit metadata. - Productization should deepen understanding on the current drilldown path instead of inventing a second detail page. **Alternatives considered**: - Add a customer-only review detail page. - Rejected: would duplicate detail truth and drift from the current policy/audit path. - Push all new explanation back onto the workspace page only. - Rejected: would keep the first drilldown operator-heavy and incomplete. ## Decision 3 — Reuse the existing review summary and artifact-truth seams for findings, accepted-risk, and proof framing **Decision**: Reuse the current `TenantReview.summary` payload, [../../apps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php](../../apps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php), and current review/evidence/pack relationships for customer-safe findings, accepted-risk, and proof framing. **Rationale**: - The workspace page already derives `finding_outcomes` and `risk_acceptance` summary content from the current review payload. - `ArtifactTruthPresenter` already normalizes review and pack freshness/publication semantics. - The productization gap is wording, priority, and explicit unavailable-state behavior, not missing domain truth. **Alternatives considered**: - Introduce a customer-review presenter or new derived persistence layer. - Rejected: adds structure without new source-of-truth need. - Inline a second page-local taxonomy for findings and proof states. - Rejected: creates shared-language drift across workspace, review, and pack surfaces. ## Decision 4 — Keep accepted-risk accountability rooted in existing finding-exception truth **Decision**: Accepted-risk accountability remains derived from existing `FindingException` and current decision truth where available; missing accountable-person or accountable-role data must surface as partial/unavailable disclosure rather than a fabricated customer-safe summary. **Rationale**: - The spec explicitly forbids new persistence and new decision stores. - Existing `FindingException` truth already includes owner, approver, current decision, validity, review due, and evidence reference relationships. - Productization requires better accountability framing, but not a parallel accepted-risk model. **Alternatives considered**: - Add a new customer-accountability projection. - Rejected: violates the no-new-persistence goal. - Hide accepted-risk accountability when details are incomplete. - Rejected: weakens the governance-of-record objective and obscures truthful partiality. ## Decision 5 — Keep workspace and tenant isolation on the current capability-first seams **Decision**: Reuse [../../apps/platform/app/Services/TenantReviews/TenantReviewRegisterService.php](../../apps/platform/app/Services/TenantReviews/TenantReviewRegisterService.php), [../../apps/platform/app/Services/Auth/RoleCapabilityMap.php](../../apps/platform/app/Services/Auth/RoleCapabilityMap.php), and [../../apps/platform/app/Support/Auth/Capabilities.php](../../apps/platform/app/Support/Auth/Capabilities.php) as the isolation and entitlement seams. **Rationale**: - The current workspace page already uses `canAccessWorkspace(...)`, `authorizedTenants(...)`, and the current workspace context. - The existing test family already proves `404` semantics for out-of-scope tenant targeting on the workspace route. - Capability-first reuse avoids new role families or customer-only policy forks. **Alternatives considered**: - Add new customer-review roles or customer-specific policy branches. - Rejected: outside scope and unnecessary for the current admin-plane audience. - Resolve optional proof access by hiding the entire review. - Rejected: the review should remain readable even when optional proof is unavailable. ## Decision 6 — Treat access, absence, unavailable, expired, and redacted conditions as derived disclosure states only **Decision**: The follow-up should make access, absence, unavailable, expired, and redacted conditions explicit across workspace, review, evidence, and pack paths, but these remain derived view semantics rather than new persisted statuses. **Rationale**: - The current workspace page already distinguishes `No published review available yet` and pack availability from persisted review lifecycle state. - The spec explicitly rejects new state families and new persistence. - Explicit customer-safe disclosure is the sellability gap; a new persisted taxonomy is not. **Alternatives considered**: - Add a new customer-availability enum family. - Rejected: presentation-only distinction with no new lifecycle consequence. - Leave absence and unavailable states implicit. - Rejected: that is the current productization gap. ## Decision 7 — Reuse the current review-pack and evidence proof routes instead of adding new proof viewers **Decision**: Keep [../../apps/platform/app/Http/Controllers/ReviewPackDownloadController.php](../../apps/platform/app/Http/Controllers/ReviewPackDownloadController.php), [../../apps/platform/app/Filament/Resources/ReviewPackResource/Pages/ViewReviewPack.php](../../apps/platform/app/Filament/Resources/ReviewPackResource/Pages/ViewReviewPack.php), and [../../apps/platform/app/Filament/Resources/EvidenceSnapshotResource/Pages/ViewEvidenceSnapshot.php](../../apps/platform/app/Filament/Resources/EvidenceSnapshotResource/Pages/ViewEvidenceSnapshot.php) as the only proof/detail routes reused by this feature. **Rationale**: - Current pack download already enforces tenant access, capability checks, readiness, expiry, and audit logging. - Current evidence resource routing already exists and is referenced by review and pack truth presenters. - The follow-up only needs clearer proof-pointer semantics and explicit unavailable states, not a new viewer family. **Alternatives considered**: - Add a new customer-proof page or customer-only download endpoint. - Rejected: duplicates existing review-pack and evidence seams. - Surface raw evidence payloads directly on the workspace page. - Rejected: violates customer-safe disclosure hierarchy. ## Decision 8 — Reuse the existing audit pipeline and extend it only where access moments are still missing **Decision**: Keep all auditing on [../../apps/platform/app/Services/Audit/WorkspaceAuditLogger.php](../../apps/platform/app/Services/Audit/WorkspaceAuditLogger.php) and [../../apps/platform/app/Support/Audit/AuditActionId.php](../../apps/platform/app/Support/Audit/AuditActionId.php). Existing review-open and pack-download actions stay authoritative, and only bounded additive action IDs should be considered if workspace access or proof access moments are not yet covered. **Rationale**: - The current customer-workspace review handoff already logs `TenantReviewOpened`. - The current signed pack download route already logs `ReviewPackDownloaded`. - The repo does not currently show a matching evidence-proof-open audit on the customer-workspace flow, so that is the bounded gap to evaluate. **Alternatives considered**: - Create a new customer-review audit table or analytics stream. - Rejected: unnecessary persistence and duplication. - Leave workspace/proof access unaudited. - Rejected: the spec explicitly requires auditability for those consumption moments. ## Decision 9 — Keep browser coverage bounded to the existing smoke harness **Decision**: Reuse [../../apps/platform/tests/Browser/Reviews/CustomerReviewWorkspaceSmokeTest.php](../../apps/platform/tests/Browser/Reviews/CustomerReviewWorkspaceSmokeTest.php) as the single browser smoke proof and expand only the existing `tests/Feature/Reviews/*` family for the rest. **Rationale**: - The repo already has a browser harness for the review-detail-to-workspace handoff and calm disclosure checks. - The rest of the productization contract is better proven in focused feature tests for omission rules, access states, and audit metadata. - Adding a broader browser family would expand governance cost without clearer business proof. **Alternatives considered**: - Add multiple new browser tests for each proof path. - Rejected: too heavy for a bounded productization follow-up. - Rely on browser testing alone. - Rejected: feature tests remain the narrower proof for RBAC and disclosure-state coverage. ## Decision 10 — Keep the feature asset-light and non-search-expanding **Decision**: Do not add a new asset bundle, new panel assets, or any new global-search scope as part of this follow-up. **Rationale**: - The work is a content/disclosure/productization pass over existing Filament surfaces. - Existing review, review-pack, and evidence resources already avoid global-search exposure in this customer-safe path. - The user explicitly scoped out heavy asset strategy and new global-search work. **Alternatives considered**: - Add new visual infrastructure or customer-safe asset loading. - Rejected: no product need for this slice. - Add a new search entry point for the customer workspace. - Rejected: outside the tenant-safe reuse boundary and unnecessary for the current route.