# 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**:

```bash
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.
