---
id: CAP-MBR-STR-009
title: Establish programs and their membership context
feature: FEAT-MBR-STR-03
product_area: membership
module: structure
revision: 1
status: draft
product_intent: proposed
implementation_evidence: partially-observed
supersedes:
  - react-console acceptance inventory CAP-MBR-CFG-001
  - react-console acceptance inventory CAP-MBR-CFG-015
  - react-console acceptance inventory CAP-MBR-CFG-016
source_sha:
  services-membership: 5994c270e8a37a30f848e99ba5b5ee6b87c08893
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-membership:README.md (D-02, approved 2026-10-17: how a program relates to organizational units)'
  - >-
    services-membership:docs/migrations/packages-as-products/README.md#Ordering profiles (Commerce's decision
    approved by Andrew on 2026-10-18)
purpose: >-
  Administrators define the contexts in which customers offer membership and describe how each relates to
  units.
outcomes:
  - Each program expresses its membership identity and classification context.
  - Consumers receive the program’s calendar and selling settings.
concepts:
  - CON-MBR-STR-003
actors:
  - ACT-MBR-001
  - ACT-MBR-002
  - ACT-MBR-003
surfaces:
  - api
  - job
preconditions: []
postconditions: []
permissions:
  - key: membership.programs.read
    where_checked: api
    scope: tenant
  - key: membership.programs.manage
    where_checked: api
    scope: tenant
  - key: membership.application.access
    where_checked: api
    scope: tenant
rules:
  - id: BR-CAP-MBR-STR-009-01
    proved_by: [ATS-MBR-STR-009-01, ATS-MBR-STR-009-07, TST-MBR-STR-057, TST-MBR-STR-095]
    statement: >-
      A program binds to units through no binding, affiliation or identity; only identity binding requires an
      identifying unit kind.
    kind: validation
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-membership:tests/e2e/database-refusals.e2e.spec.ts#mistakes only the database catches, through
      the API › DEF-MBR-0086: a configuration write a check, a foreign key or an integer column refuses ›
      refuses an identity-bound program without its identity unit type 400 naming identity_unit_type_id
    origin: none
  - id: BR-CAP-MBR-STR-009-02
    proved_by: [ATS-MBR-STR-009-02, ATS-MBR-STR-018-10, TST-MBR-STR-057]
    statement: An identifying kind and owning unit must exist in the same workspace as the program.
    kind: validation
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: observed
    source: >-
      services-membership:modules/configuration/services/configuration/configuration-records.ts:programResource
    origin: none
  - id: BR-CAP-MBR-STR-009-03
    proved_by: []
    statement: 'Programs classify eligible owners as contacts, organizations or either.'
    kind: policy
    enforced_at:
      - api
      - database
    must_prove: false
    provenance: observed
    source: 'services-membership:modules/configuration/db/programs.table.ts:programs'
    origin: none
  - id: BR-CAP-MBR-STR-009-04
    proved_by: []
    statement: 'Numbering settings select the workspace sequence, a program sequence or the owner’s CRM number.'
    kind: policy
    enforced_at:
      - api
      - database
    must_prove: false
    provenance: observed
    source: 'services-membership:modules/configuration/db/configuration-vocabularies.ts:NUMBER_SCOPES'
    origin: none
  - id: BR-CAP-MBR-STR-009-05
    proved_by: [ATS-MBR-STR-009-03, ATS-MBR-STR-009-08, ATS-MBR-STR-009-09, TST-MBR-STR-032, TST-MBR-STR-056, TST-MBR-STR-095]
    statement: >-
      Grace and continuity allowances accept nonnegative whole numbers within storage limits and are read live
      for existing memberships.
    kind: calculation
    enforced_at:
      - api
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-membership:tests/e2e/database-refusals.e2e.spec.ts#mistakes only the database catches, through
      the API › DEF-MBR-0086: a configuration write a check, a foreign key or an integer column refuses ›
      refuses a grace period of 2^31 days 400 naming grace_days, beyond what the column stores
    origin: none
  - id: BR-CAP-MBR-STR-009-06
    proved_by: [ATS-MBR-STR-009-04]
    statement: >-
      Overlapping holdings in programs of the same exclusivity group are refused during membership creation or
      sale.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-membership:tests/acceptance/configuration/MBR-ACC-0093.acceptance.ts#MBR-ACC-0093: Putting two
      programs into one exclusivity group refuses new overlapping memberships from then on while members who
      already hold both keep them, and removing the group opens them again
    origin: none
  - id: BR-CAP-MBR-STR-009-07
    proved_by: []
    statement: >-
      Program settings describe ordering, same-order member-price qualification and cancellation treatment for
      Commerce without calculating monetary amounts in Membership.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: test
    source: >-
      services-membership:tests/acceptance/configuration/MBR-ACC-0121.acceptance.ts#MBR-ACC-0121: The settings
      Commerce reads flow into the purchase plan and never into an amount: the program's same-order switch,
      ordering profile, cancellation policy and fee product, and the package's reinstatement audience,
      enrolment proration and auto-renew default each appear where the participant promises them, and a change
      is reflected on the next prepare
    origin: none
  - id: BR-CAP-MBR-STR-009-08
    proved_by: []
    statement: Grace-benefit and competing-membership preference switches are stored without an implemented consumer.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: observed
    source: 'services-membership:modules/configuration/services/configuration/configuration-records.ts:programContent'
    origin: none
  - id: BR-CAP-MBR-STR-009-09
    proved_by: []
    statement: >-
      A binding change away from affiliation is accepted while unit-kind settings and open affiliations
      remain.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: observed
    source: >-
      services-membership:modules/configuration/services/configuration/configuration-records.ts:programResource
    origin: none
  - id: BR-CAP-MBR-STR-009-10
    proved_by: []
    statement: >-
      Inactive programs reject new enrolments through the memberships module while retaining existing
      holdings.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: false
    provenance: documented
    source: 'react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-CFG-028'
    origin: none
  - id: BR-CAP-MBR-STR-009-11
    proved_by: [ATS-MBR-STR-009-05]
    statement: Program lists use identifier order despite retaining a display-order setting.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: 'services-membership:modules/configuration/services/persistence/configuration-store.ts:configurationStore'
    origin: none
  - id: BR-CAP-MBR-STR-009-12
    proved_by: [ATS-MBR-STR-008-08, ATS-MBR-STR-009-06]
    statement: >-
      An explicit program ordering profile supplies the sales context; omission delegates to application and
      workspace defaults without duplicating checkout settings.
    kind: policy
    enforced_at: []
    must_prove: true
    provenance: documented
    source: >-
      services-membership:docs/migrations/packages-as-products/README.md#Ordering profiles (added the same
      day, from Commerce's decision Andrew approved at about 15:45 UTC)
    origin: >-
      services-membership:docs/migrations/packages-as-products/README.md#Ordering profiles (Commerce's
      decision approved by Andrew on 2026-10-18)
    note: >-
      The permitted implementation stores a soft reference. The cited product record describes fallback
      resolution; this examination does not establish its execution in the owning checkout service.
scenarios:
  - id: SC-CAP-MBR-STR-009-01
    given: The association offers national membership and chapter-specific holdings.
    when: Staff configure a chapter program with chapter identity binding.
    then: Its memberships are distinguished by their chapter identity alongside national holdings.
    provenance: test
    source: >-
      services-membership:tests/acceptance/configuration/MBR-ACC-0120.acceptance.ts#MBR-ACC-0120: Scenario 11
      through the route: an identity-bound Chapter Membership program names its chapter unit type and its
      owning unit, refuses the wrong structure references in plain words and the missing identity type raw,
      and Kim holds a National and an Atlanta membership side by side
edge_cases:
  - id: SC-CAP-MBR-STR-009-02
    given: Staff increase the program’s grace allowance after a term has ended.
    when: The member’s standing is evaluated again.
    then: The live allowance can return the holding to grace.
    provenance: test
    source: >-
      services-membership:tests/acceptance/configuration/MBR-ACC-0092.acceptance.ts#MBR-ACC-0092: Changing a
      grace period moves every existing member at once: a type override wins over the program, zero is not
      blank, and even an as-of answer for a past date follows today's setting
constraints: []
depends_on:
  - CAP-MBR-STR-001
  - CAP-MBR-STR-018
related:
  - CAP-MBR-STR-010
  - CAP-MBR-STR-011
  - CAP-MBR-STR-016
journeys:
  - JNY-MBR-STR-004
open_questions:
  - OQ-MBR-STR-003
evidence:
  - 'services-membership: Examination of the programs table, request schema and configuration routes.'
  - >-
    services-membership: Examination of database refusals end-to-end and acceptance journeys MBR-ACC-0090,
    0092 to 0094, 0119 to 0121.
  - 'react-console: Review of acceptance inventory CAP-MBR-CFG-001, 015 and 016.'
  - 'react-console:acceptance/membership/inventory/business-rules.json'
  - 'services-membership:modules/configuration/db/configuration-vocabularies.ts'
  - 'services-membership:modules/configuration/db/programs.table.ts'
  - 'services-membership:modules/configuration/services/configuration/configuration-records.ts'
  - 'services-membership:modules/configuration/services/persistence/configuration-store.ts'
  - 'services-membership:tests/acceptance/configuration/MBR-ACC-0093.acceptance.ts'
  - 'services-membership:tests/acceptance/configuration/MBR-ACC-0121.acceptance.ts'
  - 'services-membership:tests/e2e/database-refusals.e2e.spec.ts'
controls: [TC-AVL-002, TC-AVL-003, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-005, TC-AZ-006, TC-CHG-001, TC-CHG-002, TC-CHG-003, TC-CHG-004, TC-CRY-001, TC-CRY-002, TC-CRY-003, TC-DAT-001, TC-DAT-004, TC-DAT-007, TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, TC-LOG-001, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-PI-001, TC-PI-003, TC-PI-005, TC-SEC-001, TC-SEC-004, TC-TEN-001, TC-TEN-002, TC-TEN-003]
exercised_by: [FAS-MBR-STR-03-01, FAS-MBR-STR-03-02, FAS-MBR-STR-03-03, FAS-MBR-STR-03-04, FAS-MBR-STR-03-05]
suites: [TST-MBR-STR-032, TST-MBR-STR-056, TST-MBR-STR-057, TST-MBR-STR-095]
---

# Establish programs and their membership context

## Purpose

Administrators define the contexts in which customers offer membership and describe how each relates to units.

## How It Works

An administrator gives the program a readable identity and describes who it serves. A program can organize membership independently of units, through affiliations or through a unit that identifies each holding. Staff choose the binding before configuring its unit requirements. Membership types provide classifications within that context. Grace and continuity settings contribute to date-based status calculations. Numbering and exclusivity settings are consumed when memberships are established. The program also supplies selling and cancellation choices for Commerce. Those choices express policy inputs rather than monetary calculations. Some saved switches have no active consumer and require a product decision before staff can rely on them. Changing the binding can leave earlier affiliation settings in place. The product should guide administrators through that transition before offering it as routine configuration.

## Relationships

- Unit-kind configuration supplies identifying and affiliation categories.
- Types and packages describe the classifications and offerings of a program.
- Term calculations consume the program’s date allowances.
