---
id: CAP-PFM-ELG-008
title: Determine eligibility with an explanation
feature: FEAT-PFM-ELG-02
product_area: platform
module: eligibility
revision: 1
status: draft
product_intent: confirmed
implementation_evidence: observed
supersedes:
  - CAP-ELIG-EVL-001
  - CAP-ELIG-EVL-002
  - CAP-ELIG-EVL-003
  - CAP-ELIG-EVL-004
  - CAP-ELIG-EVL-010
  - CAP-ELIG-EVL-011
  - CAP-ELIG-EVL-012
  - CAP-ELIG-EVL-013
  - CAP-ELIG-EVL-014
  - CAP-ELIG-SEC-005
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-platform:docs/milestones/plans/PLAT-M11-plan.md#A2'
  - 'services-platform:docs/milestones/plans/PLAT-M11-plan.md#D1'
  - 'services-platform:docs/milestones/plans/PLAT-M11-plan.md#D5'
  - 'services-platform:docs/milestones/plans/PLAT-M11-plan.md#PLAT-M11-S04'
  - 'services-platform:docs/proposals/eligibility/17-decision-register.md#D-08'
  - 'services-platform:docs/proposals/eligibility/17-decision-register.md#D-17'
  - 'services-platform:docs/proposals/eligibility/17-decision-register.md#D-31'
purpose: >-
  Applications need a dependable answer to an eligibility question. An
  explanation and explicit uncertainty handling make that answer usable.
outcomes:
  - >-
    Evaluation distinguishes qualification, refusal and uncertainty; the use’s
    policy interprets uncertain results.
  - Explanations respect the caller’s permitted detail.
concepts:
  - CON-PFM-ELG-003
  - CON-PFM-ELG-002
actors:
  - ACT-PFM-024
  - ACT-PFM-003
  - ACT-PFM-013
surfaces:
  - api
  - portal
preconditions: []
postconditions: []
permissions:
  - key: platform.eligibility.read
    where_checked: api
    scope: tenant
  - key: platform.security-self.read
    where_checked: api
    scope: tenant
rules:
  - id: BR-CAP-PFM-ELG-008-01
    proved_by: [ATS-PFM-ELG-003-07, ATS-PFM-ELG-007-20, ATS-PFM-ELG-008-01, ATS-PFM-ELG-008-15, ATS-PFM-ELG-008-16, ATS-PFM-ELG-008-18, ATS-PFM-ELG-010-08, TST-PFM-ELG-088, TST-PFM-ELG-141, TST-PFM-ELG-472]
    statement: >-
      Evaluation returns eligible, ineligible or indeterminate; an indeterminate
      result becomes denial under closed, admission requiring review under open
      with review, or an unresolved outcome under defer.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/unit/compile-and-evaluate.spec.js#makes
      an indeterminate state ineligible under closed
    origin: 'services-platform:docs/milestones/plans/PLAT-M11-plan.md#A2'
  - id: BR-CAP-PFM-ELG-008-02
    proved_by: [ATS-PFM-ELG-008-02, ATS-PFM-ELG-008-17, ATS-PFM-ELG-009-09, TST-PFM-ELG-144, TST-PFM-ELG-430, TST-PFM-ELG-490]
    statement: >-
      Evaluation verifies supplied subjects in the workspace before applying
      conditions, with an absent record yielding indeterminate and a not-found
      reason before the failure policy is applied.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/evaluate/hosted-evaluate.integration.spec.js#answers
      a contact no row of the tenant has indeterminate, subject_not_found,
      ineligible under the closed policy
    origin: 'services-platform:docs/milestones/plans/PLAT-M11-plan.md#D1'
  - id: BR-CAP-PFM-ELG-008-03
    proved_by: [ATS-PFM-ELG-008-03, TST-PFM-ELG-431]
    statement: >-
      An omitted or empty required subject yields an indeterminate result with a
      missing-subject reason.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/evaluate/plat-m11-evaluation.integration.spec.js#answers
      indeterminate with the reason subject_missing
    origin: none
  - id: BR-CAP-PFM-ELG-008-04
    proved_by: [ATS-PFM-ELG-008-04, ATS-PFM-ELG-008-19, ATS-PFM-ELG-012-06, TST-PFM-ELG-429, TST-PFM-ELG-473]
    statement: >-
      A failed data read becomes an indeterminate result with a read-failure
      reason under the binding policy rather than an exception, preserving
      results for the remaining batch entries.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/evaluate/crm-conditions.integration.spec.js#answers
      every evaluation indeterminate with the one reason read_failed
    origin: 'services-platform:docs/milestones/plans/PLAT-M11-plan.md#PLAT-M11-S04'
  - id: BR-CAP-PFM-ELG-008-05
    proved_by: [ATS-PFM-ELG-008-05, TST-PFM-ELG-431]
    statement: >-
      An empty stored value fails its condition, such as an absent address,
      instead of making the evaluation indeterminate.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/evaluate/plat-m11-evaluation.integration.spec.js#answers
      a contact with no address ineligible, not_satisfied, never fact_missing
    origin: none
  - id: BR-CAP-PFM-ELG-008-06
    proved_by: [ATS-PFM-ELG-008-06, TST-PFM-ELG-127, TST-PFM-ELG-128, TST-PFM-ELG-430, TST-PFM-ELG-431]
    statement: >-
      Evaluation selects the version effective on the requested day and resolves
      relative dates from that day.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/evaluate/hosted-evaluate.integration.spec.js#answers
      an as-of shift from the day asked about, so a contact adult today was not
      in 2015
    origin: none
  - id: BR-CAP-PFM-ELG-008-07
    proved_by: [ATS-PFM-ELG-008-07, TST-PFM-ELG-142, TST-PFM-ELG-412]
    statement: >-
      Evaluation batches accept one to 50 requests and return results in request
      order, rejecting a larger batch as a whole.
    kind: validation
    enforced_at:
      - api
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/e2e/eligibility-evaluate.e2e.spec.js#refuses
      a batch of more than 50 evaluations, 400
    origin: none
  - id: BR-CAP-PFM-ELG-008-08
    proved_by: [ATS-PFM-ELG-008-08, TST-PFM-ELG-085, TST-PFM-ELG-412, TST-PFM-ELG-477]
    statement: >-
      Purpose declarations control caller admission: portal callers require
      portal support, console callers cannot use system-only purposes and
      services require system support, with eligibility read authority also
      required for console and service callers.
    kind: permission
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/e2e/eligibility-evaluate.e2e.spec.js#refuses
      a console caller holding the read key a binding whose consumer kind takes
      system callers only, 403
    origin: none
  - id: BR-CAP-PFM-ELG-008-09
    proved_by: [ATS-PFM-ELG-008-09, TST-PFM-ELG-154, TST-PFM-ELG-412, TST-PFM-ELG-477]
    statement: >-
      Portal requests evaluate only the signed-in member’s linked contact for
      display and treat supplied facts as asserted, rejecting foreign contacts,
      stronger consistency or an unlinked member.
    kind: permission
    enforced_at:
      - api
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/e2e/eligibility-evaluate.e2e.spec.js#refuses
      a portal member an evaluation of another contact, 403
    origin: none
  - id: BR-CAP-PFM-ELG-008-10
    proved_by: [ATS-PFM-ELG-008-10, TST-PFM-ELG-140, TST-PFM-ELG-412, TST-PFM-ELG-477]
    statement: >-
      Explanation levels are none, portal, administrator and full; administrator
      and full require eligibility read authority and exclude portal callers,
      with excessive requests rejected.
    kind: permission
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/unit/evaluate-for-caller.spec.js#refuses
      a portal caller the full explanation even with the read permission
    origin: none
  - id: BR-CAP-PFM-ELG-008-11
    proved_by: [ATS-PFM-ELG-008-11, TST-PFM-ELG-126, TST-PFM-ELG-430, TST-PFM-ELG-431]
    statement: >-
      A closed-policy indeterminate result uses the rule’s portal message, with
      labelled explanations and no linked-record names exposed to portal
      readers.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/evaluate/hosted-evaluate.integration.spec.js#gives
      the portal the definition’s message for an indeterminate decision under
      the closed policy
    origin: none
  - id: BR-CAP-PFM-ELG-008-12
    proved_by: [ATS-PFM-ELG-008-12, TST-PFM-ELG-160, TST-PFM-ELG-412, TST-PFM-ELG-430]
    statement: >-
      People cannot request transactional evaluation over the web; in-process
      checks read and record within the consumer transaction, with equivalent
      SQL-function states for SQL-only expressions.
    kind: policy
    enforced_at:
      - api
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/evaluate/hosted-evaluate.integration.spec.js#answers
      the SQL function’s states the TypeScript path answers for the planted
      contacts
    origin: 'services-platform:docs/proposals/eligibility/17-decision-register.md#D-17'
  - id: BR-CAP-PFM-ELG-008-13
    proved_by: [ATS-PFM-ELG-008-13, TST-PFM-ELG-249, TST-PFM-ELG-430]
    statement: >-
      Provider evaluation uses declared batch sizes, a five-second budget and
      one retry, opening a 30-second circuit after five failures in one minute
      and returning indeterminate while open.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/evaluate/hosted-evaluate.integration.spec.js#opens
      the circuit after five failures and calls the provider no more while it is
      open
    origin: none
  - id: BR-CAP-PFM-ELG-008-14
    proved_by: [ATS-PFM-ELG-008-14, TST-PFM-ELG-430]
    statement: >-
      The eligibility data reader can inspect reporting-readable data only
      within the workspace and cannot write records.
    kind: permission
    enforced_at:
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/evaluate/hosted-evaluate.integration.spec.js#cannot
      insert into, update or delete from crm.contacts
    origin: 'services-platform:docs/milestones/plans/PLAT-M11-plan.md#D5'
  - id: BR-CAP-PFM-ELG-008-15
    proved_by: []
    statement: >-
      The product should publish evaluation for use inside consumer processes as
      the approved architecture describes; the available implementation remains
      internal to Platform.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: documented
    source: 'services-platform:docs/eligibility.md#9.6 In-process mode'
    origin: 'services-platform:docs/proposals/eligibility/17-decision-register.md#D-31'
scenarios:
  - id: SC-CAP-PFM-ELG-008-01
    given: A released active-adult expression serves a renewal desk.
    when: The desk evaluates an active adult and an inactive person.
    then: 'One qualifies and the other does not, with explanations.'
    provenance: test
    source: >-
      react-console:acceptance/eligibility/playwright/journeys/definitions/ELIG-ACC-0073.spec.ts#ELIG-ACC-0073
  - id: SC-CAP-PFM-ELG-008-02
    given: A storefront asks about a recently deleted contact.
    when: Its member-rate use applies closed policy.
    then: Not-found uncertainty produces a denial and standard pricing.
    provenance: test
    source: >-
      react-console:acceptance/eligibility/playwright/journeys/evaluation/ELIG-ACC-0287.spec.ts#ELIG-ACC-0287
edge_cases:
  - id: SC-CAP-PFM-ELG-008-03
    given: An expression depends entirely on supplied facts.
    when: Its named contact is absent.
    then: The result remains indeterminate rather than eligible.
    provenance: test
    source: >-
      react-console:acceptance/eligibility/playwright/journeys/evaluation/ELIG-ACC-0288.spec.ts#ELIG-ACC-0288
constraints: []
depends_on:
  - CAP-PFM-ELG-007
related:
  - CAP-PFM-ELG-003
  - CAP-PFM-ELG-009
  - CAP-PFM-ELG-010
journeys:
  - JNY-PFM-ELG-002
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/aws/api/evaluate.routes.ts,
    eligibility-service.routes.ts, services/evaluate/** (hosted-evaluate.ts,
    pipeline.ts, subjects.ts, subject-existence.ts, failed-reads.ts, policy.ts,
    providers.ts, circuit-breaker.ts, in-process.ts, in-transaction.ts,
    evaluate-for-caller.ts, explain-sentences.ts, explanation-names.ts),
    services/compile/**; migration 20261018010635_eligibility_check; rule-level
    source and test references
  - >-
    react-console: acceptance/eligibility/journeys/evaluation/*.json and
    matching browser specifications;
    acceptance/eligibility/inventory/capabilities.json (area EVL).
controls: [TC-AVL-004, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-CRY-001, TC-CRY-002, TC-CRY-003, TC-CRY-004, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-LOG-004, TC-LOG-005, 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-01, FAS-PFM-ELG-02-02, FAS-PFM-ELG-02-03, FAS-PFM-ELG-02-04, FAS-PFM-ELG-02-05]
suites: [TST-PFM-ELG-085, TST-PFM-ELG-088, TST-PFM-ELG-126, TST-PFM-ELG-127, TST-PFM-ELG-128, TST-PFM-ELG-140, TST-PFM-ELG-141, TST-PFM-ELG-142, TST-PFM-ELG-144, TST-PFM-ELG-154, TST-PFM-ELG-160, TST-PFM-ELG-249, TST-PFM-ELG-412, TST-PFM-ELG-429, TST-PFM-ELG-430, TST-PFM-ELG-431, TST-PFM-ELG-472, TST-PFM-ELG-473, TST-PFM-ELG-477, TST-PFM-ELG-490]
---
# Determine eligibility with an explanation

## Purpose

Applications need a dependable answer to an eligibility question. An explanation and explicit uncertainty handling make that answer usable.

## How It Works

The caller supplies a binding and the subjects being judged. Platform resolves the expression appropriate to the requested day. It checks the records and obtains the facts needed for evaluation. Conditions combine into a decision state. The binding’s policy interprets an uncertain state for the application. Explanation depth depends on the caller’s authority. Portal questions remain tied to the signed-in person. Transactional consumers have a path that shares their database transaction. Provider failures are bounded so an unavailable dependency produces an uncertain answer. The product should make consumer-process evaluation available through a published interface.

## Relationships

- Connect a rule to an application decision supplies the consumer’s expression, inputs and uncertainty policy.
