---
id: ATS-PFM-ELG-001
scope: CAP-PFM-ELG-001
product_area: platform
module: eligibility
revision: 3
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-PFM-ELG-001-01
    title: Validate readable identities
    level: api
    proves:
      - BR-CAP-PFM-ELG-001-01
      - INV-DOM-PFM-ELG-001-01
    preconditions: The caller can author rules in a workspace.
    steps: 'Submit uppercase, hyphenated, reserved, 64-character and valid keys.'
    expected: >-
      Only the valid lowercase underscore form within 63 characters persists; refusals leave no
      rule.
    negative: true
    data_needs: No fixtures beyond the described setup.
    bound_to:
      - >-
        services-platform:modules/eligibility/tests/integration/services/persistence/definitions.integration.spec.js#refuses
        an id that is not a configuration id, before anything is written
      - TST-PFM-ELG-450
      - >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definition-key-alias.e2e.spec.js#refuses
        a key outside the configuration-id grammar, 400
      - TST-PFM-ELG-410
      - >-
        react-console:acceptance/eligibility/playwright/journeys/definitions/ELIG-ACC-0052.spec.ts#ELIG-ACC-0052
      - TST-PFM-ELG-097
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/persistence/definitions.integration.spec.js#refuses
      an id that is not a configuration id, before anything is written
    category: validation
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/integration/services/persistence/definitions.integration.spec.js#refuses
        an id that is not a configuration id, before anything is written
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/integration/services/persistence/definitions.integration.spec.js#refuses
        an id that is not a configuration id, before anything is written
    binding_scope: >-
      The cited tests contribute their reachable assertions; the binding does not establish
      execution or every step of this scenario.
    binding_limitations:
      - FND-PFM-ELG-074
  - id: ATS-PFM-ELG-001-02
    title: Keep uniqueness local
    level: api
    proves:
      - BR-CAP-PFM-ELG-001-02
      - INV-DOM-PFM-ELG-001-01
    preconditions: Two workspaces are available.
    steps: Create a key twice in one workspace and once in the second.
    expected: The local duplicate fails with its key named; the second workspace accepts it.
    negative: true
    data_needs: No fixtures beyond the described setup.
    bound_to:
      - >-
        services-platform:modules/eligibility/tests/integration/services/persistence/definitions.integration.spec.js#refuses
        a second definition with the same id (key) in the tenant, naming it
      - TST-PFM-ELG-450
      - >-
        services-platform:modules/eligibility/tests/integration/services/persistence/definitions.integration.spec.js#accepts
        the same id in another tenant, because ids are unique per tenant
      - >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#refuses
        a second definition with the same key, 400
      - TST-PFM-ELG-411
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/persistence/definitions.integration.spec.js#refuses
      a second definition with the same id (key) in the tenant, naming it
    category: invariant
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/integration/services/persistence/definitions.integration.spec.js#refuses
        a second definition with the same id (key) in the tenant, naming it
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/integration/services/persistence/definitions.integration.spec.js#refuses
        a second definition with the same id (key) in the tenant, naming it
    binding_scope: >-
      The cited tests contribute their reachable assertions; the binding does not establish
      execution or every step of this scenario.
    binding_limitations:
      - FND-PFM-ELG-074
  - id: ATS-PFM-ELG-001-03
    title: Protect the permanent key
    level: api
    proves:
      - BR-CAP-PFM-ELG-001-03
      - INV-DOM-PFM-ELG-001-01
    preconditions: A saved rule is available.
    steps: Submit a metadata edit with another key.
    expected: The edit fails and the original identity remains.
    negative: true
    data_needs: No fixtures beyond the described setup.
    bound_to:
      - >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#refuses
        an edit that names the key, which never changes, 400
      - TST-PFM-ELG-411
      - >-
        services-platform:modules/eligibility/tests/integration/services/persistence/definitions.integration.spec.js#refuses
        an update that names the key, which never changes
      - TST-PFM-ELG-450
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#refuses an
      edit that names the key, which never changes, 400
    category: invariant
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#refuses
        an edit that names the key, which never changes, 400
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#refuses
        an edit that names the key, which never changes, 400
    binding_scope: >-
      The cited tests contribute their reachable assertions; the binding does not establish
      execution or every step of this scenario.
    binding_limitations:
      - FND-PFM-ELG-074
  - id: ATS-PFM-ELG-001-04
    title: Retain invalid work for repair
    level: api
    proves:
      - BR-CAP-PFM-ELG-001-04
    preconditions: Separate writing and publishing callers are available.
    steps: 'Save a misused condition, attempt release, repair it, validate and release again.'
    expected: >-
      Problems accompany the saved draft and block the first release; the corrected expression
      validates and publishes.
    negative: false
    data_needs: No fixtures beyond the described setup.
    bound_to:
      - >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#answers
        the draft’s problem, saved rather than refused
      - TST-PFM-ELG-411
      - >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#refuses
        the publish while the problem exists, 400, naming it
      - >-
        react-console:acceptance/eligibility/playwright/journeys/definitions/ELIG-ACC-0059.spec.ts#ELIG-ACC-0059
      - TST-PFM-ELG-104
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#answers
      the draft’s problem, saved rather than refused
    category: rule
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#answers
        the draft’s problem, saved rather than refused
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#answers
        the draft’s problem, saved rather than refused
    binding_scope: >-
      The cited tests contribute their reachable assertions; the binding does not establish
      execution or every step of this scenario.
    binding_limitations:
      - FND-PFM-ELG-074
  - id: ATS-PFM-ELG-001-05
    title: Replace one draft with version checks
    level: api
    proves:
      - BR-CAP-PFM-ELG-001-05
      - INV-DOM-PFM-ELG-001-02
    preconditions: A rule has an editable draft.
    steps: 'Save twice, retry the initial version, then save without a version.'
    expected: >-
      The same draft advances; the obsolete save changes nothing and the unversioned save replaces
      it.
    negative: false
    data_needs: No fixtures beyond the described setup.
    bound_to:
      - >-
        services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#replaces
        the draft in place on the next save, moving its version
      - TST-PFM-ELG-438
      - >-
        services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#refuses
        a save at a draft version that is no longer current, and leaves the draft as it was
      - >-
        react-console:acceptance/eligibility/playwright/journeys/definitions/ELIG-ACC-0056.spec.ts#ELIG-ACC-0056
      - TST-PFM-ELG-101
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#replaces
      the draft in place on the next save, moving its version
    category: concurrency
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#replaces
        the draft in place on the next save, moving its version
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#replaces
        the draft in place on the next save, moving its version
    binding_scope: >-
      The cited tests contribute their reachable assertions; the binding does not establish
      execution or every step of this scenario.
    binding_limitations:
      - FND-PFM-ELG-074
  - id: ATS-PFM-ELG-001-06
    title: Distinguish bare creation
    level: api
    proves:
      - BR-CAP-PFM-ELG-001-06
    preconditions: An author can create rules.
    steps: 'Create with and without conditions and inspect both, then save the bare rule’s draft.'
    expected: >-
      The bare rule gains its first version on save; supplied conditions create version one
      immediately.
    negative: false
    data_needs: No fixtures beyond the described setup.
    bound_to:
      - >-
        services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#creates
        a definition without a draft when the request carries no expression
      - TST-PFM-ELG-438
      - >-
        services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#makes
        the first draft of a bare definition version 1
      - >-
        services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#saves
        the expression as draft version 1 with its summary and no problems
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#creates
      a definition without a draft when the request carries no expression
    category: transition
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#creates
        a definition without a draft when the request carries no expression
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#creates
        a definition without a draft when the request carries no expression
    binding_scope: >-
      The cited tests contribute their reachable assertions; the binding does not establish
      execution or every step of this scenario.
    binding_limitations:
      - FND-PFM-ELG-074
  - id: ATS-PFM-ELG-001-07
    title: Identify invalid dependencies and subjects
    level: api
    proves:
      - BR-CAP-PFM-ELG-001-07
    preconditions: 'Published, archived and draft-only rules and a contact custom field are present.'
    steps: >-
      Validate unavailable references, a cycle, unsupported facts and fields and an organization
      primary on a contact rule.
    expected: >-
      Each invalid case returns its own problem, while an available publication and known field
      validate.
    negative: true
    data_needs: No fixtures beyond the described setup.
    bound_to:
      - >-
        services-platform:modules/eligibility/tests/integration/services/model/validate-definition.integration.spec.js#answers
        a reference to an archived definition as missing
      - TST-PFM-ELG-441
      - >-
        services-platform:modules/eligibility/tests/integration/services/model/validate-definition.integration.spec.js#answers
        a reference to a definition with only a draft as missing
      - >-
        services-platform:modules/eligibility/tests/integration/services/model/validate-definition.integration.spec.js#answers
        a draft that reaches itself through a published reference as a cycle
      - >-
        services-platform:modules/eligibility/tests/integration/services/model/validate-definition.integration.spec.js#answers
        a fact no binding supplies as unknown
      - >-
        services-platform:modules/eligibility/tests/integration/services/model/validate-definition.integration.spec.js#answers
        a field the tenant’s contacts do not have as invalid args, naming it
      - >-
        services-platform:modules/eligibility/tests/integration/services/model/validate-definition.integration.spec.js#answers
        a primary subject of another kind than the definition’s
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/model/validate-definition.integration.spec.js#answers
      a reference to an archived definition as missing
    category: validation
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/integration/services/model/validate-definition.integration.spec.js#answers
        a reference to an archived definition as missing
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/integration/services/model/validate-definition.integration.spec.js#answers
        a reference to an archived definition as missing
    binding_scope: >-
      The cited tests contribute their reachable assertions; the binding does not establish
      execution or every step of this scenario.
    binding_limitations:
      - FND-PFM-ELG-074
  - id: ATS-PFM-ELG-001-08
    title: Check parameter consistency
    level: api
    proves:
      - BR-CAP-PFM-ELG-001-08
    preconditions: An expression declares a parameter.
    steps: 'Try inverted bounds, a mistyped default, an out-of-range default and a consistent declaration.'
    expected: Invalid declarations identify the parameter; the consistent declaration validates.
    negative: true
    data_needs: No fixtures beyond the described setup.
    bound_to:
      - >-
        services-platform:modules/eligibility/tests/e2e/eligibility-governance-repairs.e2e.spec.js#refuses
        min above max, naming the parameter
      - TST-PFM-ELG-413
      - >-
        services-platform:modules/eligibility/tests/e2e/eligibility-governance-repairs.e2e.spec.js#refuses
        a default of the wrong type, naming the parameter
      - >-
        services-platform:modules/eligibility/tests/e2e/eligibility-governance-repairs.e2e.spec.js#refuses
        a default outside min and max, naming the parameter
      - >-
        services-platform:modules/eligibility/tests/unit/governance-repairs.spec.js#refuses a
        minimum above the maximum, naming the parameter
      - TST-PFM-ELG-480
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/e2e/eligibility-governance-repairs.e2e.spec.js#refuses
      min above max, naming the parameter
    category: validation
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/e2e/eligibility-governance-repairs.e2e.spec.js#refuses
        min above max, naming the parameter
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/e2e/eligibility-governance-repairs.e2e.spec.js#refuses
        min above max, naming the parameter
    binding_scope: >-
      The cited tests contribute their reachable assertions; the binding does not establish
      execution or every step of this scenario.
    binding_limitations:
      - FND-PFM-ELG-074
  - id: ATS-PFM-ELG-001-09
    title: Exercise exact expression boundaries
    level: api
    proves:
      - BR-CAP-PFM-ELG-001-09
    preconditions: A rule author is available.
    steps: Validate expressions at every size bound and one beyond each.
    expected: 'Boundary cases pass, excess cases fail and summaries stop at 4,000 characters.'
    negative: true
    data_needs: No fixtures beyond the described setup.
    bound_to:
      - >-
        react-console:acceptance/eligibility/playwright/journeys/definitions/ELIG-ACC-0061.spec.ts#ELIG-ACC-0061
      - TST-PFM-ELG-106
    provenance: test
    source: >-
      react-console:acceptance/eligibility/playwright/journeys/definitions/ELIG-ACC-0061.spec.ts#ELIG-ACC-0061
    category: boundary
    action_evidence:
      provenance: test
      source: >-
        react-console:acceptance/eligibility/playwright/journeys/definitions/ELIG-ACC-0061.spec.ts#ELIG-ACC-0061
    assertion_evidence:
      provenance: test
      source: >-
        react-console:acceptance/eligibility/playwright/journeys/definitions/ELIG-ACC-0061.spec.ts#ELIG-ACC-0061
    binding_scope: >-
      The cited tests contribute their reachable assertions; the binding does not establish
      execution or every step of this scenario.
    binding_limitations:
      - FND-PFM-ELG-074
  - id: ATS-PFM-ELG-001-10
    title: Resolve readable labels
    level: api
    proves:
      - BR-CAP-PFM-ELG-001-10
    preconditions: An expression refers to a portal role and affiliation-type choice.
    steps: Validate it and an expression referring to a removed role.
    expected: >-
      Available labels appear in the summary; the unresolved reference remains, and stored
      references are unchanged.
    negative: false
    data_needs: No fixtures beyond the described setup.
    bound_to:
      - >-
        services-platform:modules/eligibility/tests/integration/services/model/role-names.integration.spec.js#says
        the roles by name in the summary of a validation
      - TST-PFM-ELG-440
      - >-
        services-platform:modules/eligibility/tests/integration/services/model/role-names.integration.spec.js#keeps
        the id of a role that is not there, so the sentence is not wrong (negative control)
      - >-
        react-console:acceptance/eligibility/playwright/journeys/definitions/ELIG-ACC-0062.spec.ts#ELIG-ACC-0062
      - TST-PFM-ELG-107
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/model/role-names.integration.spec.js#says
      the roles by name in the summary of a validation
    category: rule
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/integration/services/model/role-names.integration.spec.js#says
        the roles by name in the summary of a validation
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/integration/services/model/role-names.integration.spec.js#says
        the roles by name in the summary of a validation
    binding_scope: >-
      The cited tests contribute their reachable assertions; the binding does not establish
      execution or every step of this scenario.
    binding_limitations:
      - FND-PFM-ELG-074
  - id: ATS-PFM-ELG-001-11
    title: Require authority to share
    level: api
    proves:
      - BR-CAP-PFM-ELG-001-11
    preconditions: 'A private rule, a writer without release authority and a publisher exist.'
    steps: 'Both callers attempt workspace sharing, and the writer renames the rule.'
    expected: Sharing fails for the writer and succeeds for the publisher; renaming remains allowed.
    negative: true
    data_needs: No fixtures beyond the described setup.
    bound_to:
      - >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#refuses
        a writer without the publish permission the promotion of a private definition, 403
      - TST-PFM-ELG-411
      - >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#lets an
        administrator who may publish promote it
      - >-
        services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#refuses
        to promote a private definition without the publish permission, 403
      - TST-PFM-ELG-438
      - >-
        react-console:acceptance/eligibility/playwright/journeys/definitions/ELIG-ACC-0057.spec.ts#ELIG-ACC-0057
      - TST-PFM-ELG-102
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#refuses a
      writer without the publish permission the promotion of a private definition, 403
    category: permission
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#refuses
        a writer without the publish permission the promotion of a private definition, 403
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#refuses
        a writer without the publish permission the promotion of a private definition, 403
    binding_scope: >-
      The cited tests contribute their reachable assertions; the binding does not establish
      execution or every step of this scenario.
    binding_limitations:
      - FND-PFM-ELG-074
  - id: ATS-PFM-ELG-001-12
    title: Select the duplication source
    level: api
    proves:
      - BR-CAP-PFM-ELG-001-12
    preconditions: 'A published rule also has a draft, and another rule has never been released.'
    steps: 'Duplicate the default source, the draft and an explicitly absent publication.'
    expected: >-
      Copies start with the chosen expression in a workspace-owned first draft; the absent source
      fails.
    negative: false
    data_needs: No fixtures beyond the described setup.
    bound_to:
      - >-
        services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#copies
        the published rule as the copy’s draft by default, with a note naming the source
      - TST-PFM-ELG-438
      - >-
        services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#copies
        the draft when asked, under the name given
      - >-
        services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#refuses
        to copy a published rule from a definition never published
      - >-
        react-console:acceptance/eligibility/playwright/journeys/definitions/ELIG-ACC-0065.spec.ts#ELIG-ACC-0065
      - TST-PFM-ELG-110
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#copies
      the published rule as the copy’s draft by default, with a note naming the source
    category: transition
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#copies
        the published rule as the copy’s draft by default, with a note naming the source
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#copies
        the published rule as the copy’s draft by default, with a note naming the source
    binding_scope: >-
      The cited tests contribute their reachable assertions; the binding does not establish
      execution or every step of this scenario.
    binding_limitations:
      - FND-PFM-ELG-074
  - id: ATS-PFM-ELG-001-13
    title: Count Unicode characters
    level: api
    proves:
      - BR-CAP-PFM-ELG-001-13
    preconditions: An author can save rule wording.
    steps: >-
      Try 1,000 and 1,001 four-byte characters in notes and boundary-length names and portal wording
      in multiple scripts.
    expected: Boundary lengths pass and one excess character fails with the limit named.
    negative: true
    data_needs: No fixtures beyond the described setup.
    bound_to:
      - >-
        services-platform:modules/eligibility/tests/integration/services/persistence/versions.integration.spec.js#refuses
        a change note of 1001 astral characters naming the limit
      - TST-PFM-ELG-462
      - >-
        services-platform:modules/eligibility/tests/unit/code-points.spec.js#counts an astral
        character once
      - TST-PFM-ELG-471
      - >-
        react-console:acceptance/eligibility/playwright/journeys/definitions/ELIG-ACC-0066.spec.ts#ELIG-ACC-0066
      - TST-PFM-ELG-111
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/persistence/versions.integration.spec.js#refuses
      a change note of 1001 astral characters naming the limit
    category: boundary
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/integration/services/persistence/versions.integration.spec.js#refuses
        a change note of 1001 astral characters naming the limit
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/integration/services/persistence/versions.integration.spec.js#refuses
        a change note of 1001 astral characters naming the limit
    binding_scope: >-
      The cited tests contribute their reachable assertions; the binding does not establish
      execution or every step of this scenario.
    binding_limitations:
      - FND-PFM-ELG-074
  - id: ATS-PFM-ELG-001-14
    title: Require restoration before drafting
    level: api
    proves:
      - BR-CAP-PFM-ELG-001-14
    preconditions: The rule is archived.
    steps: 'Attempt a draft save, restore and save again.'
    expected: Archive blocks the first save and restoration permits the second.
    negative: true
    data_needs: No fixtures beyond the described setup.
    bound_to:
      - >-
        services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#refuses
        a draft of an archived definition
      - TST-PFM-ELG-438
      - >-
        services-platform:modules/eligibility/tests/integration/services/persistence/definitions.integration.spec.js#refuses
        a new draft of an archived definition
      - TST-PFM-ELG-450
      - >-
        react-console:acceptance/eligibility/playwright/journeys/definitions/ELIG-ACC-0071.spec.ts#ELIG-ACC-0071
      - TST-PFM-ELG-116
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#refuses
      a draft of an archived definition
    category: transition
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#refuses
        a draft of an archived definition
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#refuses
        a draft of an archived definition
    binding_scope: >-
      The cited tests contribute their reachable assertions; the binding does not establish
      execution or every step of this scenario.
    binding_limitations:
      - FND-PFM-ELG-074
  - id: ATS-PFM-ELG-001-15
    title: Identity aliases agree across creation and duplication
    level: api
    proves:
      - BR-CAP-PFM-ELG-001-15
    preconditions: A writer can create and copy expressions.
    steps: >-
      Submit either alias, matching aliases, conflicting aliases and neither alias to both
      operations.
    expected: >-
      Either single alias and matching pairs succeed with equal response identities; conflicting or
      missing identities are refused.
    negative: true
    data_needs: The existing route fixture supplies the rule and authorized caller.
    bound_to:
      - >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definition-key-alias.e2e.spec.js#accepts
        id and key when they are equal
      - TST-PFM-ELG-410
      - >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definition-key-alias.e2e.spec.js#refuses
        id and key that differ, 400, naming both
      - >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definition-key-alias.e2e.spec.js#refuses
        a create naming neither id nor key, 400
      - >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definition-key-alias.e2e.spec.js#refuses
        a duplicate naming neither id nor key, 400
    provenance: test
    source: >-
      services-platform:modules/eligibility/tests/e2e/eligibility-definition-key-alias.e2e.spec.js#refuses
      id and key that differ, 400, naming both
    category: validation
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definition-key-alias.e2e.spec.js#refuses
        id and key that differ, 400, naming both
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definition-key-alias.e2e.spec.js#refuses
        id and key that differ, 400, naming both
    binding_scope: >-
      The cited tests contribute their reachable assertions; the binding does not establish
      execution or every step of this scenario.
    binding_limitations:
      - FND-PFM-ELG-074
  - id: ATS-PFM-ELG-001-16
    title: Discover a saved draft
    category: interaction
    level: api
    proves:
      - BR-CAP-PFM-ELG-001-06
      - BR-CAP-PFM-ELG-002-06
    exercises:
      - CAP-PFM-ELG-001
      - CAP-PFM-ELG-002
    preconditions: A rule author and a reader share a workspace.
    steps: >-
      Create a bare rule, save a draft that references a released rule, then inspect the list and
      detail.
    expected: >-
      The new rule is discoverable and its draft and reference counts agree with the saved
      expression.
    negative: false
    data_needs: Run-owned records and a controlled clock where timing changes the result.
    bound_to: []
    provenance: proposed
    source: >-
      services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#creates
      a definition without a draft when the request carries no expression;
      services-platform:modules/eligibility/tests/integration/services/model/explorer.integration.spec.js#answers
      the version it last published and its draft
    action_evidence:
      provenance: proposed
      source: >-
        services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#creates
        a definition without a draft when the request carries no expression;
        services-platform:modules/eligibility/tests/integration/services/model/explorer.integration.spec.js#answers
        the version it last published and its draft
    assertion_evidence:
      provenance: proposed
      source: >-
        services-platform:modules/eligibility/tests/integration/services/model/authoring.integration.spec.js#creates
        a definition without a draft when the request carries no expression;
        services-platform:modules/eligibility/tests/integration/services/model/explorer.integration.spec.js#answers
        the version it last published and its draft
    binding_scope: This sequence is proposed and has no executable proof binding.
  - id: ATS-PFM-ELG-001-17
    title: Repair work before trying it
    category: interaction
    level: api
    proves:
      - BR-CAP-PFM-ELG-001-04
      - BR-CAP-PFM-ELG-003-03
    exercises:
      - CAP-PFM-ELG-001
      - CAP-PFM-ELG-003
    preconditions: A draft has one invalid reference and a readable subject exists.
    steps: 'Save the invalid draft, attempt a trial, repair the reference and run the trial again.'
    expected: >-
      The first trial exposes draft problems; the repaired trial supplies a condition explanation
      without decision history.
    negative: false
    data_needs: Run-owned records and a controlled clock where timing changes the result.
    bound_to: []
    provenance: proposed
    source: >-
      services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#answers
      the draft’s problem, saved rather than refused;
      react-console:acceptance/eligibility/playwright/journeys/evaluation/ELIG-ACC-0294.spec.ts#ELIG-ACC-0294
    action_evidence:
      provenance: proposed
      source: >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#answers
        the draft’s problem, saved rather than refused;
        react-console:acceptance/eligibility/playwright/journeys/evaluation/ELIG-ACC-0294.spec.ts#ELIG-ACC-0294
    assertion_evidence:
      provenance: proposed
      source: >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#answers
        the draft’s problem, saved rather than refused;
        react-console:acceptance/eligibility/playwright/journeys/evaluation/ELIG-ACC-0294.spec.ts#ELIG-ACC-0294
    binding_scope: This sequence is proposed and has no executable proof binding.
  - id: ATS-PFM-ELG-001-18
    title: Keep repairable drafts out of release
    category: interaction
    level: api
    proves:
      - BR-CAP-PFM-ELG-001-04
      - BR-CAP-PFM-ELG-004-02
    exercises:
      - CAP-PFM-ELG-001
      - CAP-PFM-ELG-004
    preconditions: A writer has a draft with validation errors.
    steps: 'Save the draft, attempt publication, repair its errors and publish with authority.'
    expected: >-
      Only the repaired expression appears as a released version; the earlier refusal leaves the
      draft available.
    negative: false
    data_needs: Run-owned records and a controlled clock where timing changes the result.
    bound_to: []
    provenance: proposed
    source: >-
      services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#answers
      the draft’s problem, saved rather than refused;
      services-platform:modules/eligibility/tests/integration/services/governance/publish.integration.spec.js#refuses
      a condition type of an application the tenant is not licensed for
    action_evidence:
      provenance: proposed
      source: >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#answers
        the draft’s problem, saved rather than refused;
        services-platform:modules/eligibility/tests/integration/services/governance/publish.integration.spec.js#refuses
        a condition type of an application the tenant is not licensed for
    assertion_evidence:
      provenance: proposed
      source: >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#answers
        the draft’s problem, saved rather than refused;
        services-platform:modules/eligibility/tests/integration/services/governance/publish.integration.spec.js#refuses
        a condition type of an application the tenant is not licensed for
    binding_scope: This sequence is proposed and has no executable proof binding.
  - id: ATS-PFM-ELG-001-19
    title: Use a renamed condition in existing work
    category: interaction
    level: api
    proves:
      - BR-CAP-PFM-ELG-001-07
      - BR-CAP-PFM-ELG-006-06
    exercises:
      - CAP-PFM-ELG-001
      - CAP-PFM-ELG-006
    preconditions: A released rule uses a condition whose application declares a new key with an alias.
    steps: 'Register the rename, inspect authoring choices and validate the retained expression.'
    expected: The author sees the new vocabulary while the expression using the former key remains valid.
    negative: false
    data_needs: Run-owned records and a controlled clock where timing changes the result.
    bound_to: []
    provenance: proposed
    source: >-
      services-platform:modules/eligibility/tests/integration/services/model/validate-definition.integration.spec.js#answers
      a reference to an archived definition as missing;
      services-platform:modules/eligibility/tests/integration/services/registry/register-eligibility-registration.integration.spec.js#folds
      a renamed type into its successor rather than withdrawing it, so the old key keeps resolving
    action_evidence:
      provenance: proposed
      source: >-
        services-platform:modules/eligibility/tests/integration/services/model/validate-definition.integration.spec.js#answers
        a reference to an archived definition as missing;
        services-platform:modules/eligibility/tests/integration/services/registry/register-eligibility-registration.integration.spec.js#folds
        a renamed type into its successor rather than withdrawing it, so the old key keeps resolving
    assertion_evidence:
      provenance: proposed
      source: >-
        services-platform:modules/eligibility/tests/integration/services/model/validate-definition.integration.spec.js#answers
        a reference to an archived definition as missing;
        services-platform:modules/eligibility/tests/integration/services/registry/register-eligibility-registration.integration.spec.js#folds
        a renamed type into its successor rather than withdrawing it, so the old key keeps resolving
    binding_scope: This sequence is proposed and has no executable proof binding.
  - id: ATS-PFM-ELG-001-20
    title: Promote private product work without detaching it
    category: interaction
    level: api
    proves:
      - BR-CAP-PFM-ELG-001-11
      - BR-CAP-PFM-ELG-007-14
    exercises:
      - CAP-PFM-ELG-001
      - CAP-PFM-ELG-007
    preconditions: A product has a private rule and an active use.
    steps: >-
      Share the rule with publication authority and inspect the shared library and the product
      connection.
    expected: The rule appears in the shared library and the product retains the same connection.
    negative: false
    data_needs: Run-owned records and a controlled clock where timing changes the result.
    bound_to: []
    provenance: proposed
    source: >-
      services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#refuses a
      writer without the publish permission the promotion of a private definition, 403;
      react-console:components/eligibility/embeds/eligibility-card.tsx:EligibilityCard
    action_evidence:
      provenance: proposed
      source: >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#refuses
        a writer without the publish permission the promotion of a private definition, 403;
        react-console:components/eligibility/embeds/eligibility-card.tsx:EligibilityCard
    assertion_evidence:
      provenance: proposed
      source: >-
        services-platform:modules/eligibility/tests/e2e/eligibility-definitions.e2e.spec.js#refuses
        a writer without the publish permission the promotion of a private definition, 403;
        react-console:components/eligibility/embeds/eligibility-card.tsx:EligibilityCard
    binding_scope: This sequence is proposed and has no executable proof binding.
evidence:
  - >-
    services-platform: docs/eligibility.md; docs/milestones/PLAT-M11-eligibility-rules.md and
    plans/PLAT-M11-plan.md; docs/proposals/eligibility/17-decision-register.md;
    aws/platform.service.ts (ELIGIBILITY_PERMISSIONS);
    modules/eligibility/aws/api/definitions.routes.ts, eligibility.schemas.ts,
    services/model/authoring.ts, validate-definition.ts, role-names.ts, option-labels.ts,
    rule-names.ts, services/persistence/definitions.ts, versions.ts, binding-fit.ts
    (declarationProblems), code-points.ts, db/eligibility-definitions.table.ts,
    eligibility-versions.table.ts, eligibility-dependencies.table.ts; rule-level source and test
    references
  - >-
    react-console: components/configuration/resources/eligibility-rules.tsx,
    components/eligibility/definition-editor.tsx, components/eligibility/builder/**,
    lib/eligibility/**; acceptance/eligibility/journeys/definitions/*.json and matching browser
    specifications; acceptance/eligibility/inventory/capabilities.json (area DEF).
related_coverage:
  - capability: CAP-PFM-ELG-002
    scenario: ATS-PFM-ELG-001-16
  - capability: CAP-PFM-ELG-003
    scenario: ATS-PFM-ELG-001-17
  - capability: CAP-PFM-ELG-004
    scenario: ATS-PFM-ELG-001-18
  - capability: CAP-PFM-ELG-006
    scenario: ATS-PFM-ELG-001-19
  - capability: CAP-PFM-ELG-007
    scenario: ATS-PFM-ELG-001-20
coverage:
  rule: covered
  transition: 'gap: FND-PFM-ELG-053'
  validation: covered
  permission: 'gap: FND-PFM-ELG-053'
  edge: 'gap: FND-PFM-ELG-053'
  failure: 'gap: FND-PFM-ELG-053'
  boundary: covered
  concurrency: covered
  invariant: 'gap: FND-PFM-ELG-053'
  interaction: covered
invariant_gaps:
  - invariant: INV-DOM-PFM-ELG-001-03
    finding: FND-PFM-ELG-053
    source: 'services-platform:modules/eligibility/lifecycle.ts:VERSION_TRANSITIONS'
  - invariant: INV-DOM-PFM-ELG-001-08
    finding: FND-PFM-ELG-053
    source: >-
      services-platform:modules/eligibility/db/eligibility-definitions.table.ts:eligibility_definitions_replaced_by_check
transition_coverage:
  - model: STATE-PFM-ELG-002
    from: draft
    to: draft
    trigger: >-
      saveEligibilityDefinitionDraft, createEligibilityDefinition when expression is supplied,
      duplicateEligibilityDefinition
    source: 'services-platform:modules/eligibility/services/model/authoring.ts:saveDefinitionDraft'
    scenario: ATS-PFM-ELG-001-05
  - model: STATE-PFM-ELG-002
    from: draft
    to: published
    trigger: publishEligibilityDefinition
    source: 'services-platform:modules/eligibility/services/governance/publish.ts:publishDefinition'
    scenario: ATS-PFM-ELG-004-03
  - model: STATE-PFM-ELG-002
    from: published
    to: superseded
    trigger: Later overlapping publication or rollback
    source: 'services-platform:docs/eligibility.md#2. The lifecycle rules'
    scenario: ATS-PFM-ELG-004-03
  - model: STATE-PFM-ELG-002
    from: published
    to: retired
    trigger: retireVersion through persistence only
    finding: FND-PFM-ELG-053
    source: 'services-platform:modules/eligibility/services/persistence/versions.ts:retireVersion'
  - model: STATE-PFM-ELG-002
    from: superseded
    to: retired
    trigger: retireVersion through persistence only
    finding: FND-PFM-ELG-053
    source: 'services-platform:modules/eligibility/lifecycle.ts:VERSION_TRANSITIONS'
permission_coverage:
  - key: platform.eligibility.write
    finding: FND-PFM-ELG-053
    reason: A capability-level authority scenario does not prove every operation protected by this key.
  - key: platform.eligibility.read
    finding: FND-PFM-ELG-053
    reason: A capability-level authority scenario does not prove every operation protected by this key.
  - key: platform.eligibility.publish
    finding: FND-PFM-ELG-053
    reason: A capability-level authority scenario does not prove every operation protected by this key.
coverage_notes:
  meaning: >-
    Covered means a detailed scenario exists; it does not mean the scenario ran or every executable
    assertion conforms.
  gaps: >-
    Draft authoring lacks a separate negative write-authority case and injected save failures.
    Immutable release editing and draft replacement under a concurrent lifecycle change need
    explicit proof.
---

# Author a readable eligibility rule: Capability Test Specification

## Coverage

The scenarios check observable outcomes against the cited contracts. The coverage map retains partial proof and unresolved design boundaries as findings.

| Required Rule | Scenarios |
|---|---|
| `BR-CAP-PFM-ELG-001-01` | `ATS-PFM-ELG-001-01` |
| `BR-CAP-PFM-ELG-001-02` | `ATS-PFM-ELG-001-02` |
| `BR-CAP-PFM-ELG-001-03` | `ATS-PFM-ELG-001-03` |
| `BR-CAP-PFM-ELG-001-04` | `ATS-PFM-ELG-001-04`, `ATS-PFM-ELG-001-17`, `ATS-PFM-ELG-001-18` |
| `BR-CAP-PFM-ELG-001-05` | `ATS-PFM-ELG-001-05` |
| `BR-CAP-PFM-ELG-001-06` | `ATS-PFM-ELG-001-06`, `ATS-PFM-ELG-001-16` |
| `BR-CAP-PFM-ELG-001-07` | `ATS-PFM-ELG-001-07`, `ATS-PFM-ELG-001-19` |
| `BR-CAP-PFM-ELG-001-08` | `ATS-PFM-ELG-001-08` |
| `BR-CAP-PFM-ELG-001-09` | `ATS-PFM-ELG-001-09` |
| `BR-CAP-PFM-ELG-001-10` | `ATS-PFM-ELG-001-10` |
| `BR-CAP-PFM-ELG-001-11` | `ATS-PFM-ELG-001-11`, `ATS-PFM-ELG-001-20` |
| `BR-CAP-PFM-ELG-001-12` | `ATS-PFM-ELG-001-12` |
| `BR-CAP-PFM-ELG-001-13` | `ATS-PFM-ELG-001-13` |
| `BR-CAP-PFM-ELG-001-14` | `ATS-PFM-ELG-001-14` |
| `BR-CAP-PFM-ELG-001-15` | `ATS-PFM-ELG-001-15` |

## Interactions With Related Capabilities

Discover a saved draft. Create a bare rule, save a draft that references a released rule, then inspect the list and detail.

Repair work before trying it. Save the invalid draft, attempt a trial, repair the reference and run the trial again.

Keep repairable drafts out of release. Save the draft, attempt publication, repair its errors and publish with authority.

Use a renamed condition in existing work. Register the rename, inspect authoring choices and validate the retained expression.

Promote private product work without detaching it. Share the rule with publication authority and inspect the shared library and the product connection.
