TenantAtlas/specs/258-customer-review-productization/plan.md
ahmido 55338a88c6
Some checks failed
Main Confidence / confidence (push) Failing after 59s
merge: platform-dev into dev (#311)
## Summary
- sync platform-dev back into dev with the latest integrated feature and spec work
- include the customer review workspace productization flow and its related review, review-pack, evidence, audit, and test updates
- carry forward the recent governance and roadmap/spec updates already merged on platform-dev

## Included highlights
- customer review workspace productization and customer-safe released-review drilldown
- governance decision convergence work
- cross-tenant compare and promotion work
- external support desk handoff work
- product, roadmap, permissions, and spec artifact updates

## Validation context
- platform-dev currently contains the already-validated feature work from the merged branch PRs
- latest customer review workspace batch included focused Pest suites, one bounded browser smoke, and Pint

## Notes
- this is an integration PR from platform-dev into dev
- no separate provider-registration or asset-strategy expansion is introduced by the customer review workspace slice

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #311
2026-04-30 18:33:56 +00:00

302 lines
32 KiB
Markdown

# Implementation Plan: Customer Review Workspace Productization v1
**Branch**: `258-customer-review-productization` | **Date**: 2026-04-30 | **Spec**: [spec.md](spec.md)
**Input**: Feature specification from [spec.md](spec.md)
## Summary
Productize the existing customer review workspace into a calmer, customer-safe governance-of-record surface by tightening the current [../../apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php](../../apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php) page and the existing released-review drilldown in [../../apps/platform/app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php](../../apps/platform/app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php). The implementation should reuse current review, finding, accepted-risk, evidence, review-pack, localization, RBAC, and audit truth rather than adding a portal shell, new persistence, or a second presentation framework.
This is a bounded follow-up to Spec 249, not a fresh workspace foundation. Filament remains on Livewire v4 under v5, panel-provider registration stays where it is today in [../../apps/platform/bootstrap/providers.php](../../apps/platform/bootstrap/providers.php), no new panel or provider work is planned, no new globally searchable scope is introduced, no destructive actions are in scope, and no new asset registration strategy is expected.
## Technical Context
**Language/Version**: PHP 8.4, Laravel 12
**Primary Dependencies**: Filament v5, Livewire v4, Pest v4, existing review/evidence/review-pack services, capability helpers, localization copy, and workspace audit infrastructure
**Storage**: PostgreSQL via existing `tenant_reviews`, `review_packs`, `evidence_snapshots`, `finding_exceptions`, memberships, and `audit_logs`; no new persistence planned
**Testing**: Pest v4 feature coverage plus one bounded browser smoke slice on the existing workspace flow
**Validation Lanes**: confidence, browser
**Target Platform**: Laravel monolith in `apps/platform`, existing admin plane only (`/admin` plus existing tenant-scoped `/admin/t/{tenant}` reuse)
**Project Type**: Web application (Laravel monolith with Filament pages/resources)
**Performance Goals**: keep workspace and detail rendering DB-only and scope-safe, reuse eager-loaded existing review/pack/evidence relations, and avoid any new Graph calls, queue starts, or heavy asset work on render
**Constraints**: no new page shell, no new persistence, no review publishing engine, no remediation flow, no new customer identity plane, no new global-search scope, no new heavy asset strategy, and no destructive action exposure
**Scale/Scope**: 1 existing workspace page, 1 existing released-review detail page, 2 existing proof/detail resources, 2 localization files, 1 shared audit pipeline, and the existing `tests/Feature/Reviews/*` plus 1 existing browser smoke
## Likely Affected Repo Surfaces
- [../../apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php](../../apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php) for calmer workspace copy, derived summary semantics, explicit access or absence states, and table action hierarchy.
- [../../apps/platform/resources/views/filament/pages/reviews/customer-review-workspace.blade.php](../../apps/platform/resources/views/filament/pages/reviews/customer-review-workspace.blade.php) for the page intro and disclosure framing.
- [../../apps/platform/app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php](../../apps/platform/app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php) for the released-review secondary-context contract, customer-workspace query-flag behavior, and audit handoff.
- [../../apps/platform/app/Filament/Resources/TenantReviewResource.php](../../apps/platform/app/Filament/Resources/TenantReviewResource.php) for existing released-review detail sections, proof links, and current pack/evidence affordances.
- [../../apps/platform/app/Services/TenantReviews/TenantReviewRegisterService.php](../../apps/platform/app/Services/TenantReviews/TenantReviewRegisterService.php) for workspace membership, entitled tenant scoping, and latest-published review composition.
- [../../apps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php](../../apps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php) plus `SurfaceCompressionContext` for outcome, freshness, and publication wording already used by review and pack surfaces.
- [../../apps/platform/app/Filament/Resources/ReviewPackResource.php](../../apps/platform/app/Filament/Resources/ReviewPackResource.php), [../../apps/platform/app/Filament/Resources/ReviewPackResource/Pages/ViewReviewPack.php](../../apps/platform/app/Filament/Resources/ReviewPackResource/Pages/ViewReviewPack.php), and [../../apps/platform/app/Http/Controllers/ReviewPackDownloadController.php](../../apps/platform/app/Http/Controllers/ReviewPackDownloadController.php) for current pack availability, safe deep links, and signed download auditing.
- [../../apps/platform/app/Filament/Resources/EvidenceSnapshotResource.php](../../apps/platform/app/Filament/Resources/EvidenceSnapshotResource.php) and [../../apps/platform/app/Filament/Resources/EvidenceSnapshotResource/Pages/ViewEvidenceSnapshot.php](../../apps/platform/app/Filament/Resources/EvidenceSnapshotResource/Pages/ViewEvidenceSnapshot.php) for proof-pointer routing and explicit unavailable states.
- [../../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) for auditable workspace access, review access, proof access, and pack download behavior through the shared audit path.
- [../../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) for capability-first RBAC and workspace/tenant-safe omission rules.
- [../../apps/platform/lang/en/localization.php](../../apps/platform/lang/en/localization.php) and [../../apps/platform/lang/de/localization.php](../../apps/platform/lang/de/localization.php) for calmer customer-safe wording without introducing a second vocabulary system.
- [../../apps/platform/tests/Feature/Reviews/CustomerReviewWorkspacePageTest.php](../../apps/platform/tests/Feature/Reviews/CustomerReviewWorkspacePageTest.php), [../../apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceAuthorizationTest.php](../../apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceAuthorizationTest.php), [../../apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceNavigationContextTest.php](../../apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceNavigationContextTest.php), [../../apps/platform/tests/Feature/Reviews/CustomerReviewWorkspacePackAccessTest.php](../../apps/platform/tests/Feature/Reviews/CustomerReviewWorkspacePackAccessTest.php), [../../apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceLaunchLinksTest.php](../../apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceLaunchLinksTest.php), and [../../apps/platform/tests/Browser/Reviews/CustomerReviewWorkspaceSmokeTest.php](../../apps/platform/tests/Browser/Reviews/CustomerReviewWorkspaceSmokeTest.php) for the bounded proof surface already in the repo.
## UI / Filament & Livewire Fit
- Keep [../../apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php](../../apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php) as the canonical customer-safe landing surface. This follow-up productizes the existing page instead of adding a new page class, a new Resource, or a new panel.
- Keep [../../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 via the existing `customer_workspace` query flag. The drilldown should deepen the governance record, not reopen operator lifecycle controls.
- Preserve the current Livewire-safe filter and remembered-tenant behavior already implemented on the workspace page. Any added state must remain public, query-backed, or session-backed; no private state should control postback-critical disclosure.
- Retain one dominant next action per surface. On the workspace page that remains `Open released review`; pack download or proof routes stay secondary and capability-gated. On the detail page, review-pack access remains the dominant safe action while evidence proof stays lower priority.
- Keep the entire feature in native Filament primitives plus the existing review/evidence shared seams. No custom shell, no heavy asset registration, and no new global-search scope are planned.
## RBAC / Policy Fit
- Workspace membership remains the first isolation boundary through the existing workspace context and `TenantReviewRegisterService::canAccessWorkspace(...)` path.
- Entitled-tenant composition remains capability-first: page entry and rows continue to derive from the current role-capability map and `TENANT_REVIEW_VIEW` path rather than new customer-only roles or raw role-string checks.
- Proof pointers and safe secondary actions continue to reuse existing gates: `REVIEW_PACK_VIEW` for current pack download, `EVIDENCE_VIEW` for proof detail, `TENANT_FINDINGS_VIEW` and `FINDING_EXCEPTION_VIEW` for deeper review content when surfaced, and existing policy checks on review/evidence resources.
- Non-members and explicit out-of-scope tenant targets remain `404`. Member actors who can read the review surface but lack an optional deep-link capability should still see the review with an explicit unavailable state for that optional path.
- No new panel, tenant plane, customer portal plane, or identity model is introduced. This remains an admin-plane follow-up only.
## Audit / Logging Fit
- Reuse [../../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) for all auditable moments. No new audit store, no telemetry sidecar, and no page-local logging subsystem are justified.
- Current review access from the customer-workspace drilldown already logs `TenantReviewOpened` with `source_surface=customer_review_workspace`, and current pack downloads already log `ReviewPackDownloaded` through the signed download route.
- Planning should explicitly account for two remaining audit moments required by this spec: workspace access itself and evidence-summary or proof access when the actor opens an explicit proof route from the customer-safe flow. If those moments are not already covered, the narrowest acceptable change is additive stable action IDs on the existing audit pipeline.
- Passive rendering should still avoid noisy event spam. The auditable boundary is explicit workspace entry or explicit artifact/proof consumption, not every Livewire repaint.
## Data & Query Fit
- Keep the base row query on the existing `customerWorkspaceTenantQuery(...)` seam in [../../apps/platform/app/Services/TenantReviews/TenantReviewRegisterService.php](../../apps/platform/app/Services/TenantReviews/TenantReviewRegisterService.php). This feature productizes the presentation contract over that query; it does not replace it with a new projection.
- Findings and accepted-risk summaries remain derived from the current `TenantReview.summary` payload already used by the workspace page, including `finding_count`, `finding_outcomes`, and `risk_acceptance` substructures.
- Accepted-risk accountability follow-through should reuse existing `FindingException` and current decision truth where that data already exists. Missing accountable-person or accountable-role truth must surface as explicit partial or unavailable disclosure, not invented copy.
- Evidence proof semantics should stay anchored to existing `EvidenceSnapshot`, related context entries, and `ArtifactTruthPresenter` output. The feature may reorder or reword disclosure, but it should not create a second evidence summary model.
- Access, absence, unavailable, expired, and redacted states remain derived UI or route-state semantics only. They must not become new persisted lifecycle fields or a new presentation enum family.
## UI / Surface Guardrail Plan
- **Guardrail scope**: changed surfaces
- **Native vs custom classification summary**: native Filament
- **Shared-family relevance**: status messaging, evidence/report viewers, action links, navigation entry points, access-state messaging, and review-pack access affordances
- **State layers in scope**: page, detail, URL-query, table/session restore
- **Audience modes in scope**: customer/read-only, customer-admin, auditor-read-only, operator-MSP
- **Decision/diagnostic/raw hierarchy plan**: decision-first, diagnostics-second, support-raw-third
- **Raw/support gating plan**: collapsed and capability-gated on reused detail/proof routes only
- **One-primary-action / duplicate-truth control**: `Open released review` remains the workspace primary action; review-pack access is the detail primary action; equal-priority duplicate summary blocks across workspace and detail are out of scope
- **Handling modes by drift class or surface**: review-mandatory
- **Repository-signal treatment**: review-mandatory
- **Special surface test profiles**: standard-native-filament, shared-detail-family
- **Required tests or manual smoke**: functional-core, state-contract, bounded-browser-smoke
- **Exception path and spread control**: none planned; any new presenter/taxonomy/customer-shell proposal becomes exception-required drift
- **Active feature PR close-out entry**: Guardrail / Smoke Coverage
## Shared Pattern & System Fit
- **Cross-cutting feature marker**: yes
- **Systems touched**: `CustomerReviewWorkspace`, `ViewTenantReview`, `TenantReviewResource`, `ReviewPackResource`, `EvidenceSnapshotResource`, `TenantReviewRegisterService`, `ArtifactTruthPresenter`, `SurfaceCompressionContext`, `ActionSurfaceDeclaration`, `ReviewPackDownloadController`, `WorkspaceAuditLogger`, `AuditActionId`, and review localization copy
- **Shared abstractions reused**: `TenantReviewRegisterService`, `ArtifactTruthPresenter`, `SurfaceCompressionContext`, existing resource URL helpers, existing action-surface declarations, `ReviewPackService`, and the shared audit logger
- **New abstraction introduced? why?**: none planned. If implementation discovers a small copy or disclosure helper is needed, it should stay inside the existing review surface family instead of becoming a new reusable framework
- **Why the existing abstraction was sufficient or insufficient**: the repo already has the page, detail route, truth envelopes, pack download path, and audit seams; what is insufficient today is the product contract over those seams, not the underlying domain model
- **Bounded deviation / spread control**: none planned. This slice should tighten the current path rather than add a parallel customer-review language, mirror page, or publication layer
## OperationRun UX Impact
- **Touches OperationRun start/completion/link UX?**: no
- **Central contract reused**: `N/A`
- **Delegated UX behaviors**: `N/A`
- **Surface-owned behavior kept local**: read-only workspace and detail rendering only; any existing operation-run links remain secondary diagnostics on reused detail surfaces
- **Queued DB-notification policy**: `N/A`
- **Terminal notification path**: `N/A`
- **Exception path**: none
## Provider Boundary & Portability Fit
- **Shared provider/platform boundary touched?**: no
- **Provider-owned seams**: `N/A`
- **Platform-core seams**: existing workspace, tenant, review, evidence, risk acceptance, review pack, and audit vocabulary only
- **Neutral platform terms / contracts preserved**: `workspace`, `tenant`, `review`, `evidence`, `review pack`, `accepted risk`, `proof`, and existing artifact-truth wording
- **Retained provider-specific semantics and why**: none new
- **Bounded extraction or follow-up path**: `N/A`
## Constitution Check
*GATE: Must pass before implementation preparation continues. Re-check after Phase 1 design artifacts.*
- Inventory-first / snapshot truth: PASS. The slice consumes existing review, pack, and evidence artifacts as read-only truth.
- Read/write separation: PASS. No new create, publish, regenerate, refresh, remediation, or destructive flow is introduced.
- Graph contract path: PASS. No new Graph work or provider contract work is part of this slice.
- Deterministic capabilities: PASS. Existing capability registries and role maps remain authoritative.
- Workspace and tenant isolation: PASS. Workspace membership and tenant entitlement remain non-negotiable `404` boundaries.
- RBAC-UX plane separation: PASS. Everything stays in the existing `/admin` plane and current tenant-scoped detail routes.
- Destructive confirmation standard: PASS by non-use. Destructive actions are out of scope.
- Global search safety: PASS. No new globally searchable resource or search scope is added; any mention of search remains tenant-safe reuse only.
- OperationRun / Ops-UX: PASS by non-use. The productization slice starts no runs and changes no run lifecycle UX.
- Data minimization: PASS. Default-visible content remains decision-first; raw payloads and unrestricted diagnostics stay gated.
- Test governance (TEST-GOV-001): PASS. Planned proof stays in focused feature coverage plus one bounded browser smoke.
- Proportionality / no premature abstraction: PASS. The feature productizes existing surfaces instead of adding persistence, a shell, or a second presenter framework.
- Persisted truth (PERSIST-001): PASS. No new table, artifact, or cache is planned.
- Behavioral state (STATE-001): PASS. Access, absence, unavailable, expired, and redacted conditions remain derived presentation semantics.
- UI semantics / shared pattern first / Filament-native UI: PASS. Native Filament pages/resources and existing truth abstractions remain the default path.
- Provider boundary (PROV-001): PASS. No provider/platform seam widens.
- Filament / Laravel planning contract: PASS. Filament v5 stays on Livewire v4, provider registration remains in [../../apps/platform/bootstrap/providers.php](../../apps/platform/bootstrap/providers.php), no new panel/provider work is planned, no new global-search scope is created, and asset handling stays unchanged (`cd apps/platform && php artisan filament:assets` remains deploy-only if future registered assets are ever added).
**Gate evaluation**: PASS.
- The feature stays in the existing admin plane and current workspace/tenant membership model.
- The canonical entry surface remains the existing customer review workspace, not a new shell.
- Existing truth seams are sufficient if implementation resists adding a mirror presenter or publication engine.
**Post-design re-check**: PASS (design artifacts: [research.md](research.md), [data-model.md](data-model.md), [quickstart.md](quickstart.md), [contracts/customer-review-productization.openapi.yaml](contracts/customer-review-productization.openapi.yaml)).
## Test Governance Check
- **Test purpose / classification by changed surface**: Feature for workspace rows, access/absence/unavailable states, navigation context, pack access, and audit metadata; Browser for one bounded end-to-end calm disclosure path on the existing workspace handoff
- **Affected validation lanes**: confidence, browser
- **Why this lane mix is the narrowest sufficient proof**: the repo already has the exact workspace feature family and a single smoke harness; expanding those files is cheaper and more honest than adding new browser families or generalized helpers
- **Narrowest proving command(s)**:
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Reviews/CustomerReviewWorkspacePageTest.php tests/Feature/Reviews/CustomerReviewWorkspaceAuthorizationTest.php tests/Feature/Reviews/CustomerReviewWorkspaceLaunchLinksTest.php`
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Reviews/CustomerReviewWorkspaceNavigationContextTest.php tests/Feature/TenantReview/TenantReviewUiContractTest.php tests/Feature/TenantReview/TenantReviewExplanationSurfaceTest.php tests/Feature/Reviews/CustomerReviewWorkspacePackAccessTest.php tests/Feature/ReviewPack/ReviewPackDownloadTest.php tests/Feature/ReviewPack/ReviewPackResourceTest.php tests/Feature/Evidence/EvidenceSnapshotResourceTest.php tests/Feature/Evidence/EvidenceSnapshotAuditLogTest.php`
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Reviews/CustomerReviewWorkspaceSmokeTest.php`
- **Fixture / helper / factory / seed / context cost risks**: moderate but contained; reuse existing workspace membership, entitled-tenant, published review, finding-exception, evidence snapshot, review pack, and audit fixtures
- **Expensive defaults or shared helper growth introduced?**: no; any new helper should stay explicit and inside the reviews family
- **Heavy-family additions, promotions, or visibility changes**: none beyond the already-existing single browser smoke
- **Surface-class relief / special coverage rule**: standard-native-filament relief on the workspace page, shared-detail-family coverage on the released-review handoff
- **Closing validation and reviewer handoff**: rerun the focused commands above, verify customer-safe default visibility, verify `404` on out-of-scope tenant targeting, verify optional proof paths show explicit unavailable states instead of leaking content, and verify audit metadata stays on the shared logger path
- **Budget / baseline / trend follow-up**: none expected beyond small feature-local assertions in the existing reviews suite
- **Review-stop questions**: lane fit, hidden fixture growth, browser sprawl, duplicate-truth regressions, audit-gap drift
- **Escalation path**: `document-in-feature` for contained audit metadata placement notes; `reject-or-split` for any drift into new persistence, portal scope, or expanded browser coverage
- **Active feature PR close-out entry**: Guardrail / Smoke Coverage
- **Why no dedicated follow-up spec is needed**: this is already the bounded follow-up to Spec 249; remaining work stays inside this productization lane unless it tries to become publishing/remediation/portal scope
## Rollout & Risk Controls
- Keep the canonical entry surface on the existing workspace page and the canonical secondary surface on the existing released-review detail route.
- Keep all proof and packaged artifact flows on the existing tenant review, review-pack, and evidence routes. Do not add a new proof viewer or download endpoint.
- Treat missing accountability truth or missing proof availability as explicit partial or unavailable disclosure, never as fabricated customer-safe copy.
- Prefer localization-key updates in the existing review language namespace over page-local inline wording.
- Keep browser validation bounded to the existing smoke harness before considering any wider UI rollout.
## Guardrail / Smoke Coverage Close-Out
- **Close-out date**: 2026-04-30
- **Confidence lane**: PASS via the focused customer-workspace, TenantReview detail, ReviewPack, EvidenceSnapshot, audit, capability, and download feature suites listed in [quickstart.md](quickstart.md).
- **Browser lane**: PASS via the bounded customer-review workspace smoke test. Tested path: `/admin/reviews/workspace` as a readonly-capable actor, released review row visibility, customer-safe pack/proof availability labels, workspace-to-detail handoff, and customer-safe released-review detail text.
- **Audit-gap outcome**: bounded additive action IDs were required for explicit workspace entry and proof-open events (`customer_review_workspace.opened`, `evidence_snapshot.opened`). Existing `tenant_review.opened` and `review_pack.downloaded` paths were reused with `source_surface=customer_review_workspace`.
- **Localization / copy outcome**: contained to the existing review localization namespace in English and German; no new vocabulary framework or page-local copy layer was introduced.
- **Global-search safety outcome**: no new globally searchable resource or search scope was introduced. Touched review, pack, and evidence resources remain on their existing tenant-scoped resource paths and customer-workspace query context.
- **Follow-up decision**: no `follow-up-spec` is required for the implemented scope. Broader portal, publication, remediation, baseline/control overlays, and management-packaging expansion remain outside this feature.
## Project Structure
### Documentation (this feature)
```text
specs/258-customer-review-productization/
├── checklists/
│ └── requirements.md
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
│ └── customer-review-productization.openapi.yaml
└── tasks.md # Created later by /speckit.tasks, not by this plan step
```
### Source Code (repository root)
```text
apps/platform/
├── app/
│ ├── Filament/
│ │ ├── Pages/Reviews/
│ │ │ └── CustomerReviewWorkspace.php
│ │ └── Resources/
│ │ ├── TenantReviewResource.php
│ │ ├── TenantReviewResource/Pages/ViewTenantReview.php
│ │ ├── ReviewPackResource.php
│ │ ├── ReviewPackResource/Pages/ViewReviewPack.php
│ │ ├── EvidenceSnapshotResource.php
│ │ └── EvidenceSnapshotResource/Pages/ViewEvidenceSnapshot.php
│ ├── Http/Controllers/ReviewPackDownloadController.php
│ ├── Models/
│ │ ├── TenantReview.php
│ │ ├── ReviewPack.php
│ │ ├── EvidenceSnapshot.php
│ │ └── FindingException.php
│ ├── Services/
│ │ ├── Audit/WorkspaceAuditLogger.php
│ │ └── TenantReviews/TenantReviewRegisterService.php
│ ├── Support/
│ │ ├── Audit/AuditActionId.php
│ │ ├── Auth/Capabilities.php
│ │ └── Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php
├── lang/
│ ├── de/localization.php
│ └── en/localization.php
├── bootstrap/providers.php
├── resources/views/filament/pages/reviews/customer-review-workspace.blade.php
└── tests/
├── Browser/Reviews/CustomerReviewWorkspaceSmokeTest.php
├── Feature/ReviewPack/ReviewPackDownloadTest.php
└── Feature/Reviews/
```
**Structure Decision**: Laravel monolith. The implementation stays inside the existing `apps/platform` reviews, review-pack, evidence, localization, and audit surfaces, with no new panel/provider locations and no new persistence layer.
## Complexity Tracking
| Violation | Why Needed | Simpler Alternative Rejected Because |
|-----------|------------|-------------------------------------|
| None expected at planning time | The intended implementation is a productization pass over existing pages, routes, copy, and audit seams | Adding a portal, new presenter layer, or persisted customer-review projection would import unnecessary structure |
## Proportionality Review
- **Current operator problem**: the repo already has customer-review truth, but the current workspace and drilldown still feel too operator-led and under-explain accountability, proof, and unavailable states for a customer-safe governance record.
- **Existing structure is insufficient because**: Spec 249 created the canonical entry route, but the product contract across workspace summary, released-review detail, proof pointers, pack access, and auditable access semantics is still incomplete.
- **Narrowest correct implementation**: tighten the existing workspace page, released-review detail, proof affordances, localization copy, and shared audit metadata without adding a new page shell, persistence, or customer-specific presenter family.
- **Ownership cost created**: limited copy/disclosure maintenance on existing surfaces, a small extension to focused tests, and at most bounded additive audit action IDs if current coverage is incomplete.
- **Alternative intentionally rejected**: a new portal, publication engine, remediation flow, or second customer-review explanation framework was rejected because the repo already has the required read-only truth seams.
- **Release truth**: current-release productization follow-up to Spec 249.
## Phase 0 — Research (output: research.md)
Research resolves the remaining implementation-shaping decisions:
- keep the existing `CustomerReviewWorkspace` page as the canonical customer-safe landing surface
- keep `ViewTenantReview` as the secondary detail surface under the current `customer_workspace` query flag
- reuse existing localization, artifact-truth, and accepted-risk seams instead of adding a second vocabulary
- keep workspace and tenant isolation on the current capability-first RBAC paths
- reuse the existing audit pipeline and identify only the bounded missing access moments that may need additive action IDs
- keep browser coverage bounded to the existing workspace smoke path and focused feature tests
**Output**: [research.md](research.md)
## Phase 1 — Design (outputs: data-model.md, contracts/, quickstart.md)
Design artifacts capture the narrow productization shape:
- no new persistence; reused truth stays in tenant reviews, finding exceptions, review packs, evidence snapshots, memberships, and audit logs
- one derived workspace presentation contract and one derived released-review disclosure contract document the existing surfaces without becoming stored entities
- the conceptual contract documents current workspace, review detail, proof, and pack-download route expectations plus explicit access/absence/unavailable semantics
- quickstart records the intended implementation order, bounded validation commands, Filament v5 / Livewire v4 posture, provider-registration location, and no-new-assets expectation
**Artifacts**:
- [data-model.md](data-model.md)
- [contracts/customer-review-productization.openapi.yaml](contracts/customer-review-productization.openapi.yaml)
- [quickstart.md](quickstart.md)
## Phase 2 — Planning (for tasks.md)
Dependency-ordered implementation outline for the later `tasks.md` step:
1. Tighten the existing workspace page and Blade intro so the default-visible path is calm, customer-safe, and explicit about absence/unavailable states.
2. Tighten the existing released-review detail flow under the `customer_workspace` context flag so it remains read-only and deepens understanding without exposing operator lifecycle actions.
3. Reuse existing review summary, finding outcome, accepted-risk, proof, and pack truth to improve explanation quality and customer-safe disclosure hierarchy without adding a second presenter or new persistence.
4. Align proof pointers and review-pack affordances so optional deep links are capability-gated and unavailable states are explicit.
5. Reuse the shared audit pipeline for workspace access, review access, proof access, and pack downloads, adding only bounded audit registry entries if the current actions do not cover required moments.
6. Expand the focused review feature suite and keep the single existing browser smoke as the only browser proof for this slice.
## Planning Guardrail Notes
- Planning guardrail result: PASS. Filament remains v5 on Livewire v4, panel providers remain in [../../apps/platform/bootstrap/providers.php](../../apps/platform/bootstrap/providers.php), no new global-search scope is introduced, no destructive action is added, and no new asset bundle is planned.
- Shared seam result: the plan stays on existing page/resource/service/audit seams, not a new customer-review framework.
- Smoke plan: the existing [../../apps/platform/tests/Browser/Reviews/CustomerReviewWorkspaceSmokeTest.php](../../apps/platform/tests/Browser/Reviews/CustomerReviewWorkspaceSmokeTest.php) remains the single bounded browser proof.
- Agent context update: intentionally skipped during this plan pass because the feature introduces no new technology and the user requested preparation-artifact-only changes.