Implements platform feature branch `285-workspace-rbac-environment-access`. Summary: - switch managed environment authorization to workspace-first role resolution with explicit environment-scope narrowing - rewire Filament pages, resources, policies, and user tenant access helpers to the shared access-scope resolver - add Spec 285 coverage across unit, feature, and browser tests plus full spec artifacts Validation: - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Auth/WorkspaceFirstCapabilityResolverTest.php tests/Unit/Auth/ManagedEnvironmentAccessScopeResolverTest.php` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Auth/WorkspaceFirstManagedEnvironmentAccessTest.php tests/Feature/Filament/ManagedEnvironmentAccessScopeManagementTest.php tests/Feature/Filament/WorkspaceMembershipRoleManagementTest.php tests/Feature/Rbac/GovernanceArtifactsWorkspaceFirstAuthorizationTest.php tests/Feature/Rbac/OperationRunWorkspaceFirstAuthorizationTest.php tests/Feature/Rbac/ProviderConnectionWorkspaceFirstPolicyTest.php` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Verification/ProviderExecutionReauthorizationTest.php tests/Feature/ProviderConnections/ProviderConnectionHealthCheckStartSurfaceTest.php tests/Feature/Tenants/TenantProviderBackedActionStartTest.php` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Audit/TenantMembershipAuditLogTest.php tests/Feature/Filament/TenantMembersTest.php tests/Feature/TenantRBAC/TenantMembershipCrudTest.php tests/Feature/TenantRBAC/TenantSwitcherScopeTest.php` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec285WorkspaceRbacEnvironmentAccessSmokeTest.php` - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` Target branch: `platform-dev`. Follow-up integration path after merge: - `platform-dev` -> `dev`. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #344
201 lines
24 KiB
Markdown
201 lines
24 KiB
Markdown
---
|
|
description: "Task list for Workspace-first RBAC & Environment Access Scoping"
|
|
---
|
|
|
|
# Tasks: Workspace-first RBAC & Environment Access Scoping
|
|
|
|
**Input**: Design documents from `specs/285-workspace-rbac-environment-access/`
|
|
**Prerequisites**: `specs/285-workspace-rbac-environment-access/spec.md`, `specs/285-workspace-rbac-environment-access/plan.md`, `specs/285-workspace-rbac-environment-access/checklists/requirements.md`, `specs/285-workspace-rbac-environment-access/research.md`, `specs/285-workspace-rbac-environment-access/data-model.md`, `specs/285-workspace-rbac-environment-access/quickstart.md`, and `specs/285-workspace-rbac-environment-access/contracts/workspace-rbac-environment-access.logical.openapi.yaml`
|
|
**Implementation Posture**: Runtime implementation completed in this branch.
|
|
**Tests**: REQUIRED (Pest). Keep proof bounded to `apps/platform/tests/Unit/Auth/WorkspaceFirstCapabilityResolverTest.php`, `apps/platform/tests/Unit/Auth/ManagedEnvironmentAccessScopeResolverTest.php`, `apps/platform/tests/Feature/Auth/WorkspaceFirstManagedEnvironmentAccessTest.php`, `apps/platform/tests/Feature/Rbac/ProviderConnectionWorkspaceFirstPolicyTest.php`, `apps/platform/tests/Feature/Rbac/OperationRunWorkspaceFirstAuthorizationTest.php`, `apps/platform/tests/Feature/Rbac/GovernanceArtifactsWorkspaceFirstAuthorizationTest.php`, `apps/platform/tests/Feature/Filament/WorkspaceMembershipRoleManagementTest.php`, `apps/platform/tests/Feature/Filament/ManagedEnvironmentAccessScopeManagementTest.php`, and `apps/platform/tests/Browser/Spec285WorkspaceRbacEnvironmentAccessSmokeTest.php`.
|
|
**Operations**: No new `OperationRun` family. Reuse `apps/platform/app/Support/Operations/OperationRunCapabilityResolver.php`, the current `OperationRunPolicy`, existing run links or monitoring surfaces, and the current `OperationRunService` lifecycle ownership.
|
|
**RBAC**: Workspace membership is the first `404` boundary, managed-environment scope is the second `404` boundary, and in-scope capability denials remain `403`. Provider capability or operability blockers remain downstream of local RBAC and must not be folded into user authorization.
|
|
**Shared Pattern Reuse**: Reuse `WorkspaceCapabilityResolver`, `CapabilityResolver`, `WorkspaceContext`, `WorkspaceMembershipManager`, `TenantMembershipManager` or its in-slice successor, `OperationRunCapabilityResolver`, and the current Filament relation-manager patterns. Do not add a new role family, a second ACL product, a compatibility shim, or adjacent Spec `284`, `286`, or `287` work.
|
|
**Filament / Panel Guardrails**: Filament remains v5 on Livewire v4. Provider registration remains in `apps/platform/bootstrap/providers.php`. `ProviderConnectionResource` remains non-globally-searchable while keeping valid `View` and `Edit` pages. Any touched destructive action must continue to use `->action(...)`, `->requiresConfirmation()`, and current server authorization. Asset strategy stays unchanged.
|
|
**Compatibility Posture**: Reject dual-write or fallback reads between workspace and environment role truth, reject per-environment role overrides, reject a second role selector on environment-scope surfaces, and keep Specs `284`, `286`, and `287` deferred.
|
|
**External Prerequisites**: Specs `280`, `281`, and `283` must already be merged or otherwise present on the implementation branch before any runtime or test task starts.
|
|
**Organization**: Tasks are grouped by user story so workspace-first core authorization, explicit environment-scope narrowing, and operator-facing membership-surface migration remain independently testable.
|
|
**Review Outcome**: `implemented-and-validated`
|
|
**Workflow Outcome**: `complete`
|
|
**Test-governance Outcome**: `keep`
|
|
|
|
## Test Governance Checklist
|
|
|
|
- [x] Lane assignment stays `fast-feedback`, `confidence`, and one narrow `browser` lane.
|
|
- [x] New or changed tests stay in the named unit, feature, and browser files only.
|
|
- [x] Workspace, managed-environment, and access-scope fixtures remain explicit and opt-in; no hidden global defaults or compatibility fixtures are planned.
|
|
- [x] Planned validation commands match `spec.md`, `plan.md`, and `quickstart.md` exactly.
|
|
- [x] `standard-native-filament`, `global-context-shell`, and shared authorization expectations stay explicit for touched surfaces.
|
|
- [x] Any attempt to absorb Specs `284`, `286`, or `287` resolves as `split` or `reject-or-split`, not hidden follow-up.
|
|
|
|
## Phase 0: External Gate
|
|
|
|
**Purpose**: Confirm the prerequisite cutover slices are present before implementation begins.
|
|
|
|
- [x] T000 Confirm Specs `280`, `281`, and `283` are already merged or otherwise present on the implementation branch before any runtime or test task begins.
|
|
|
|
---
|
|
|
|
## Phase 1: Setup (Shared Context)
|
|
|
|
**Purpose**: Confirm the exact repo seams, bounded proof files, and deferred-scope posture before runtime edits begin.
|
|
|
|
- [x] T001 Review `specs/285-workspace-rbac-environment-access/spec.md`, `plan.md`, `checklists/requirements.md`, `research.md`, `data-model.md`, `quickstart.md`, and `contracts/workspace-rbac-environment-access.logical.openapi.yaml` together so implementation stays on Spec `285` only.
|
|
- [x] T002 [P] Confirm the current workspace-role seams in `apps/platform/app/Models/WorkspaceMembership.php`, `apps/platform/app/Services/Auth/WorkspaceCapabilityResolver.php`, `apps/platform/app/Services/Auth/WorkspaceMembershipManager.php`, and any supporting workspace-role enums or policies before changing shared authorization logic.
|
|
- [x] T003 [P] Confirm the current managed-environment membership seams in `apps/platform/app/Models/ManagedEnvironmentMembership.php`, `apps/platform/app/Services/Auth/CapabilityResolver.php`, `apps/platform/app/Services/Auth/TenantMembershipManager.php`, and any supporting tenant-role or role-capability mapping files before retargeting environment access.
|
|
- [x] T004 [P] Confirm the current user and workspace-context seams in `apps/platform/app/Models/User.php` and `apps/platform/app/Support/Workspaces/WorkspaceContext.php` before retargeting tenant selection, remembered context, and `canAccessTenant()`.
|
|
- [x] T005 [P] Confirm the current policy and run-authorization seams in `apps/platform/app/Policies/ProviderConnectionPolicy.php`, `apps/platform/app/Policies/OperationRunPolicy.php`, `apps/platform/app/Policies/FindingPolicy.php`, `apps/platform/app/Policies/EvidenceSnapshotPolicy.php`, `apps/platform/app/Policies/ReviewPackPolicy.php`, `apps/platform/app/Policies/TenantReviewPolicy.php`, `apps/platform/app/Policies/TenantOnboardingSessionPolicy.php`, and `apps/platform/app/Support/Operations/OperationRunCapabilityResolver.php` before changing environment-owned access rules.
|
|
- [x] T006 [P] Confirm the current operator-facing membership and searchable-resource seams in `apps/platform/app/Filament/Resources/TenantResource/Pages/ManageTenantMemberships.php`, `apps/platform/app/Filament/Resources/TenantResource/RelationManagers/TenantMembershipsRelationManager.php`, `apps/platform/app/Filament/Resources/Workspaces/RelationManagers/WorkspaceMembershipsRelationManager.php`, `apps/platform/app/Filament/Resources/TenantResource.php`, `apps/platform/app/Filament/Resources/Workspaces/WorkspaceResource.php`, `apps/platform/app/Filament/Resources/ProviderConnectionResource.php`, and any touched action helpers so the implementation does not leave duplicate role-editing paths or unsafe searchable results behind.
|
|
|
|
---
|
|
|
|
## Phase 2: Foundational (Blocking Prerequisites)
|
|
|
|
**Purpose**: Establish the proving suite and the canonical workspace-first access contract that all user stories depend on.
|
|
|
|
**Critical**: No user-story work should begin until this phase is complete.
|
|
|
|
- [x] T007 [P] Add failing coverage in `apps/platform/tests/Unit/Auth/WorkspaceFirstCapabilityResolverTest.php` for workspace-role resolution, per-request caching, capability evaluation without role-bearing managed-environment membership fallback, and boundary-safe denied-access diagnostics.
|
|
- [x] T008 [P] Add failing coverage in `apps/platform/tests/Unit/Auth/ManagedEnvironmentAccessScopeResolverTest.php` for inherited access when no scope rows exist, allowlist narrowing when scope rows exist, invalid scope rows outside the workspace boundary, and scope-row invalidation when workspace membership ends.
|
|
- [x] T009 [P] Add failing coverage in `apps/platform/tests/Feature/Auth/WorkspaceFirstManagedEnvironmentAccessTest.php` for `User::canAccessTenant()`, `getTenants()`, `getDefaultTenant()`, `WorkspaceContext`, and representative environment-owned list, run-list, and bulk-authorization preflight behavior using one shared workspace-first access contract without avoidable N+1 membership or scope lookups.
|
|
- [x] T010 [P] Add failing coverage in `apps/platform/tests/Feature/Rbac/ProviderConnectionWorkspaceFirstPolicyTest.php`, `apps/platform/tests/Feature/Rbac/OperationRunWorkspaceFirstAuthorizationTest.php`, and `apps/platform/tests/Feature/Rbac/GovernanceArtifactsWorkspaceFirstAuthorizationTest.php` for `404` versus `403` semantics across provider connections, runs, findings, evidence, review packs, and tenant reviews, including boundary-safe denied-access logging with no raw provider detail.
|
|
- [x] T011 [P] Add failing coverage in `apps/platform/tests/Feature/Filament/WorkspaceMembershipRoleManagementTest.php` and `apps/platform/tests/Feature/Filament/ManagedEnvironmentAccessScopeManagementTest.php` for workspace role management staying canonical, last-owner protection remaining workspace-scoped, environment-scope CRUD staying scope-only, and destructive actions preserving confirmation and authorization.
|
|
- [x] T012 [P] Add the narrow browser smoke in `apps/platform/tests/Browser/Spec285WorkspaceRbacEnvironmentAccessSmokeTest.php` for one workspace owner managing a member role, narrowing that member to one managed environment, and confirming shell access plus one environment-bound drilldown follow the new contract.
|
|
- [x] T013 Introduce the smallest shared workspace-first access contract under `apps/platform/app/Services/Auth/` by retargeting `WorkspaceCapabilityResolver`, `CapabilityResolver`, and any supporting helper seam so one canonical access decision answers workspace membership, optional environment scope, required capability, search visibility, and boundary-safe denied-access diagnostics without keeping dual role authority.
|
|
- [x] T014 Update `apps/platform/app/Models/ManagedEnvironmentMembership.php`, `apps/platform/app/Services/Auth/TenantMembershipManager.php`, and any directly cooperating support or audit seams so managed-environment membership semantics become a narrow access-scope overlay with no role-bearing authority and so scope rows are removed or invalidated when workspace membership ends.
|
|
|
|
**Checkpoint**: The proving files exist, the shared access contract is explicit, and no later story needs to invent a second authorization path.
|
|
|
|
---
|
|
|
|
## Phase 3: User Story 1 - Workspace membership alone authorizes environment resources (Priority: P1)
|
|
|
|
**Goal**: A workspace member with the required role can open environment-owned resources without any second role-bearing managed-environment membership.
|
|
|
|
**Independent Test**: Add a user through workspace membership only, open an allowed managed environment in that workspace, and confirm provider connections plus governance artifacts authorize from workspace role plus capability while non-members remain `404`.
|
|
|
|
### Tests for User Story 1
|
|
|
|
- [x] T015 [P] [US1] Extend `apps/platform/tests/Feature/Auth/WorkspaceFirstManagedEnvironmentAccessTest.php` after T013-T014 to prove workspace membership alone is sufficient when no explicit environment scope rows exist.
|
|
- [x] T016 [P] [US1] Extend `apps/platform/tests/Feature/Rbac/ProviderConnectionWorkspaceFirstPolicyTest.php` and `apps/platform/tests/Feature/Rbac/GovernanceArtifactsWorkspaceFirstAuthorizationTest.php` after T013-T014 to prove provider connections, findings, evidence snapshots, review packs, tenant reviews, onboarding sessions, and any touched searchable-resource destinations all authorize from workspace membership first and keep `404` versus `403` semantics honest.
|
|
|
|
### Implementation for User Story 1
|
|
|
|
- [x] T017 [US1] Update `apps/platform/app/Models/User.php` and `apps/platform/app/Support/Workspaces/WorkspaceContext.php` so tenant selection, default tenant resolution, remembered tenant context, and `canAccessTenant()` all consume the shared workspace-first access contract.
|
|
- [x] T018 [US1] Update `apps/platform/app/Policies/ProviderConnectionPolicy.php`, `apps/platform/app/Policies/FindingPolicy.php`, `apps/platform/app/Policies/EvidenceSnapshotPolicy.php`, `apps/platform/app/Policies/ReviewPackPolicy.php`, `apps/platform/app/Policies/TenantReviewPolicy.php`, `apps/platform/app/Policies/TenantOnboardingSessionPolicy.php`, and any directly touched searchable-resource visibility helpers or queries so workspace membership is the only role-bearing authority for environment-owned resources and inaccessible results stay hidden.
|
|
|
|
**Checkpoint**: Environment-owned pages and artifacts no longer require a second role-bearing managed-environment membership to authorize.
|
|
|
|
---
|
|
|
|
## Phase 4: User Story 2 - Explicit environment scope narrows access without changing roles (Priority: P1)
|
|
|
|
**Goal**: Workspace role stays canonical while optional explicit scope rows narrow which managed environments a member may open.
|
|
|
|
**Independent Test**: Give a workspace member access to only one managed environment, confirm the allowed environment opens, confirm a sibling environment in the same workspace returns `404`, and confirm the same workspace role capabilities apply inside the allowed environment.
|
|
|
|
### Tests for User Story 2
|
|
|
|
- [x] T019 [P] [US2] Extend `apps/platform/tests/Feature/Auth/WorkspaceFirstManagedEnvironmentAccessTest.php` after T013-T014 to prove explicit environment-scope allowlists narrow visibility, stale remembered tenant context is cleared, and missing scope rows default to inheritance across currently selectable managed environments in the workspace.
|
|
- [x] T020 [P] [US2] Extend `apps/platform/tests/Feature/Rbac/OperationRunWorkspaceFirstAuthorizationTest.php` after T013-T014 to prove workspace-bound runs authorize from workspace membership only while environment-bound runs additionally honor explicit environment scope before capability checks.
|
|
|
|
### Implementation for User Story 2
|
|
|
|
- [x] T021 [US2] Update `apps/platform/app/Models/User.php`, `apps/platform/app/Support/Workspaces/WorkspaceContext.php`, and any directly touched chooser or tenant-list helpers so explicit environment-scope rows narrow selection visibility and stale out-of-scope remembered environments are cleared.
|
|
- [x] T022 [US2] Update `apps/platform/app/Support/Operations/OperationRunCapabilityResolver.php`, `apps/platform/app/Policies/OperationRunPolicy.php`, and any directly touched run-link or monitoring helpers so workspace-bound and environment-bound runs follow the same workspace-first access contract.
|
|
|
|
**Checkpoint**: Environment scope acts only as visibility narrowing, and mixed workspace-bound versus environment-bound runs still authorize correctly.
|
|
|
|
---
|
|
|
|
## Phase 5: User Story 3 - Membership management surfaces stop editing duplicate role truth (Priority: P2)
|
|
|
|
**Goal**: Operators manage workspace roles in one place and managed-environment visibility in another, with no second role selector on the environment surface.
|
|
|
|
**Independent Test**: Open workspace membership management and the retargeted managed-environment access-scope surface, confirm roles are edited only at workspace level, confirm environment scope CRUD never exposes a role selector, and confirm destructive actions remain confirmation-protected.
|
|
|
|
### Tests for User Story 3
|
|
|
|
- [x] T023 [P] [US3] Extend `apps/platform/tests/Feature/Filament/WorkspaceMembershipRoleManagementTest.php` after T013-T014 to prove workspace membership remains the sole role editor, last-owner protection stays anchored at workspace scope, and audit logging remains intact.
|
|
- [x] T024 [P] [US3] Extend `apps/platform/tests/Feature/Filament/ManagedEnvironmentAccessScopeManagementTest.php` after T013-T014 to prove the retargeted managed-environment surface manages visibility scope only, never shows a second role selector, keeps destructive mutations behind `->requiresConfirmation()`, and writes audit records for scope add, remove, and clear or narrowing actions.
|
|
|
|
### Implementation for User Story 3
|
|
|
|
- [x] T025 [US3] Update `apps/platform/app/Services/Auth/WorkspaceMembershipManager.php`, `apps/platform/app/Filament/Resources/Workspaces/RelationManagers/WorkspaceMembershipsRelationManager.php`, and any directly touched workspace-role actions so workspace membership remains the only operator-facing role-editing path.
|
|
- [x] T026 [US3] Retarget `apps/platform/app/Filament/Resources/TenantResource/Pages/ManageTenantMemberships.php`, `apps/platform/app/Filament/Resources/TenantResource/RelationManagers/TenantMembershipsRelationManager.php`, and any directly touched action or label helpers so the surface becomes managed-environment access-scope management with no second role authority.
|
|
|
|
**Checkpoint**: The operator-facing UI can no longer recreate dual role truth after the backend cutover.
|
|
|
|
---
|
|
|
|
## Phase 6: Polish & Cross-Cutting Validation
|
|
|
|
**Purpose**: Run the exact bounded proof set, review the touched auth and Filament seams, and confirm the slice stayed inside Spec `285`.
|
|
|
|
- [x] T027 [P] Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Unit/Auth/WorkspaceFirstCapabilityResolverTest.php tests/Unit/Auth/ManagedEnvironmentAccessScopeResolverTest.php)`.
|
|
- [x] T028 [P] Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Feature/Auth/WorkspaceFirstManagedEnvironmentAccessTest.php tests/Feature/Rbac/ProviderConnectionWorkspaceFirstPolicyTest.php tests/Feature/Rbac/OperationRunWorkspaceFirstAuthorizationTest.php tests/Feature/Rbac/GovernanceArtifactsWorkspaceFirstAuthorizationTest.php tests/Feature/Filament/WorkspaceMembershipRoleManagementTest.php tests/Feature/Filament/ManagedEnvironmentAccessScopeManagementTest.php)`.
|
|
- [x] T029 [P] Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Browser/Spec285WorkspaceRbacEnvironmentAccessSmokeTest.php)`.
|
|
- [x] T030 [P] Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail bin pint --dirty --format agent)`.
|
|
- [x] T031 [P] Review `apps/platform/app/Models/User.php`, `apps/platform/app/Models/WorkspaceMembership.php`, `apps/platform/app/Models/ManagedEnvironmentMembership.php`, `apps/platform/app/Services/Auth/WorkspaceCapabilityResolver.php`, `apps/platform/app/Services/Auth/CapabilityResolver.php`, `apps/platform/app/Services/Auth/WorkspaceMembershipManager.php`, `apps/platform/app/Services/Auth/TenantMembershipManager.php`, `apps/platform/app/Support/Workspaces/WorkspaceContext.php`, `apps/platform/app/Policies/ProviderConnectionPolicy.php`, `apps/platform/app/Policies/OperationRunPolicy.php`, `apps/platform/app/Policies/FindingPolicy.php`, `apps/platform/app/Policies/EvidenceSnapshotPolicy.php`, `apps/platform/app/Policies/ReviewPackPolicy.php`, `apps/platform/app/Policies/TenantReviewPolicy.php`, `apps/platform/app/Policies/TenantOnboardingSessionPolicy.php`, `apps/platform/app/Filament/Resources/TenantResource/Pages/ManageTenantMemberships.php`, `apps/platform/app/Filament/Resources/TenantResource/RelationManagers/TenantMembershipsRelationManager.php`, `apps/platform/app/Filament/Resources/Workspaces/RelationManagers/WorkspaceMembershipsRelationManager.php`, `apps/platform/app/Support/Operations/OperationRunCapabilityResolver.php`, `apps/platform/app/Filament/Resources/TenantResource.php`, `apps/platform/app/Filament/Resources/Workspaces/WorkspaceResource.php`, `apps/platform/app/Filament/Resources/ProviderConnectionResource.php`, and `apps/platform/bootstrap/providers.php` to confirm Filament v5 / Livewire v4 compliance, unchanged provider-registration location, truthful non-global-search posture, preserved destructive-action confirmation plus authorization, boundary-safe denied-access diagnostics, unchanged asset strategy, and Specs `284`, `286`, and `287` staying deferred.
|
|
|
|
---
|
|
|
|
## Dependencies & Execution Order
|
|
|
|
### Phase Dependencies
|
|
|
|
- **Phase 0 (External Gate)**: no dependencies; complete before implementation starts.
|
|
- **Phase 1 (Setup)**: depends on Phase 0.
|
|
- **Phase 2 (Foundational)**: depends on Phase 1 and blocks all story work.
|
|
- **Phase 3 (US1)**: depends on Phase 2 and establishes workspace-first authorization for environment-owned resources.
|
|
- **Phase 4 (US2)**: depends on Phase 2 and should ship with or immediately after US1 so explicit environment narrowing lands on the final shared access contract.
|
|
- **Phase 5 (US3)**: depends on Phase 2 and should land after or with US1 and US2 so UI semantics match the backend contract.
|
|
- **Phase 6 (Polish)**: depends on all desired user stories being complete.
|
|
|
|
### User Story Dependencies
|
|
|
|
- **US1 (P1)**: independently testable after Phase 2 and is the first required increment.
|
|
- **US2 (P1)**: independently testable after Phase 2, but should ship after or with US1 because explicit scope narrowing depends on the final shared workspace-first access contract.
|
|
- **US3 (P2)**: independently testable after Phase 2, but should land after or with US1 and US2 so the UI reflects the final backend semantics instead of an intermediate state.
|
|
|
|
### Within Each User Story
|
|
|
|
- Write or extend the listed Pest coverage first and make it fail for the intended gap.
|
|
- Apply the smallest shared-seam changes needed to satisfy the story without reopening Specs `284`, `286`, or `287`.
|
|
- Re-run the narrowest relevant validation command for that story before moving to the next story.
|
|
|
|
## Parallel Execution Examples
|
|
|
|
- **Setup**: T002 through T006 can run in parallel once T000 and T001 fix the bounded scope.
|
|
- **Foundational**: T007 through T012 can run in parallel before T013 and T014 converge the shared access contract.
|
|
- **US1**: T015 and T016 can run in parallel; T017 and T018 should merge serially around shared user, context, and policy files.
|
|
- **US2**: T019 and T020 can run in parallel; T021 and T022 should merge serially around shared tenant-access and run-authorization seams.
|
|
- **US3**: T023 and T024 can run in parallel; T025 and T026 should merge serially around shared Filament membership surfaces.
|
|
- **Polish**: T027 through T030 can run in parallel after implementation is complete; T031 should close the bounded-scope review last.
|
|
|
|
## Implementation Strategy
|
|
|
|
### Suggested MVP Scope
|
|
|
|
- MVP = **US1 + US2 + US3**. The spec is not complete until the operator-facing role and scope surfaces are split in the same workspace-first model.
|
|
|
|
### Incremental Delivery
|
|
|
|
1. Complete Phase 0, Phase 1, and Phase 2.
|
|
2. Deliver US1 so workspace membership alone authorizes environment-owned resources.
|
|
3. Deliver US2 so optional explicit environment scope narrows visibility without changing role semantics.
|
|
4. Deliver US3 so operators can no longer edit duplicate role truth in the UI.
|
|
5. Finish with the exact validation commands and final bounded-scope review in Phase 6.
|
|
|
|
### Team Strategy
|
|
|
|
1. Parallelize the failing test work first.
|
|
2. Serialize merges around `apps/platform/app/Services/Auth/`, `apps/platform/app/Models/User.php`, `apps/platform/app/Support/Workspaces/WorkspaceContext.php`, `apps/platform/app/Policies/`, and the touched Filament relation managers to avoid conflicting contract-shape edits.
|
|
3. Reject any implementation branch that introduces a second role family, compatibility fallbacks, provider-boundary work, or adjacent-spec cutover work.
|
|
|
|
## Deferred Follow-Ups / Non-Goals
|
|
|
|
- Spec `284` provider-neutral artifact source taxonomy work
|
|
- Spec `286` broader UI copy, IA, and localization neutralization
|
|
- Spec `287` cutover quality gates and no-legacy enforcement beyond this bounded RBAC slice
|