TenantAtlas/specs/303-admin-directory-groups-cutover/spec.md
ahmido 1cd8d48474 feat: cut over admin directory groups (#358)
## Summary
- cut over `EntraGroupResource` to an environment-bound admin Directory Groups surface in the workspace-first runtime
- adopt workspace-scoped admin list/detail URLs and add the bounded `Directory > Groups` navigation entry in the admin panel
- keep workspace-home navigation clean while preserving existing scoped list, detail, and global-search behavior
- update focused feature coverage and add a browser smoke for the rendered sidebar drilldown path
- include the Spec 303 package under `specs/303-admin-directory-groups-cutover/`

## Testing
- updated focused Pest coverage for admin navigation segregation, Entra group admin scoping, Entra group global search scoping, and directory group browsing
- added browser smoke coverage in `apps/platform/tests/Browser/Spec303AdminDirectoryGroupsCutoverSmokeTest.php`

## Filament / Runtime Notes
- remains compliant with Filament v5 on Livewire v4
- no provider registration changes; provider registration location remains `apps/platform/bootstrap/providers.php`
- `EntraGroupResource` remains eligible for global search because it has a View page
- no destructive actions were added or changed; confirmation and authorization behavior is unchanged
- no asset registration changes; existing `cd apps/platform && php artisan filament:assets` deploy posture is unchanged

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #358
2026-05-14 22:44:44 +00:00

31 KiB

Feature Specification: Admin Directory Groups Cutover

Feature Branch: 303-admin-directory-groups-cutover Created: 2026-05-14 Status: Draft Input: User description: "Erstelle die naechste Spec als 303-admin-directory-groups-cutover. Entscheide und implementiere den admin role contract fuer EntraGroupResource als environment-bound Directory/Identity Surface im workspace-first Admin Runtime Modell."

Spec Candidate Check (mandatory - SPEC-GATE-001)

  • Problem: EntraGroupResource is already a scoped admin runtime surface with list, detail, and global-search behavior, but its navigation contract still preserves an older blanket admin-hidden assumption. Spec 302 identified this as the only real blocker for the next runtime repair.
  • Today's failure: Operators can reach directory groups through direct/scoped admin paths and global search, while admin navigation still says Groups are never an admin surface. Current tests also protect that stale hidden assumption.
  • User-visible improvement: Operators who are inside an active Workspace plus Managed Environment context can discover read-oriented Directory Groups consistently, while the workspace-home sidebar stays clean.
  • Smallest enterprise-capable version: Make Entra Groups a secondary environment-bound Directory/Identity surface. Keep list/detail/global search scoped to the active Managed Environment, ensure search destinations use canonical admin View URLs, and update stale navigation/search tests.
  • Explicit non-goals: No generic M365 Admin mirror, no broad Identity Center, no group lifecycle management, no group membership mutation workflow, no new admin actions, no tenant-panel dead-code cleanup, no navigation-contract-split except minimal test adjustment, no migrations, no assets.
  • Permanent complexity imported: No new models, tables, statuses, enums, services, registries, provider adapters, or UI frameworks. The permanent cost is a documented admin role contract plus focused navigation/search/scope tests.
  • Why now: docs/product/spec-candidates.md sequences admin-directory-groups-cutover directly after Spec 301 and Spec 302. Spec 302's audit matrix names Entra Groups product IA as the only blocker before the next runtime repair.
  • Why not local: A local one-line navigation flip would risk workspace-home leakage or unscoped search/detail destinations. The contract must distinguish workspace-home cleanliness from environment-bound Directory visibility and keep server-side RBAC/context checks authoritative.
  • Approval class: Workflow Compression
  • Red flags triggered: One provider-facing surface is touched, but it is bounded as provider-owned Directory inventory and does not introduce a platform-core identity framework.
  • Score: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 2 | Produktnaehe: 2 | Wiederverwendung: 1 | Gesamt: 11/12
  • Decision: approve

Spec Scope Fields (mandatory)

  • Scope: canonical-view
  • Primary Routes:
    • Entra Groups collection route in the admin panel, resolved only with an active Managed Environment context.
    • Entra Groups View route in the admin panel, resolved only for records in the active Managed Environment context.
    • Workspace-home route /admin/workspaces/{workspace} as the negative-control surface.
    • Canonical environment route /admin/workspaces/{workspace}/environments/{environment} as the positive-control surface.
  • Data Ownership: Existing EntraGroup rows remain managed-environment-owned directory cache records. This spec does not change tables, columns, Graph payload storage, or snapshot truth.
  • RBAC: Workspace membership and Managed Environment access are required for visibility and access. Existing server-side policy/capability checks remain the authority for list, detail, search, and any existing operation-start action. UI visibility is never authorization.

For canonical-view specs, the spec MUST define:

  • Default filter behavior when tenant-context is active: The Groups list and global search are scoped to the active Managed Environment resolved by the workspace-first admin shell. If no Managed Environment context exists, list access must deny as not found and search must return no unsafe records.
  • Explicit entitlement checks preventing cross-tenant leakage: Direct URL manipulation, stale remembered context, cross-workspace records, and cross-environment records must not reveal data. Non-members remain deny-as-not-found; members without the relevant capability remain denied by existing policy/capability semantics.

Cross-Cutting / Shared Pattern Reuse (mandatory when the feature touches notifications, status messaging, action links, header actions, dashboard signals/cards, alerts, navigation entry points, evidence/report viewers, or any other existing shared operator interaction family; otherwise write N/A - no shared interaction family touched)

  • Cross-cutting feature?: yes
  • Interaction class(es): Filament resource navigation, environment-bound sidebar visibility, global-search result destinations, read-only resource list/detail access.
  • Systems touched:
    • apps/platform/app/Filament/Resources/EntraGroupResource.php
    • apps/platform/app/Filament/Resources/EntraGroupResource/Pages/ListEntraGroups.php
    • apps/platform/app/Filament/Resources/EntraGroupResource/Pages/ViewEntraGroup.php
    • apps/platform/app/Filament/Concerns/ScopesGlobalSearchToTenant.php
    • apps/platform/app/Filament/Concerns/ResolvesPanelTenantContext.php
    • apps/platform/app/Filament/Concerns/WorkspaceScopedTenantRoutes.php
    • apps/platform/app/Providers/Filament/AdminPanelProvider.php
    • apps/platform/app/Support/Navigation/NavigationScope.php
    • apps/platform/app/Support/OperateHub/OperateHubShell.php
    • focused tests under apps/platform/tests/Feature/Filament/ and apps/platform/tests/Feature/DirectoryGroups/
  • Existing pattern(s) to extend: NavigationScope::shouldRegisterEnvironmentNavigation(), OperateHubShell environment context resolution, ScopesGlobalSearchToTenant, ResolvesPanelTenantContext, InteractsWithTenantOwnedRecords, and the existing canonical admin route/link helpers.
  • Shared contract / presenter / builder / renderer to reuse: Existing navigation/context/search traits and helpers. No new Directory navigation framework is introduced.
  • Why the existing shared path is sufficient or insufficient: The shared paths already solve environment detection, scoped query/search, and tenant-owned record resolution. They are insufficient only where EntraGroupResource::shouldRegisterNavigation() still returns false for every admin context.
  • Allowed deviation and why: No route-posture deviation is applied. EntraGroupResource adopts WorkspaceScopedTenantRoutes; the rendered sidebar link is registered explicitly in AdminPanelProvider because the runtime navigation contract uses explicit environment-bound entries for operator-facing surface links.
  • Consistency impact: Directory Groups must follow the same workspace-home clean-sidebar rule and environment-bound visibility rule as migrated tenant-owned surfaces, without becoming a broader Identity Center.
  • Review focus: Reviewers must verify the implementation removes only the stale Groups admin-hidden assumption, does not reopen workspace-home tenant-owned navigation, keeps search scoped, and does not introduce group mutation workflows.
  • Touches OperationRun start/completion/link UX?: no new OperationRun behavior.
  • Shared OperationRun UX contract/layer reused: Existing directory group sync behavior, if still present, remains outside this spec's new behavior and must continue using existing operation-start, notification, and link helpers.
  • Delegated start/completion UX behaviors: N/A for new behavior.
  • Local surface-owned behavior that remains: Existing Groups list operation/header actions may remain only as pre-existing behavior. This spec must not add, promote, or redesign mutation/admin actions.
  • Queued DB-notification policy: N/A.
  • Terminal notification path: N/A.
  • Exception required?: none.

Provider Boundary / Platform Core Check (mandatory when the feature changes shared provider/platform seams, identity scope, governed-subject taxonomy, compare strategy selection, provider connection descriptors, or operator vocabulary that may leak provider-specific semantics into platform-core truth; otherwise write N/A - no shared provider/platform boundary touched)

  • Shared provider/platform boundary touched?: yes, bounded to operator vocabulary and resource navigation.
  • Boundary classification: mixed, with provider-owned Directory data inside platform-owned workspace/environment context.
  • Seams affected: navigation label, resource label, global-search destination URL, empty-state copy if adjusted, tests that name the surface.
  • Neutral platform terms preserved or introduced: Workspace, Managed Environment, Directory Groups, Directory inventory, environment-bound surface.
  • Provider-specific semantics retained and why: "Microsoft Entra" and "Entra Group" remain where accuracy is required for the source object and provider cache. They must not become a broad platform-core identity framework.
  • Why this does not deepen provider coupling accidentally: The implementation is limited to one existing provider-owned resource and does not add shared identity abstractions, provider capability registries, tables, or Graph adapters.
  • Follow-up path: navigation-contract-split remains conditional after this spec; broader Directory/Admin Roles IA remains out of scope unless separately promoted.

UI / Surface Guardrail Impact (mandatory when operator-facing surfaces are changed; otherwise write N/A)

Surface / Change Operator-facing surface change? Native vs Custom Shared-Family Relevance State Layers Touched Exception Needed? Low-Impact / N/A Note
Workspace-home sidebar yes, negative control Native Filament navigation navigation shell, route context no Must remain clean; no Groups entry without active environment context
Environment-bound admin sidebar Directory Groups entry yes Native Filament resource navigation navigation shell, route context no Secondary Directory surface visible only in active Managed Environment context
Entra Groups list page yes, contract clarification Native Filament resource table resource list, empty state page, table, tenant-owned query no Read-oriented list remains scoped; no new actions
Entra Group View page yes, destination contract Native Filament View page/infolist resource detail, global-search destination page, record resolution no Scoped View destination must be canonical and not legacy /admin/t
Global search result yes Native Filament global search search result link shell, query, URL no Results remain environment-scoped and point to View page

Decision-First Surface Role (mandatory when operator-facing surfaces are changed)

Surface Decision Role Human-in-the-loop Moment Immediately Visible for First Decision On-Demand Detail / Evidence Why This Is Primary or Why Not Workflow Alignment Attention-load Reduction
Environment-bound Directory Groups navigation Secondary Context Operator needs to inspect directory group inventory for the selected environment Directory group and Groups item List and View pages Secondary because it helps inspect context, not operate a full identity control plane Workspace -> Managed Environment -> Directory Groups Avoids direct URL knowledge without adding a broad Identity Center
Groups list Secondary Context Operator checks known groups for diagnostics, governance, restore mapping, or supportability Group name, type, source/freshness signals already in model View page diagnostics and existing enterprise detail sections Not primary because it does not decide remediation by itself Read-oriented directory inventory Keeps Directory visibility separate from governance decision surfaces
Group View Tertiary Evidence / Diagnostics Operator inspects one group safely Group identity and source details Existing diagnostics/detail layout Detail supports evidence and troubleshooting, not lifecycle management Scoped inspection Reduces cross-page reconstruction from search or references
Workspace-home sidebar Secondary Context Operator is at workspace level without an environment selected Workspace-owned entries only N/A Negative-control surface Workspace overview IA Prevents environment-owned noise

Audience-Aware Disclosure (mandatory when operator-facing surfaces are changed)

Surface Audience Modes In Scope Decision-First Default-Visible Content Operator Diagnostics Support / Raw Evidence One Dominant Next Action Hidden / Gated By Default Duplicate-Truth Prevention
Directory Groups navigation operator-MSP Groups entry under Directory only in environment context None in navigation None in navigation Open Groups Hidden on workspace home and without environment context Navigation only links to the list; it does not repeat status summaries
Groups list operator-MSP, support-platform by capability Known groups for current environment, type, last seen/freshness where available Provider IDs and less common columns stay toggleable or detail-only Raw payloads stay out of default list Open group Mutations, raw provider data, and cross-environment data List scope is the truth; no duplicated environment selector
Group View operator-MSP, support-platform by capability Safe group identity summary Existing enterprise detail diagnostics Support/raw detail only where already gated by existing detail patterns Inspect group Mutation actions and cross-environment data View adds evidence instead of restating list filters

UI/UX Surface Classification (mandatory when operator-facing surfaces are changed)

Surface Action Surface Class Surface Type Likely Next Operator Action Primary Inspect/Open Model Row Click Secondary Actions Placement Destructive Actions Placement Canonical Collection Route Canonical Detail Route Scope Signals Canonical Noun Critical Truth Visible by Default Exception Type / Justification
Directory Groups sidebar entry Navigation / Sidebar Resource navigation Open Groups Sidebar item N/A Existing page actions only N/A Admin Groups collection in active environment context N/A Active workspace and environment shell Groups Entry exists only when context is active none
Groups list List / Table Read-oriented resource list Open a group Clickable row or identifier link allowed if existing pattern remains Existing safe secondary actions only N/A Admin Groups collection in active environment context Admin Groups View route for record Active environment route/session context Groups Group name, type, freshness/source signals none
Group View Detail / Evidence Read-only View page Inspect group View page N/A Existing safe links in header/detail only N/A N/A Admin Groups View route for record Active environment and record ownership Group Group identity and source context none
Global search result Search / Navigation Scoped result link Open matching group Search result URL N/A N/A N/A N/A Admin Groups View route for record Active environment context Group Matching group title none

Operator Surface Contract (mandatory when operator-facing surfaces are changed)

Surface Primary Persona Decision / Operator Action Supported Surface Type Primary Operator Question Default-visible Information Diagnostics-only Information Status Dimensions Used Mutation Scope Primary Actions Dangerous Actions
Directory Groups navigation Tenant operator Continue into directory group inventory for the selected environment Navigation Where can I inspect groups for this environment? Directory / Groups navigation label None Environment context only Navigation only Open Groups none
Groups list Tenant operator, support operator Determine whether a group is known and inspect it Read-oriented table Which groups are known for this managed environment? Name, type, last seen/source cues already available Provider IDs, raw/source detail, diagnostics freshness/source availability, provider type Existing behavior only; no new actions Open Group none added
Group View Tenant operator, support operator Inspect one group safely View page What is this group and what source context does it belong to? Group identity and readable metadata Raw/provider diagnostics if already present/gated source, freshness, provider type Read-only inspection Return/list navigation, existing safe links none added

Proportionality Review (mandatory when structural complexity is introduced)

  • New source of truth?: no
  • New persisted entity/table/artifact?: no
  • New abstraction?: no
  • New enum/state/reason family?: no
  • New cross-domain UI framework/taxonomy?: no
  • Current operator problem: Groups are scoped and reachable but undiscoverable in the correct environment-bound admin context.
  • Existing structure is insufficient because: The resource bypasses the shared environment-navigation decision with a blanket admin-panel hidden check.
  • Narrowest correct implementation: Update EntraGroupResource and focused tests to express the environment-bound Directory Groups contract while preserving scoped access/search.
  • Ownership cost: Focused navigation, access, and global-search tests. No new architecture ownership.
  • Alternative intentionally rejected: A broad Identity Center or M365 admin mirror is rejected because the current product need is only read-oriented Directory Groups visibility inside the selected environment.
  • Release truth: Current-release runtime repair.

Compatibility posture

This feature assumes a pre-production environment.

Backward compatibility, legacy aliases, migration shims, historical fixtures, and compatibility-specific tests are out of scope unless explicitly required by this spec.

Canonical replacement is preferred over preservation. Legacy /admin/t routes must not be revived.

Testing / Lane / Runtime Impact (mandatory for runtime behavior changes)

  • Test purpose / classification: Feature
  • Validation lane(s): confidence
  • Why this classification and these lanes are sufficient: Feature tests can prove navigation registration, sidebar cleanliness/presence in response HTML, list/detail scope, global-search scoping, canonical result URLs, no-context denial, cross-environment denial, and no legacy route revival. One focused Browser smoke is required for the real rendered Filament sidebar link and Groups View drilldown.
  • New or expanded test families: Focused updates to existing Filament and Directory Groups feature tests plus one explicit Spec 303 Browser smoke. No new heavy-governance family.
  • Fixture / helper cost impact: Low. Reuse createUserWithTenant, ManagedEnvironment factories, WorkspaceContext, ManagedEnvironmentLinks, and current EntraGroup factories.
  • Heavy-family visibility / justification: none.
  • Special surface test profile: standard-native-filament
  • Standard-native relief or required special coverage: Native Filament resource/navigation/search behavior; use feature tests for backend/context/search truth and one Browser smoke for rendered navigation.
  • Reviewer handoff: Confirm lane fit, workspace-home negative controls, environment-bound positive controls, search URL canonicality, no /admin/t, and no new mutation actions.
  • Budget / baseline / trend impact: Low; focused feature tests plus one narrow Browser smoke.
  • Escalation needed: document-in-feature
  • Active feature PR close-out entry: Guardrail / Exception / Smoke Coverage
  • Planned validation commands:
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/PanelNavigationSegregationTest.php tests/Feature/Filament/AdminTenantSurfaceParityTest.php tests/Feature/Filament/AdminSharedSurfacePanelParityTest.php tests/Feature/Filament/TenantOwnedResourceScopeParityTest.php tests/Feature/Filament/EntraGroupAdminScopeTest.php tests/Feature/Filament/EntraGroupGlobalSearchScopeTest.php tests/Feature/Filament/PolicyResourceAdminSearchParityTest.php tests/Feature/Filament/PolicyVersionAdminSearchParityTest.php
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/DirectoryGroups/BrowseGroupsTest.php tests/Feature/Filament/EntraGroupEnterpriseDetailPageTest.php tests/Feature/Filament/EntraGroupResolvedReferencePresentationTest.php tests/Feature/Filament/PolicyVersionResolvedReferenceLinksTest.php tests/Browser/Spec303AdminDirectoryGroupsCutoverSmokeTest.php
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/InventoryCoverageAdminTenantParityTest.php tests/Feature/Filament/InventoryHubDbOnlyTest.php tests/Feature/Filament/InventoryPagesTest.php tests/Feature/Filament/GovernanceArtifacts/GovernanceArtifactAdminPanelRegistrationTest.php tests/Feature/Filament/GovernanceArtifacts/GovernanceArtifactEnvironmentContextTest.php tests/Feature/Filament/GovernanceArtifacts/GovernanceArtifactLegacyTenantPanelGuardTest.php tests/Feature/Operations/LegacyRunRoutesNotFoundTest.php
    • cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent
    • git diff --check

User Scenarios & Testing (mandatory)

User Story 1 - Groups are visible inside an active environment context (Priority: P1)

As a tenant operator working inside a selected Managed Environment, I need a secondary Directory Groups entry so I can inspect known directory groups without knowing a direct URL.

Why this priority: This resolves the exact stale navigation contract identified by Spec 302.

Independent Test: Render or evaluate the canonical environment-bound admin context and assert EntraGroupResource registers navigation while existing authorization checks still protect access.

Acceptance Scenarios:

  1. Given an authenticated user with workspace and environment membership, When the canonical environment route is active, Then Groups appears as an environment-bound Directory surface.
  2. Given the same user on the Groups list, When records exist in the active environment and another environment, Then only active-environment groups are listed.
  3. Given the environment context is missing, When the admin Groups list is requested, Then the response is deny-as-not-found and no groups are leaked.

User Story 2 - Workspace home remains clean (Priority: P2)

As an operator on the workspace home page, I need the sidebar to stay workspace-focused, even if the system remembers my last environment, so I do not confuse environment-owned Directory inventory with workspace-wide state.

Why this priority: The workspace-home clean-sidebar rule is intentional and must survive the Groups cutover.

Independent Test: Open the workspace home route with a remembered Managed Environment in session and assert Groups/Directory Groups are absent.

Acceptance Scenarios:

  1. Given a workspace-home route and remembered environment context, When the sidebar renders, Then Groups is absent.
  2. Given no active Managed Environment context, When EntraGroupResource::shouldRegisterNavigation() is evaluated for the admin panel, Then it returns false.

User Story 3 - Global search stays scoped and lands on valid View pages (Priority: P3)

As an operator using global search, I need group results to only include the active environment and open the correct View page, so search cannot bypass context or send me to retired routes.

Why this priority: Global search is already enabled for EntraGroupResource; its safety depends on scoped queries and truthful destinations.

Independent Test: Seed matching groups in multiple workspaces/environments, run admin global search with and without active context, and assert results plus URLs.

Acceptance Scenarios:

  1. Given no active Managed Environment context, When admin global search runs for a matching group, Then no group results are returned.
  2. Given matching groups in two environments, When admin global search runs with environment A active, Then only environment A's group appears.
  3. Given a matching result, When its URL is inspected, Then it points to the canonical admin View destination for that group and does not contain /admin/t.
  4. Given a user manipulates a View URL for a group in another workspace or environment, When the request is made, Then access is denied as not found.

Edge Cases

  • Remembered environment belongs to a different workspace than the current workspace session.
  • Current user is a workspace member but not an environment member.
  • Current user is an environment member but lacks the capability required by existing list/detail policy.
  • A global-search result is generated from a record whose relation is not eager-loaded.
  • A stale URL references a retired /admin/t/{tenant} path.
  • A stale direct /admin/entra-groups URL is requested after cutover.
  • Existing directory sync action remains present; the implementation must not create or promote new mutation/admin actions.

Functional Requirements

  • FR-001: EntraGroupResource MUST have an explicit admin contract as a secondary environment-bound Directory/Identity surface.
  • FR-002: Entra Groups MUST NOT appear in workspace-home sidebar navigation when no active Managed Environment context exists.
  • FR-003: Entra Groups MUST appear in the environment-bound admin context when the user has required workspace and environment access.
  • FR-004: The Groups list MUST only show groups for the active Managed Environment.
  • FR-005: The Group View page MUST deny access to records outside the active Managed Environment or workspace.
  • FR-006: Admin global search MUST return no Entra Group records without an active authorized Managed Environment context.
  • FR-007: Admin global search MUST remain scoped to the active Managed Environment and MUST NOT leak cross-workspace or cross-environment records.
  • FR-008: Admin global-search result URLs MUST point to valid View destinations and MUST NOT use retired /admin/t or tenant-panel routes.
  • FR-009: Existing RBAC, policy, and capability enforcement MUST remain server-side and MUST NOT rely on navigation visibility.
  • FR-010: This spec MUST NOT introduce create, edit, delete, membership mutation, sync mutation, destructive group actions, or a broad Directory/Identity Center.
  • FR-011: Existing Inventory, Policy, PolicyVersion, BackupSchedule, BackupSet, RestoreRun, Finding, EvidenceSnapshot, EnvironmentReview, StoredReport, and OperationRun routing/navigation behavior MUST NOT regress.
  • FR-012: Filament v5 and Livewire v4 patterns MUST be preserved. No Livewire v3 or legacy Filament APIs may be introduced.
  • FR-013: Provider registration MUST remain unchanged in apps/platform/bootstrap/providers.php.
  • FR-014: No assets may be registered or changed by this spec.

Non-Functional Requirements

  • NFR-001: The implementation MUST remain a narrow runtime repair and avoid new abstractions unless repo evidence proves the existing shared helpers cannot express the contract.
  • NFR-002: Tests MUST distinguish workspace-home sidebar cleanliness from environment-bound navigation visibility.
  • NFR-003: Test fixture and helper cost MUST stay low and reuse existing workspace/environment helpers.
  • NFR-004: UI copy MUST avoid implying TenantPilot is a full Microsoft 365 or Entra administration center.

Acceptance Criteria

  • Entra Groups has a written admin role contract as an environment-bound Directory/Identity surface.
  • Workspace-home sidebar remains clean with and without remembered environment context.
  • Environment-bound admin context can consistently reach Groups when RBAC/context allows.
  • List and View access remain scoped and deny no-context, cross-environment, and cross-workspace access.
  • Global search remains scoped and opens valid View destinations.
  • Search and related links do not point to legacy /admin/t routes.
  • Old blanket admin-hidden tests no longer protect Entra Groups incorrectly.
  • Existing focused Inventory, Policy, Evidence, Review, and Operation routing tests remain green.

Success Criteria

  • Focused validation commands pass.
  • No application code outside the scoped Entra Groups/navigation/search/tests surface is modified.
  • No migrations, assets, provider registration, Graph adapters, jobs, or tenant-panel retirement changes are introduced.
  • Reviewers can tell from spec.md, plan.md, and tasks.md why Groups is visible only in environment context and why this is not an M365 Admin mirror.

Assumptions

  • Spec 301 is completed and Inventory is the reference for environment-bound navigation without workspace-home leakage.
  • Spec 302 is completed and its audit matrix is authoritative for Entra Groups as the next blocker.
  • Existing Entra Group list/detail/global-search scoping is mostly correct and should be preserved unless tests reveal a narrow bug.
  • Existing directory sync operation behavior is outside this spec unless a test must prove no new action was added.

Risks

  • Adding WorkspaceScopedTenantRoutes to EntraGroupResource affects direct admin URLs and related links, so focused route, search, reference-link, and browser-smoke tests must prove the canonical workspace/environment path.
  • Navigation labels such as Directory could be mistaken for a larger Identity Center if copy and scope are not restrained.
  • Existing tests may encode the blanket hidden assumption in more than one file.

Open Questions

  • None blocking. Route posture was verified during implementation; the narrow safe change is to use workspace/environment resource routes and keep scoped canonical View destinations away from /admin/t.

Follow-up Spec Candidates

  • navigation-contract-split, only if workspace-home and environment-bound assertions still collide after this cutover.
  • tenant-panel-dead-code-retirement, only after active route/navigation dependencies no longer rely on retired tenant-panel assumptions.
  • A broader Directory/Admin Roles IA spec only if future roadmap work explicitly promotes a Directory suite beyond read-oriented Groups.