---
id: CAP-PFM-ELG-010
title: Refresh decisions and request role rechecks
feature: FEAT-PFM-ELG-02
product_area: platform
module: eligibility
revision: 1
status: draft
product_intent: confirmed
implementation_evidence: partially-observed
supersedes:
  - CAP-ELIG-EVL-005
  - CAP-ELIG-INV-001
  - CAP-ELIG-INV-002
  - CAP-ELIG-INV-003
  - CAP-ELIG-INV-004
  - CAP-ELIG-GOV-010
  - CAP-ELIG-AUT-010
  - CAP-ELIG-AUT-013
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-platform:docs/proposals/eligibility/17-decision-register.md#D-22'
  - 'services-platform:docs/proposals/eligibility/17-decision-register.md#D-25'
  - 'services-platform:docs/milestones/plans/PLAT-M11-plan.md#2. Scope'
purpose: >-
  Cached answers and rule-derived roles need a response to changing inputs. This
  capability invalidates answers and asks the role owner to reconcile holdings.
outcomes:
  - A release changes which expression subsequent requests select.
  - >-
    Registered change events request role rechecks; CRM has not yet registered
    its events.
concepts:
  - CON-PFM-ELG-003
  - CON-PFM-ELG-002
actors:
  - ACT-PFM-024
  - ACT-PFM-026
surfaces:
  - api
  - job
preconditions: []
postconditions: []
permissions:
  - key: platform.eligibility.reconcile
    where_checked: api
    scope: tenant
rules:
  - id: BR-CAP-PFM-ELG-010-01
    proved_by: [ATS-PFM-ELG-008-18, ATS-PFM-ELG-010-01, ATS-PFM-ELG-010-08, TST-PFM-ELG-147, TST-PFM-ELG-412, TST-PFM-ELG-477]
    statement: >-
      Compiled display evaluations may reuse an answer for two minutes;
      authorization, transactional, dry-run, test and indeterminate results are
      excluded, and cache hits create no new decision record.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/e2e/eligibility-evaluate.e2e.spec.js#never
      answers an authorization evaluation from the cache
    origin: none
  - id: BR-CAP-PFM-ELG-010-02
    proved_by: [ATS-PFM-ELG-004-16, ATS-PFM-ELG-010-02, ATS-PFM-ELG-010-07, TST-PFM-ELG-193, TST-PFM-ELG-412]
    statement: >-
      Publication, rollback and reference replacement invalidate cached answers
      for the changed rule and its followers before their next evaluation.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/e2e/eligibility-evaluate.e2e.spec.js#answers
      from the data again once the publish has flushed the definition’s
      decisions
    origin: none
  - id: BR-CAP-PFM-ELG-010-03
    proved_by: [ATS-PFM-ELG-010-03, ATS-PFM-ELG-010-09, ATS-PFM-ELG-010-10, ATS-PFM-ELG-011-10, ATS-PFM-ELG-012-08, TST-PFM-ELG-179, TST-PFM-ELG-198, TST-PFM-ELG-464]
    statement: >-
      Publication and rollback enqueue current rule-derived role holders and
      simulation gains, limited to 10,000 newly eligible subjects, and report
      the queued count.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/population/population-run.integration.spec.js#queues
      a reconcile for every subject the simulation found newly eligible when the
      version is published
    origin: none
  - id: BR-CAP-PFM-ELG-010-04
    proved_by: [ATS-PFM-ELG-010-04, TST-PFM-ELG-464]
    statement: >-
      CRM contact, organization and affiliation events invalidate subject
      answers and request role rechecks only when a relevant condition declares
      event refresh; time-only conditions acknowledge the event without work.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/population/population-run.integration.spec.js#does
      nothing for a change a ttl-only type reads: nothing dropped, nothing
      queued
    origin: none
  - id: BR-CAP-PFM-ELG-010-05
    proved_by: [ATS-PFM-ELG-010-05, TST-PFM-ELG-511]
    statement: >-
      The system-only reconcile route requires a staff key, accepts at most 100
      subjects and deduplicates both repeated subjects and already-pending
      requests.
    kind: permission
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/dispatch/derived-assignment-reconciles.integration.spec.js#is
      a system route asking for the staff-only platform.eligibility.reconcile
    origin: none
  - id: BR-CAP-PFM-ELG-010-06
    proved_by: []
    statement: >-
      Switching a condition to event refresh requires a higher declaration
      version, and that switch alone produces no change record.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: documented
    source: 'services-platform:docs/eligibility.md#16. Invalidation (P4-05)'
    origin: none
  - id: BR-CAP-PFM-ELG-010-07
    proved_by: [ATS-PFM-ELG-010-06, TST-PFM-ELG-194]
    statement: >-
      Portal-message edits change the plan and bypass earlier cached answers,
      suspension rejects requests immediately and resumption may reuse the
      unchanged plan’s answer until its two-minute expiry.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      react-console:acceptance/eligibility/playwright/journeys/invalidation/ELIG-ACC-0481.spec.ts#ELIG-ACC-0481
    origin: none
  - id: BR-CAP-PFM-ELG-010-08
    proved_by: []
    statement: >-
      Security owns role rechecks, nightly reconciliation and grant expiry,
      while eligibility supplies evaluations and queues the requests.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: documented
    source: 'services-platform:docs/eligibility.md#13. Derived assignments'
    origin: none
scenarios:
  - id: SC-CAP-PFM-ELG-010-01
    given: A member becomes inactive while a display answer is cached.
    when: The administrator republishes the expression.
    then: The subsequent answer reads the changed membership data.
    provenance: test
    source: >-
      react-console:acceptance/eligibility/playwright/journeys/invalidation/ELIG-ACC-0480.spec.ts#ELIG-ACC-0480
  - id: SC-CAP-PFM-ELG-010-02
    given: A released expression controls a role.
    when: Its publication completes.
    then: Current holders and sampled simulation gains are queued for recheck.
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/population/population-run.integration.spec.js#queues
      a reconcile for every subject the simulation found newly eligible when the
      version is published
edge_cases:
  - id: SC-CAP-PFM-ELG-010-03
    given: An organization used by many cached decisions changes.
    when: The change receiver handles its event.
    then: >-
      Some earlier route-cache answers remain until expiry because subject
      indexing is absent.
    provenance: documented
    source: 'services-platform:docs/debt/eligibility-decision-cache-subject-keys.md'
constraints: []
depends_on:
  - CAP-PFM-ELG-008
related:
  - CAP-PFM-ELG-004
  - CAP-PFM-ELG-011
journeys: []
open_questions: []
evidence:
  - >-
    services-platform: docs/eligibility.md;
    docs/milestones/PLAT-M11-eligibility-rules.md,
    PLAT-M12-eligibility-who-qualifies.md,
    PLAT-M13-eligibility-roles-and-permissions.md, plans/PLAT-M11-plan.md;
    docs/proposals/eligibility/17-decision-register.md;
    modules/eligibility/services/evaluate/decision-cache.ts,
    services/invalidation/** (decision-cache-keys.ts, handle-change-events.ts,
    on-definition-published.ts), services/compile/plan-cache.ts,
    aws/api/reconcile.routes.ts, aws/logic/eligibility-change-events.lambda.ts;
    modules/security/tests/integration/services/dispatch/derived-assignment-reconciles.integration.spec.js
    (the reconcile queue, named as a dependency);
    docs/debt/eligibility-decision-cache-subject-keys.md; rule-level source and
    test references
  - >-
    react-console: acceptance/eligibility/journeys/invalidation/*.json and
    matching browser specifications.
controls: [TC-AVL-004, TC-AVL-005, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-006, TC-DAT-001, TC-DAT-003, TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, TC-IAM-006, TC-LOG-001, TC-MON-001, 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]
exercised_by: [FAS-PFM-ELG-02-02, FAS-PFM-ELG-02-03, FAS-PFM-ELG-03-02]
suites: [TST-PFM-ELG-147, TST-PFM-ELG-179, TST-PFM-ELG-193, TST-PFM-ELG-194, TST-PFM-ELG-198, TST-PFM-ELG-412, TST-PFM-ELG-464, TST-PFM-ELG-477, TST-PFM-ELG-511]
---
# Refresh decisions and request role rechecks

## Purpose

Cached answers and rule-derived roles need a response to changing inputs. This capability invalidates answers and asks the role owner to reconcile holdings.

## How It Works

Display requests can reuse a short-lived answer. Stronger consistency and trials use fresh evaluation. A release invalidates the relevant expression answers and plans. It also requests rechecks for affected role holders. Simulation gains extend that request to newly eligible subjects. Declared CRM change events provide another refresh trigger. Without event-enabled conditions, those events perform no refresh. A separate system request can queue specific subjects. Portal wording, suspension and resumption affect cached display answers differently. Security performs the role update after eligibility queues the request.

## Relationships

- Determine eligibility with an explanation produces the display answers whose freshness is managed.
