TenantAtlas/specs/298-managed-environment-terminology-copy-cleanup/spec.md
ahmido 5722c4f051 feat: clean up managed environment terminology copy (#353)
## Summary
- replace tenant-first operator copy with environment and managed environment terminology across Filament pages, resources, services, Blade views, and localization
- align baseline compare, findings, governance, monitoring, backup schedule, and required-permissions surfaces with the managed-environment vocabulary
- update guard, feature, and browser smoke coverage and add the Spec 298 audit artifacts documenting allowed provider, internal, and regression-guard tenant references

## Validation
- cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Guards
- cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Localization
- cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Workspaces
- cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections
- cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/RequiredPermissions
- cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec190BaselineCompareMatrixSmokeTest.php tests/Browser/Spec281ProviderConnectionScopeSmokeTest.php tests/Browser/Spec285WorkspaceRbacEnvironmentAccessSmokeTest.php tests/Browser/Dashboard/TenantDashboardProductizationSmokeTest.php
- cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent

## Notes
- Filament remains on Livewire v4.
- No panel provider or asset-strategy changes are included in this branch.
- Existing destructive actions retain their confirmation and authorization behavior.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #353
2026-05-13 09:34:08 +00:00

32 KiB

Feature Specification: Managed Environment Terminology & Copy Cleanup

Feature Branch: 298-managed-environment-terminology-copy-cleanup
Created: 2026-05-13
Status: Ready
Input: User-provided Spec 298 draft: clean up remaining visible and test-side tenant terminology after Spec 297 retired the active legacy tenant route/runtime layer.

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

  • Problem: The route/runtime cutover from legacy tenant surfaces is complete enough to make old tenant-first language misleading, but active copy, localization values, tests, guard descriptions, browser-smoke selectors, and some sidebar navigation decisions still expose the retired TenantPanel mental model.
  • Today's failure: Operators and contributors can still see or assert strings such as Tenant dashboard, Tenant scope, Select tenant, No active tenants, Open tenant detail, Remove tenant, Restore tenant, Tenant memberships, tenant blocker, or guard/helper language around setTenantPanelContext() even though the product is workspace-first and managed-environment-first. A stale selected environment can also make Workspace Overview show environment-owned navigation such as Policies, Policy Versions, Backup Sets, Restore Runs, Findings, Baselines, Evidence, or Risk exceptions.
  • User-visible improvement: Current UI surfaces, localization strings, tests, smoke anchors, and sidebar navigation read as Workspace -> Managed Environment / Environment context, while provider-specific phrases such as Microsoft tenant ID remain allowed only where they describe external Microsoft/Entra truth.
  • Smallest enterprise-capable version: Run and record a terminology/navigation audit, update active user-facing copy and localization values for the targeted phrases, clarify/rename ambiguous test helper and guard wording, update affected browser-smoke selectors or assertions, gate environment-owned navigation by route surface instead of stale session/Filament tenant state, keep active legacy route scans clean, and document allowed technical/provider/historical exceptions.
  • Explicit non-goals: No database/table/model rename from Tenant to ManagedEnvironment, no migration rewrite, no new routing architecture, no new localization foundation, no UI redesign, no RBAC remodel, no old route or provider restoration, no broad historical spec rewrite, and no full-suite fix-all.
  • Permanent complexity imported: One spec-local terminology audit artifact, one small route-scope navigation helper, plus targeted tests/guard updates. No new table, enum, status family, provider framework, broad route framework, or localization architecture is introduced.
  • Why now: Spec 297 retired active legacy tenant route surfaces and centralized canonical managed-environment links. Leaving visible/test copy on the old vocabulary makes future specs and tests regress toward tenant-first product truth.
  • Why not local: The drift crosses localization catalogs, Blade views, Filament labels/actions, support copy, tests, guard regex literals, and browser smokes. A single local copy fix would leave contradictory terminology in other active surfaces.
  • Approval class: Cleanup
  • Red flags triggered: Cross-cutting copy/test cleanup and terminology audit. Defense: the scope is explicitly bounded to existing strings, tests, and guard wording; it does not introduce a new vocabulary framework or rename persistence.
  • Score: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 1 | Produktnaehe: 2 | Wiederverwendung: 2 | Gesamt: 11/12
  • Decision: approve

Spec Scope Fields (mandatory)

  • Scope: canonical-view
  • Primary Routes:
    • Canonical context: /admin/workspaces/{workspace}/environments
    • Canonical context: /admin/workspaces/{workspace}/environments/{environment}
    • Canonical environment support surfaces such as required permissions, diagnostics, access scopes, provider connections, operations, findings, reviews, evidence, and stored reports where repo-real
    • Retired and forbidden as product truth: /admin/t... and /admin/tenants...
  • Data Ownership:
    • No persisted data ownership changes.
    • Existing internal Tenant model/table/column names may remain technical implementation truth where DB/model rename is out of scope.
    • Provider-specific Microsoft/Entra tenant identifiers remain provider-owned external truth, not TenantPilot platform vocabulary.
  • RBAC:
    • Workspace membership remains the primary authorization boundary.
    • Managed-environment access scoping remains narrowing/access-scope behavior where repo-real.
    • Non-member or out-of-scope access remains deny-as-not-found (404).
    • Established member missing capability remains 403.
    • UI visibility is not authorization; Gates/Policies remain server-side truth.

For canonical-view specs:

  • Default filter behavior when tenant-context is active: Current environment context may prefilter workspace-wide pages, but copy must name that state as environment or managed-environment context, not tenant-panel context.
  • Explicit entitlement checks preventing cross-tenant leakage: This spec must not weaken existing workspace/environment entitlement checks. Any changed links, labels, or smoke selectors must continue to use the canonical route/link helpers and existing authorization proof.

Cross-Cutting / Shared Pattern Reuse (mandatory)

  • Cross-cutting feature?: yes
  • Interaction class(es): localization values, Filament page/resource labels, action labels, modal headings, empty states, helper text, notification/modal copy, context-bar copy, Blade view copy, test names, test helper wording, guard regex descriptions, browser-smoke selectors.
  • Systems touched:
    • apps/platform/lang/en/localization.php
    • apps/platform/lang/de/localization.php
    • apps/platform/resources/views/**
    • apps/platform/app/Filament/**
    • apps/platform/app/Support/**
    • apps/platform/app/Services/** where visible copy is emitted
    • apps/platform/tests/Pest.php
    • apps/platform/tests/Feature/Guards/Spec288NoLegacyRouteAndHelperGuardTest.php
    • affected apps/platform/tests/Feature/** and apps/platform/tests/Browser/**
    • specs/298-managed-environment-terminology-copy-cleanup/terminology-audit.md
  • Existing pattern(s) to extend: Spec 297 canonical managed-environment route/link contract, existing ManagedEnvironmentLinks, existing setAdminEnvironmentContext() helper, current localization arrays, existing TenantPageCategory route categorization, existing Spec 288 guard-test style, existing browser-smoke anchors.
  • Shared contract / presenter / builder / renderer to reuse: Use existing localization keys where key rename is risky; update visible values first. Use ManagedEnvironmentLinks, TenantPageCategory, and existing data-testid patterns for browser-safe anchors when selectors are needed.
  • Why the existing shared path is sufficient or insufficient: The canonical route/link path and route category enum already exist. What remains insufficient is visible/test vocabulary and sidebar navigation that still use tenant-first product language or stale selected-environment state for current workspace surfaces.
  • Allowed deviation and why: Internal model/class names such as TenantResource, TenantDashboard, TenantRequiredPermissions, tenant_id, and Microsoft/Entra tenant ID copy may remain where they are internal, provider-specific, historical, or out of scope for DB/model rename. They must be documented in the audit if surfaced by final scans.
  • Consistency impact: Current UI, tests, localization values, smoke anchors, and guard descriptions must converge on Workspace, Managed Environment, Environment, Provider Connection, Operation, Finding, Review, Evidence, and Governance vocabulary.
  • Review focus: Reviewers must verify that no active product UI uses retired TenantPanel or tenant-first language, route/runtime legacy scans remain clean, and guard literals only remain when they explicitly forbid retired behavior.

OperationRun UX Impact (mandatory)

  • Touches OperationRun start/completion/link UX?: no new OperationRun behavior; possible copy-only updates on operation-related strings.
  • Shared OperationRun UX contract/layer reused: Existing OperationRunLinks, OperationUxPresenter, and canonical operations routes remain unchanged if touched.
  • Delegated start/completion UX behaviors: Existing queued/running/terminal UX behavior remains owned by the shared OperationRun path.
  • Local surface-owned behavior that remains: Copy and labels only.
  • Queued DB-notification policy: N/A.
  • Terminal notification path: unchanged.
  • Exception required?: none.

Provider Boundary / Platform Core Check (mandatory)

  • Shared provider/platform boundary touched?: yes, through operator vocabulary and allowed provider-specific terminology.
  • Boundary classification: mixed
  • Seams affected: localization values, visible provider readiness copy, required-permissions copy, support diagnostics copy, dashboard copy, Microsoft/Entra tenant ID labels, and tests that distinguish platform vocabulary from provider vocabulary.
  • Neutral platform terms preserved or introduced: workspace, managed environment, environment, provider connection, environment scope, required permissions, diagnostics, operation, finding, review, evidence, governance.
  • Provider-specific semantics retained and why: Microsoft tenant ID, Entra tenant ID, Microsoft Graph, Intune, and tenant ID payload metadata remain valid when the external Microsoft provider is the subject.
  • Why this does not deepen provider coupling accidentally: The spec removes generic platform tenant-first vocabulary and narrows provider-specific tenant wording to Microsoft/Entra contexts only.
  • Follow-up path: document-in-feature for remaining technical/internal names; follow-up-spec only for structural DB/model rename or broader customer-facing localization adoption.

UI / Surface Guardrail Impact (mandatory)

Surface / Change Operator-facing surface change? Native vs Custom Shared-Family Relevance State Layers Touched Exception Needed? Low-Impact / N/A Note
Localization values yes Existing Laravel translation arrays shell, dashboard, customer workspace, support copy copy/value only no key rename optional only when low risk
Filament labels/actions/empty states yes Native Filament surfaces action labels, modal headings, page titles, empty states page/action/copy no no layout redesign
Blade/context-bar copy yes Existing Blade/Filament partials shell/context, dashboard, matrix, queue copy view copy only no no new custom styling
Tests/guards/browser smokes no direct operator UI N/A validation and smoke anchors test wording/selectors no selectors should be stable and not timeout-based

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 dashboard/detail copy Primary Decision Surface Operator reviews current environment state environment context, readiness, current blockers, next action diagnostics and raw provider detail remain secondary Primary because environment detail is the canonical environment entry point Workspace -> Managed Environment -> domain pages removes tenant-first ambiguity
Context bar / workspace shell copy Secondary Context Surface Operator confirms current workspace/environment context workspace and environment labels none unless existing shell exposes detail Secondary because it orients current scope workspace-first context switching clarifies workspace-wide pages can exist with no environment selected
Required permissions/provider readiness copy Secondary Context Surface Operator checks provider readiness environment/provider permission state provider-specific Graph/Microsoft detail Secondary because it supports readiness decisions provider detail under environment context keeps Microsoft tenant terms provider-specific
Browser/test anchors N/A maintainer validation stable selectors or current copy assertions test output only not an operator surface validation lane only prevents brittle old-copy assertions

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
Environment dashboard/detail copy operator-MSP, support-platform environment status, readiness, next action provider detail, support diagnostics raw payloads only where already permitted page-owned primary action raw/support detail one environment noun across labels
Context bar / shell copy operator-MSP, support-platform workspace and environment scope unavailable context reason none choose/switch environment when applicable none added no tenant-panel wording
Required permissions/provider copy operator-MSP, support-platform required permission state and provider context Microsoft/Graph/Entra details raw provider IDs if already shown review/grant required permissions raw payloads provider-specific tenant wording only where externally true

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
Managed environments context Shell / Detail Workspace-scoped environment context Choose or inspect environment existing canonical route/link existing behavior existing placement unchanged; verify confirmation if label touched /admin/workspaces/{workspace}/environments /admin/workspaces/{workspace}/environments/{environment} workspace + environment Managed environment / Environment selected or missing environment state no route redesign
Required permissions/provider readiness Detail / Readiness Environment-scoped provider readiness Review permissions existing page route N/A existing placement none added inherited environment route /admin/workspaces/{workspace}/environments/{environment}/required-permissions workspace + environment + provider Required permissions missing permission state provider tenant terms allowed only for Microsoft/Entra
Tests and guards Validation Guard/browser smoke Prove retired copy/routes stay retired N/A N/A N/A N/A N/A N/A test context Admin environment context forbidden legacy patterns allowed regression-guard literals only

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
Environment dashboard/detail copy Workspace operator Decide what needs attention in the selected environment detail/dashboard What needs action in this environment? environment identity, readiness, blockers, next action provider IDs, support diagnostics readiness, governance result, lifecycle/outcome where existing unchanged existing page actions with environment wording unchanged
Context bar / shell copy Workspace operator Confirm or switch current context shell/context Which workspace/environment am I operating in? workspace, environment or no-environment state none added context availability TenantPilot only choose/switch/clear environment none
Required permissions/provider readiness Workspace operator Decide whether provider permission state blocks environment workflows readiness detail Which provider permissions are missing? required permission state and remediation path Graph/Microsoft detail provider readiness Microsoft tenant only when existing action says so review required permissions unchanged

Proportionality Review (mandatory when structural complexity is introduced)

  • New source of truth?: no
  • New persisted entity/table/artifact?: no application persistence; one spec-local terminology-audit.md artifact records scan results and allowed exceptions.
  • New abstraction?: no.
  • New enum/state/reason family?: no.
  • New cross-domain UI framework/taxonomy?: no.
  • Current operator problem: old tenant-first wording in active UI/tests makes the managed-environment cutover look incomplete and encourages future contributors to reintroduce retired route/runtime concepts.
  • Existing structure is insufficient because: copy drift is scattered across localization, Filament labels, Blade, support services, and tests; implementation needs an audit artifact and focused guard proof, not a new framework.
  • Narrowest correct implementation: update visible values and tests in place, prefer existing localization keys where key rename is risky, document allowed technical/provider references, and add or adjust only focused guards.
  • Ownership cost: low; one audit artifact and targeted copy/test updates.
  • Alternative intentionally rejected: repo-wide removal of every Tenant string or DB/model rename. Those would be larger structural changes and out of scope.
  • Release truth: current-release cleanup after route/runtime cutover in a pre-production environment.

Compatibility posture

This feature assumes the repo's pre-production lean doctrine.

Backward compatibility aliases, legacy route fallbacks, old helper aliases, and tenant-first compatibility copy are out of scope. Current visible copy should be replaced rather than preserved with aliases unless the phrase is provider-specific, internal, historical, or explicitly documented as a regression guard.

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

  • Test purpose / classification: Feature guard tests for route/copy/helper contracts; Feature/Filament tests for affected labels/actions/pages; Browser tests only for affected smoke anchors; no Unit lane unless pure helper logic is touched.
  • Validation lane(s): Feature/Guards, Feature/Localization, Feature/Filament, Feature/Workspaces, Feature/ProviderConnections, Feature/RequiredPermissions, affected Feature areas, and targeted Browser smoke anchors.
  • Why this classification and these lanes are sufficient: The risk is terminology, labels, selectors, and guard drift, not a new product workflow. Focused scans and existing affected suites prove the cleanup without pulling in unrelated full-suite repair.
  • New or expanded test families: possible focused guard assertions for terminology; no new permanent lane.
  • Fixture / helper cost impact: no new expensive setup. Existing setAdminEnvironmentContext() remains the current helper; do not introduce provider setup or browser defaults into cheap Feature tests.
  • Heavy-family visibility / justification: Browser lane is explicit and limited to smoke tests whose selectors/copy are touched.
  • Special surface test profile: standard-native-filament, global-context-shell, and browser-smoke for touched browser anchors.
  • Standard-native relief or required special coverage: ordinary Pest/Filament coverage is sufficient for copy-only native Filament updates unless browser-visible anchors change.
  • Reviewer handoff: Reviewers must confirm Filament v5 on Livewire v4.0+, panel providers remain registered through apps/platform/bootstrap/providers.php, globally searchable resources have Edit/View pages or disabled global search, touched destructive actions still use ->action(...), ->requiresConfirmation(), and authorization, asset strategy is unchanged, and tests cover changed pages/actions/widgets through Livewire/Filament where applicable.
  • Budget / baseline / trend impact: no planned material runtime shift. Browser tests remain targeted; no blind timeout increases.
  • Escalation needed: document-in-feature for allowed technical/provider/historical tenant references; follow-up-spec only for structural DB/model rename or broader customer localization adoption.
  • Active feature PR close-out entry: Guardrail / Terminology Cleanup / Smoke Coverage.
  • Planned validation commands:
cd apps/platform
./vendor/bin/sail artisan test --compact tests/Feature/Guards
./vendor/bin/sail artisan test --compact tests/Feature/Localization
./vendor/bin/sail artisan test --compact tests/Feature/Workspaces
./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections
./vendor/bin/sail artisan test --compact tests/Feature/RequiredPermissions
./vendor/bin/sail artisan test --compact tests/Feature/Filament
./vendor/bin/sail artisan test --compact tests/Browser/Spec281ProviderConnectionScopeSmokeTest.php tests/Browser/Spec285WorkspaceRbacEnvironmentAccessSmokeTest.php
./vendor/bin/sail bin pint --dirty --format agent
git diff --check

Repo Baseline From Preparation

Read-only preparation scans on 2026-05-13 found:

  • The active route/link source scan for retired route generators under apps/platform/app, apps/platform/resources, and apps/platform/routes returned no hits for filament.admin.resources.tenants, /admin/tenants, /admin/t/, direct legacy TenantResource::getUrl(...), TenantDashboard::getUrl(...), TenantRequiredPermissions::getUrl(...), or tenant panel IDs.
  • ManagedEnvironmentLinks and setAdminEnvironmentContext() are repo-real and should remain the canonical route/helper vocabulary.
  • Remaining target copy hits exist in localization values, Blade copy, Filament/support copy, and tests. Representative hits include Tenant scope, Select tenant, No tenant selected, No active tenants, Tenant dashboard, Open tenant detail, Restore tenant, Remove tenant assignment, and tenant blocker.
  • Spec288NoLegacyRouteAndHelperGuardTest.php still contains setTenantPanelContext regex literals as forbidden-pattern checks. These are allowed only if the test description clearly says they forbid reintroducing the retired helper.

The implementation must refresh terminology-audit.md with full required scans before editing runtime code.

User Scenarios & Testing (mandatory)

User Story 1 - Operators See Environment Vocabulary (Priority: P1)

As a workspace operator, I need active admin surfaces to describe current context as workspace, managed environment, or environment, not as a tenant panel.

Why this priority: This is the visible product truth after Spec 297.

Independent Test: Render affected shell/dashboard/detail/readiness surfaces and scan active UI/localization values for targeted tenant-first phrases.

Acceptance Scenarios:

  1. Given a workspace-wide page with no environment selected, When the context copy renders, Then it says no environment is selected and does not say no tenant is selected.
  2. Given an environment dashboard/detail surface, When the heading, empty states, and helper text render, Then they use Environment or Managed environment wording.
  3. Given provider-specific Microsoft detail, When it refers to external Microsoft identity, Then Microsoft tenant ID or Entra tenant ID may remain.

User Story 2 - Tests And Guards Describe Current Runtime Truth (Priority: P1)

As a maintainer, I need test names, helpers, and guard messages to use admin environment context vocabulary unless they are explicitly forbidding retired TenantPanel behavior.

Why this priority: Test vocabulary is a durable product contract for future agents and contributors.

Independent Test: Run the guard scans and focused guard tests; verify remaining setTenantPanelContext text appears only as forbidden legacy regex literals with clear descriptions.

Acceptance Scenarios:

  1. Given tests/Pest.php, When helper names are scanned, Then the active helper is setAdminEnvironmentContext() or equivalent current vocabulary with no setTenantPanelContext() alias.
  2. Given Spec 288 guard tests, When they retain setTenantPanelContext regex literals, Then the test description and failure message state that the retired helper must not be reintroduced.
  3. Given feature/browser tests for current admin environment flows, When their names and assertions are reviewed, Then they do not describe the current runtime as tenant panel context.

User Story 3 - Browser Smokes Remain Stable After Copy Cleanup (Priority: P2)

As a maintainer, I need browser smokes to follow stable current selectors or intentionally stable current copy without increasing timeouts.

Why this priority: Copy cleanup should not make the browser lane brittle.

Independent Test: Run affected browser smokes individually after selector/copy updates.

Acceptance Scenarios:

  1. Given a smoke test that previously clicked old tenant copy, When the target UI has a stable data-testid, Then the smoke uses that selector.
  2. Given a smoke test that asserts current UI copy, When the copy is a product contract, Then the assertion uses the new environment wording.
  3. Given an affected browser smoke, When it is updated, Then no timeout is raised without a documented timing cause.

Functional Requirements

  • FR-001 Initial scan before changes: Before implementation edits, run the status, route, source, test, and copy scans listed in plan.md and record results in terminology-audit.md.
  • FR-002 Guard literals updated: Spec288NoLegacyRouteAndHelperGuardTest.php must not present setTenantPanelContext as a current helper. It may retain the regex only as an explicit forbidden legacy pattern.
  • FR-003 Test helper terminology finalized: Current tests must use admin/managed-environment context wording and active helper names such as setAdminEnvironmentContext().
  • FR-004 User-facing tenant copy neutralized: Active UI copy for the targeted phrases must move to Environment or Managed Environment vocabulary, except provider-specific Microsoft/Entra terms.
  • FR-005 Filament labels and actions cleaned: Page titles, navigation labels, breadcrumbs, action labels, empty states, helper texts, badge labels, modal headings, and notifications in active surfaces must not use old tenant-first product language.
  • FR-006 Blade/context-bar copy cleaned: Active Blade and Filament partials must use environment context wording and avoid class-name-like visible copy.
  • FR-007 Localization values cleaned: Existing EN/DE localization values must output current vocabulary. Key renames are optional and only allowed when all usages are safely updated.
  • FR-008 Browser smokes updated: Affected smokes must use stable selectors or current copy, with no blind timeout increases.
  • FR-009 Allowed exceptions documented: Remaining tenant-related hits must be categorized in terminology-audit.md.
  • FR-010 No active legacy route reintroduced: Final route/source scans must remain clean for /admin/t..., /admin/tenants..., old URL generators, tenant panel IDs, and setTenantPanelContext() in runtime surfaces.
  • FR-011 Route-scope-first navigation gating: Sidebar navigation must decide workspace vs environment navigation from the current route/surface first. Stale session, remembered environment, or Filament::getTenant() state must not make Workspace Overview show environment-owned navigation.
  • FR-012 Workspace sidebar stays portfolio-oriented: Workspace-level surfaces must keep repo-real workspace-owned navigation available, including Overview, Operations, Alerts, Audit Log, Governance inbox, Customer reviews, Manage workspaces, Integrations, and Settings where authorized. Stored reports and Review Packs remain environment-owned until a separate workspace aggregate route exists.
  • FR-013 Environment sidebar appears only in environment surface scope: Environment-owned entries such as Policies, Policy Versions, Backup Schedules, Backup Sets, Restore Runs, Findings, Baselines, Baseline Snapshots, Baseline Compare, Evidence, Risk exceptions, Required permissions, and Diagnostics may appear only when the route is clearly environment-scoped.

Acceptance Criteria

  • AC-001: Source scan is clean for active old TenantPanel route/generator patterns in app, resources, and routes.
  • AC-002: Test helper scan is clean or contains only explicit forbidden legacy guard literals with clear descriptions.
  • AC-003: Targeted tenant-first copy is absent from active UI surfaces or documented as provider-specific, internal, historical, or regression-guard-only.
  • AC-004: terminology-audit.md documents every remaining allowed tenant reference found by final scans.
  • AC-005: Route scan does not show active /admin/t... or /admin/tenants... product routes.
  • AC-006: Spec 297 route/runtime proof remains intact.
  • AC-007: Canonical browser anchors pass when affected.
  • AC-008: Workspace Overview hides environment-owned primary navigation even when a previous environment remains selected in session or Filament tenant state.
  • AC-009: Environment dashboard/detail routes show the intended environment-owned navigation for entitled users.
  • AC-008: Pint dirty and git diff --check pass.

Out Of Scope

  • DB table rename
  • Tenant model rename
  • tenant_id column rename
  • migration rewrite
  • historical spec rewrite
  • broad docs cleanup
  • new localization architecture
  • new customer workspace feature
  • new decision inbox feature
  • new routing model
  • new RBAC model
  • new provider abstraction
  • UI redesign
  • reactivation of /admin/t..., /admin/tenants..., TenantPanelProvider, or setTenantPanelContext()

Risks

  • Some localization keys still contain tenant_*; changing keys broadly could create avoidable risk. Values should be updated first unless key rename is proven bounded.
  • Some visible tenant terms may be valid provider-specific Microsoft/Entra terminology. The audit must distinguish provider truth from product vocabulary.
  • Browser smokes may rely on old visible text. Prefer stable selectors where the copy is not the contract.
  • Guard regex literals can look like drift if test names/messages are ambiguous. Clarify the guard contract rather than weakening it.

Assumptions

  • Spec 297 has retired active route/runtime legacy surfaces and ManagedEnvironmentLinks is the canonical URL owner.
  • The repo remains pre-production, so old compatibility aliases are not required.
  • The active product mental model is Workspace first, then Managed Environment / Environment context.
  • Internal technical names may remain until a separate DB/model rename spec exists.

Open Questions

  • None blocking preparation. Implementation must update the audit if scans reveal an active visible tenant-first phrase outside the targeted list that is clearly current product UX.

Follow-Up Spec Candidates

  • Structural DB/model rename from Tenant to ManagedEnvironment, if product and persistence maturity require it later.
  • Broader customer-facing localization adoption beyond the targeted cleanup, aligned with the existing localization roadmap.
  • Historical docs/spec cleanup, if the repository later decides historical artifacts should be normalized separately.