# Tasks: Spec 341 - Canonical Link / Query Cleanup - Input: `specs/341-canonical-link-query-cleanup/spec.md`, `specs/341-canonical-link-query-cleanup/plan.md` - Preparation status: implementation-ready. **Tests**: Required. This spec hardens scope/URL semantics and must be guarded by deterministic Feature tests. ## Test Governance Checklist - [x] Lane assignment is explicit and narrow: Feature (navigation/scope contract). - [x] No new default-heavy helpers/factories/seeds are introduced. - [x] Contract tests are written before refactors to keep review safe. - [x] Any exception resolves as `document-in-feature`, `follow-up-spec`, or `reject-or-split`. ## Phase 1: Preparation And Repo Truth (blocks runtime changes) **Purpose**: Identify every remaining legacy scope query parsing seam and the canonical link helpers to reuse. - [x] T001 Re-read `specs/341-canonical-link-query-cleanup/spec.md`, `specs/341-canonical-link-query-cleanup/plan.md`, and this `tasks.md`. - [x] T002 Confirm branch and working tree intent and record baseline commit (`git status --short --branch`, `git log -1 --oneline`). - [x] T003 Inventory legacy scope query parsing in runtime code (focus: request query keys, not DB column names): - `apps/platform/app/Http/Middleware/EnsureWorkspaceSelected.php` (`query('tenant')`, `query('managed_environment_id')`) - `apps/platform/app/Support/Middleware/EnsureEnvironmentContextSelected.php` (legacy query hints) - `apps/platform/app/Support/OperateHub/OperateHubShell.php` (legacy query tenant hints) - `apps/platform/app/Filament/Pages/EnvironmentRequiredPermissions.php` (legacy query hint) - Search guard: `rg -n \"query\\('tenant'\\)|query\\('managed_environment_id'\\)\" apps/platform/app` - [x] T004 Inventory existing navigation contract tests and decide where Spec 341 regression coverage belongs: - `apps/platform/tests/Feature/Navigation/Spec322LegacyQueryAliasGuardTest.php` - `apps/platform/tests/Feature/Navigation/WorkspaceHubEnvironmentFilterContractTest.php` - `apps/platform/tests/Feature/Navigation/WorkspaceHubClearFilterContractTest.php` - `apps/platform/tests/Feature/Workspaces/WorkspaceHubContextContractTest.php` ## Phase 2: Add failing contract tests first **Purpose**: Make the cleanup reviewable and prevent accidental reintroduction of legacy scope hints. - [x] T005 Add a Spec 341 Feature test proving legacy scope query keys do not establish authority in shared seams: - Requests with `?tenant=` or `?managed_environment_id=` do not establish environment context and do not widen access. - Implement in: `apps/platform/tests/Feature/Navigation/Spec341CanonicalLinkQueryCleanupTest.php` - [x] T006 [P] Add a test proving workspace hub narrowing is `environment_id`-only: - Every in-scope hub URL accepts `environment_id`; - legacy aliases (`tenant`, `tenant_id`, `managed_environment_id`, `environment`, `tenant_scope`, `tableFilters`) are rejected/ignored. - Extend/verify: `apps/platform/tests/Feature/Navigation/WorkspaceHubEnvironmentFilterContractTest.php` - [x] T007 [P] Add a test proving environment-bound pages remain route-owned: - No environment-bound route derives environment scope from legacy query keys. - Target at least one representative environment-bound route (e.g. Baseline Compare) plus one middleware-driven entry. ## Phase 3: Remove legacy query scope hint parsing (Spec 341 contract) **Purpose**: Remove hidden environment authority sources and converge on explicit `environment_id` (hubs) or route-owned environment context (environment-bound pages). - [x] T008 Update `apps/platform/app/Http/Middleware/EnsureWorkspaceSelected.php`: - remove `?tenant=` / `?managed_environment_id=` handling as “explicit tenant context” signals; - keep workspace selection and deny-as-not-found semantics correct. - [x] T009 Update `apps/platform/app/Support/Middleware/EnsureEnvironmentContextSelected.php`: - remove legacy scope query hint parsing; - ensure workspace hubs remain exempt from tenant/environment selection requirements. - [x] T010 Update `apps/platform/app/Support/OperateHub/OperateHubShell.php`: - remove `resolveQueryTenantHint()` and related “explicit query tenant hint” behavior (or convert to ignore-only with no authority); - ensure all environment-bound context comes from route parameters + validated workspace context. - [x] T011 Update `apps/platform/app/Filament/Pages/EnvironmentRequiredPermissions.php`: - remove legacy query hint parsing; route-owned environment only. ## Phase 4: Align canonical link generation **Purpose**: Ensure the code never generates legacy scope query keys and that “clear filter” links return to clean canonical URLs. - [x] T012 Remove/replace any link generation that emits legacy scope query keys (focus: URL query keys, not Graph tenant context): - Use `rg -n \"\\?tenant=|\\btenant=\\\"|query\\('tenant'\\)\" apps/platform` to find offenders. - [x] T013 Confirm `apps/platform/app/Support/Navigation/WorkspaceHubNavigation.php` and `WorkspaceHubEnvironmentFilter.php` remain the single source for hub filter link building and parsing (`environment_id` only). - [x] T014 Confirm `apps/platform/app/Filament/Concerns/UsesAdminEnvironmentFilterQueryParameter.php` continues to strip legacy scope keys and that no new legacy keys are added elsewhere. ## Phase 5: Regression guards **Purpose**: Prevent future drift back to legacy scope query keys. - [x] T015 Add a guard test that fails if generated navigation URLs contain forbidden scope query keys (e.g. `tenant`, `tenant_id`, `managed_environment_id`, `environment`, `tenant_scope`, `tableFilters`). - [x] T016 If a bounded exception is proven necessary, document it explicitly in the spec/PR and add a dedicated test; otherwise treat legacy scope alias preservation as a blocker. ## Phase 6: Validation - [x] T017 Run narrow tests first: - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Navigation --filter=Spec341` - [x] T018 Run formatting and patch checks: - `cd apps/platform && ./vendor/bin/sail pint --dirty` - `git diff --check` ## Explicit Non-Goals - [x] NT001 Do not add migrations, new tables, or new persisted truth. - [x] NT002 Do not introduce a new link-normalization abstraction framework. - [x] NT003 Do not add compatibility redirects for legacy query keys. - [x] NT004 Do not change provider/OAuth behavior or credential flows (Spec 281 family).