TenantAtlas/apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceExemptions.php
2026-04-13 09:46:47 +02:00

953 lines
47 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Support\Ui\ActionSurface;
use App\Filament\Pages\BreakGlassRecovery;
use App\Filament\Pages\ChooseTenant;
use App\Filament\Pages\ChooseWorkspace;
use App\Filament\Pages\BaselineCompareLanding;
use App\Filament\Pages\BaselineCompareMatrix;
use App\Filament\Pages\Monitoring\Alerts;
use App\Filament\Pages\Monitoring\AuditLog;
use App\Filament\Pages\Monitoring\EvidenceOverview;
use App\Filament\Pages\Monitoring\FindingExceptionsQueue;
use App\Filament\Pages\Monitoring\Operations;
use App\Filament\Pages\Operations\TenantlessOperationRunViewer;
use App\Filament\Pages\Reviews\ReviewRegister;
use App\Filament\Pages\TenantDashboard;
use App\Filament\Pages\TenantDiagnostics;
use App\Filament\Pages\Tenancy\RegisterTenant;
use App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard;
use App\Filament\Pages\Workspaces\ManagedTenantsLanding;
use App\Filament\Resources\AlertDeliveryResource\Pages\ListAlertDeliveries;
use App\Filament\Resources\AlertDestinationResource\Pages\ViewAlertDestination;
use App\Filament\Resources\BackupSetResource\Pages\ViewBackupSet;
use App\Filament\Resources\BaselineProfileResource\Pages\ViewBaselineProfile;
use App\Filament\Resources\BaselineSnapshotResource\Pages\ViewBaselineSnapshot;
use App\Filament\Resources\EvidenceSnapshotResource\Pages\ViewEvidenceSnapshot;
use App\Filament\Resources\FindingExceptionResource\Pages\ViewFindingException;
use App\Filament\Resources\FindingResource\Pages\ViewFinding;
use App\Filament\Resources\PolicyVersionResource\Pages\ViewPolicyVersion;
use App\Filament\Resources\ProviderConnectionResource\Pages\ViewProviderConnection;
use App\Filament\Resources\ReviewPackResource\Pages\ViewReviewPack;
use App\Filament\Resources\TenantResource\Pages\EditTenant;
use App\Filament\Resources\TenantResource\Pages\ViewTenant;
use App\Filament\Resources\TenantReviewResource\Pages\ViewTenantReview;
use App\Filament\Resources\Workspaces\Pages\ViewWorkspace;
use App\Filament\System\Pages\Dashboard as SystemDashboard;
use App\Filament\System\Pages\Directory\ViewTenant as SystemDirectoryViewTenant;
use App\Filament\System\Pages\Directory\ViewWorkspace as SystemDirectoryViewWorkspace;
use App\Filament\System\Pages\Ops\Runbooks;
use App\Filament\System\Pages\Ops\ViewRun;
use App\Filament\System\Pages\RepairWorkspaceOwners;
use App\Support\WorkspaceIsolation\TenantOwnedModelFamilies;
final class ActionSurfaceExemptions
{
/**
* @param array<string, string> $componentReasons
*/
public function __construct(
private readonly array $componentReasons,
) {}
public static function baseline(): self
{
return new self(array_merge([
// Baseline allowlist for legacy surfaces. Keep shrinking this list.
// Declared system table pages are discovered directly; deferred system tooling stays out of scope by not opting in.
'App\\Filament\\Pages\\Auth\\Login' => 'Auth entry page is out-of-scope for action-surface retrofits in spec 082.',
'App\\Filament\\Pages\\ChooseTenant' => 'Tenant chooser has no contract-style table action surface.',
'App\\Filament\\Pages\\ChooseWorkspace' => 'Workspace chooser has no contract-style table action surface.',
'App\\Filament\\Pages\\Tenancy\\RegisterTenant' => 'Tenant onboarding route is covered by onboarding/RBAC specs.',
'App\\Filament\\Pages\\TenantDashboard' => 'Dashboard retrofit deferred; widget and summary surfaces are excluded from this contract.',
'App\\Filament\\Pages\\Workspaces\\ManagedTenantOnboardingWizard' => 'Onboarding wizard has dedicated conformance tests in spec 172 (OnboardingVerificationTest, OnboardingVerificationClustersTest, OnboardingVerificationV1_5UxTest) and remains exempt from blanket discovery.',
'App\\Filament\\Pages\\Workspaces\\ManagedTenantsLanding' => 'Managed-tenant landing retrofit deferred to workspace feature track.',
], TenantOwnedModelFamilies::actionSurfaceBaselineExemptions()));
}
/**
* @return array<string, string>
*/
public function all(): array
{
return $this->componentReasons;
}
public function reasonForClass(string $className): ?string
{
return $this->componentReasons[$className] ?? null;
}
public function hasClass(string $className): bool
{
return array_key_exists($className, $this->componentReasons);
}
/**
* @return array<string, array{
* surfaceKey: string,
* classification: string,
* canonicalNoun: string,
* panelScope: string,
* ownerScope: string,
* routeKind: string,
* requiresHeaderRemediation: bool,
* exceptionReason: ?string,
* maxVisiblePrimaryActions: int,
* allowsNoPrimaryAction: bool,
* requiresGroupedSecondaryActions: bool,
* requiresDangerSeparation: bool,
* allowsPrimaryNavigation: bool,
* browserSmokeRequired: bool
* }>
*/
public static function spec192RecordPageInventory(): array
{
return [
ViewBaselineProfile::class => [
'surfaceKey' => 'baseline_profile_view',
'classification' => 'remediation_required',
'canonicalNoun' => 'Baseline profile',
'panelScope' => 'admin',
'ownerScope' => 'workspace-owned',
'routeKind' => 'view',
'requiresHeaderRemediation' => true,
'exceptionReason' => null,
'maxVisiblePrimaryActions' => 1,
'allowsNoPrimaryAction' => false,
'requiresGroupedSecondaryActions' => true,
'requiresDangerSeparation' => false,
'allowsPrimaryNavigation' => false,
'browserSmokeRequired' => true,
],
ViewEvidenceSnapshot::class => [
'surfaceKey' => 'evidence_snapshot_view',
'classification' => 'remediation_required',
'canonicalNoun' => 'Evidence snapshot',
'panelScope' => 'tenant',
'ownerScope' => 'tenant-owned',
'routeKind' => 'view',
'requiresHeaderRemediation' => true,
'exceptionReason' => null,
'maxVisiblePrimaryActions' => 1,
'allowsNoPrimaryAction' => false,
'requiresGroupedSecondaryActions' => false,
'requiresDangerSeparation' => true,
'allowsPrimaryNavigation' => false,
'browserSmokeRequired' => true,
],
ViewFindingException::class => [
'surfaceKey' => 'finding_exception_view',
'classification' => 'remediation_required',
'canonicalNoun' => 'Finding exception',
'panelScope' => 'tenant',
'ownerScope' => 'tenant-owned',
'routeKind' => 'view',
'requiresHeaderRemediation' => true,
'exceptionReason' => null,
'maxVisiblePrimaryActions' => 1,
'allowsNoPrimaryAction' => true,
'requiresGroupedSecondaryActions' => false,
'requiresDangerSeparation' => true,
'allowsPrimaryNavigation' => false,
'browserSmokeRequired' => true,
],
ViewTenantReview::class => [
'surfaceKey' => 'tenant_review_view',
'classification' => 'remediation_required',
'canonicalNoun' => 'Tenant review',
'panelScope' => 'tenant',
'ownerScope' => 'tenant-owned',
'routeKind' => 'view',
'requiresHeaderRemediation' => true,
'exceptionReason' => null,
'maxVisiblePrimaryActions' => 1,
'allowsNoPrimaryAction' => false,
'requiresGroupedSecondaryActions' => true,
'requiresDangerSeparation' => true,
'allowsPrimaryNavigation' => false,
'browserSmokeRequired' => true,
],
EditTenant::class => [
'surfaceKey' => 'tenant_edit',
'classification' => 'remediation_required',
'canonicalNoun' => 'Tenant',
'panelScope' => 'admin',
'ownerScope' => 'tenant-owned',
'routeKind' => 'edit',
'requiresHeaderRemediation' => true,
'exceptionReason' => null,
'maxVisiblePrimaryActions' => 1,
'allowsNoPrimaryAction' => true,
'requiresGroupedSecondaryActions' => true,
'requiresDangerSeparation' => true,
'allowsPrimaryNavigation' => false,
'browserSmokeRequired' => true,
],
ViewTenant::class => [
'surfaceKey' => 'tenant_view',
'classification' => 'workflow_heavy_special_type',
'canonicalNoun' => 'Tenant',
'panelScope' => 'admin',
'ownerScope' => 'tenant-owned',
'routeKind' => 'view',
'requiresHeaderRemediation' => false,
'exceptionReason' => 'Tenant detail remains a workflow-heavy hub for external links, verification/setup, and lifecycle operations. It may show one dominant next step, but it must never silently fall back to a flat multi-button strip.',
'maxVisiblePrimaryActions' => 1,
'allowsNoPrimaryAction' => true,
'requiresGroupedSecondaryActions' => true,
'requiresDangerSeparation' => true,
'allowsPrimaryNavigation' => false,
'browserSmokeRequired' => true,
],
ViewProviderConnection::class => [
'surfaceKey' => 'provider_connection_view',
'classification' => 'minor_alignment_only',
'canonicalNoun' => 'Provider connection',
'panelScope' => 'admin',
'ownerScope' => 'tenant-owned',
'routeKind' => 'view',
'requiresHeaderRemediation' => false,
'exceptionReason' => null,
'maxVisiblePrimaryActions' => 1,
'allowsNoPrimaryAction' => true,
'requiresGroupedSecondaryActions' => true,
'requiresDangerSeparation' => true,
'allowsPrimaryNavigation' => true,
'browserSmokeRequired' => false,
],
ViewFinding::class => [
'surfaceKey' => 'finding_view',
'classification' => 'minor_alignment_only',
'canonicalNoun' => 'Finding',
'panelScope' => 'tenant',
'ownerScope' => 'tenant-owned',
'routeKind' => 'view',
'requiresHeaderRemediation' => false,
'exceptionReason' => null,
'maxVisiblePrimaryActions' => 1,
'allowsNoPrimaryAction' => true,
'requiresGroupedSecondaryActions' => true,
'requiresDangerSeparation' => true,
'allowsPrimaryNavigation' => true,
'browserSmokeRequired' => false,
],
ViewReviewPack::class => [
'surfaceKey' => 'review_pack_view',
'classification' => 'compliant_reference',
'canonicalNoun' => 'Review pack',
'panelScope' => 'tenant',
'ownerScope' => 'tenant-owned',
'routeKind' => 'view',
'requiresHeaderRemediation' => false,
'exceptionReason' => null,
'maxVisiblePrimaryActions' => 1,
'allowsNoPrimaryAction' => true,
'requiresGroupedSecondaryActions' => false,
'requiresDangerSeparation' => false,
'allowsPrimaryNavigation' => true,
'browserSmokeRequired' => true,
],
ViewAlertDestination::class => [
'surfaceKey' => 'alert_destination_view',
'classification' => 'compliant_reference',
'canonicalNoun' => 'Alert destination',
'panelScope' => 'admin',
'ownerScope' => 'workspace-owned',
'routeKind' => 'view',
'requiresHeaderRemediation' => false,
'exceptionReason' => null,
'maxVisiblePrimaryActions' => 1,
'allowsNoPrimaryAction' => true,
'requiresGroupedSecondaryActions' => false,
'requiresDangerSeparation' => false,
'allowsPrimaryNavigation' => true,
'browserSmokeRequired' => true,
],
ViewPolicyVersion::class => [
'surfaceKey' => 'policy_version_view',
'classification' => 'compliant_reference',
'canonicalNoun' => 'Policy version',
'panelScope' => 'admin',
'ownerScope' => 'workspace-owned',
'routeKind' => 'view',
'requiresHeaderRemediation' => false,
'exceptionReason' => null,
'maxVisiblePrimaryActions' => 1,
'allowsNoPrimaryAction' => true,
'requiresGroupedSecondaryActions' => false,
'requiresDangerSeparation' => false,
'allowsPrimaryNavigation' => true,
'browserSmokeRequired' => true,
],
ViewWorkspace::class => [
'surfaceKey' => 'workspace_view',
'classification' => 'compliant_reference',
'canonicalNoun' => 'Workspace',
'panelScope' => 'admin',
'ownerScope' => 'workspace-owned',
'routeKind' => 'view',
'requiresHeaderRemediation' => false,
'exceptionReason' => null,
'maxVisiblePrimaryActions' => 1,
'allowsNoPrimaryAction' => true,
'requiresGroupedSecondaryActions' => false,
'requiresDangerSeparation' => false,
'allowsPrimaryNavigation' => true,
'browserSmokeRequired' => true,
],
ViewBaselineSnapshot::class => [
'surfaceKey' => 'baseline_snapshot_view',
'classification' => 'compliant_reference',
'canonicalNoun' => 'Baseline snapshot',
'panelScope' => 'admin',
'ownerScope' => 'workspace-owned',
'routeKind' => 'view',
'requiresHeaderRemediation' => false,
'exceptionReason' => null,
'maxVisiblePrimaryActions' => 1,
'allowsNoPrimaryAction' => true,
'requiresGroupedSecondaryActions' => false,
'requiresDangerSeparation' => false,
'allowsPrimaryNavigation' => true,
'browserSmokeRequired' => true,
],
ViewBackupSet::class => [
'surfaceKey' => 'backup_set_view',
'classification' => 'compliant_reference',
'canonicalNoun' => 'Backup set',
'panelScope' => 'tenant',
'ownerScope' => 'tenant-owned',
'routeKind' => 'view',
'requiresHeaderRemediation' => false,
'exceptionReason' => null,
'maxVisiblePrimaryActions' => 1,
'allowsNoPrimaryAction' => true,
'requiresGroupedSecondaryActions' => true,
'requiresDangerSeparation' => true,
'allowsPrimaryNavigation' => true,
'browserSmokeRequired' => true,
],
];
}
/**
* @return array<string, array{
* surfaceKey: string,
* classification: string,
* canonicalNoun: string,
* panelScope: string,
* ownerScope: string,
* surfaceKind: string,
* primaryInspectModel: string,
* sharedPattern: string,
* requiresHeaderRemediation: bool,
* requiresExplicitDeclaration: bool,
* exceptionReason: ?string,
* browserSmokeRequired: bool
* }>
*/
public static function spec193MonitoringSurfaceInventory(): array
{
return [
FindingExceptionsQueue::class => [
'surfaceKey' => 'finding_exceptions_queue',
'classification' => 'remediation_required',
'canonicalNoun' => 'Finding exceptions',
'panelScope' => 'admin',
'ownerScope' => 'workspace-visible-tenant-owned',
'surfaceKind' => 'queue_workbench',
'primaryInspectModel' => 'explicit_inspect_action',
'sharedPattern' => 'operate_hub_shell',
'requiresHeaderRemediation' => true,
'requiresExplicitDeclaration' => true,
'exceptionReason' => null,
'browserSmokeRequired' => true,
],
TenantlessOperationRunViewer::class => [
'surfaceKey' => 'tenantless_operation_run_viewer',
'classification' => 'remediation_required',
'canonicalNoun' => 'Operation run',
'panelScope' => 'admin',
'ownerScope' => 'workspace-owned',
'surfaceKind' => 'monitoring_detail',
'primaryInspectModel' => 'singleton_detail_surface',
'sharedPattern' => 'operate_hub_shell',
'requiresHeaderRemediation' => true,
'requiresExplicitDeclaration' => true,
'exceptionReason' => null,
'browserSmokeRequired' => true,
],
Operations::class => [
'surfaceKey' => 'operations',
'classification' => 'remediation_required',
'canonicalNoun' => 'Operations',
'panelScope' => 'admin',
'ownerScope' => 'workspace-owned',
'surfaceKind' => 'monitoring_landing',
'primaryInspectModel' => 'clickable_row',
'sharedPattern' => 'operate_hub_shell',
'requiresHeaderRemediation' => true,
'requiresExplicitDeclaration' => true,
'exceptionReason' => null,
'browserSmokeRequired' => true,
],
Alerts::class => [
'surfaceKey' => 'alerts',
'classification' => 'minor_alignment_only',
'canonicalNoun' => 'Alerts',
'panelScope' => 'admin',
'ownerScope' => 'workspace-owned',
'surfaceKind' => 'monitoring_landing',
'primaryInspectModel' => 'page_level_overview',
'sharedPattern' => 'cluster_entry',
'requiresHeaderRemediation' => false,
'requiresExplicitDeclaration' => true,
'exceptionReason' => null,
'browserSmokeRequired' => false,
],
AuditLog::class => [
'surfaceKey' => 'audit_log',
'classification' => 'minor_alignment_only',
'canonicalNoun' => 'Audit log',
'panelScope' => 'admin',
'ownerScope' => 'workspace-visible-tenant-owned',
'surfaceKind' => 'read_only_report',
'primaryInspectModel' => 'explicit_inspect_action',
'sharedPattern' => 'operate_hub_shell',
'requiresHeaderRemediation' => false,
'requiresExplicitDeclaration' => true,
'exceptionReason' => null,
'browserSmokeRequired' => false,
],
ListAlertDeliveries::class => [
'surfaceKey' => 'alert_deliveries',
'classification' => 'minor_alignment_only',
'canonicalNoun' => 'Alert deliveries',
'panelScope' => 'admin',
'ownerScope' => 'workspace-owned',
'surfaceKind' => 'read_only_report',
'primaryInspectModel' => 'clickable_row',
'sharedPattern' => 'operate_hub_shell',
'requiresHeaderRemediation' => false,
'requiresExplicitDeclaration' => false,
'exceptionReason' => null,
'browserSmokeRequired' => false,
],
EvidenceOverview::class => [
'surfaceKey' => 'evidence_overview',
'classification' => 'compliant_no_op',
'canonicalNoun' => 'Evidence overview',
'panelScope' => 'admin',
'ownerScope' => 'workspace-visible-tenant-owned',
'surfaceKind' => 'read_only_report',
'primaryInspectModel' => 'clickable_row',
'sharedPattern' => 'none',
'requiresHeaderRemediation' => false,
'requiresExplicitDeclaration' => true,
'exceptionReason' => null,
'browserSmokeRequired' => true,
],
BaselineCompareLanding::class => [
'surfaceKey' => 'baseline_compare_landing',
'classification' => 'compliant_no_op',
'canonicalNoun' => 'Baseline compare',
'panelScope' => 'tenant',
'ownerScope' => 'tenant-owned',
'surfaceKind' => 'monitoring_landing',
'primaryInspectModel' => 'page_level_overview',
'sharedPattern' => 'none',
'requiresHeaderRemediation' => false,
'requiresExplicitDeclaration' => true,
'exceptionReason' => null,
'browserSmokeRequired' => true,
],
BaselineCompareMatrix::class => [
'surfaceKey' => 'baseline_compare_matrix',
'classification' => 'compliant_no_op',
'canonicalNoun' => 'Baseline compare matrix',
'panelScope' => 'tenant',
'ownerScope' => 'tenant-owned',
'surfaceKind' => 'read_only_report',
'primaryInspectModel' => 'matrix_itself',
'sharedPattern' => 'none',
'requiresHeaderRemediation' => false,
'requiresExplicitDeclaration' => true,
'exceptionReason' => null,
'browserSmokeRequired' => true,
],
ReviewRegister::class => [
'surfaceKey' => 'review_register',
'classification' => 'compliant_no_op',
'canonicalNoun' => 'Review register',
'panelScope' => 'admin',
'ownerScope' => 'workspace-visible-tenant-owned',
'surfaceKind' => 'read_only_report',
'primaryInspectModel' => 'clickable_row',
'sharedPattern' => 'none',
'requiresHeaderRemediation' => false,
'requiresExplicitDeclaration' => true,
'exceptionReason' => null,
'browserSmokeRequired' => true,
],
TenantDiagnostics::class => [
'surfaceKey' => 'tenant_diagnostics',
'classification' => 'special_type_acceptable',
'canonicalNoun' => 'Tenant diagnostics',
'panelScope' => 'tenant',
'ownerScope' => 'tenant-owned',
'surfaceKind' => 'diagnostic_exception',
'primaryInspectModel' => 'singleton_detail_surface',
'sharedPattern' => 'none',
'requiresHeaderRemediation' => false,
'requiresExplicitDeclaration' => true,
'exceptionReason' => 'Tenant diagnostics is already the focused diagnostic surface for the active tenant and may expose repair actions only when a real defect exists.',
'browserSmokeRequired' => true,
],
];
}
/**
* @return array{
* surfaceKey: string,
* classification: string,
* canonicalNoun: string,
* panelScope: string,
* ownerScope: string,
* routeKind: string,
* requiresHeaderRemediation: bool,
* exceptionReason: ?string,
* maxVisiblePrimaryActions: int,
* allowsNoPrimaryAction: bool,
* requiresGroupedSecondaryActions: bool,
* requiresDangerSeparation: bool,
* allowsPrimaryNavigation: bool,
* browserSmokeRequired: bool
* }|null
*/
public static function spec192RecordPageSurface(string $className): ?array
{
return self::spec192RecordPageInventory()[$className] ?? null;
}
/**
* @return array{
* surfaceKey: string,
* classification: string,
* canonicalNoun: string,
* panelScope: string,
* ownerScope: string,
* surfaceKind: string,
* primaryInspectModel: string,
* sharedPattern: string,
* requiresHeaderRemediation: bool,
* requiresExplicitDeclaration: bool,
* exceptionReason: ?string,
* browserSmokeRequired: bool
* }|null
*/
public static function spec193MonitoringSurface(string $className): ?array
{
return self::spec193MonitoringSurfaceInventory()[$className] ?? null;
}
/**
* @return array<string, array{
* surfaceKey: string,
* surfaceName: string,
* pageClass: string,
* panelPlane: string,
* surfaceKind: string,
* discoveryState: string,
* closureDecision: string,
* reasonCategory: ?string,
* explicitReason: string,
* evidence: array<int, array{
* kind: string,
* reference: string,
* proves: string
* }>,
* followUpAction: string,
* mustRemainBaselineExempt: bool,
* mustNotRemainBaselineExempt: bool
* }>
*/
public static function spec195ResidualSurfaceInventory(): array
{
return [
SystemDashboard::class => [
'surfaceKey' => 'system_dashboard',
'surfaceName' => 'System Console Dashboard',
'pageClass' => SystemDashboard::class,
'panelPlane' => 'system',
'surfaceKind' => 'dashboard_shell',
'discoveryState' => 'outside_primary_discovery',
'closureDecision' => 'separately_governed',
'reasonCategory' => 'workflow_specific_governance',
'explicitReason' => 'The system dashboard keeps its console-window and break-glass controls under dedicated system and recovery tests instead of the generic declaration-backed contract.',
'evidence' => [
[
'kind' => 'feature_livewire_test',
'reference' => 'tests/Feature/System/Spec114/ControlTowerDashboardTest.php',
'proves' => 'The control-tower shell keeps its window action and dashboard rendering behavior under focused system coverage.',
],
[
'kind' => 'feature_livewire_test',
'reference' => 'tests/Feature/Auth/BreakGlassModeTest.php',
'proves' => 'Break-glass entry and exit remain confirmed, audited dashboard actions rather than silent utility links.',
],
],
'followUpAction' => 'add_guard_only',
'mustRemainBaselineExempt' => false,
'mustNotRemainBaselineExempt' => true,
],
ViewRun::class => [
'surfaceKey' => 'system_ops_view_run',
'surfaceName' => 'System Ops View Run',
'pageClass' => ViewRun::class,
'panelPlane' => 'system',
'surfaceKind' => 'system_detail',
'discoveryState' => 'outside_primary_discovery',
'closureDecision' => 'separately_governed',
'reasonCategory' => 'system_triage_surface',
'explicitReason' => 'Run triage remains a dedicated decision surface with confirmed retry, cancel, and investigate behavior instead of fitting the generic declaration-backed list/detail shape.',
'evidence' => [
[
'kind' => 'feature_livewire_test',
'reference' => 'tests/Feature/System/Spec114/OpsTriageActionsTest.php',
'proves' => 'The view-run surface keeps explicit navigation, triage actions, and capability-sensitive visibility.',
],
[
'kind' => 'guard_test',
'reference' => 'tests/Feature/Guards/Spec194GovernanceActionSemanticsGuardTest.php',
'proves' => 'The retry, cancel, and investigate actions remain part of the governed system action semantics inventory.',
],
],
'followUpAction' => 'add_guard_only',
'mustRemainBaselineExempt' => false,
'mustNotRemainBaselineExempt' => true,
],
Runbooks::class => [
'surfaceKey' => 'system_ops_runbooks',
'surfaceName' => 'System Ops Runbooks',
'pageClass' => Runbooks::class,
'panelPlane' => 'system',
'surfaceKind' => 'system_utility',
'discoveryState' => 'outside_primary_discovery',
'closureDecision' => 'separately_governed',
'reasonCategory' => 'workflow_specific_governance',
'explicitReason' => 'Runbooks is a workflow utility hub with its own trusted-state, authorization, and confirmation semantics rather than a declaration-backed record or table surface.',
'evidence' => [
[
'kind' => 'feature_livewire_test',
'reference' => 'tests/Feature/System/OpsRunbooks/FindingsLifecycleBackfillStartTest.php',
'proves' => 'The runbooks shell enforces preflight-first execution, typed confirmation, and capability-gated run behavior.',
],
[
'kind' => 'authorization_test',
'reference' => 'tests/Feature/System/Spec113/AuthorizationSemanticsTest.php',
'proves' => 'The system plane still returns 403 when runbook-view capabilities are missing.',
],
[
'kind' => 'guard_test',
'reference' => 'tests/Feature/Guards/LivewireTrustedStateGuardTest.php',
'proves' => 'Runbooks keeps its trusted-state policy under explicit guard coverage.',
],
],
'followUpAction' => 'add_guard_only',
'mustRemainBaselineExempt' => false,
'mustNotRemainBaselineExempt' => true,
],
RepairWorkspaceOwners::class => [
'surfaceKey' => 'repair_workspace_owners',
'surfaceName' => 'Repair Workspace Owners',
'pageClass' => RepairWorkspaceOwners::class,
'panelPlane' => 'system',
'surfaceKind' => 'system_utility',
'discoveryState' => 'outside_primary_discovery',
'closureDecision' => 'separately_governed',
'reasonCategory' => 'break_glass_repair_utility',
'explicitReason' => 'Emergency owner repair stays under dedicated break-glass and table guard coverage instead of the generic declaration-backed system-table contract.',
'evidence' => [
[
'kind' => 'feature_livewire_test',
'reference' => 'tests/Feature/Auth/BreakGlassWorkspaceOwnerRecoveryTest.php',
'proves' => 'The repair utility requires break-glass context and records audited recovery behavior.',
],
[
'kind' => 'guard_test',
'reference' => 'tests/Feature/Guards/FilamentTableStandardsGuardTest.php',
'proves' => 'The table shell keeps explicit empty-state and table-standard coverage even while remaining outside the primary declaration path.',
],
],
'followUpAction' => 'add_guard_only',
'mustRemainBaselineExempt' => false,
'mustNotRemainBaselineExempt' => true,
],
SystemDirectoryViewTenant::class => [
'surfaceKey' => 'system_directory_view_tenant',
'surfaceName' => 'System Directory View Tenant',
'pageClass' => SystemDirectoryViewTenant::class,
'panelPlane' => 'system',
'surfaceKind' => 'read_mostly_context',
'discoveryState' => 'outside_primary_discovery',
'closureDecision' => 'harmless_special_case',
'reasonCategory' => 'read_mostly_context_detail',
'explicitReason' => 'The tenant directory detail page is a read-mostly drilldown that links outward to canonical admin and run surfaces without introducing its own mutating controls.',
'evidence' => [
[
'kind' => 'feature_livewire_test',
'reference' => 'tests/Feature/System/Spec195/SystemDirectoryResidualSurfaceTest.php',
'proves' => 'The detail page renders contextual connectivity and recent-run information while staying read-mostly and capability-gated.',
],
[
'kind' => 'authorization_test',
'reference' => 'tests/Feature/System/Spec114/DirectoryTenantsTest.php',
'proves' => 'Directory-view capability remains required before the detail route becomes visible.',
],
],
'followUpAction' => 'add_focused_test',
'mustRemainBaselineExempt' => false,
'mustNotRemainBaselineExempt' => true,
],
SystemDirectoryViewWorkspace::class => [
'surfaceKey' => 'system_directory_view_workspace',
'surfaceName' => 'System Directory View Workspace',
'pageClass' => SystemDirectoryViewWorkspace::class,
'panelPlane' => 'system',
'surfaceKind' => 'read_mostly_context',
'discoveryState' => 'outside_primary_discovery',
'closureDecision' => 'harmless_special_case',
'reasonCategory' => 'read_mostly_context_detail',
'explicitReason' => 'The workspace directory detail page is a read-mostly drilldown that exposes context and links, not a declaration-backed mutable system workbench.',
'evidence' => [
[
'kind' => 'feature_livewire_test',
'reference' => 'tests/Feature/System/Spec195/SystemDirectoryResidualSurfaceTest.php',
'proves' => 'The workspace detail page stays capability-gated and renders contextual tenant and run links without mutating actions.',
],
[
'kind' => 'authorization_test',
'reference' => 'tests/Feature/System/Spec114/DirectoryWorkspacesTest.php',
'proves' => 'Directory-view capability remains required before workspace directory routes become available.',
],
],
'followUpAction' => 'add_focused_test',
'mustRemainBaselineExempt' => false,
'mustNotRemainBaselineExempt' => true,
],
BreakGlassRecovery::class => [
'surfaceKey' => 'break_glass_recovery',
'surfaceName' => 'Break Glass Recovery',
'pageClass' => BreakGlassRecovery::class,
'panelPlane' => 'admin',
'surfaceKind' => 'recovery_flow',
'discoveryState' => 'primary_discovered',
'closureDecision' => 'retired_no_longer_relevant',
'reasonCategory' => 'disabled_or_actionless_surface',
'explicitReason' => 'The page currently denies access and exposes no header actions, so it should not remain a live baseline exemption.',
'evidence' => [
[
'kind' => 'audit_test',
'reference' => 'app/Filament/Pages/BreakGlassRecovery.php',
'proves' => 'The page returns false from canAccess() and exposes no header actions.',
],
[
'kind' => 'feature_livewire_test',
'reference' => 'tests/Feature/Auth/BreakGlassWorkspaceOwnerRecoveryTest.php',
'proves' => 'The active recovery path now lives on the system dashboard and repair utility instead of this retired page shell.',
],
],
'followUpAction' => 'tighten_reason',
'mustRemainBaselineExempt' => false,
'mustNotRemainBaselineExempt' => true,
],
ChooseWorkspace::class => [
'surfaceKey' => 'choose_workspace',
'surfaceName' => 'Choose Workspace',
'pageClass' => ChooseWorkspace::class,
'panelPlane' => 'admin',
'surfaceKind' => 'selector',
'discoveryState' => 'primary_discovered_baseline_exempt',
'closureDecision' => 'harmless_special_case',
'reasonCategory' => 'selector_routing_only',
'explicitReason' => 'The workspace chooser is a routing-only selector with explicit membership checks and audit logging, not a declaration-backed action table.',
'evidence' => [
[
'kind' => 'feature_livewire_test',
'reference' => 'tests/Feature/Workspaces/ChooseWorkspacePageTest.php',
'proves' => 'The chooser keeps membership-scoped selection, redirect behavior, and deny-as-not-found semantics.',
],
[
'kind' => 'audit_test',
'reference' => 'tests/Feature/Workspaces/WorkspaceAuditTrailTest.php',
'proves' => 'Manual workspace selection remains explicitly audited.',
],
],
'followUpAction' => 'none',
'mustRemainBaselineExempt' => true,
'mustNotRemainBaselineExempt' => false,
],
ChooseTenant::class => [
'surfaceKey' => 'choose_tenant',
'surfaceName' => 'Choose Tenant',
'pageClass' => ChooseTenant::class,
'panelPlane' => 'tenant',
'surfaceKind' => 'selector',
'discoveryState' => 'primary_discovered_baseline_exempt',
'closureDecision' => 'harmless_special_case',
'reasonCategory' => 'selector_routing_only',
'explicitReason' => 'The tenant chooser is a selector-only surface that filters operable tenants and routes to the tenant dashboard without its own contract-style action surface.',
'evidence' => [
[
'kind' => 'feature_livewire_test',
'reference' => 'tests/Feature/Auth/TenantChooserSelectionTest.php',
'proves' => 'The chooser redirects only for active selectable tenants and rejects non-operable selections with 404.',
],
[
'kind' => 'authorization_test',
'reference' => 'tests/Feature/TenantRBAC/TenantSwitcherScopeTest.php',
'proves' => 'Selector eligibility remains narrower than global tenant discoverability and stays tenant-scope aware.',
],
],
'followUpAction' => 'none',
'mustRemainBaselineExempt' => true,
'mustNotRemainBaselineExempt' => false,
],
RegisterTenant::class => [
'surfaceKey' => 'register_tenant',
'surfaceName' => 'Register Tenant',
'pageClass' => RegisterTenant::class,
'panelPlane' => 'admin',
'surfaceKind' => 'wizard',
'discoveryState' => 'primary_discovered_baseline_exempt',
'closureDecision' => 'separately_governed',
'reasonCategory' => 'registration_form_with_dedicated_rbac',
'explicitReason' => 'Tenant registration is a dedicated creation workflow with its own visibility rules, bootstrap membership side effects, and audit logging.',
'evidence' => [
[
'kind' => 'authorization_test',
'reference' => 'tests/Feature/Rbac/RegisterTenantAuthorizationTest.php',
'proves' => 'Registration visibility remains explicitly capability-sensitive for owner versus readonly members.',
],
[
'kind' => 'feature_livewire_test',
'reference' => 'tests/Feature/TenantRBAC/TenantBootstrapAssignTest.php',
'proves' => 'Registration still bootstraps tenant ownership and audit behavior through the dedicated flow.',
],
],
'followUpAction' => 'none',
'mustRemainBaselineExempt' => true,
'mustNotRemainBaselineExempt' => false,
],
ManagedTenantOnboardingWizard::class => [
'surfaceKey' => 'managed_tenant_onboarding_wizard',
'surfaceName' => 'Managed Tenant Onboarding Wizard',
'pageClass' => ManagedTenantOnboardingWizard::class,
'panelPlane' => 'admin',
'surfaceKind' => 'wizard',
'discoveryState' => 'primary_discovered_baseline_exempt',
'closureDecision' => 'separately_governed',
'reasonCategory' => 'workflow_specific_governance',
'explicitReason' => 'The onboarding wizard is a workflow-specific surface with draft continuity, capability-gated steps, confirmations, and dedicated audit coverage.',
'evidence' => [
[
'kind' => 'authorization_test',
'reference' => 'tests/Feature/Rbac/OnboardingWizardUiEnforcementTest.php',
'proves' => 'The wizard enforces capability checks on its interactive paths instead of inheriting the generic declaration contract.',
],
[
'kind' => 'authorization_test',
'reference' => 'tests/Feature/Onboarding/OnboardingDraftAccessTest.php',
'proves' => 'Workspace and tenant continuity for onboarding drafts remains guarded by dedicated 404 and 403 semantics.',
],
],
'followUpAction' => 'none',
'mustRemainBaselineExempt' => true,
'mustNotRemainBaselineExempt' => false,
],
ManagedTenantsLanding::class => [
'surfaceKey' => 'managed_tenants_landing',
'surfaceName' => 'Managed Tenants Landing',
'pageClass' => ManagedTenantsLanding::class,
'panelPlane' => 'admin',
'surfaceKind' => 'landing',
'discoveryState' => 'primary_discovered_baseline_exempt',
'closureDecision' => 'harmless_special_case',
'reasonCategory' => 'landing_routing_surface',
'explicitReason' => 'The managed-tenants landing is a workspace routing shell that keeps discoverability and open-tenant navigation explicit without pretending to be a generic declaration-backed table page.',
'evidence' => [
[
'kind' => 'feature_livewire_test',
'reference' => 'tests/Feature/Workspaces/Spec195ManagedTenantsLandingTest.php',
'proves' => 'The landing stays membership-scoped, preserves selector routing, and rejects outsider tenant openings.',
],
[
'kind' => 'feature_livewire_test',
'reference' => 'tests/Feature/Filament/ManagedTenantsLandingLifecycleTest.php',
'proves' => 'The landing intentionally exposes broader administrative discoverability than the tenant chooser.',
],
],
'followUpAction' => 'add_focused_test',
'mustRemainBaselineExempt' => true,
'mustNotRemainBaselineExempt' => false,
],
TenantDashboard::class => [
'surfaceKey' => 'tenant_dashboard',
'surfaceName' => 'Tenant Dashboard',
'pageClass' => TenantDashboard::class,
'panelPlane' => 'tenant',
'surfaceKind' => 'dashboard_shell',
'discoveryState' => 'primary_discovered_baseline_exempt',
'closureDecision' => 'harmless_special_case',
'reasonCategory' => 'dashboard_shell_widget_owned',
'explicitReason' => 'The tenant dashboard is a widget shell whose meaningful mutations and visibility rules live in its widgets and follow-up routes rather than in page-level generic actions.',
'evidence' => [
[
'kind' => 'db_only_surface_test',
'reference' => 'tests/Feature/Filament/TenantDashboardDbOnlyTest.php',
'proves' => 'The dashboard shell renders DB-only and keeps its main behavior in widget rendering rather than page-level actions.',
],
[
'kind' => 'authorization_test',
'reference' => 'tests/Feature/Rbac/TenantDashboardArrivalContextVisibilityTest.php',
'proves' => 'Arrival context CTAs remain permission-aware and deny-as-not-found for non-members.',
],
],
'followUpAction' => 'none',
'mustRemainBaselineExempt' => true,
'mustNotRemainBaselineExempt' => false,
],
];
}
/**
* @return array{
* surfaceKey: string,
* surfaceName: string,
* pageClass: string,
* panelPlane: string,
* surfaceKind: string,
* discoveryState: string,
* closureDecision: string,
* reasonCategory: ?string,
* explicitReason: string,
* evidence: array<int, array{
* kind: string,
* reference: string,
* proves: string
* }>,
* followUpAction: string,
* mustRemainBaselineExempt: bool,
* mustNotRemainBaselineExempt: bool
* }|null
*/
public static function spec195ResidualSurface(string $className): ?array
{
return self::spec195ResidualSurfaceInventory()[$className] ?? null;
}
}