Some checks failed
Main Confidence / confidence (push) Failing after 57s
## Summary - add a read-first governance inbox page at `/admin/governance/inbox` - aggregate assigned findings, intake, stale operations, alert-delivery failures, and review follow-up into one canonical routing surface - add focused coverage for inbox authorization, navigation context, page behavior, and section builder logic - include the Spec Kit artifacts for spec 250 ## Notes - branch is synced with `dev` - this PR supersedes #290 for the governance inbox work Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #291
5.8 KiB
5.8 KiB
Research: Decision-Based Governance Inbox v1
Date: 2026-04-28
Feature: 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
MyFindingsInboxandFindingsIntakeQueue. - 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.phpapps/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
Operationspage. - 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.phpapps/platform/app/Filament/Pages/Operations/TenantlessOperationRunViewer.phpapps/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.phpapps/platform/app/Filament/Resources/AlertDeliveryResource.phpapps/platform/app/Models/AlertDelivery.php
5. Use triage-review follow-up as the review-family signal
- Decision: The review section should derive from
TenantTriageReviewstates such asfollow_up_neededand 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.phpapps/platform/app/Models/TenantTriageReview.phpapps/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.phpapps/platform/app/Support/Navigation/RelatedNavigationResolver.phpapps/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
- findings sections require
- Explicit out-of-scope
tenant_idinputs return404.
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
- tenant-prefilter-hidden attention ->
- 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.