---
id: WF-PFM-CSH-006
title: Resolve an older console address
trigger: A person opens the bare root or an older context-free console link.
product_area: platform
module: console-shell
revision: 1
status: draft
design_intent: confirmed
origin: >-
  react-console:docs/url-architecture.md#7. Compatibility redirects and #4.3 Not
  tenant pages (decided by Andrew 2026-10-14; final acceptance 2026-10-15);
  retirement open (OQ-PFM-CSH-001)
implementation_evidence: observed
source_sha:
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
implements:
  - CAP-PFM-CSH-004
  - CAP-PFM-CSH-012
  - CAP-PFM-CSH-013
crosses:
  - SVC-PFM-CSH-console-shell
inference: []
idempotency: >-
  Identical mapping inputs produce the same target, with browser history
  replaced.
concurrency: >-
  Client redirect waits for the held context and current query before resolving
  the target.
hops:
  - 'n': 1
    actor_or_service: console server
    action: >-
      Apply server-side permanent redirects for older authentication, preview
      and custom-query-table paths.
    anchor: 'react-console:next.config.mjs:redirects'
    seam: sync
    on_failure: These server mappings declare no recovery.
    left_inconsistent: No client workspace mapping is needed for these destinations.
    observer: Person through the changed address.
    provenance: observed
    source: 'react-console:next.config.mjs:redirects'
  - 'n': 2
    actor_or_service: console (start-up)
    action: >-
      Run boot to establish a context from workspace preference or staff landing
      policy.
    anchor: 'react-console:lib/security-context/provider.tsx:boot'
    seam: sync
    on_failure: Use the existing start-up failure presentation.
    left_inconsistent: Security reads can have bookkeeping effects before redirect.
    observer: Person through boot presentation.
    provenance: observed
    source: 'react-console:lib/security-context/boot.ts:bootSecurityContext'
  - 'n': 3
    actor_or_service: console (staff gates)
    action: >-
      Redirect staff with no selected workspace to HQ; other older paths use the
      held workspace.
    anchor: >-
      react-console:components/console/hq/staff-context-gate.tsx:StaffContextGate;
      components/console/hq/staff-landing-gate.tsx:StaffLandingGate
    seam: sync
    on_failure: This staff-context decision has no separate retry.
    left_inconsistent: Staff HQ selection retains any still-valid workspace preference.
    observer: Person through HQ destination.
    provenance: observed
    source: >-
      react-console:components/console/hq/staff-context-gate.tsx:StaffContextGate
  - 'n': 4
    actor_or_service: console (older-address redirect)
    action: >-
      Resolve the compatibility mapping while retaining record values and query
      and converting defined older path words.
    anchor: 'react-console:lib/routes/legacy.ts:legacyTenantPath'
    seam: sync
    on_failure: Show not found for a path outside the compatibility catalogue.
    left_inconsistent: A context-free link depends on the workspace selected now.
    observer: Person through not-found presentation when unmapped.
    provenance: test
    source: >-
      react-console:e2e/mock/url-architecture.mock.spec.ts#an old tenant-less
      URL lands on its canonical URL, id and query kept
  - 'n': 5
    actor_or_service: console
    action: >-
      Replace browser history with the mapped workspace destination, then allow
      workspace entry to resolve it.
    anchor: >-
      react-console:components/console/legacy-redirect.tsx:LegacyRedirect
      (router.replace)
    seam: sync
    on_failure: Workspace entry owns any refusal at the target.
    left_inconsistent: History no longer retains the compatibility address.
    observer: Person through the target address.
    provenance: observed
    source: 'react-console:components/console/legacy-redirect.tsx:LegacyRedirect'
branches:
  - >-
    Bare-root compatibility mapping selects the workspace home, while staff
    landing selects HQ.
waits:
  - Client mapping waits until start-up supplies working context.
evidence:
  - >-
    react-console at baf6dae: app/(console)/{page.tsx,[...legacy]/page.tsx};
    components/console/{legacy-redirect.tsx,hq/staff-landing-gate.tsx,hq/staff-context-gate.tsx};
    lib/routes/legacy.ts; next.config.mjs; docs/url-architecture.md §7.
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-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-IAM-001, TC-IAM-002, TC-IAM-003, TC-IAM-004, TC-IAM-005, TC-LOG-001, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-MON-001, TC-MON-002, TC-MON-003, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-004, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-PRV-004, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-VEN-001, TC-VEN-002, TC-VEN-003]
---
# Resolve an older console address

## What It Does

Older console links resolve under the workspace selected during start-up. Compatibility mapping preserves record values and queries and replaces the history entry. Bare-root arrival selects the workspace home or HQ for staff.

## The Flow

```mermaid
sequenceDiagram
  participant C as Compatibility redirect
  participant S as Route mapping
  Note over C: context selected
  C->>S: older path and query
  S-->>C: canonical path or no mapping
  Note over C: replace history or show not found
```

## When Something Fails

Unmapped paths show not found. Start-up errors are handled before client mapping. Because old links carry no workspace, changed browser preferences can make them open under a different context than when they were saved.

## Open Design Questions

Product must record a dated retirement decision for the compatibility table, catch-all and associated tests.
