--- description: "Task list for Spec 082 implementation" --- # Tasks: Action Surface Contract + CI Enforcement **Input**: Design documents from `/specs/082-action-surface-contract/` **Prerequisites**: plan.md (required), spec.md (required), research.md, data-model.md, contracts/, quickstart.md **Tests**: Required (Pest) — this feature adds/changes CI enforcement. ## Phase 1: Setup (Shared Infrastructure) **Purpose**: Introduce the new support namespace and a guard-test entry point. - [X] T001 Create ActionSurface namespaces in app/Support/Ui/ActionSurface/ - [X] T002 [P] Add guard test skeleton in tests/Feature/Guards/ActionSurfaceContractTest.php - [X] T003 [P] Add validator test skeleton in tests/Feature/Guards/ActionSurfaceValidatorTest.php --- ## Phase 2: Foundational (Blocking Prerequisites) **Purpose**: Core contract model + discovery + validation that all user stories rely on. - [X] T004 Create enums for component/profile/slot in app/Support/Ui/ActionSurface/Enums/ActionSurfaceComponentType.php - [X] T005 [P] Create slot + exemption value objects in app/Support/Ui/ActionSurface/ActionSurfaceExemption.php - [X] T006 [P] Create declaration + defaults DTOs in app/Support/Ui/ActionSurface/ActionSurfaceDeclaration.php - [X] T007 Implement profile definitions (required slots per profile) in app/Support/Ui/ActionSurface/ActionSurfaceProfileDefinition.php - [X] T008 Implement in-scope discovery (tenant discovery roots + admin explicit registrations/routes; exclude Widgets and System panel) in app/Support/Ui/ActionSurface/ActionSurfaceDiscovery.php - [X] T009 Implement declaration contract validation (declare-or-exempt; reason required; More label; Export default) in app/Support/Ui/ActionSurface/ActionSurfaceValidator.php - [X] T010 Add fast unit-style tests for validator rules in tests/Feature/Guards/ActionSurfaceValidatorTest.php (pure validation logic, no DB or Filament boot) **Checkpoint**: Validator can enumerate + validate in-scope components deterministically. --- ## Phase 3: User Story 1 — Prevent incomplete UI action surfaces (Priority: P1) 🎯 MVP **Goal**: CI fails if an in-scope Filament component lacks a declaration (or an explicit exemption with a non-empty reason). **Independent Test**: Add a new in-scope Filament component without a declaration; run the guard and confirm it fails with an actionable message; add a declaration/exemption and confirm it passes. - [X] T011 [US1] Implement the CI guard that runs validation in tests/Feature/Guards/ActionSurfaceContractTest.php - [X] T012 [US1] Add baseline exemptions registry in app/Support/Ui/ActionSurface/ActionSurfaceExemptions.php (reason required, explicit class allowlist with shrink-over-time rule) - [X] T013 [US1] Wire exemptions into validator output in app/Support/Ui/ActionSurface/ActionSurfaceValidator.php - [X] T014 [US1] Make guard output actionable (class + slot + hint) in tests/Feature/Guards/ActionSurfaceContractTest.php - [X] T015 [US1] Add tests proving widgets are excluded from scope in tests/Feature/Guards/ActionSurfaceContractTest.php - [X] T031 [US1] Add tests proving unknown classes are not auto-exempted and every exemption reason is non-empty in tests/Feature/Guards/ActionSurfaceContractTest.php **Checkpoint**: Guard passes on main branch state, but blocks missing declarations going forward. --- ## Phase 4: User Story 2 — Consistent, enterprise-grade actions and empty-state guidance (Priority: P2) **Goal**: Provide consistent action-surface conventions (More grouping, Export default for RunLog/ReadOnly, empty-state CTA) and demonstrate them on representative surfaces. **Independent Test**: Pick one CRUD-style list and one run-log style list; verify each has expected action areas (header/row/bulk/empty-state; detail header actions) and consistent ordering/grouping. - [X] T016 [P] [US2] Define required slots for CRUD/ReadOnly/RunLog/RelationManager profiles in app/Support/Ui/ActionSurface/ActionSurfaceProfileDefinition.php - [X] T017 [P] [US2] Enforce defaults: More label + Export expectation for ReadOnly/RunLog in app/Support/Ui/ActionSurface/ActionSurfaceValidator.php - [X] T018 [US2] Add a declaration to a representative CRUD surface in app/Filament/Resources/PolicyResource.php - [X] T019 [US2] Ensure list empty-state CTA exists for the CRUD surface in app/Filament/Resources/PolicyResource/Pages/ListPolicies.php - [X] T020 [US2] Add a declaration to a representative RunLog surface in app/Filament/Resources/OperationRunResource.php - [X] T021 [US2] Ensure Export bulk action is present (or exempted with reason) for the RunLog surface in app/Filament/Resources/OperationRunResource.php - [X] T022 [US2] Add a declaration to one embedded relationship sub-list in app/Filament/Resources/PolicyResource/RelationManagers/VersionsRelationManager.php - [X] T023 [US2] Add tests asserting the representative declarations satisfy required slots in tests/Feature/Guards/ActionSurfaceContractTest.php - [X] T032 [US2] Add representative runtime test asserting PolicyResource row/bulk grouping uses “More” conventions in tests/Feature/Guards/ActionSurfaceContractTest.php - [X] T033 [US2] Add representative runtime test asserting canonical tenantless “View run” link usage in tests/Feature/Guards/ActionSurfaceContractTest.php - [X] T035 [US2] Add golden regression tests for “view-only lists use clickable rows without row actions” in tests/Feature/Guards/ActionSurfaceContractTest.php - [X] T036 [US2] Document action-surface contract rules (including “no lone View button; prefer clickable rows”) in docs/ui/action-surface-contract.md **Checkpoint**: At least one CRUD + one RunLog + one embedded sub-list visibly follow the conventions. --- ## Phase 5: User Story 3 — Predictable RBAC behavior for members vs non-members (Priority: P3) **Goal**: Validate consistent 404 vs 403 semantics and disabled-UI behavior for capability-gated actions. **Independent Test**: Use a representative surface and verify (a) non-member receives not-found, and (b) member without capability receives forbidden and sees disabled UI with a helpful explanation. - [X] T024 [P] [US3] Add non-member 404 route test on representative operations detail route in tests/Feature/Rbac/ActionSurfaceRbacSemanticsTest.php - [X] T025 [US3] Add member-without-capability 403 server-side test by attempting to execute ListEntraGroupSyncRuns::sync_groups as a readonly member in tests/Feature/Filament/EntraGroupSyncRunResourceTest.php - [X] T026 [US3] In that 403 test, assert no EntraGroupSyncJob is pushed and no EntraGroupSyncRun is created for the tenant in tests/Feature/Filament/EntraGroupSyncRunResourceTest.php - [X] T027 [US3] Ensure disabled-UI semantics are covered for the same action (visible + disabled + standard tooltip) in tests/Feature/Filament/EntraGroupSyncRunResourceTest.php - [X] T034 [US3] Add representative observability/audit regression assertion for an operation-start action (OperationRun record present with scope + actor) in tests/Feature/Guards/ActionSurfaceContractTest.php **Checkpoint**: One surface per profile has coverage for 404 vs 403 semantics. --- ## Phase 6: Polish & Cross-Cutting Concerns - [X] T028 [P] Run formatter on changed files via vendor/bin/sail bin pint --dirty - [X] T029 Run focused guard tests via vendor/bin/sail artisan test --compact tests/Feature/Guards/ActionSurfaceContractTest.php - [X] T030 Run RBAC semantics test via vendor/bin/sail artisan test --compact tests/Feature/Rbac/ActionSurfaceRbacSemanticsTest.php --- ## Dependencies & Execution Order - Setup (Phase 1) → Foundational (Phase 2) → US1 (Phase 3) → US2/US3 (Phases 4–5 can proceed in parallel) → Polish (Phase 6) ## Parallel Opportunities - Phase 2: DTOs/enums (T004–T006) can be done in parallel. - US2: Profile definition + validator rules (T016–T017) can be done in parallel. - US3: Test scaffolding (T024) can be done in parallel with US2 retrofit tasks. ## Parallel Example: US2 - T018 (PolicyResource declaration) can be implemented in parallel with T020 (OperationRunResource declaration). ## Implementation Strategy ### MVP First (US1 only) 1. Complete Phase 1 + Phase 2. 2. Implement Phase 3 (US1) guard + exemptions. 3. Validate guard behavior by adding/removing a declaration locally. ### Incremental Delivery - Add US2 representative surfaces next (PolicyResource + OperationRunResource + one RelationManager). - Add US3 RBAC semantics tests last (keeps scope tight while contract infrastructure stabilizes).