# Research: Tenant Review Layer ## Decision 1: Model the review layer as a new tenant-owned aggregate - **Decision**: Introduce a dedicated `TenantReview` aggregate as the primary recurring review record, separate from `EvidenceSnapshot` and separate from `ReviewPack` export artifacts. - **Rationale**: The codebase already distinguishes evidence curation from stakeholder export. `EvidenceSnapshot` is a data-curation substrate with completeness/freshness semantics, while `ReviewPack` is an export artifact with file retention and download behavior. The missing concept is the recurring governance review itself: a curated, inspectable, publishable tenant review that can remain intelligible and historically stable over time. - **Alternatives considered**: - Reuse `EvidenceSnapshot` directly as the review record: rejected because evidence snapshots intentionally stop at curated inputs and do not own executive summary composition or review lifecycle. - Reuse `ReviewPack` directly as the review record: rejected because `ReviewPack` is file/export-oriented and does not provide a durable, inspectable in-product review aggregate. ## Decision 2: Reuse the existing review-pack export pipeline instead of inventing a second export model - **Decision**: Keep `ReviewPack` as the export/download artifact pattern and link it to `TenantReview` in the first slice instead of creating a second export model. - **Rationale**: The current code already has deterministic fingerprinting, `OperationRun` integration, retention/expiry, signed downloads, and Filament surfaces for review-pack artifacts. Reusing that pipeline minimizes churn and lets the new review layer focus on composition, publication, and executive inspection rather than rebuilding artifact storage from scratch. - **Alternatives considered**: - New `ExecutiveReviewPack` table and controller: rejected because it duplicates status, file, retention, and async-export concerns that `ReviewPack` already solves. - Inline synchronous file generation from review detail: rejected because it violates current Ops-UX and export-artifact patterns. ## Decision 3: Store ordered review sections as child records, not one opaque JSON blob - **Decision**: Represent section-level review composition as `TenantReviewSection` child rows under `TenantReview`, each with a section key, ordering, completeness state, and summary payload. - **Rationale**: Existing evidence uses `EvidenceSnapshotItem` child rows for ordered dimensions with their own metadata. The review layer has similar needs: ordered sections, per-section completeness, selective rendering, and future section-level evolution. Child rows keep section logic explicit and reduce coupling to one large JSON document. - **Alternatives considered**: - Single JSONB payload on `TenantReview`: rejected because it obscures section ordering and completeness as first-class data and makes future section-level evolution more brittle. - One table per section type: rejected as over-modeled for the first slice. ## Decision 4: Keep publish and archive synchronous, but make composition and export asynchronous - **Decision**: Review composition and executive-pack export may use `OperationRun`; publish and archive remain synchronous audited DB mutations. - **Rationale**: Composition and export can involve section assembly, pack rendering, and file persistence, which fit the existing async pattern. Publish and archive are governance-state transitions and should behave like explicit DB-backed lifecycle mutations with immediate auditability. - **Alternatives considered**: - Make every lifecycle action asynchronous: rejected because publish/archive do not need background processing and would add unnecessary Monitoring noise. - Make export synchronous: rejected because the repo already treats pack generation as an observable background operation. ## Decision 5: Canonical workspace review surface is a register, not a tenantless detail viewer - **Decision**: In v1, `/admin/reviews` is a workspace-scoped canonical register with tenant-safe filtering and row-level drill-down back into tenant-scoped review detail. - **Rationale**: This matches the current boundary used by other tenant-owned domains: canonical workspace context can safely summarize and list entitled tenant records, while authoritative inspection remains tenant-scoped. This lowers tenant-leak risk and aligns with the existing middleware and tenant-owned query-scoping model. - **Alternatives considered**: - Add a fully tenantless canonical review detail viewer under `/admin/reviews/{review}`: rejected for the first slice because it introduces extra tenant-resolution and wrong-tenant guard complexity before the domain proves its value. - Keep everything tenant-only with no canonical register: rejected because recurring review management across multiple tenants is a core requirement. ## Decision 6: Treat review publication readiness as review completeness, not compliance readiness - **Decision**: Publication/export gating is based on review completeness and required section presence, not on BSI, NIS2, or CIS mapping. - **Rationale**: The spec explicitly defers Compliance Readiness. The first slice needs an internal readiness rule for “is this review good enough to publish/export?” without collapsing into framework-oriented compliance scoring. - **Alternatives considered**: - Add lightweight framework labels now: rejected because even “lightweight” framework mapping would blur the product boundary the spec intentionally separates. - Allow publish/export regardless of completeness: rejected because it would undermine stakeholder trust in the executive pack.