8.2 KiB
Implementation Plan: Tenant Review Layer
Branch: 155-tenant-review-layer | Date: 2026-03-20 | Spec: 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
/adminand tenant-safe. Non-member access is 404, member-but-missing-capability is 403. No/systemplane overlap is introduced. - Workspace isolation: PASS. All review records are tenant-owned with
workspace_idandtenant_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
OperationRunfor 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
OperationRuntransitions remain inOperationRunService; 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)
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)
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
TenantReviewtenant-owned and avoids persisting tenant data in workspace-owned templates or registers. - Evidence foundation boundary: PASS. Review records consume
EvidenceSnapshotand 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.