---
id: WF-PFM-CSH-002
title: Enter the workspace an address names
trigger: The requested workspace differs from the selected console context.
product_area: platform
module: console-shell
revision: 1
status: draft
design_intent: confirmed
origin: >-
  react-console:docs/url-architecture.md#2.2 The context of the URL's tenant and
  #6. Tenant from the URL (decided by Andrew 2026-10-14; final acceptance
  2026-10-15)
implementation_evidence: observed
source_sha:
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
implements:
  - CAP-PFM-CSH-010
  - CAP-PFM-CSH-011
  - CAP-PFM-CSH-013
moves:
  - STATE-PFM-CSH-002
  - STATE-PFM-CSH-001
crosses:
  - SVC-PFM-CSH-console-shell
inference: []
idempotency: >-
  Current-workspace entry skips the read. Other repeat requests can observe
  changed access, with a short remembered refusal avoiding remount duplication.
concurrency: >-
  Context-change tickets allow only the newest request to install a selected
  workspace.
hops:
  - 'n': 1
    actor_or_service: console (workspace gate)
    action: >-
      Decode and normalize the requested identifier, rendering immediately when
      the held workspace matches.
    anchor: 'react-console:components/console/tenant-id-gate.tsx:TenantIdGate'
    seam: sync
    on_failure: This comparison has no failure branch.
    left_inconsistent: The comparison changes no stored state.
    observer: No dedicated observer.
    provenance: observed
    source: >-
      react-console:components/console/tenant-id-gate.tsx:TenantIdGate (decode,
      inTenant)
  - 'n': 2
    actor_or_service: console (workspace gate)
    action: >-
      Use a refusal remembered within ten seconds, or delay a just-left
      workspace request by six seconds.
    anchor: >-
      react-console:components/console/tenant-id-gate.tsx:rememberedRefusal;
      lib/security-context/left-tenant.ts:wasJustLeft
    seam: sync
    on_failure: The remembered outcome is reused; delay schedules its own retry.
    left_inconsistent: A refusal or temporary wait keeps requested content withheld.
    observer: Person through refusal or loading presentation.
    provenance: observed
    source: 'react-console:components/console/tenant-id-gate.tsx:TenantIdGate'
  - 'n': 3
    actor_or_service: console (provider)
    action: >-
      Consume the matching boot outcome once; otherwise allocate a
      context-change ticket and set entry busy.
    anchor: >-
      react-console:lib/security-context/provider.tsx:openTenantId
      (pendingUrlAnswer)
    seam: sync
    on_failure: No separate recovery is declared for this setup.
    left_inconsistent: The previous context remains while entry is pending.
    observer: Person through switcher activity.
    provenance: observed
    source: 'react-console:lib/security-context/provider.tsx:openTenantId'
  - 'n': 4
    actor_or_service: 'Security (getMySecurityContext, strict)'
    action: Ask Security for exactly the workspace named by the address.
    anchor: >-
      react-console:lib/security-context/tenant-id.ts:fetchSecurityContextForTenantId
    seam: sync
    on_failure: >-
      Convert expected refusals into entry outcomes; display unexpected or
      mismatched-response failure.
    left_inconsistent: Security bookkeeping can occur during the read.
    observer: Person through the gate; browser warning for mismatched context.
    provenance: observed
    source: >-
      react-console:lib/security-context/tenant-id.ts:fetchSecurityContextForTenantId;
      services-platform:modules/security/aws/api/access.routes.ts:getMySecurityContext
  - 'n': 5
    actor_or_service: console (provider)
    action: >-
      After a latest-ticket success, clear SWR data for a changed workspace,
      remember it and install its context.
    anchor: 'react-console:lib/security-context/provider.tsx:openTenantId'
    seam: sync
    on_failure: Ignore data from a superseded ticket.
    left_inconsistent: >-
      A prior switch toast can precede installation; SWR clearing occurs before
      the new context is applied.
    observer: Person through the resulting context.
    provenance: observed
    source: 'react-console:lib/security-context/provider.tsx:openTenantId'
  - 'n': 6
    actor_or_service: console (workspace gate)
    action: >-
      Retain refusal briefly and render its panel; denied staff leave the held
      workspace and navigate to HQ with notice.
    anchor: >-
      react-console:components/console/tenant-id-gate.tsx:TenantIdGate,
      deniedDestination, deniedReturnTenant
    seam: sync
    on_failure: >-
      The gate displays the classified refusal without another automatic
      request.
    left_inconsistent: >-
      Customer refusal keeps the old context; denied staff proceed to leave for
      HQ.
    observer: Person through refusal panel or HQ notice.
    provenance: test
    source: 'react-console:components/console/__tests__/tenant-id-gate.test.tsx'
  - 'n': 7
    actor_or_service: console (application route gate)
    action: >-
      Let the application route gate evaluate the destination once the workspace
      context is settled.
    anchor: >-
      react-console:components/console/application-route-gate.tsx:ApplicationRouteGate
    seam: sync
    on_failure: Render the application-unavailable state.
    left_inconsistent: No destination content mounts for an absent application.
    observer: Person through application refusal presentation.
    provenance: observed
    source: >-
      react-console:components/console/application-route-gate.tsx:ApplicationRouteGate
branches:
  - A matching boot outcome is consumed once rather than requested again.
  - Denied staff follow the HQ departure and notice path.
waits:
  - >-
    A recent departure schedules a six-second retry while the address still
    requests that workspace.
evidence:
  - >-
    react-console at baf6dae:
    components/console/{tenant-id-gate,application-route-gate}.tsx;
    lib/security-context/{provider.tsx,tenant-id.ts,left-tenant.ts};
    components/console/__tests__/tenant-id-gate.test.tsx.
  - 'services-platform at ad3f6a6: modules/security/aws/api/access.routes.ts.'
controls: [TC-AVL-001, TC-AVL-004, TC-AVL-005, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-005, TC-AZ-006, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-IAM-001, TC-IAM-002, TC-IAM-003, TC-IAM-004, TC-IAM-005, TC-IAM-006, TC-LOG-001, TC-LOG-004, TC-LOG-005, TC-MON-001, TC-MON-002, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-004, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-VEN-001, TC-VEN-002, TC-VEN-003]
---
# Enter the workspace an address names

## What It Does

Entry resolves the workspace requested by an address before mounting its content. A matching current context renders immediately. Otherwise a recent refusal, a just-left delay or a strict Security answer determines the result.

## The Flow

```mermaid
sequenceDiagram
  participant C as Workspace gate
  participant S as Security
  Note over C: address workspace
  C->>S: strict context request
  S-->>C: matching context or refusal
  Note over C: install latest context or explain refusal
```

## When Something Fails

Not found, denied and unavailable produce separate outcomes. Denied staff leave for HQ with a notice. A mismatched successful response is warned about and rejected. Unexpected failures show a message. Successful entry clears SWR data before installing the context; a switcher toast may already have announced success.

## Open Design Questions

Product should settle the intended cache-clearing and confirmation timing, with browser proof for refusals and competing context changes.
