# Research: Tenant Operate Hub / Tenant Overview IA (Spec 085) **Date**: 2026-02-09 **Branch**: 085-tenant-operate-hub **Spec**: specs/085-tenant-operate-hub/spec.md This research consolidates repo evidence + the final clarification decisions, so the implementation plan and tests can be deterministic. ## Repository Evidence (high-signal) - Canonical monitoring pages already exist in the Admin panel: - Operations index: app/Filament/Pages/Monitoring/Operations.php - Run detail (tenantless viewer): app/Filament/Pages/Operations/TenantlessOperationRunViewer.php - Alerts: app/Filament/Pages/Monitoring/Alerts.php - Audit log: app/Filament/Pages/Monitoring/AuditLog.php - Tenant selection + clear tenant context already exist (UI + route/controller): - Context bar partial: resources/views/filament/partials/context-bar.blade.php - Tenant select controller: app/Http/Controllers/SelectTenantController.php ## Decisions (resolved) ### Decision: Tenant context may use last-tenant memory for cross-panel flows - Decision: “Tenant context is active” on Monitoring pages is resolved from the active Filament tenant when present, otherwise from the remembered last-tenant id for the current workspace. - Rationale: Central Monitoring routes are canonical and tenantless, but users enter them from the tenant panel and expect consistent scoping. - Alternatives considered: - Query param `?tenant=`: rejected (would introduce an implicit switching vector). ### Decision: “Show all tenants” explicitly exits tenant context - Decision: The CTA “Show all tenants” clears tenant context (single meaning) and returns the user to workspace-wide Monitoring. - Rationale: Prevents the confusing state where tenant context is still active but filters are reset. - Alternatives considered: - Only reset table filter: rejected (context remains active and confuses scope semantics). ### Decision: Stale tenant context is handled without leaks - Decision: If tenant context is active but the user is no longer entitled to that tenant, Monitoring pages behave as workspace-wide: - Scope shows `Workspace — all tenants` - No tenant name is shown - No “Back to tenant” is rendered - Tenant pages remain deny-as-not-found - Rationale: Preserves deny-as-not-found and avoids tenant existence hints. - Alternatives considered: - 404 the Monitoring page: rejected (feels like being “thrown out”). - Auto-clear tenant context implicitly: rejected (implicit context mutation). ### Decision: Run detail shows an explicit tenant return + secondary escape hatch - Decision: When tenant context is active and entitled, run detail shows: - `← Back to ` (tenant dashboard) - secondary `Show all operations` → `/admin/operations` - Rationale: “Back to tenant” is deterministic; the secondary link provides a canonical escape hatch. - Alternatives considered: - Only show `Back to tenant`: rejected by clarification (secondary escape hatch approved). ### Decision: Tenant panel navigation uses a “Monitoring” group with central shortcuts - Decision: Replace the tenant-panel “Operations” item with group “Monitoring” containing shortcuts: - Runs → `/admin/operations` - Alerts → `/admin/alerts` - Audit Log → `/admin/audit-log` - Rationale: Keep tenant sidebar labels minimal while still providing correct central Monitoring entry points, while preserving canonical URLs and avoiding tenant-scoped monitoring routes. - Alternatives considered: - New tenant-scoped monitoring routes: rejected (explicitly forbidden). ### Decision: “No outbound calls on render” is enforced by tests - Decision: Monitoring GET renders must not trigger outbound network calls or start background work as a side effect. - Rationale: Aligns with constitution (“Monitoring pages MUST be DB-only at render time”). - Alternatives considered: - Rely on convention: rejected; this needs regression protection. ## Open Questions None remaining for Phase 0. The spec clarifications cover all scope-affecting ambiguities.