# Implementation Plan: Tenant Review Layer **Branch**: `155-tenant-review-layer` | **Date**: 2026-03-20 | **Spec**: [spec.md](./spec.md) **Input**: Feature specification from `/specs/155-tenant-review-layer/spec.md` **Note**: This plan covers the first delivery slice for Executive Review Packs / Tenant Review Layer and intentionally excludes later Compliance Readiness, MSP portfolio rollups, and cross-tenant compare. ## Summary Introduce a first-class tenant-owned review aggregate that anchors one recurring tenant review to a chosen evidence snapshot, renders ordered executive-facing review sections, and reuses the existing review-pack export pipeline for stakeholder delivery. The implementation keeps review preparation and review inspection DB-backed and tenant-safe, uses `OperationRun` only for long-running composition/export work, preserves immutable published review history, and exposes a workspace-scoped canonical review register without introducing framework-oriented readiness scoring. ## Technical Context **Language/Version**: PHP 8.4, Laravel 12, Livewire 4, Filament 5 **Primary Dependencies**: Filament resources/pages/actions, Eloquent models, queued Laravel jobs, existing `EvidenceSnapshotService`, existing `ReviewPackService`, capability registry, `OperationRunService` **Storage**: PostgreSQL with JSONB-backed summary payloads and tenant/workspace ownership columns **Testing**: Pest feature tests, Livewire/Filament page tests, policy/authorization tests, operation-run regression coverage **Target Platform**: Laravel Sail web application with tenant/admin Filament panel and workspace-admin canonical routes **Project Type**: Laravel monolith with Filament admin UI and queued background jobs **Performance Goals**: Tenant review create/refresh/export actions enqueue or complete intent feedback in under 2 seconds; review list/detail render from DB-backed precomputed data with no live Graph calls; stakeholder pack generation remains asynchronous **Constraints**: No live Microsoft Graph collection during review preparation or export; published reviews remain immutable; tenant/workspace isolation stays strict with 404/403 semantics; long-running work must use `OperationRun`; destructive lifecycle actions require confirmation **Scale/Scope**: One new tenant-owned aggregate (`TenantReview`) with ordered section data, one workspace-scoped canonical review register, one tenant-scoped review library/detail flow, and reuse of the existing export artifact pipeline for executive packs ## Constitution Check *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* - **Inventory-first, Snapshots-second**: PASS. Tenant reviews consume evidence snapshots and stored governance summaries as the last observed substrate. They do not replace inventory or evidence snapshots and do not create a second mutable evidence truth. - **Read/write separation**: PASS. Review inspection is read-only. Review creation/refresh/publish/archive/export are explicit mutations with audit logging; archive is destructive-like and requires confirmation. No silent mutation of published reviews is allowed. - **Graph contract path**: PASS. The feature does not add Microsoft Graph calls. Review generation reads existing DB-backed evidence and review data only. - **Deterministic capabilities**: PASS. New review capabilities will be added to the central capability registry and tested through policies/UI enforcement helpers. - **RBAC-UX**: PASS. Tenant review library/detail live in the tenant/admin plane; workspace review register remains canonical `/admin` and tenant-safe. Non-member access is 404, member-but-missing-capability is 403. No `/system` plane overlap is introduced. - **Workspace isolation**: PASS. All review records are tenant-owned with `workspace_id` and `tenant_id`; canonical register only lists reviews for tenants the actor is entitled to in the selected workspace context. - **Tenant isolation**: PASS. Every review read/write resolves through tenant-owned scoping. No tenantless direct ID shortcut is introduced for review detail. - **Run observability**: PASS. Review create/refresh/export may create or reuse `OperationRun` for long-running composition/export. Publish and archive remain synchronous DB-backed actions with audit logs, not runs. - **Ops-UX 3-surface feedback**: PASS. Asynchronous review composition/export will use the existing pattern: intent-only toast, progress in active ops and Monitoring run detail, one terminal completion notification via `OperationRunCompleted`. - **Ops-UX lifecycle ownership**: PASS. Any `OperationRun` transitions remain in `OperationRunService`; the review feature will not update status/outcome directly. - **Ops-UX summary counts**: PASS. New review/export runs will use allowed numeric keys only, likely limited to section count, completed sections, and exported artifact count if needed. - **Ops-UX guards**: PASS. Existing regression guard patterns remain applicable; new operation types must be covered where added. - **Automation/idempotency**: PASS. Create/refresh/export flows will reuse fingerprint/dedup semantics to prevent duplicate active work or duplicate artifacts from unchanged review state. - **Data minimization**: PASS. Review summaries store stakeholder-ready summaries and source references, not raw evidence payload dumps or secrets. - **Badge semantics (BADGE-001)**: PASS. New review lifecycle/publication/readiness badges will extend centralized badge domains instead of adding page-local color mappings. - **UI naming (UI-NAMING-001)**: PASS. Primary operator verbs remain `Create review`, `Refresh review`, `Publish review`, `Export executive pack`, `Archive review`. - **Filament Action Surface Contract**: PASS with explicit design choice. Tenant review list/detail and workspace register will use clickable-row inspection, no lone view action, no bulk actions in v1, and confirmation for archive. - **Filament UX-001**: PASS. Detail uses Infolist-style inspection, lists include scoped filters/search/sort, and empty states have one CTA. ## Project Structure ### Documentation (this feature) ```text specs/155-tenant-review-layer/ ├── plan.md ├── research.md ├── data-model.md ├── quickstart.md ├── contracts/ │ └── review-layer.openapi.yaml └── tasks.md ``` ### Source Code (repository root) ```text app/ ├── Filament/ │ ├── Pages/ │ ├── Resources/ │ └── Widgets/ ├── Http/Controllers/ ├── Jobs/ ├── Models/ ├── Policies/ ├── Services/ │ └── Evidence/ └── Support/ ├── Auth/ ├── Badges/ └── WorkspaceIsolation/ database/ ├── factories/ └── migrations/ routes/ └── web.php tests/ ├── Feature/ └── Unit/ ``` **Structure Decision**: Use the existing Laravel monolith structure. Add the new review aggregate under `app/Models`, review orchestration under `app/Services`, review/export jobs under `app/Jobs`, tenant/admin and canonical review surfaces under `app/Filament`, new migrations under `database/migrations`, route glue under `routes/web.php` only where signed downloads or canonical register endpoints are needed, and Pest coverage under `tests/Feature` plus targeted unit tests for composition/fingerprint logic. ## Complexity Tracking | Violation | Why Needed | Simpler Alternative Rejected Because | |-----------|------------|-------------------------------------| | None | N/A | N/A | ## Post-Design Constitution Re-check - **Ownership model**: PASS. The design keeps `TenantReview` tenant-owned and avoids persisting tenant data in workspace-owned templates or registers. - **Evidence foundation boundary**: PASS. Review records consume `EvidenceSnapshot` and related summaries but do not replace evidence-domain storage. - **Compliance readiness boundary**: PASS. Framework mapping and compliance scoring remain deferred; this slice only defines recurring tenant review and executive pack composition. - **Operations UX boundary**: PASS. Only composition/export use `OperationRun`; review lifecycle DB mutations remain audited synchronous actions. - **RBAC / tenant safety**: PASS. Canonical register remains list-only and tenant-safe; detail inspection stays tenant-scoped.