---
id: CAP-PFM-ELG-009
title: Retain the eligibility decisions that matter
feature: FEAT-PFM-ELG-02
product_area: platform
module: eligibility
revision: 1
status: draft
product_intent: confirmed
implementation_evidence: observed
supersedes:
  - CAP-ELIG-EVL-006
  - CAP-ELIG-EVL-007
  - CAP-ELIG-EVL-008
  - CAP-ELIG-OBS-006
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-platform:docs/proposals/eligibility/17-decision-register.md#D-10'
  - 'services-platform:docs/milestones/plans/PLAT-M11-plan.md#2. Scope'
purpose: >-
  Recorded decisions give support a way to explain a consequential answer later.
  The record ties that answer to the expression that produced it.
outcomes:
  - >-
    Transactional, authorization and uncertain answers retain their supporting
    reasons.
  - Retention removes recorded decisions after thirteen months.
concepts:
  - CON-PFM-ELG-003
actors:
  - ACT-PFM-013
  - ACT-PFM-025
surfaces:
  - console
  - api
preconditions: []
postconditions: []
permissions:
  - key: platform.eligibility.read
    where_checked: api
    scope: tenant
rules:
  - id: BR-CAP-PFM-ELG-009-01
    proved_by: [ATS-PFM-ELG-009-01, TST-PFM-ELG-146, TST-PFM-ELG-430, TST-PFM-ELG-472]
    statement: >-
      Transactional, authorization and indeterminate decisions are recorded,
      display decisions retain the first and then every twentieth by default per
      workspace, and dry runs, unbound tests and requests without a primary
      subject are excluded.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/unit/compile-and-evaluate.spec.js#records
      the first display decision of a tenant and then one in every rate
    origin: 'services-platform:docs/proposals/eligibility/17-decision-register.md#D-10'
  - id: BR-CAP-PFM-ELG-009-02
    proved_by: [ATS-PFM-ELG-009-02, TST-PFM-ELG-420]
    statement: >-
      Decision records permit application insertion and reading but no update or
      deletion, retaining the binding, expression version, plan, subject,
      evaluation day, state, outcome, up to 50 reasons and a summary trace.
    kind: invariant
    enforced_at:
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/db/eligibility-decisions.table.integration.spec.js#grants
      the application role SELECT and INSERT and nothing else, and no other role
      anything
    origin: none
  - id: BR-CAP-PFM-ELG-009-03
    proved_by: [ATS-PFM-ELG-009-03, TST-PFM-ELG-256, TST-PFM-ELG-420]
    statement: >-
      Monthly decision storage retains 13 complete months and drops older months
      without archival.
    kind: lifecycle
    enforced_at:
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/db/eligibility-decisions.table.integration.spec.js#detaches
      and drops October 2025, fourteen months old
    origin: 'services-platform:docs/proposals/eligibility/17-decision-register.md#D-10'
  - id: BR-CAP-PFM-ELG-009-04
    proved_by: [ATS-PFM-ELG-009-07, TST-PFM-ELG-448]
    statement: >-
      Decision identities are generated at evaluation time, preserving
      chronological ordering and assigning records to that month.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/persistence/decisions.integration.spec.js#answers
      the decision with a UUIDv7 minted at the evaluation’s instant
    origin: none
  - id: BR-CAP-PFM-ELG-009-05
    proved_by: [ATS-PFM-ELG-009-04, TST-PFM-ELG-148, TST-PFM-ELG-412, TST-PFM-ELG-413]
    statement: >-
      Decision lists require a subject or rule, omit traces, sort newest first
      and return 50 records by default or at most 100, accepting workspace dates
      or instants and rejecting unknown bindings.
    kind: validation
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/e2e/eligibility-evaluate.e2e.spec.js#refuses
      a list that names neither a subject nor a definition, 400
    origin: none
  - id: BR-CAP-PFM-ELG-009-06
    proved_by: [ATS-PFM-ELG-002-12, ATS-PFM-ELG-009-05, ATS-PFM-ELG-009-08, TST-PFM-ELG-149, TST-PFM-ELG-412, TST-PFM-ELG-420]
    statement: >-
      Decision reads explicitly constrain the workspace because the storage has
      no row policy, and an outside-workspace decision appears absent.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/e2e/eligibility-evaluate.e2e.spec.js#answers
      404 for a decision the tenant does not have
    origin: none
  - id: BR-CAP-PFM-ELG-009-07
    proved_by: [ATS-PFM-ELG-008-17, ATS-PFM-ELG-009-09, ATS-PFM-ELG-009-10, ATS-PFM-ELG-009-11, ATS-PFM-ELG-012-07]
    statement: >-
      Transactional and authorization decisions are persisted before returning,
      while sampled display writes happen afterward and failures are logged.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/evaluate/hosted-evaluate.integration.spec.js#records
      a display decision after answering it, at a sample rate of one
    origin: none
  - id: BR-CAP-PFM-ELG-009-08
    proved_by: [ATS-PFM-ELG-009-06, ATS-PFM-ELG-011-12, TST-PFM-ELG-437]
    statement: >-
      Workspace deletion purges decisions through a restricted purger function
      that accepts only a workspace undergoing deletion.
    kind: lifecycle
    enforced_at:
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/maintenance/tenant-participant.integration.spec.js#removes
      the decisions first, through the definer function, one batch a call
    origin: none
scenarios:
  - id: SC-CAP-PFM-ELG-009-01
    given: A person has 101 retained answers.
    when: 'Support traverses history and narrows rule, consumer and local date.'
    then: >-
      Every matching record appears once in reverse time order within the
      local-day window.
    provenance: test
    source: >-
      react-console:acceptance/eligibility/playwright/journeys/evaluation/ELIG-ACC-0292.spec.ts#ELIG-ACC-0292
edge_cases:
  - id: SC-CAP-PFM-ELG-009-02
    given: Two answers straddle a month boundary in universal time.
    when: A chapter searches by local dates.
    then: >-
      Storage follows the universal-time month and local-day filters still find
      the relevant answers.
    provenance: test
    source: >-
      react-console:acceptance/eligibility/playwright/journeys/observability/ELIG-ACC-0668.spec.ts#ELIG-ACC-0668
constraints: []
depends_on:
  - CAP-PFM-ELG-008
related:
  - CAP-PFM-ELG-002
  - CAP-PFM-ELG-012
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/aws/api/evaluate.routes.ts (decisions),
    services/evaluate/decision-recording.ts, decision-history.ts,
    services/persistence/decisions.ts,
    services/maintenance/workspace-participant.ts,
    db/eligibility-decisions.table.ts, db/partitioned-tables.ts;
    docs/debt/eligibility-display-decision-outbox.md; rule-level source and test
    references
  - >-
    react-console: acceptance/eligibility/journeys/evaluation/ELIG-ACC-0290,
    0292, 0293; observability/ELIG-ACC-0668, 0669.
controls: [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-002, TC-LOG-003, TC-LOG-005, 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-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-146, TST-PFM-ELG-148, TST-PFM-ELG-149, TST-PFM-ELG-256, TST-PFM-ELG-412, TST-PFM-ELG-413, TST-PFM-ELG-420, TST-PFM-ELG-430, TST-PFM-ELG-437, TST-PFM-ELG-448, TST-PFM-ELG-472]
---
# Retain the eligibility decisions that matter

## Purpose

Recorded decisions give support a way to explain a consequential answer later. The record ties that answer to the expression that produced it.

## How It Works

Platform records consequential decisions as evaluation proceeds. Frequent display questions are sampled instead of all retained. Dry runs and tests avoid creating decision history. A reader searches by subject or rule and can narrow the period. List entries provide a compact view; opening an entry exposes its trace. Stored answers retain their original evaluation context. Applications cannot revise those answers afterward. Monthly retention limits how far support can look back. A display-record write can fail after the answer has already returned, leaving only diagnostic evidence.

## Relationships

- Determine eligibility with an explanation produces the answers selected for retention.
