---

description: "Task list for Spec 195 action-surface closure implementation"

---

# Tasks: Action Surface Enforcement, Enrollment, and Exception Closure

**Input**: Design documents from `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/195-action-surface-closure/`
**Prerequisites**: plan.md, spec.md, research.md, data-model.md, quickstart.md, contracts/action-surface-closure.logical.openapi.yaml

**Tests**: Runtime behavior changes in this repo require Pest coverage. This task list includes guard, feature, and focused residual-surface tests.
**Operations**: This feature does not add new long-running or queued work. Existing `OperationRun` and audit behavior on residual surfaces must remain unchanged.
**RBAC**: Existing 404 vs 403 semantics, capability checks, and destructive-action confirmations remain mandatory across the admin, tenant-context admin, and system planes.
**UI Naming**: No new operator-facing vocabulary is introduced; existing action copy remains domain-first and consistent.
**Operator Surfaces**: The affected surfaces are already classified in the spec and must be kept aligned with those classifications during implementation.
**Filament UI Action Surfaces**: This feature governs existing Filament pages and utilities without introducing a new page framework.
**Proportionality / Anti-Bloat**: Keep the implementation to one bounded residual inventory, validator checks, and focused tests. Do not add new persistence, enums, or runtime registries unless the implementation proves they are unavoidable.

## Phase 1: Setup (Shared Review Inputs)

**Purpose**: Confirm the current residual-surface scope and evidence sources before editing the shared support layer.

- [X] T001 Audit the current primary discovery and exemption entry points in `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceDiscovery.php`, `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceExemptions.php`, and `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceValidator.php`
- [X] T002 [P] Audit the existing focused evidence sources for residual surfaces in `apps/platform/tests/Feature/System/Spec114/OpsTriageActionsTest.php`, `apps/platform/tests/Feature/System/OpsRunbooks/FindingsLifecycleBackfillStartTest.php`, `apps/platform/tests/Feature/Auth/BreakGlassWorkspaceOwnerRecoveryTest.php`, `apps/platform/tests/Feature/Auth/TenantChooserSelectionTest.php`, `apps/platform/tests/Feature/Rbac/RegisterTenantAuthorizationTest.php`, `apps/platform/tests/Feature/Rbac/OnboardingWizardUiEnforcementTest.php`, and `apps/platform/tests/Feature/Filament/TenantDashboardDbOnlyTest.php`

---

## Phase 2: Foundational (Blocking Prerequisites)

**Purpose**: Add the shared Spec 195 inventory and validation scaffolding that all user stories depend on.

**⚠️ CRITICAL**: No user story work should begin until this phase is complete.

- [X] T003 [P] Add shared residual-inventory schema assertions for Spec 195 in `apps/platform/tests/Feature/Guards/ActionSurfaceValidatorTest.php`
- [X] T004 [P] Add shared contract-harness expectations for Spec 195 residual inventory consumption in `apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php`
- [X] T005 Implement the `spec195ResidualSurfaceInventory()` skeleton, required `surfaceName` field, and allowed closure vocabulary in `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceExemptions.php`
- [X] T006 Implement a validator-side residual-candidate boundary helper that preserves the existing primary discovery contract in `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceValidator.php`
- [X] T007 Extend `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceValidator.php` with reusable Spec 195 schema validation for allowed values, duplicate keys, evidence presence, and truthful discovery state

**Checkpoint**: Shared residual inventory and validator scaffolding are ready; user story work can now proceed.

---

## Phase 3: User Story 1 - Close the residual inventory (Priority: P1) 🎯 MVP

**Goal**: Make every in-scope residual surface appear exactly once with one closure decision, reason category where needed, and explicit evidence.

**Independent Test**: Review the final residual inventory and guard output alone and verify that the initial seed plus any additional audited residual surfaces have exactly one decision, no duplicates, and no missing evidence.

### Tests for User Story 1

- [X] T008 [P] [US1] Add completeness expectations for all Spec 195 residual surface keys in `apps/platform/tests/Feature/Guards/ActionSurfaceValidatorTest.php`
- [X] T009 [P] [US1] Add contract assertions for unique closure decisions, structured evidence descriptors, and baseline-alignment expectations in `apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php`

### Implementation for User Story 1

- [X] T010 [US1] Populate the initial seed and any newly audited Spec 195 residual closure entries with `surfaceName`, discovery state, closure decision, reason category, `explicitReason`, structured `evidence`, and `followUpAction` in `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceExemptions.php`
- [X] T011 [US1] Wire Spec 195 residual inventory consumption into `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceValidator.php` so every residual surface is checked exactly once

**Checkpoint**: User Story 1 is complete when the repo has a single complete Spec 195 inventory and its completeness is guard-tested.

---

## Phase 4: User Story 2 - Remove silent system and utility exceptions (Priority: P1)

**Goal**: Explicitly classify the currently uncatalogued system and utility surfaces so dangerous or decision-bearing system pages no longer live outside review discipline.

**Independent Test**: Review the system residual entries plus focused system tests and verify that `ViewRun`, `Runbooks`, `RepairWorkspaceOwners`, `ViewTenant`, and `ViewWorkspace` all have explicit closure states and no silent fallback path.

### Tests for User Story 2

- [X] T012 [P] [US2] Add residual guard coverage for `App\Filament\System\Pages\Ops\ViewRun`, `App\Filament\System\Pages\Ops\Runbooks`, and `App\Filament\System\Pages\RepairWorkspaceOwners` in `apps/platform/tests/Feature/Guards/Spec195ResidualActionSurfaceClosureGuardTest.php`
- [X] T013 [P] [US2] Add focused read-mostly closure coverage for `App\Filament\System\Pages\Directory\ViewTenant` and `App\Filament\System\Pages\Directory\ViewWorkspace` in `apps/platform/tests/Feature/System/Spec195/SystemDirectoryResidualSurfaceTest.php`

### Implementation for User Story 2

- [X] T014 [US2] Audit `apps/platform/app/Filament/System/Pages/Ops/ViewRun.php`, `apps/platform/app/Filament/System/Pages/Ops/Runbooks.php`, and `apps/platform/app/Filament/System/Pages/RepairWorkspaceOwners.php` and, if implementation reality differs from the design seed, update the matching entries in `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceExemptions.php`, `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceValidator.php`, and `apps/platform/tests/Feature/Guards/Spec195ResidualActionSurfaceClosureGuardTest.php`
- [X] T015 [US2] Audit `apps/platform/app/Filament/System/Pages/Directory/ViewTenant.php` and `apps/platform/app/Filament/System/Pages/Directory/ViewWorkspace.php` and, if the pages are not truly read-mostly harmless cases, update the matching entries in `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceExemptions.php`, `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceValidator.php`, and `apps/platform/tests/Feature/System/Spec195/SystemDirectoryResidualSurfaceTest.php`
- [X] T016 [US2] Tighten `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceValidator.php` so outside-primary-discovery system and utility pages cannot pass without Spec 195 closure data and, if any audited system page is promoted into generic contract enrollment, extend `apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php` and `apps/platform/tests/Feature/Guards/ActionSurfaceValidatorTest.php` to enforce inherited contract continuity

**Checkpoint**: User Story 2 is complete when the system/detail residual tail is explicitly classified and validated instead of relying on discovery accidents.

---

## Phase 5: User Story 3 - Keep only justified exemptions (Priority: P2)

**Goal**: Remove stale exemptions and require every remaining discovered exception to carry an explicit reason category and coverage note.

**Independent Test**: Review the discovered-page exemption set alone and verify that every remaining entry has a reason category, explicit reason, structured evidence, and no stale `BreakGlassRecovery` carry-over.

### Tests for User Story 3

- [X] T017 [P] [US3] Add stale-exemption and reason-category failure cases in `apps/platform/tests/Feature/Guards/Spec195ResidualActionSurfaceClosureGuardTest.php`
- [X] T018 [P] [US3] Add stale-exemption and baseline-removal assertions for `apps/platform/app/Filament/Pages/BreakGlassRecovery.php` in `apps/platform/tests/Feature/Guards/Spec195ResidualActionSurfaceClosureGuardTest.php` and `apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php`

### Implementation for User Story 3

- [X] T019 [US3] Audit `apps/platform/app/Filament/Pages/BreakGlassRecovery.php` and either retire it from live baseline handling or keep it as a live `intentional_exemption` with `security_flow_exception` in `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceExemptions.php`, `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceValidator.php`, and `apps/platform/tests/Feature/Guards/Spec195ResidualActionSurfaceClosureGuardTest.php`
- [X] T020 [US3] Tighten stale-baseline cleanup rules for retired or reasonless discovered exceptions in `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceExemptions.php` and `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceValidator.php`
- [X] T021 [US3] Extend `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceValidator.php` to reject reasonless discovered exemptions and retired surfaces that still remain in `baseline()`

**Checkpoint**: User Story 3 is complete when every surviving discovered-page exception is explicit, reasoned, and evidence-backed.

---

## Phase 6: User Story 4 - Block future unclassified residuals (Priority: P2)

**Goal**: Fail fast when future residual surfaces or exemptions appear without an explicit closure decision.

**Independent Test**: Introduce representative missing-classification and missing-reason cases in the guard suite and verify CI-style failures occur with actionable output.

### Tests for User Story 4

- [X] T022 [P] [US4] Create regression cases for missing closure decision, missing reason category, missing structured evidence, and stale baseline entries in `apps/platform/tests/Feature/Guards/Spec195ResidualActionSurfaceClosureGuardTest.php`
- [X] T023 [P] [US4] Extend `apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php` with a representative uncatalogued residual-surface failure path

### Implementation for User Story 4

- [X] T024 [US4] Extend `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceValidator.php` with namespace-scoped residual-candidate checks that preserve the existing generic discovery boundary and require Spec 195 inventory coverage for qualifying pages
- [X] T025 [US4] Improve `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceValidator.php` failure output and update `specs/195-action-surface-closure/quickstart.md` so missing Spec 195 classifications report actionable class and file context plus the reviewer classification workflow

**Checkpoint**: User Story 4 is complete when new residual surfaces or exemptions cannot merge silently without a closure decision.

---

## Phase 7: User Story 5 - Preserve good special surfaces without forced churn (Priority: P3)

**Goal**: Keep legitimately special selector, registration, onboarding, landing, and dashboard surfaces outside the generic contract where that is the safer and clearer choice.

**Independent Test**: Review the special-surface entries plus focused tests and verify that selectors, onboarding, registration, landing, and dashboard shells can remain separately governed or harmless without being mislabeled as defects.

### Tests for User Story 5

- [X] T026 [P] [US5] Create focused landing-surface coverage in `apps/platform/tests/Feature/Workspaces/Spec195ManagedTenantsLandingTest.php`
- [X] T027 [P] [US5] Extend special-surface evidence coverage with explicit positive and negative authorization paths in `apps/platform/tests/Feature/Rbac/RegisterTenantAuthorizationTest.php`, `apps/platform/tests/Feature/Rbac/OnboardingWizardUiEnforcementTest.php`, and `apps/platform/tests/Feature/Filament/TenantDashboardDbOnlyTest.php`
- [X] T028 [P] [US5] Extend selector-surface evidence coverage in `apps/platform/tests/Feature/Workspaces/ChooseWorkspacePageTest.php` and `apps/platform/tests/Feature/Auth/TenantChooserSelectionTest.php`

### Implementation for User Story 5

- [X] T029 [US5] If audit changes the design-seed classification for `apps/platform/app/Filament/Pages/ChooseWorkspace.php`, `apps/platform/app/Filament/Pages/ChooseTenant.php`, `apps/platform/app/Filament/Pages/TenantDashboard.php`, `apps/platform/app/Filament/Pages/Tenancy/RegisterTenant.php`, `apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php`, or `apps/platform/app/Filament/Pages/Workspaces/ManagedTenantsLanding.php`, update the matching entry in `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceExemptions.php` and the paired expectation in `apps/platform/tests/Feature/Guards/Spec195ResidualActionSurfaceClosureGuardTest.php`
- [X] T030 [US5] Align `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceValidator.php` so discovered special surfaces can remain `separately_governed` or `harmless_special_case` without forced `actionSurfaceDeclaration()` enrollment

**Checkpoint**: User Story 5 is complete when good special surfaces remain explicitly governed without unnecessary normalization.

---

## Phase 8: Polish & Cross-Cutting Verification

**Purpose**: Run the focused verification pack, format the touched files, and confirm the implementation matches the planning contract.

- [X] T031 Run the focused Spec 195 Sail verification pack from `specs/195-action-surface-closure/quickstart.md` against `apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php`, `apps/platform/tests/Feature/Guards/ActionSurfaceValidatorTest.php`, `apps/platform/tests/Feature/Guards/Spec195ResidualActionSurfaceClosureGuardTest.php`, `apps/platform/tests/Feature/Guards/Spec194GovernanceActionSemanticsGuardTest.php`, `apps/platform/tests/Feature/Guards/LivewireTrustedStateGuardTest.php`, `apps/platform/tests/Feature/Guards/FilamentTableStandardsGuardTest.php`, `apps/platform/tests/Feature/System/Spec113/AuthorizationSemanticsTest.php`, `apps/platform/tests/Feature/System/Spec114/OpsTriageActionsTest.php`, `apps/platform/tests/Feature/System/OpsRunbooks/FindingsLifecycleBackfillStartTest.php`, `apps/platform/tests/Feature/Auth/BreakGlassWorkspaceOwnerRecoveryTest.php`, `apps/platform/tests/Feature/Auth/TenantChooserSelectionTest.php`, `apps/platform/tests/Feature/Workspaces/ChooseWorkspacePageTest.php`, `apps/platform/tests/Feature/Workspaces/WorkspaceAuditTrailTest.php`, `apps/platform/tests/Feature/TenantRBAC/TenantSwitcherScopeTest.php`, `apps/platform/tests/Feature/Rbac/RegisterTenantAuthorizationTest.php`, `apps/platform/tests/Feature/TenantRBAC/TenantBootstrapAssignTest.php`, `apps/platform/tests/Feature/Rbac/OnboardingWizardUiEnforcementTest.php`, `apps/platform/tests/Feature/Onboarding/OnboardingDraftAccessTest.php`, `apps/platform/tests/Feature/Filament/TenantDashboardDbOnlyTest.php`, `apps/platform/tests/Feature/Rbac/TenantDashboardArrivalContextVisibilityTest.php`, `apps/platform/tests/Feature/System/Spec195/SystemDirectoryResidualSurfaceTest.php`, and `apps/platform/tests/Feature/Workspaces/Spec195ManagedTenantsLandingTest.php`
- [X] T032 Run `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` and resolve formatting issues in `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceDiscovery.php`, `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceExemptions.php`, `apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceValidator.php`, `apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php`, `apps/platform/tests/Feature/Guards/ActionSurfaceValidatorTest.php`, `apps/platform/tests/Feature/Guards/Spec195ResidualActionSurfaceClosureGuardTest.php`, `apps/platform/tests/Feature/System/Spec195/SystemDirectoryResidualSurfaceTest.php`, and `apps/platform/tests/Feature/Workspaces/Spec195ManagedTenantsLandingTest.php`
- [X] T033 Verify the final residual inventory matches `specs/195-action-surface-closure/contracts/action-surface-closure.logical.openapi.yaml`, includes human-readable `surfaceName` values, and covers the initial seed plus any newly audited residual surfaces described in `specs/195-action-surface-closure/data-model.md`

---

## Dependencies

- Setup tasks T001-T002 precede all implementation work.
- Foundational tasks T003-T007 block all user stories.
- User Story 1 depends on Phase 2 and unlocks the actual residual inventory.
- User Story 2, User Story 3, and User Story 5 depend on User Story 1 because they classify concrete residual entries inside the shared inventory.
- User Story 4 depends on User Story 1, User Story 2, User Story 3, and User Story 5 because the regression guard must validate the final closure state.
- Polish tasks T031-T033 depend on all user stories being complete.

## Parallel Execution Examples

- After T001, run T002 in parallel with any remaining setup review.
- In Phase 2, T003 and T004 can run in parallel before T005-T007 land.
- In User Story 1, T008 and T009 can run in parallel.
- In User Story 2, T012 and T013 can run in parallel.
- In User Story 3, T017 and T018 can run in parallel.
- In User Story 4, T022 and T023 can run in parallel.
- In User Story 5, T026, T027, and T028 can run in parallel.

## Implementation Strategy

- Start with Phase 2 and User Story 1 to establish the residual inventory and validator contract.
- Deliver User Story 2 next to close the highest-risk system and utility surfaces first.
- Follow with User Story 3 and User Story 5 to normalize discovered exceptions and preserve legitimate special workflows.
- Complete User Story 4 only after the closure states are finalized so the new guard enforces the finished model instead of a moving target.
- Finish with the focused Sail verification pack and Pint formatting from Phase 8.
