TenantAtlas/specs/195-action-surface-closure/data-model.md
ahmido 1c291fb9fe feat: close spec 195 action surface residuals (#230)
## 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
2026-04-13 07:47:58 +00:00

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.