TenantAtlas/specs/298-managed-environment-terminology-copy-cleanup/spec.md
Ahmed Darrazi 5cad4eb8fd
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 6m50s
feat: clean up managed environment terminology copy
2026-05-13 10:53:53 +02:00

303 lines
30 KiB
Markdown

# 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, and browser-smoke selectors 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.
- **User-visible improvement**: Current UI surfaces, localization strings, tests, and smoke anchors 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 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, 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 plus targeted tests/guard updates. No new table, enum, status family, provider framework, 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 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` 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 already exists. What remains insufficient is visible and test vocabulary that still uses tenant-first product language for current environment 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.
## 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**: 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.