---
id: CAP-PFM-CSH-016
title: Refresh application choices when access changes
feature: FEAT-PFM-CSH-04
product_area: platform
module: console-shell
revision: 2
status: draft
product_intent: proposed
implementation_evidence: observed
supersedes: []
source_sha:
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
intent_sources:
  - >-
    services-platform:docs/proposals/application-access-and-entitlements.md#6.4 Console integration
    (built and accepted by Andrew 2026-10-15)
  - >-
    services-platform:docs/proposals/application-access-and-entitlements.md#7.1 The person's
    applications (built and accepted by Andrew 2026-10-15)
purpose: The console updates application navigation when its current access answer becomes stale.
outcomes:
  - Recognized application refusals trigger an updated answer.
  - Failed or outdated refreshes do not replace the current workspace context.
concepts:
  - CON-PFM-CSH-004
actors:
  - ACT-PFM-002
  - ACT-PFM-006
surfaces:
  - console
preconditions: []
postconditions: []
permissions:
  - key: platform.security-self.read
    where_checked: api
    scope: tenant
rules:
  - id: BR-CAP-PFM-CSH-016-01
    proved_by: [ATS-PFM-CSH-016-01, ATS-PFM-CSH-016-02, ATS-PFM-CSH-016-09, TST-PFM-CSH-011, TST-PFM-CSH-030]
    statement: >-
      A forbidden request naming lost application permission or licensing prompts an application
      refresh and notifies each registered refusal listener once.
    kind: lifecycle
    enforced_at:
      - console
    must_prove: true
    provenance: test
    source: >-
      react-console:e2e/mock/application-access.mock.spec.ts#brings the launcher up to date instead
      of leaving it offering what is gone
    origin: >-
      services-platform:docs/proposals/application-access-and-entitlements.md#6.4 Console
      integration, item 4 (built and accepted by Andrew 2026-10-15)
  - id: BR-CAP-PFM-CSH-016-02
    proved_by: [ATS-PFM-CSH-016-02, TST-PFM-CSH-030]
    statement: Other refusal statuses or codes do not notify application-refresh listeners.
    kind: validation
    enforced_at:
      - console
    must_prove: true
    provenance: test
    source: >-
      react-console:lib/security-context/application-refusal.test.ts#leaves every other refusal
      alone
    origin: none
  - id: BR-CAP-PFM-CSH-016-03
    proved_by: [ATS-PFM-CSH-016-03, ATS-PFM-CSH-016-08]
    statement: >-
      A visible tab regaining focus or visibility requests applications after at least five minutes
      since the last recorded read.
    kind: lifecycle
    enforced_at:
      - console
    must_prove: true
    provenance: observed
    source: 'react-console:lib/security-context/provider.tsx:SecurityContextProvider'
    origin: >-
      services-platform:docs/proposals/application-access-and-entitlements.md#6.4 Console
      integration, item 4 (built and accepted by Andrew 2026-10-15)
  - id: BR-CAP-PFM-CSH-016-04
    proved_by: [ATS-PFM-CSH-016-05]
    statement: >-
      Application refresh replaces applications and features while retaining roles, permission rules
      and reachable workspaces.
    kind: invariant
    enforced_at:
      - console
    must_prove: true
    provenance: observed
    source: 'react-console:lib/security-context/provider.tsx:refreshApplications'
    origin: >-
      services-platform:docs/proposals/application-access-and-entitlements.md#7.1 The person's
      applications (built and accepted by Andrew 2026-10-15)
  - id: BR-CAP-PFM-CSH-016-05
    proved_by: [ATS-PFM-CSH-016-06, ATS-PFM-CSH-016-07]
    statement: >-
      Concurrent refresh calls reuse one request, and failures leave the existing application list
      without a separate error screen.
    kind: lifecycle
    enforced_at:
      - console
    must_prove: true
    provenance: observed
    source: 'react-console:lib/security-context/provider.tsx:refreshApplications'
    origin: none
  - id: BR-CAP-PFM-CSH-016-06
    proved_by: [ATS-PFM-CSH-016-04]
    statement: A refresh response is discarded when a workspace change supersedes the request.
    kind: invariant
    enforced_at:
      - console
    must_prove: true
    provenance: observed
    source: 'react-console:lib/security-context/provider.tsx:refreshApplications'
    origin: none
  - id: BR-CAP-PFM-CSH-016-07
    proved_by: []
    statement: A context without a selected workspace performs no application refresh.
    kind: policy
    enforced_at:
      - console
    must_prove: false
    provenance: observed
    source: 'react-console:lib/security-context/provider.tsx:refreshApplications'
    origin: none
scenarios:
  - id: SC-CAP-PFM-CSH-016-01
    given: CRM is offered but a request is refused for lost application access.
    when: The refusal triggers a refresh.
    then: CRM leaves navigation while other offered applications remain.
    provenance: test
    source: >-
      react-console:e2e/mock/application-access.mock.spec.ts#brings the launcher up to date instead
      of leaving it offering what is gone
  - id: SC-CAP-PFM-CSH-016-02
    given: An application refresh is pending for the old workspace.
    when: The person enters another workspace before that answer arrives.
    then: The old result does not replace the new workspace’s application choices.
    provenance: observed
    source: 'react-console:lib/security-context/provider.tsx:SecurityContextProvider'
edge_cases: []
constraints: []
depends_on:
  - CAP-PFM-CSH-014
related:
  - CAP-PFM-CSH-006
journeys: []
open_questions: []
evidence:
  - >-
    react-console at baf6dae:
    lib/security-context/{application-refusal,application-refusal.test,provider}.ts*,
    lib/auth/api.ts (reports refusals), e2e/mock/application-access.mock.spec.ts.
  - >-
    services-platform at ad3f6a6: modules/security/aws/api/access.routes.ts (getMySecurityContext,
    getMySecurityContextInTenant, getMyApplications),
    modules/security/services/access/security-context.ts (applications_of),
    docs/security/application-access.md, docs/licensing.md §2 and §9,
    docs/proposals/application-access-and-entitlements.md §6.4, §7.1, §10.1.
controls: [TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-LOG-004, TC-LOG-005, TC-MON-002, TC-PI-001, TC-PI-003, TC-PI-005, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-VEN-001, TC-VEN-002, TC-VEN-003]
exercised_by: [FAS-PFM-CSH-04-02, FAS-PFM-CSH-04-03]
suites: [TST-PFM-CSH-011, TST-PFM-CSH-030]
---
# Refresh application choices when access changes

## Purpose

The console updates application navigation when its current access answer becomes stale.

## How It Works

A working tab can outlive a change made elsewhere. The shared refusal reporter detects application-related refusals and prompts the access provider. Tab focus also provides an opportunity to refresh an old answer. Refresh updates only the application portion of the context. A failed request leaves the person’s current answer in place. The product should test overlapping refreshes and workspace changes with controlled timing.

## Relationships

- Security supplies the applications refresh operation.
- Application navigation responds when the context’s application list changes.
