## Summary
- add the full Spec 195 residual action-surface design package under `specs/195-action-surface-closure`
- implement residual surface inventory and validator enforcement for uncatalogued system and special Filament pages
- add focused regression coverage for residual guards, system directory pages, managed-tenants landing, and readonly register-tenant / tenant-dashboard access
- fix the system workspace detail surface by loading tenant route keys and disabling lazy system database notifications to avoid the Livewire 404 on `/system/directory/workspaces/{workspace}`
## Testing
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/System/Spec195/SystemDirectoryResidualSurfaceTest.php tests/Feature/Filament/DatabaseNotificationsPollingTest.php`
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
## Notes
- branch: `195-action-surface-closure`
- target: `dev`
- no new assets, migrations, or provider-registration changes
Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #230
150 lines
12 KiB
Markdown
150 lines
12 KiB
Markdown
# Data Model: Action Surface Enforcement, Enrollment, and Exception Closure
|
|
|
|
## Overview
|
|
|
|
This feature introduces no new persisted entity, table, or user-facing workflow model. It adds a derived repository-governance model for residual action-bearing surfaces that currently sit outside clearly catalogued generic-contract coverage.
|
|
|
|
The goal of the model is to answer five questions for every residual surface:
|
|
|
|
1. Is the surface discovered by the primary validator path?
|
|
2. If not, is the gap explicit?
|
|
3. What is the final closure decision?
|
|
4. Why is that decision justified?
|
|
5. Which existing tests or guards prove the decision is real?
|
|
|
|
Each entry must also stay human-reviewable, so the inventory carries both a stable machine key and a human-readable surface name.
|
|
|
|
## Existing Source Truths Reused Without Change
|
|
|
|
The following truths remain authoritative and are not redefined by this feature:
|
|
|
|
- existing page and route classes
|
|
- existing authorization semantics, capability registries, and `UiEnforcement` rules
|
|
- existing `OperationRun`, audit, and break-glass behavior
|
|
- existing `ActionSurfaceDiscovery` behavior for declaration-backed generic surfaces
|
|
- existing baseline exemptions for discovered pages that are intentionally outside the generic contract
|
|
- existing system, onboarding, chooser, and dashboard test suites
|
|
|
|
This feature changes classification and regression proof only.
|
|
|
|
## New Derived Planning Models
|
|
|
|
### ResidualSurfaceInventoryEntry
|
|
|
|
**Type**: Spec 195 inventory entry
|
|
**Source**: one structured in-code inventory plus validator checks
|
|
|
|
| Field | Type | Notes |
|
|
|------|------|-------|
|
|
| `surfaceKey` | string | Stable identifier such as `system_ops_view_run` or `choose_workspace` |
|
|
| `surfaceName` | string | Human-readable review name such as `System Ops View Run` or `Choose Workspace` |
|
|
| `pageClass` | string | Concrete Filament page class |
|
|
| `panelPlane` | string | `admin`, `tenant`, or `system` |
|
|
| `surfaceKind` | string | `system_detail`, `system_utility`, `selector`, `wizard`, `landing`, `dashboard_shell`, `recovery_flow`, or `read_mostly_context` |
|
|
| `discoveryState` | string | `primary_discovered`, `primary_discovered_baseline_exempt`, or `outside_primary_discovery` |
|
|
| `closureDecision` | string | `generic_contract_enrollment`, `intentional_exemption`, `separately_governed`, `retired_no_longer_relevant`, or `harmless_special_case` |
|
|
| `reasonCategory` | string or null | Required for every decision except pure enrollment |
|
|
| `explicitReason` | string | Short reviewable explanation |
|
|
| `evidence` | array<CoverageEvidenceDescriptor> | Structured evidence descriptors that justify the decision |
|
|
| `followUpAction` | string | `none`, `tighten_reason`, `add_guard_only`, `add_focused_test`, or `consider_enrollment` |
|
|
| `mustRemainBaselineExempt` | boolean | True when the discovered page must stay in `baseline()` |
|
|
| `mustNotRemainBaselineExempt` | boolean | True when the surface must not remain in `baseline()` |
|
|
|
|
### CoverageEvidenceDescriptor
|
|
|
|
**Type**: derived proof entry
|
|
**Source**: existing test and spec references
|
|
|
|
| Field | Type | Notes |
|
|
|------|------|-------|
|
|
| `surfaceKey` | string | Links the evidence to one residual surface |
|
|
| `kind` | string | `guard_test`, `feature_livewire_test`, `authorization_test`, `workflow_spec`, `audit_test`, or `db_only_surface_test` |
|
|
| `reference` | string | Relative file path or stable spec reference |
|
|
| `proves` | string | What the evidence actually proves |
|
|
| `gapIfMissing` | boolean | True when Spec 195 should add or tighten coverage |
|
|
|
|
### DiscoveryBoundaryRule
|
|
|
|
**Type**: derived validator rule
|
|
**Source**: existing `ActionSurfaceDiscovery` behavior plus Spec 195 clarification
|
|
|
|
| Field | Type | Notes |
|
|
|------|------|-------|
|
|
| `boundaryKey` | string | Stable identifier for one primary-discovery boundary |
|
|
| `appliesTo` | string | `resources`, `relation_managers`, `pages`, `system_table_pages`, or `non_discovered_special_pages` |
|
|
| `currentRule` | string | Human-readable statement of what discovery includes or excludes |
|
|
| `silentGapRisk` | boolean | Whether a surface can currently evade review if the rule stays implicit |
|
|
| `spec195Mitigation` | string | How the residual inventory or guard closes that gap |
|
|
|
|
### ResidualSurfaceRegressionExpectation
|
|
|
|
**Type**: guard expectation entry
|
|
**Source**: Spec 195 validation rules derived from `mustRemainBaselineExempt`, `mustNotRemainBaselineExempt`, and the other closure-entry fields
|
|
|
|
| Field | Type | Notes |
|
|
|------|------|-------|
|
|
| `surfaceKey` | string | Residual surface under guard |
|
|
| `mustHaveClosureDecision` | boolean | Always true for in-scope residuals |
|
|
| `mustHaveReasonCategory` | boolean | True when not enrolled |
|
|
| `mustHaveEvidence` | boolean | True for every non-retired residual |
|
|
| `mustRemainInBaselineExemptions` | boolean | True only for discovered pages still intentionally outside the generic contract |
|
|
| `mustNotRemainInBaselineExemptions` | boolean | True for retired surfaces and non-discovered system pages |
|
|
| `needsFocusedTest` | boolean | True when existing evidence is not yet strong enough |
|
|
|
|
## Initial Seed Inventory for Spec 195
|
|
|
|
This is the planned closure inventory derived from current code and test evidence. The implementation audit added `system_dashboard` to the original 12-row seed because it is an action-bearing system surface that also sits outside primary discovery.
|
|
|
|
| Surface Key | Surface Name | Page Class | Current State | Planned Closure Decision | Reason Category | Strongest Evidence | Planned Follow-up |
|
|
|---|---|---|---|---|---|---|---|
|
|
| `system_dashboard` | `System Console Dashboard` | `App\Filament\System\Pages\Dashboard` | outside primary discovery, not exempt | `separately_governed` | `workflow_specific_governance` | `tests/Feature/System/Spec114/ControlTowerDashboardTest.php`, `tests/Feature/Auth/BreakGlassModeTest.php` | `add_guard_only` |
|
|
| `system_ops_view_run` | `System Ops View Run` | `App\Filament\System\Pages\Ops\ViewRun` | outside primary discovery, not exempt | `separately_governed` | `system_triage_surface` | `tests/Feature/System/Spec114/OpsTriageActionsTest.php`, `tests/Feature/Guards/Spec194GovernanceActionSemanticsGuardTest.php` | `add_guard_only` |
|
|
| `system_ops_runbooks` | `System Ops Runbooks` | `App\Filament\System\Pages\Ops\Runbooks` | outside primary discovery, not exempt | `separately_governed` | `workflow_specific_governance` | `tests/Feature/System/OpsRunbooks/FindingsLifecycleBackfillStartTest.php`, `tests/Feature/System/Spec113/AuthorizationSemanticsTest.php`, `tests/Feature/Guards/LivewireTrustedStateGuardTest.php` | `add_guard_only` |
|
|
| `repair_workspace_owners` | `Repair Workspace Owners` | `App\Filament\System\Pages\RepairWorkspaceOwners` | outside primary discovery, not exempt | `separately_governed` | `break_glass_repair_utility` | `tests/Feature/Auth/BreakGlassWorkspaceOwnerRecoveryTest.php`, `tests/Feature/Guards/FilamentTableStandardsGuardTest.php` | `add_guard_only` |
|
|
| `system_directory_view_tenant` | `System Directory View Tenant` | `App\Filament\System\Pages\Directory\ViewTenant` | outside primary discovery, not exempt | `harmless_special_case` | `read_mostly_context_detail` | current code is read-mostly with contextual links only | `add_focused_test` |
|
|
| `system_directory_view_workspace` | `System Directory View Workspace` | `App\Filament\System\Pages\Directory\ViewWorkspace` | outside primary discovery, not exempt | `harmless_special_case` | `read_mostly_context_detail` | current code is read-mostly with contextual links only | `add_focused_test` |
|
|
| `break_glass_recovery` | `Break Glass Recovery` | `App\Filament\Pages\BreakGlassRecovery` | primary discovered + baseline exempt, but currently inaccessible and actionless | `retired_no_longer_relevant` | `disabled_or_actionless_surface` | current page code: `canAccess() === false`, empty header actions | `tighten_reason` |
|
|
| `choose_workspace` | `Choose Workspace` | `App\Filament\Pages\ChooseWorkspace` | primary discovered + baseline exempt | `harmless_special_case` | `selector_routing_only` | `tests/Feature/Workspaces/ChooseWorkspacePageTest.php`, `tests/Feature/Workspaces/WorkspaceAuditTrailTest.php` | `none` |
|
|
| `choose_tenant` | `Choose Tenant` | `App\Filament\Pages\ChooseTenant` | primary discovered + baseline exempt | `harmless_special_case` | `selector_routing_only` | `tests/Feature/Auth/TenantChooserSelectionTest.php`, `tests/Feature/TenantRBAC/TenantSwitcherScopeTest.php` | `none` |
|
|
| `register_tenant` | `Register Tenant` | `App\Filament\Pages\Tenancy\RegisterTenant` | primary discovered + baseline exempt | `separately_governed` | `registration_form_with_dedicated_rbac` | `tests/Feature/Rbac/RegisterTenantAuthorizationTest.php`, `tests/Feature/TenantRBAC/TenantBootstrapAssignTest.php` | `none` |
|
|
| `managed_tenant_onboarding_wizard` | `Managed Tenant Onboarding Wizard` | `App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard` | primary discovered + baseline exempt | `separately_governed` | `workflow_specific_governance` | Spec 172 + extensive onboarding, audit, RBAC, and secret-safety tests | `none` |
|
|
| `managed_tenants_landing` | `Managed Tenants Landing` | `App\Filament\Pages\Workspaces\ManagedTenantsLanding` | primary discovered + baseline exempt | `harmless_special_case` | `landing_routing_surface` | current page code plus indirect workspace routing coverage | `add_focused_test` |
|
|
| `tenant_dashboard` | `Tenant Dashboard` | `App\Filament\Pages\TenantDashboard` | primary discovered + baseline exempt | `harmless_special_case` | `dashboard_shell_widget_owned` | `tests/Feature/Filament/TenantDashboardDbOnlyTest.php`, arrival-context and visibility tests | `none` |
|
|
|
|
## Discovery Boundary Rules
|
|
|
|
### Rule 1 — Generic primary discovery stays declaration-first
|
|
|
|
- Resources, relation managers, and normal pages remain discovered through the existing primary validator path.
|
|
- System pages remain discovered only when they are table-backed and declaration-backed.
|
|
- Spec 195 does not change that rule; it documents and guards it.
|
|
|
|
### Rule 2 — Residual non-discovered system/detail/workflow pages require supplemental closure inventory
|
|
|
|
- Any in-scope residual page outside primary discovery must still appear in the Spec 195 inventory.
|
|
- Being outside primary discovery no longer implies being outside governance.
|
|
|
|
### Rule 3 — Baseline exemptions remain only for discovered pages still intentionally outside the generic contract
|
|
|
|
- `baseline()` remains the compatibility mechanism for discovered pages without generic declarations.
|
|
- Spec 195 inventory adds the stronger closure semantics and structured evidence.
|
|
- Retired pages should leave `baseline()`.
|
|
|
|
## Resolution Rules
|
|
|
|
1. Every residual surface gets exactly one closure decision.
|
|
2. Non-enrolled residual surfaces must include a reason category, explicit reason, and at least one structured evidence descriptor.
|
|
3. Discovered pages that stay outside the generic contract may still remain in `baseline()`, but only if the Spec 195 inventory explains why.
|
|
4. Non-discovered pages must never rely on `baseline()` alone for closure; the residual inventory is the authoritative closure record.
|
|
5. `retired_no_longer_relevant` surfaces must not keep active baseline exemptions.
|
|
6. `harmless_special_case` is reserved for routing-only, read-mostly, or shell-like surfaces whose risk stays low and explicit.
|
|
7. `separately_governed` is reserved for surfaces with dedicated workflow rules, tests, or guards that already meaningfully constrain behavior.
|
|
8. If audit reveals a new residual surface outside the initial seed, it must be added to the inventory, contract surface key set, and guard expectations before the feature is considered complete. `system_dashboard` is the first such audited addition in this spec.
|
|
|
|
## Safety Rules
|
|
|
|
- No residual closure entry may weaken existing route scope, capability enforcement, audit behavior, or confirmation semantics.
|
|
- No residual surface may be marked harmless merely because it has low coverage; low coverage requires new tests, not a softer category.
|
|
- No special workflow may remain exempt only by historical memory; explicit evidence is required.
|
|
- No new residual page in the relevant namespaces may merge without a closure decision and structured evidence.
|