TenantAtlas/specs/363-explicit-uiactioncontext-contract/tasks.md
Ahmed Darrazi 9e435ea91f
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m2s
feat: implement explicit UiActionContext contract
2026-06-07 13:12:02 +02:00

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 --branch before Spec Kit creation: clean
  • Spec Kit branch created: 363-explicit-uiactioncontext-contract
  • Implementation PR branch target: feat/363-explicit-uiactioncontext-contract from dev; 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-contract from dev.
  • Repo-truth names differ from the draft: TenantReviewResource, TenantDiagnostics, and TenantDashboard are the current environment review/diagnostics/dashboard surfaces.
  • apps/platform/tests/Support/Filament/ScopedActionAssertions.php was 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, and specs/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 --branch and git log -1 --oneline; before runtime edits, ensure implementation runs on feat/363-explicit-uiactioncontext-contract from dev or document the branch reconciliation in close-out.
  • T003 [P] Re-verify current UiEnforcement and WorkspaceUiEnforcement behavior in apps/platform/app/Support/Rbac/UiEnforcement.php and apps/platform/app/Support/Rbac/WorkspaceUiEnforcement.php.
  • T004 [P] Re-verify Livewire referer context behavior in apps/platform/app/Filament/Concerns/ResolvesPanelTenantContext.php; the draft-named tests/Unit/Filament/ResolvesPanelTenantContextLivewireRefererTest.php is not present on this branch, so resolver behavior is covered through ResolvesUiActionContextTest and admin resolver guard tests.
  • T005 [P] Re-inventory scoped no-record action callsites in apps/platform/app/Filament and 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.php for workspace context, environment context, record context, system context, missing context, requireWorkspace(), and requireEnvironment().
  • T008 [P] Add failing Unit tests in apps/platform/tests/Unit/Support/Rbac/Actions/ResolvesUiActionContextTest.php or 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.php proving 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.php with workspace, environment, record, and system scope values.
  • T012 Add apps/platform/app/Support/Rbac/Actions/UiActionContextSource.php with explicit, page resolver, workspace context, record, Livewire referer, and missing source values where currently justified.
  • T013 Add apps/platform/app/Support/Rbac/Actions/UiActionContext.php as a readonly request-time value object with forWorkspace(), forEnvironment(), forRecord(), forSystem(), missing(), isMissing(), missing-reason accessors, requireWorkspace(), and requireEnvironment() behavior or equivalent constructors/accessors.
  • T014 Add apps/platform/app/Support/Rbac/Actions/ResolvesUiActionContext.php or an equivalent helper that wraps existing ResolvesPanelTenantContext and 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 UiEnforcement so scoped no-record actions do not silently fall back to Filament::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.php was also run as the existing resource file.
  • T023 [P] Extend apps/platform/tests/Feature/PolicySyncStartSurfaceTest.php to keep first-click modal mount, no OperationRun, and no queued job on modal open under Livewire referer context.
  • T024 [P] Extend apps/platform/tests/Feature/RunStartAuthorizationTest.php / directory group coverage for sync_groups no-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.php for create_snapshot first-click modal/no-run behavior; create_first_snapshot is 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.php for generate_pack first-click modal/no-run behavior; generate_first stays 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_review in existing tenant review UI tests and static guard.
  • T028 [P] Extend Environment Diagnostics coverage for repo-current TenantDiagnostics actions bootstrapOwner and mergeDuplicateMemberships through 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 TenantDashboard support 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.php so run_inventory_sync uses explicit action context and keeps handler reauthorization/no-run-on-modal-open behavior.
  • T032 Update apps/platform/app/Filament/Resources/PolicyResource.php and apps/platform/app/Filament/Resources/PolicyResource/Pages/ListPolicies.php so Policy Sync uses explicit action context and keeps existing queued OperationRun UX.
  • T033 Update apps/platform/app/Filament/Resources/EntraGroupResource/Pages/ListEntraGroups.php so sync_groups uses explicit environment action context and no longer depends on implicit Filament::getTenant() for scoped no-record state.
  • T034 Update apps/platform/app/Filament/Resources/EvidenceSnapshotResource.php and apps/platform/app/Filament/Resources/EvidenceSnapshotResource/Pages/ListEvidenceSnapshots.php so create_snapshot and create_first_snapshot use explicit environment action context.
  • T035 Update apps/platform/app/Filament/Resources/ReviewPackResource.php so generate_pack and generate_first use explicit environment action context and entitlement/readonly checks use the same context.
  • T036 Update repo-current apps/platform/app/Filament/Resources/TenantReviewResource.php so create_review uses 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.php so bootstrapOwner and mergeDuplicateMemberships use explicit environment action context and modal open remains non-mutating.
  • T038 Update apps/platform/app/Filament/Resources/RestoreRunResource.php so Restore create entry/wizard context is explicit and restore/write gates remain separate.
  • T039 Update repo-current apps/platform/app/Filament/Pages/TenantDashboard.php so 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.php only 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.php to scan risky scoped no-record action patterns under apps/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 UiEnforcement API.
  • 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 UiEnforcement API 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:assets because 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.