18 KiB
Tasks: Spec 363 - Explicit UiActionContext Contract for Scoped No-Record Actions
Input: /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/363-explicit-uiactioncontext-contract/spec.md, plan.md, and checklists/requirements.md
Prerequisites: spec.md and plan.md
Tests: REQUIRED (Pest). Use Unit + Feature/Filament-Livewire + Architecture/guard. Browser is optional only if visible copy/hierarchy changes materially.
Operations: Modal open must not create OperationRun records, dispatch provider/write jobs, or mutate records. Submit/execute must reauthorize with explicit context.
RBAC: Reuse existing policies/gates, UiEnforcement, WorkspaceUiEnforcement, capability resolvers, and deny-as-not-found semantics. No new capability strings.
Filament / Panel Guardrails: Filament remains v5 on Livewire v4. Provider registration stays in apps/platform/bootstrap/providers.php. No new panel, global-search change, or asset strategy is allowed.
Organization: Tasks are ordered by dependency. Tests and guardrails come before or alongside runtime edits.
Repo Baseline At Prep Time
- Branch before Spec Kit creation:
platform-dev - HEAD before Spec Kit creation:
548a37c8 feat: implement sync capture backup operation semantics (#433) git status --short --branchbefore Spec Kit creation: clean- Spec Kit branch created:
363-explicit-uiactioncontext-contract - Implementation PR branch target:
feat/363-explicit-uiactioncontext-contractfromdev; reconcile branch shape before runtime edits - Candidate source: direct user-provided Spec 363 draft in
/Users/ahmeddarrazi/.codex/attachments/36f3aea8-0303-4548-a83c-9f1cdd15f527/pasted-text.txt - Completed-spec context only: Specs 338, 340, 358, 359, 360, 361, and 362 are dependency/history context and must not be reopened during Spec 363 implementation
- Scope guardrail: no migrations, no panel/provider changes, no assets, no global-search changes, no OperationRun redesign, no broad record-backed action migration, and no product-feature expansion
Test Governance Checklist
- Lane assignment remains explicit and narrowest sufficient (Unit + Feature/Filament-Livewire + Architecture/guard; Browser optional only when visible UI changes require it).
- Shared helpers keep workspace/environment/member/capability setup opt-in and do not create expensive defaults.
- Tests prove business truth: context resolution, RBAC affordance, server reauthorization, no-run/no-job on modal open, and wrong-scope fail-closed behavior.
- Static guard failures are actionable and do not rely on broad permanent legacy allowlists.
- Final close-out records no-migration, no-asset, no-panel-provider, no-global-search, and no-compatibility-shim status.
Implementation Close-Out Notes
- Runtime implementation ran on
feat/363-explicit-uiactioncontext-contractfromdev. - Repo-truth names differ from the draft:
TenantReviewResource,TenantDiagnostics, andTenantDashboardare the current environment review/diagnostics/dashboard surfaces. apps/platform/tests/Support/Filament/ScopedActionAssertions.phpwas not added because the final focused tests did not duplicate enough setup to justify a new helper.- Browser smoke was not run because the implementation does not materially change visible hierarchy or add new visible page/modal copy beyond the existing disabled-context tooltip path.
- No migrations, assets, panel/provider registration changes, global-search changes, new capabilities, new operation types, or compatibility shim were introduced.
Phase 1: Setup and Repo Truth Inventory
Purpose: confirm exact current branch, callsites, action names, and related completed-spec context before runtime edits.
- T001 Re-read
spec.md,plan.md,checklists/requirements.md,.specify/memory/constitution.md,docs/ai-coding-rules.md,docs/architecture-guidelines.md,docs/security-guidelines.md,docs/testing-guidelines.md,docs/filament-guidelines.md,docs/research/filament-v5-notes.md, andspecs/362-sync-capture-backup-operation-semantics/artifacts/action-context-root-cause-audit.md. - T002 Confirm current branch, working tree, and baseline commit with
git status --short --branchandgit log -1 --oneline; before runtime edits, ensure implementation runs onfeat/363-explicit-uiactioncontext-contractfromdevor document the branch reconciliation in close-out. - T003 [P] Re-verify current
UiEnforcementandWorkspaceUiEnforcementbehavior inapps/platform/app/Support/Rbac/UiEnforcement.phpandapps/platform/app/Support/Rbac/WorkspaceUiEnforcement.php. - T004 [P] Re-verify Livewire referer context behavior in
apps/platform/app/Filament/Concerns/ResolvesPanelTenantContext.php; the draft-namedtests/Unit/Filament/ResolvesPanelTenantContextLivewireRefererTest.phpis not present on this branch, so resolver behavior is covered throughResolvesUiActionContextTestand admin resolver guard tests. - T005 [P] Re-inventory scoped no-record action callsites in
apps/platform/app/Filamentand record the exact current action names for Inventory, Policy, Entra Groups, Evidence Snapshot, Review Pack, Environment Review, Environment Diagnostics, Restore Run, and Environment Dashboard. - T006 Confirm no application implementation from Specs 338/340/358/359/360/361/362 needs to be rewritten; use those packages as context only.
Phase 2: Contract Unit Tests
Purpose: define the request-time action-context contract before changing action code.
- T007 [P] Add failing Unit tests in
apps/platform/tests/Unit/Support/Rbac/Actions/UiActionContextTest.phpfor workspace context, environment context, record context, system context, missing context,requireWorkspace(), andrequireEnvironment(). - T008 [P] Add failing Unit tests in
apps/platform/tests/Unit/Support/Rbac/Actions/ResolvesUiActionContextTest.phpor equivalent to prove page resolver, record resolver, workspace resolver, and missing-context behavior against actual repo relation names. - T009 [P] Add failing Unit tests in
apps/platform/tests/Unit/Support/Rbac/UiEnforcementScopedActionContextTest.phpproving scoped no-record actions require explicit context and missing context is distinct from non-membership/missing capability. - T010 [P] Add regression tests proving record-backed actions can still resolve scope from records without mandatory no-record context plumbing.
Checkpoint: tests describe the contract and fail for the current implicit fallback behavior.
Phase 3: Add Narrow Action Context Contract
Purpose: add the smallest support-layer API needed for scoped action context.
- T011 Add
apps/platform/app/Support/Rbac/Actions/UiActionScope.phpwith workspace, environment, record, and system scope values. - T012 Add
apps/platform/app/Support/Rbac/Actions/UiActionContextSource.phpwith explicit, page resolver, workspace context, record, Livewire referer, and missing source values where currently justified. - T013 Add
apps/platform/app/Support/Rbac/Actions/UiActionContext.phpas a readonly request-time value object withforWorkspace(),forEnvironment(),forRecord(),forSystem(),missing(),isMissing(), missing-reason accessors,requireWorkspace(), andrequireEnvironment()behavior or equivalent constructors/accessors. - T014 Add
apps/platform/app/Support/Rbac/Actions/ResolvesUiActionContext.phpor an equivalent helper that wraps existingResolvesPanelTenantContextand actual model relation names without inventing fake relations. - T015 Confirm no new persistence, migration, capability, operation type, panel/provider, route, asset, or global-search behavior was introduced.
Checkpoint: the new contract is narrow, request-time only, and covered by Unit tests.
Phase 4: Harden UiEnforcement For Scoped No-Record Actions
Purpose: make the shared RBAC UI path enforce explicit scoped context without breaking record-backed actions.
- T016 Add an explicit scoped-action entrypoint such as
UiEnforcement::forScopedAction(Action $action, UiActionContext|Closure $context)or a narrow compatible signature change that cannot be confused with nullable no-record context. - T017 Update context resolution inside
UiEnforcementso scoped no-record actions do not silently fall back toFilament::getTenant()as product scope truth. - T018 Add internal missing-context classification so tests can distinguish context-missing from non-member and missing-capability states.
- T019 Preserve existing record/action/table/bulk behavior where product scope is derived from a record or selected records.
- T020 Keep destructive/high-impact action confirmation behavior intact:
Action::make(...)->action(...),->requiresConfirmation()where applicable, server authorization, audit, and notification paths. - T021 Run the core Unit gate:
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/Rbac/Actions tests/Unit/Support/Rbac/UiEnforcementScopedActionContextTest.php tests/Unit/Support/Rbac/UiEnforcementTest.php
Checkpoint: UiEnforcement supports explicit context, fails closed for missing context, and does not break existing record-backed tests.
Phase 5: Retrofitted Action Tests First
Purpose: protect representative action lifecycle behavior before or during runtime retrofit.
- T022 [P] Extend inventory start-surface coverage in
apps/platform/tests/Feature/Inventory/InventorySyncStartSurfaceTest.php;apps/platform/tests/Feature/Filament/InventoryItemResourceTest.phpwas also run as the existing resource file. - T023 [P] Extend
apps/platform/tests/Feature/PolicySyncStartSurfaceTest.phpto keep first-click modal mount, noOperationRun, and no queued job on modal open under Livewire referer context. - T024 [P] Extend
apps/platform/tests/Feature/RunStartAuthorizationTest.php/ directory group coverage forsync_groupsno-record action: readonly and no run/job until submit; shared missing-context behavior is covered in Unit because the page itself aborts before mounting without environment context. - T025 [P] Extend
apps/platform/tests/Feature/Evidence/EvidenceSnapshotResourceTest.phpforcreate_snapshotfirst-click modal/no-run behavior;create_first_snapshotis covered by the static guard and existing empty-state coverage because it has no modal-open lifecycle. - T026 [P] Extend
apps/platform/tests/Feature/ReviewPack/ReviewPackResourceTest.phpforgenerate_packfirst-click modal/no-run behavior;generate_firststays covered through the shared action factory/static guard and existing readonly/entitlement empty-state assertions. - T027 [P] Extend Tenant Review coverage for repo-current
TenantReviewResource::makeCreateReviewAction()/create_reviewin existing tenant review UI tests and static guard. - T028 [P] Extend Environment Diagnostics coverage for repo-current
TenantDiagnosticsactionsbootstrapOwnerandmergeDuplicateMembershipsthrough existing diagnostics tests plus static guard. - T029 [P] Extend restore UI/enforcement coverage for
RestoreRunResource::makeCreateAction()and restore create/wizard through existing restore tests and static guard. - T030 [P] Extend Environment Dashboard support action coverage for repo-current
TenantDashboardsupport request and support diagnostics tests; support diagnostics retains its intentional audit-on-open behavior.
Checkpoint: tests capture representative action behavior and fail until actions use explicit context consistently.
Phase 6: Retrofit Representative Actions
Purpose: move known latent-risk no-record scoped actions to explicit UiActionContext.
- T031 Update
apps/platform/app/Filament/Resources/InventoryItemResource/Pages/ListInventoryItems.phpsorun_inventory_syncuses explicit action context and keeps handler reauthorization/no-run-on-modal-open behavior. - T032 Update
apps/platform/app/Filament/Resources/PolicyResource.phpandapps/platform/app/Filament/Resources/PolicyResource/Pages/ListPolicies.phpso Policy Sync uses explicit action context and keeps existing queued OperationRun UX. - T033 Update
apps/platform/app/Filament/Resources/EntraGroupResource/Pages/ListEntraGroups.phpsosync_groupsuses explicit environment action context and no longer depends on implicitFilament::getTenant()for scoped no-record state. - T034 Update
apps/platform/app/Filament/Resources/EvidenceSnapshotResource.phpandapps/platform/app/Filament/Resources/EvidenceSnapshotResource/Pages/ListEvidenceSnapshots.phpsocreate_snapshotandcreate_first_snapshotuse explicit environment action context. - T035 Update
apps/platform/app/Filament/Resources/ReviewPackResource.phpsogenerate_packandgenerate_firstuse explicit environment action context and entitlement/readonly checks use the same context. - T036 Update repo-current
apps/platform/app/Filament/Resources/TenantReviewResource.phpsocreate_reviewuses explicit environment action context and submit still validates capability/access before creating review/compose work. - T037 Update repo-current
apps/platform/app/Filament/Pages/TenantDiagnostics.phpsobootstrapOwnerandmergeDuplicateMembershipsuse explicit environment action context and modal open remains non-mutating. - T038 Update
apps/platform/app/Filament/Resources/RestoreRunResource.phpso Restore create entry/wizard context is explicit and restore/write gates remain separate. - T039 Update repo-current
apps/platform/app/Filament/Pages/TenantDashboard.phpso support request and support diagnostics actions use explicit environment action context. - T040 For any listed action whose current repo name differs from the draft, document the actual action name in the active feature close-out rather than inventing aliases.
Checkpoint: representative latent-risk actions use explicit context and tests prove first-click/modal/submit lifecycle behavior.
Phase 7: Test Helper and Static Guard
Purpose: prevent recurrence without creating a broad framework.
- T041 Add reusable test helper
apps/platform/tests/Support/Filament/ScopedActionAssertions.phponly if it reduces duplication across at least two retrofitted action tests; evaluated and not added. - T042 Helper assertion requirements are satisfied inline in focused tests where needed; no helper was introduced.
- T043 Add
apps/platform/tests/Feature/Architecture/ScopedUiActionContextContractTest.phpto scan risky scoped no-record action patterns underapps/platform/app/Filament. - T044 The guard flags guarded no-record action names, scoped-action wrapper markers, and regression to
UiEnforcement::forAction. - T045 Tune the guard to avoid record-backed row/table/detail false positives without hiding known risky actions.
- T046 Ensure guard failure output includes file, action or nearest action name, reason, and a fix hint such as using explicit
UiActionContext/ scoped action resolver. - T047 Do not add a permanent legacy allowlist for old no-record scoped action patterns.
Checkpoint: future risky no-record scoped actions fail fast unless they declare explicit context.
Phase 8: Validation
- T048 Run the core context and enforcement Unit gate:
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/Rbac/Actions tests/Unit/Support/Rbac/UiEnforcementScopedActionContextTest.php tests/Unit/Support/Rbac/UiEnforcementTest.php
- T049 Run the primary action lifecycle and guard gate:
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Architecture/ScopedUiActionContextContractTest.php tests/Feature/Filament/InventoryItemResourceTest.php tests/Feature/PolicySyncStartSurfaceTest.php tests/Feature/RunStartAuthorizationTest.php
- T050 Run the representative contextual action tests:
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/EntraGroupAdminScopeTest.php tests/Feature/Evidence/EvidenceSnapshotResourceTest.php tests/Feature/ReviewPack/ReviewPackResourceTest.php tests/Feature/Filament/RestoreRunUiEnforcementTest.php
- T051 Run additional focused tests for repo-current Tenant Review, Tenant Diagnostics, Restore create, and Tenant Dashboard support files after implementation names the exact existing or new test files, including the relevant existing SupportDiagnostics/SupportRequests action tests when those surfaces are touched.
- T052 Browser smoke not run; implementation changed existing action context behavior but not visible hierarchy/copy materially enough to require a browser pass under this spec's rule.
- T053 Run
cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent. - T054 Run
git diff --check. - T055 Record final close-out: changed files, new contract classes, retrofitted actions, intentionally untouched actions, static guard result, tests run, no legacy fallback retained for scoped no-record actions, and no migrations/assets/panel/global-search changes.
Dependencies & Execution Order
- Phase 1 must complete first.
- Phase 2 and Phase 3 establish the contract and should precede broad action retrofit.
- Phase 4 blocks action retrofit because callsites need the final
UiEnforcementAPI. - Phase 5 tests should be written before or beside Phase 6 runtime changes.
- Phase 7 guard can be developed after the first retrofits clarify the marker pattern, but must pass before close-out.
- Phase 8 closes the package.
Parallel Opportunities
- T003, T004, and T005 can run in parallel.
- T007, T008, T009, and T010 can run in parallel.
- T022 through T030 can be split by action family after the helper approach is decided.
- T031 through T039 can be split by action family after
UiEnforcementAPI stabilizes.
Explicit Non-Goals For Implementers
- Do not modify completed spec artifacts outside Spec 363.
- Do not add migrations, tables, persisted status, or action-context audit tables.
- Do not add new capabilities or operation types.
- Do not change Filament panel provider registration or panel paths.
- Do not enable or alter global search.
- Do not add assets or require
filament:assetsbecause of this spec. - Do not rewrite record-backed actions unless the guard proves they are actually no-record scoped risk.
- Do not turn this into support desk, billing, promotion, governance inbox, restore redesign, or AI runtime implementation.