# Research: Decision-Based Governance Inbox v1 **Date**: 2026-04-28 **Feature**: [spec.md](spec.md) ## Decision Summary The repo already contains the underlying governance attention signals. The missing product slice is not another source page or another workflow state, but one bounded decision-first page that composes the existing source seams into a calm workspace starting point. ## Key Decisions ### 1. Use section-based composition, not a generic task engine - **Decision**: Build the inbox as one read-only Filament page with bounded family sections and preview entries. - **Why**: A polymorphic table or persisted inbox-item model would import a second workflow truth before the first read-only operator surface is proven. - **Repo truth**: Findings, operations, alerts, and review follow-up already have their own truthful pages and models. ### 2. Reuse findings queue semantics directly - **Decision**: The assigned-findings and intake sections should reuse the inclusion and urgency rules already owned by `MyFindingsInbox` and `FindingsIntakeQueue`. - **Why**: Those pages already codify open-status filtering, tenant entitlement, urgency ordering, and calm empty states. - **Source seams**: - `apps/platform/app/Filament/Pages/Findings/MyFindingsInbox.php` - `apps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.php` ### 3. Use stale or terminal-follow-up operations as the operations-family signal - **Decision**: The operations section should derive from the same stale or follow-up attention rules already exposed on the canonical `Operations` page. - **Why**: The repo already has a canonical operations monitoring surface and run-detail route; the inbox should route into it instead of inventing a second operations diagnostic layer. - **Source seams**: - `apps/platform/app/Filament/Pages/Monitoring/Operations.php` - `apps/platform/app/Filament/Pages/Operations/TenantlessOperationRunViewer.php` - `apps/platform/app/Support/OperationRunLinks.php` ### 4. Keep the alert-family slice narrow: failed alert deliveries, not alert-rule config - **Decision**: The alerts section should surface delivery failures or similar operator-attention alert outcomes, not alert-rule configuration. - **Why**: Delivery failure is the actionable alerting gap that belongs in an attention inbox. Alert-rule editing stays a configuration workflow on its existing surfaces. - **Source seams**: - `apps/platform/app/Filament/Pages/Monitoring/Alerts.php` - `apps/platform/app/Filament/Resources/AlertDeliveryResource.php` - `apps/platform/app/Models/AlertDelivery.php` ### 5. Use triage-review follow-up as the review-family signal - **Decision**: The review section should derive from `TenantTriageReview` states such as `follow_up_needed` and changed-since-review semantics. - **Why**: The repo already distinguishes review follow-up from the underlying review artifact; the inbox should reuse that distinction rather than invent a second attention reason model. - **Source seams**: - `apps/platform/app/Services/PortfolioTriage/TenantTriageReviewService.php` - `apps/platform/app/Models/TenantTriageReview.php` - `apps/platform/app/Filament/Resources/TenantReviewResource.php` ### 6. Preserve navigation continuity through shared context helpers - **Decision**: Every section and preview entry should use existing navigation helpers for back links and canonical destinations. - **Why**: The inbox only reduces attention load if it preserves return context instead of opening detached utility flows. - **Source seams**: - `apps/platform/app/Support/Navigation/CanonicalNavigationContext.php` - `apps/platform/app/Support/Navigation/RelatedNavigationResolver.php` - `apps/platform/app/Support/OperateHub/OperateHubShell.php` ### 7. Keep the inbox read-only in v1 - **Decision**: No claim, snooze, acknowledge, assign, or triage mutations are introduced on the inbox page. - **Why**: Those mutations already belong to source surfaces and would force the inbox to become a second workflow owner. - **Result**: The inbox remains a decision hub, not an execution surface. ## Access Model Decision - Workspace membership remains the first gate. - The page only needs to exist for actors who can already see at least one family. - Rows and counts must stay family-specific: - findings sections require `Capabilities::TENANT_FINDINGS_VIEW` - review follow-up requires `Capabilities::TENANT_REVIEW_VIEW` - alert-family sections require `Capabilities::ALERTS_VIEW` - source mutations remain on source pages with their existing capabilities - Explicit out-of-scope `tenant_id` inputs return `404`. ## Rejected Alternatives ### Rejected: persisted inbox-item table - **Reason**: adds durable workflow truth, migration cost, audit burden, and new lifecycle semantics before the read-only composition page is proven. ### Rejected: generic cross-domain work-item abstraction - **Reason**: over-generalizes five concrete families into a second vocabulary and invites a platform-level task framework that current-release truth does not require. ### Rejected: extend one existing page instead of adding a canonical inbox - **Reason**: no single existing page can truthfully host all five families without becoming the wrong domain owner. ## Implications For Implementation - Prefer one bounded `Support/GovernanceInbox/` seam only if page-local composition becomes unreadable. - Keep source-family labels close to existing UI copy to avoid a second UX language. - Keep empty states honest: - tenant-prefilter-hidden attention -> `Clear tenant filter` - globally calm -> one neutral workspace return CTA - Do not add page-level audit noise for mere page views. ## Planning Outcome The smallest viable implementation slice is one new read-only workspace page that reuses existing source-page queries, existing navigation helpers, and existing capability semantics. No new persistence or mutation lane is justified.