---
id: DOM-PFM-CSH-003
title: Console Address
realises: CON-PFM-CSH-003
product_area: platform
module: console-shell
revision: 1
status: draft
design_intent: confirmed
origin: >-
  react-console:docs/url-architecture.md (decided by Andrew 2026-10-14; final
  acceptance 2026-10-15)
implementation_evidence: observed
source_sha:
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
owned_by: SVC-PFM-CSH-console-shell
readable_by: []
lifecycle: STATE-PFM-CSH-002
custom_fields: none
identity: >-
  Path and query identify an address. Workspace paths carry an immutable
  identifier decoded and compared without case; HQ paths carry no selected
  workspace.
attributes:
  - name: root
    kind: enum
    required: true
    computed: false
    notes: >-
      Console and staff HQ are distinct roots; other surfaces are enumerated by
      route guards.
  - name: workspace identifier
    kind: text
    required: false
    computed: false
    notes: Every workspace address carries its immutable identifier.
  - name: workspace-relative path
    kind: text
    required: true
    computed: false
    notes: >-
      The relative route identifies area, resource and optional records, with
      children beneath parents.
  - name: destination key
    kind: computed
    required: false
    computed: true
    notes: >-
      Matching identifies a route-tree destination where available; planned or
      unknown tails can have no matched nodes.
  - name: record values
    kind: collection
    required: false
    computed: false
    notes: Encoded path values identify records in their workspace.
  - name: query
    kind: text
    required: false
    computed: false
    notes: >-
      Builders and compatibility mapping preserve queries; switching workspace
      drops them.
  - name: planned destination
    kind: enum
    required: true
    computed: true
    notes: The registry marks whether a destination is still planned.
  - name: remembered workspace
    kind: reference
    required: false
    computed: false
    notes: >-
      Browser storage remembers a workspace per person for context-free entry,
      without replacing an address’s requested workspace.
  - name: older address mapping
    kind: collection
    required: true
    computed: false
    notes: >-
      A temporary compatibility catalogue maps earlier paths into current
      console destinations.
relationships:
  - to: DOM-PFM-CSH-001
    cardinality: one current address to one rendered shell context
    ownership: The address requests workspace entry and supplies the shell-mode input.
    cross_service: false
  - to: DOM-PFM-CSH-002
    cardinality: one address to zero or one highlighted menu destination
    ownership: Navigation derives highlighting from the current address.
    cross_service: false
  - to: DOM-PFM-CSH-004
    cardinality: one path to zero or one first matching application domain
    ownership: The domain registry identifies application paths for route gating.
    cross_service: false
invariants:
  - id: INV-DOM-PFM-CSH-003-01
    statement: >-
      Requested workspace content mounts only when the held context matches the
      address workspace.
    enforced_at:
      - console
    provenance: documented
    source: 'react-console:docs/url-architecture.md#2.2 The context of the URL''s tenant'
  - id: INV-DOM-PFM-CSH-003-02
    statement: >-
      Strict entry rejects another workspace’s answer rather than substituting
      it for the requested one.
    enforced_at:
      - api
      - console
    provenance: observed
    source: >-
      react-console:lib/security-context/tenant-id.ts:fetchSecurityContextForTenantId
      (TenantIdUnconfirmedError);
      services-platform:modules/security/aws/api/access.routes.ts
      (getMySecurityContext with tenant_id)
  - id: INV-DOM-PFM-CSH-003-03
    statement: >-
      Static guards require console links to use shared builders instead of
      literal console paths.
    enforced_at:
      - console
    provenance: test
    source: >-
      react-console:lib/routes/__tests__/guards.test.ts#finds no literal console
      path outside lib/routes
  - id: INV-DOM-PFM-CSH-003-04
    statement: >-
      Static console path words use lowercase or camelCase without hyphens or
      underscores.
    enforced_at:
      - console
    provenance: test
    source: >-
      react-console:lib/routes/__tests__/guards.test.ts#names every folder under
      app/ with a lowercase word or camelCase
  - id: INV-DOM-PFM-CSH-003-05
    statement: >-
      Switching preserves the area and list, removes record values and queries,
      and retains unmatched planned paths.
    enforced_at:
      - console
    provenance: test
    source: >-
      react-console:lib/routes/__tests__/routes.test.ts#keeps the workspace and
      resource list and drops record ids and queries
  - id: INV-DOM-PFM-CSH-003-06
    statement: Route builders encode record values so punctuation remains path data.
    enforced_at:
      - console
    provenance: test
    source: >-
      react-console:lib/console/__tests__/record-destination.test.ts#escapes the
      record id into the path
  - id: INV-DOM-PFM-CSH-003-07
    statement: >-
      Compatibility mapping retains record values and query under the selected
      remembered or default workspace.
    enforced_at:
      - console
    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
  - id: INV-DOM-PFM-CSH-003-08
    statement: >-
      Registered catch-all destinations render guarded placeholders and unknown
      paths produce not found.
    enforced_at:
      - console
    provenance: observed
    source: >-
      react-console:app/(console)/console/[tenantId]/[...slug]/page.tsx:ModulePage
  - id: INV-DOM-PFM-CSH-003-09
    statement: Entry decodes the address identifier and compares it without case.
    enforced_at:
      - console
    provenance: observed
    source: 'react-console:components/console/tenant-id-gate.tsx:TenantIdGate'
physical: []
evidence:
  - >-
    react-console at baf6dae: docs/url-architecture.md (decided by Andrew
    2026-10-14, final acceptance 2026-10-15);
    lib/routes/{definitions,build,match,legacy}.ts; lib/console/record-types.ts;
    components/console/{tenant-id-gate,tenant-switcher,legacy-redirect}.tsx;
    lib/auth/session.ts (rememberTenantFor, rememberedTenantFor);
    next.config.mjs.
  - >-
    services-platform at ad3f6a6: modules/security/aws/api/access.routes.ts
    (getMySecurityContext).
---
# Console Address

## What It Models

A console address identifies work within a particular workspace. Shared links, bookmarks and history therefore carry the context needed to reopen that work. Rhythm HQ uses a separate address root, and temporary compatibility handling resolves older links.

## Identity and Attributes

The address consists of a path and optional query. Workspace paths carry the immutable workspace identifier followed by the area and resource; child records remain beneath their parent. Route matching identifies known nodes, while unmatched tails can represent planned destinations. A remembered workspace is a browser preference used when the address supplies none.

## Relationships

The workspace address drives entry into the shell context and helps the menu highlight the current place. The application registry classifies destination paths so application gating can run before page permissions.

## Invariants

The invariant rows cover strict context matching, shared builders, encoded record values and compatibility handling. Workspace switches discard record identities and queries. The registered catch-all supplies guarded placeholders, and unregistered paths produce not found.

## How It Is Stored and Shared

Route definitions and compatibility mappings reside in console code. Browser storage retains only the remembered-workspace preference. Security answers the entry request for the workspace named by the address; there is no stored address object shared with another service.

## Open Design Questions

Product must record when compatibility redirects retire. Remembered-workspace preferences are device-specific, so a bare address can resolve differently on different devices.
