---
id: ATS-MBR-STR-016
scope: CAP-MBR-STR-016
product_area: membership
module: structure
revision: 2
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-membership: 5994c270e8a37a30f848e99ba5b5ee6b87c08893
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-MBR-STR-016-01
    title: Competing status conditions use precedence
    level: unit
    proves:
      - BR-CAP-MBR-STR-016-01
    preconditions: Explicit inputs or a recording fixture represent the cases exercised below.
    steps: >-
      Evaluate suspension during grace, a covering renewal, grace before a future term and future
      alongside pending.
    expected: Each result selects the applicable higher-priority standing.
    negative: false
    data_needs: 'Literal term, state or declaration fixtures for the described cases.'
    bound_to:
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the precedence of §2
        › puts suspended over grace
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the precedence of §2
        › puts active over grace: a renewal that started covers the date though the previous term ended
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the precedence of §2
        › puts grace over future: a lapsed term ended recently and the next starts later
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the precedence of §2
        › puts future over pending
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the precedence of §2
        › puts pending over none: a cancelled term and a pending one
      - >-
        services-membership:modules/terms/tests/unit/define-term-engine.spec.ts#defineTermEngine ›
        derives the status with the holding’s grace days from the hook
      - TST-MBR-STR-016
      - TST-MBR-STR-013
    provenance: test
    source: >-
      services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the precedence of §2 ›
      puts suspended over grace
    category: rule
  - id: ATS-MBR-STR-016-02
    title: Only effective states contribute coverage
    level: unit
    proves:
      - BR-CAP-MBR-STR-016-02
    preconditions: Explicit inputs or a recording fixture represent the cases exercised below.
    steps: 'Evaluate pending, cancelled and terminated periods over their dates.'
    expected: >-
      Pending and cancelled periods supply no effective coverage; terminated periods retain their covered
      days.
    negative: false
    data_needs: 'Literal term, state or declaration fixtures for the described cases.'
    bound_to:
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the effective states
        of §1 › never lets a pending term cover a date
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the effective states
        of §1 › never lets a cancelled term cover a date
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the effective states
        of §1 › never measures grace from a cancelled term
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the effective states
        of §1 › answers a terminated term for the days it covered
      - TST-MBR-STR-016
    provenance: test
    source: >-
      services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the effective states of
      §1 › never lets a pending term cover a date
    category: rule
  - id: ATS-MBR-STR-016-03
    title: Grace boundaries use the deciding classification
    level: unit
    proves:
      - BR-CAP-MBR-STR-016-03
      - AS-JNY-MBR-STR-005-01
    preconditions: Explicit inputs or a recording fixture represent the cases exercised below.
    steps: 'Evaluate the last grace day, its successor and a type-specific override.'
    expected: 'The boundary returns grace, its successor returns lapse and the override supplies the allowance.'
    negative: false
    data_needs: 'Literal term, state or declaration fixtures for the described cases.'
    bound_to:
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the rows of §2 › is
        in grace on the last day of grace (D = E + grace_days)
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the rows of §2 › is
        lapsed the day after grace ends
      - >-
        services-membership:modules/terms/tests/unit/holding-cache.spec.ts#the holding cache › names no
        current term in grace, measured with the grace of the term that ended
      - >-
        services-membership:tests/e2e/s04-lapse-and-rejoin.e2e.spec.ts#scenario 4: lapse, drop and rejoin
        through a staff term › answers grace the day after the term ended and lapsed once the 60 days are
        over
      - TST-MBR-STR-016
      - TST-MBR-STR-014
      - TST-MBR-STR-097
    provenance: test
    source: >-
      services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the rows of §2 › is in
      grace on the last day of grace (D = E + grace_days)
    category: boundary
  - id: ATS-MBR-STR-016-04
    title: Covering periods can omit benefits
    level: unit
    proves:
      - BR-CAP-MBR-STR-016-04
    preconditions: Explicit inputs or a recording fixture represent the cases exercised below.
    steps: Evaluate a holding with an effective no-benefit classification.
    expected: The result is active without benefits.
    negative: false
    data_needs: 'Literal term, state or declaration fixtures for the described cases.'
    bound_to:
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the rows of §2 › is
        active without benefits when the covering term’s classification confers none
      - >-
        services-membership:modules/terms/tests/unit/holding-cache.spec.ts#the holding cache › caches
        active without benefits for a covering term whose classification confers none
      - TST-MBR-STR-016
      - TST-MBR-STR-014
    provenance: test
    source: >-
      services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the rows of §2 › is
      active without benefits when the covering term’s classification confers none
    category: rule
  - id: ATS-MBR-STR-016-05
    title: Continuity breaks beyond the allowed gap
    level: unit
    proves:
      - BR-CAP-MBR-STR-016-05
      - AS-JNY-MBR-STR-005-03
    preconditions: Explicit inputs or a recording fixture represent the cases exercised below.
    steps: Compare effective periods separated by the allowance and by one additional day.
    expected: The allowed gap stays within an episode and the larger gap begins a new episode.
    negative: false
    data_needs: 'Literal term, state or declaration fixtures for the described cases.'
    bound_to:
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#continuity episodes: §8 › keeps the
        run when the gap equals the allowance (starts_on = ends_on + gap + 1)
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#continuity episodes: §8 › breaks the
        run when the gap is one day more than the allowance
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#continuity episodes: §8 › gives
        continuous_since as the start of the run the date falls in
      - >-
        services-membership:tests/e2e/s04-lapse-and-rejoin.e2e.spec.ts#scenario 4: lapse, drop and rejoin
        through a staff term › answers two continuity episodes
      - TST-MBR-STR-016
      - TST-MBR-STR-097
    provenance: test
    source: >-
      services-membership:modules/terms/tests/unit/status.spec.ts#continuity episodes: §8 › keeps the run
      when the gap equals the allowance (starts_on = ends_on + gap + 1)
    category: boundary
  - id: ATS-MBR-STR-016-06
    title: Join-date selection ignores ineffective periods
    level: unit
    proves:
      - BR-CAP-MBR-STR-016-06
    preconditions: Explicit inputs or a recording fixture represent the cases exercised below.
    steps: >-
      Calculate the first join decision with pending, cancelled and effective terms, then add a later
      effective term.
    expected: The earliest effective start remains the computed join date.
    negative: false
    data_needs: 'Literal term, state or declaration fixtures for the described cases.'
    bound_to:
      - >-
        services-membership:modules/terms/tests/unit/holding-cache.spec.ts#the holding cache › takes the
        join date from the first effective term, a pending or cancelled one never
      - >-
        services-membership:tests/e2e/s04-lapse-and-rejoin.e2e.spec.ts#scenario 4: lapse, drop and rejoin
        through a staff term › keeps the original join date and restarts continuity at the rejoin (a gap
        of 437 days is more than 60)
      - TST-MBR-STR-014
      - TST-MBR-STR-097
    provenance: test
    source: >-
      services-membership:modules/terms/tests/unit/holding-cache.spec.ts#the holding cache › takes the
      join date from the first effective term, a pending or cancelled one never
    category: rule
  - id: ATS-MBR-STR-016-07
    title: Sweep planning detects missing prior work
    level: unit
    proves:
      - BR-CAP-MBR-STR-016-07
    preconditions: Explicit inputs or a recording fixture represent the cases exercised below.
    steps: 'Compare a previous-day sweep, a missed night and no previous sweep.'
    expected: Normal work selects boundaries and the other cases request full recomputation.
    negative: false
    data_needs: 'Literal term, state or declaration fixtures for the described cases.'
    bound_to:
      - >-
        services-membership:modules/terms/tests/unit/sweep.spec.ts#the sweep’s boundaries › looks at the
        terms starting on D
      - >-
        services-membership:modules/terms/tests/unit/sweep.spec.ts#the sweep’s boundaries › looks, for
        each grace configured, at the terms whose grace ended on D - 1
      - >-
        services-membership:modules/terms/tests/unit/sweep.spec.ts#the sweep’s catch-up rule › catches up
        after a missed night
      - >-
        services-membership:modules/terms/tests/unit/sweep.spec.ts#the sweep’s catch-up rule › catches up
        for a tenant never swept
      - TST-MBR-STR-017
    provenance: test
    source: >-
      services-membership:modules/terms/tests/unit/sweep.spec.ts#the sweep’s boundaries › looks at the
      terms starting on D
    category: failure
  - id: ATS-MBR-STR-016-08
    title: Sweep detections distinguish boundaries and suppression
    level: unit
    proves:
      - BR-CAP-MBR-STR-016-08
    preconditions: Explicit inputs or a recording fixture represent the cases exercised below.
    steps: 'Evaluate expiry, the last grace day, the first lapsed day and suspension.'
    expected: 'Expiry is detectable after ending, lapse begins after grace, and suspension suppresses detections.'
    negative: false
    data_needs: 'Literal term, state or declaration fixtures for the described cases.'
    bound_to:
      - >-
        services-membership:modules/terms/tests/unit/sweep.spec.ts#the sweep’s detections › detects the
        expiry the day after the end, effective that day
      - >-
        services-membership:modules/terms/tests/unit/sweep.spec.ts#the sweep’s detections › detects no
        lapse on the last day of grace
      - >-
        services-membership:modules/terms/tests/unit/sweep.spec.ts#the sweep’s detections › detects the
        lapse the day after grace ends, effective that day, with the expiry
      - >-
        services-membership:modules/terms/tests/unit/sweep.spec.ts#the sweep’s detections › detects
        nothing for a suspended holding
      - TST-MBR-STR-017
    provenance: test
    source: >-
      services-membership:modules/terms/tests/unit/sweep.spec.ts#the sweep’s detections › detects the
      expiry the day after the end, effective that day
    category: transition
  - id: ATS-MBR-STR-016-09
    title: Column declarations constrain dates and vocabulary
    level: unit
    proves:
      - BR-CAP-MBR-STR-016-11
    preconditions: Explicit inputs or a recording fixture represent the cases exercised below.
    steps: Inspect generated term and holding columns and their check expressions.
    expected: 'The declarations restrict date order, term states and cached status values.'
    negative: true
    data_needs: 'Literal term, state or declaration fixtures for the described cases.'
    bound_to:
      - >-
        services-membership:modules/terms/tests/unit/columns.spec.ts#term columns (§3.2) › order the
        dates: an end, when there is one, on or after the start
      - >-
        services-membership:modules/terms/tests/unit/columns.spec.ts#term columns (§3.2) › close the
        state to the five states of 04-lifecycle §1
      - >-
        services-membership:modules/terms/tests/unit/columns.spec.ts#holding columns (§3.1) › close the
        status cache to the eight statuses of 04-lifecycle §2
      - TST-MBR-STR-012
    provenance: test
    source: >-
      services-membership:modules/terms/tests/unit/columns.spec.ts#term columns (§3.2) › order the dates:
      an end, when there is one, on or after the start
    category: invariant
  - id: ATS-MBR-STR-016-10
    title: Undelivered engine hooks fail explicitly
    category: failure
    level: api
    proves:
      - BR-CAP-MBR-STR-016-12
    preconditions: An isolated workspace contains the records and current versions needed for the case.
    steps: Call the engine’s purchase-participant and billing entry points with a valid domain definition.
    expected: Both calls fail with the intended delivery phase in the error.
    negative: true
    data_needs: Separate fixture records for the accepted and refused operations.
    bound_to:
      - >-
        services-membership:modules/terms/tests/unit/define-term-engine.spec.ts#refuses the Commerce
        participant, naming P3
      - >-
        services-membership:modules/terms/tests/unit/define-term-engine.spec.ts#refuses the billing runs,
        naming P3
      - TST-MBR-STR-013
    provenance: test
    source:
      - >-
        services-membership:modules/terms/tests/unit/define-term-engine.spec.ts#refuses the billing runs,
        naming P3
      - >-
        services-membership:modules/terms/tests/unit/define-term-engine.spec.ts#refuses the Commerce
        participant, naming P3
      - >-
        services-membership:modules/terms/tests/unit/define-term-engine.spec.ts#defineTermEngine ›
        refuses the Commerce participant, naming P3
  - id: ATS-MBR-STR-016-11
    title: Changing benefits changes current interpretation
    category: interaction
    level: api
    proves:
      - BR-CAP-MBR-STR-011-02
      - BR-CAP-MBR-STR-016-04
    preconditions: An isolated workspace contains the records and current versions needed for the case.
    steps: >-
      Evaluate a covering term with benefits, disable benefits on its type and evaluate again from live
      settings.
    expected: The same period becomes active without benefits without changing its dates.
    negative: false
    data_needs: Separate fixture records for the accepted and refused operations.
    bound_to: []
    provenance: proposed
    source:
      - 'services-membership:modules/configuration/db/membership-types.table.ts:membershipTypes'
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the rows of §2 › is
        active without benefits when the covering term’s classification confers none
    exercises:
      - CAP-MBR-STR-016
      - CAP-MBR-STR-011
  - id: ATS-MBR-STR-016-12
    title: Workspace authority gates this capability
    category: permission
    level: api
    proves:
      - BR-CAP-MBR-STR-019-04
    preconditions: An isolated workspace contains the records and current versions needed for the case.
    steps: >-
      Exercise the capability’s exposed operations with its read-only and management callers, then repeat
      with application access removed, an unlicensed workspace and an unavailable workspace.
    expected: >-
      Each named operation requires its declared authority; admission failures occur before any record or
      calculated result is exposed.
    negative: true
    data_needs: Separate fixture records for the accepted and refused operations.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-membership:tests/unit/route-authorization.spec.ts#route authorization: every Membership
        operation names its permission › requires membership.structure.read of every structure read and
        membership.structure.manage of every change
      - >-
        services-membership:modules/configuration/aws/api/configuration.routes.ts:configurationModuleRoutes
      - >-
        services-membership:tests/e2e/terms-api.e2e.spec.ts#the terms API, end to end in process ›
        refuses a caller who holds no key in the tenant
    exercises:
      - CAP-MBR-STR-016
      - CAP-MBR-STR-019
evidence:
  - 'services-membership:modules/terms/tests/unit/columns.spec.ts'
  - 'services-membership:modules/terms/tests/unit/define-term-engine.spec.ts'
  - 'services-membership:modules/terms/tests/unit/holding-cache.spec.ts'
  - 'services-membership:modules/terms/tests/unit/status.spec.ts'
  - 'services-membership:modules/terms/tests/unit/sweep.spec.ts'
  - 'services-membership:tests/e2e/s04-lapse-and-rejoin.e2e.spec.ts'
  - >-
    services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the precedence of §2 ›
    puts suspended over grace
  - >-
    services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the effective states of
    §1 › never lets a pending term cover a date
  - >-
    services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the rows of §2 › is in
    grace on the last day of grace (D = E + grace_days)
  - >-
    services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the rows of §2 › is
    active without benefits when the covering term’s classification confers none
  - 'services-membership:modules/terms/services/status.ts:continuousSinceOf'
  - 'services-membership:modules/terms/services/holding-cache.ts:firstJoinDateOf'
  - >-
    services-membership:modules/terms/tests/unit/sweep.spec.ts#the sweep’s catch-up rule › catches up
    after a missed night
  - >-
    services-membership:modules/terms/tests/unit/sweep.spec.ts#the sweep’s detections › detects the lapse
    the day after grace ends, effective that day, with the expiry
  - 'services-membership:modules/terms/services/holding-cache.ts:holdingCacheChanges'
  - >-
    services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the effective states of
    §1 › refuses a negative number of grace days
  - >-
    services-membership:modules/terms/tests/unit/columns.spec.ts#term columns (§3.2) › order the dates:
    an end, when there is one, on or after the start
  - >-
    services-membership:modules/terms/tests/unit/define-term-engine.spec.ts#defineTermEngine › refuses
    the Commerce participant, naming P3
  - >-
    services-membership:modules/terms/tests/unit/status.spec.ts#continuity episodes: §8 › keeps the run
    when the gap equals the allowance (starts_on = ends_on + gap + 1)
  - >-
    services-membership:modules/terms/tests/unit/holding-cache.spec.ts#the holding cache › takes the join
    date from the first effective term, a pending or cancelled one never
  - >-
    services-membership:modules/terms/tests/unit/sweep.spec.ts#the sweep’s boundaries › looks at the
    terms starting on D
  - >-
    services-membership:modules/terms/tests/unit/sweep.spec.ts#the sweep’s detections › detects the
    expiry the day after the end, effective that day
  - >-
    services-membership:modules/terms/tests/unit/define-term-engine.spec.ts#refuses the billing runs,
    naming P3
  - >-
    services-membership:modules/terms/tests/unit/define-term-engine.spec.ts#refuses the Commerce
    participant, naming P3
  - 'services-membership:modules/configuration/db/membership-types.table.ts:membershipTypes'
  - membership.application.access
  - >-
    services-membership:tests/unit/route-authorization.spec.ts#route authorization: every Membership
    operation names its permission › requires membership.structure.read of every structure read and
    membership.structure.manage of every change
  - 'services-membership:modules/configuration/aws/api/configuration.routes.ts:configurationModuleRoutes'
  - >-
    services-membership:tests/e2e/terms-api.e2e.spec.ts#the terms API, end to end in process › refuses a
    caller who holds no key in the tenant
coverage:
  rule: covered
  transition: covered
  validation: 'gap: FND-MBR-STR-069'
  permission: covered
  edge: 'gap: FND-MBR-STR-069'
  failure: covered
  boundary: covered
  concurrency: 'gap: FND-MBR-STR-069'
  invariant: covered
  interaction: covered
coverage_notes:
  validation: >-
    No dedicated scenario establishes this category across the capability’s declared operations and
    design obligations.
  edge: >-
    No dedicated scenario establishes this category across the capability’s declared operations and
    design obligations.
  concurrency: >-
    No dedicated scenario establishes this category across the capability’s declared operations and
    design obligations.
unproved_rules: []
coverage_obligations:
  permissions:
    - key: membership.application.access
      scenario_ids:
        - ATS-MBR-STR-019-04
      local_scenario_ids:
        - ATS-MBR-STR-016-12
      coverage: partial
      gap: FND-MBR-STR-069
      provenance: unknown
      source: FND-MBR-STR-069
      note: >-
        These cases establish declared authority or representative admission; exhaustive operation and
        caller combinations remain open.
  state_models:
    - id: STATE-MBR-STR-004
      transitions:
        - from: pending
          to: committed
          trigger: Commerce completes a claimed package purchase.
          provenance: unknown
          source: FND-MBR-STR-069
          scenario_ids: []
          coverage: gap
          gap: FND-MBR-STR-069
        - from: pending
          to: cancelled
          trigger: Commerce authorizes cancellation of a pending purchase.
          provenance: unknown
          source: FND-MBR-STR-069
          scenario_ids: []
          coverage: gap
          gap: FND-MBR-STR-069
        - from: committed
          to: committed
          trigger: 'Staff correct dates, classification or package on a committed term.'
          provenance: unknown
          source: FND-MBR-STR-069
          scenario_ids: []
          coverage: gap
          gap: FND-MBR-STR-069
        - from: committed
          to: terminated
          trigger: 'Staff end a started term, or Commerce applies an authorized termination.'
          provenance: unknown
          source: FND-MBR-STR-069
          scenario_ids: []
          coverage: gap
          gap: FND-MBR-STR-069
        - from: committed
          to: cancelled
          trigger: 'Staff end a term on or before its start, or Commerce cancels an unstarted term.'
          provenance: unknown
          source: FND-MBR-STR-069
          scenario_ids: []
          coverage: gap
          gap: FND-MBR-STR-069
      gap: FND-MBR-STR-069
    - id: STATE-MBR-STR-005
      transitions:
        - from: future
          to: active
          trigger: The requested day reaches a future term's start.
          provenance: unknown
          source: FND-MBR-STR-069
          scenario_ids: []
          coverage: gap
          gap: FND-MBR-STR-069
        - from: pending
          to: active
          trigger: A prepared term is fulfilled while its dates cover today.
          provenance: unknown
          source: FND-MBR-STR-069
          scenario_ids: []
          coverage: gap
          gap: FND-MBR-STR-069
        - from: active
          to: grace
          trigger: The requested day passes the covering term's last day.
          provenance: unknown
          source: FND-MBR-STR-069
          scenario_ids: []
          coverage: gap
          gap: FND-MBR-STR-069
        - from: active
          to: lapsed
          trigger: The requested day passes an effective term's end with zero grace.
          provenance: unknown
          source: FND-MBR-STR-069
          scenario_ids: []
          coverage: gap
          gap: FND-MBR-STR-069
        - from: grace
          to: lapsed
          trigger: The requested date passes the inclusive grace boundary.
          provenance: unknown
          source: FND-MBR-STR-069
          scenario_ids: []
          coverage: gap
          gap: FND-MBR-STR-069
        - from: grace
          to: active
          trigger: A renewal supplies effective coverage for the requested date.
          provenance: unknown
          source: FND-MBR-STR-069
          scenario_ids: []
          coverage: gap
          gap: FND-MBR-STR-069
        - from: lapsed
          to: active
          trigger: A reinstatement or rejoin supplies effective coverage.
          provenance: unknown
          source: FND-MBR-STR-069
          scenario_ids: []
          coverage: gap
          gap: FND-MBR-STR-069
        - from: active
          to: suspended
          trigger: Staff suspend an active membership.
          provenance: unknown
          source: FND-MBR-STR-069
          scenario_ids: []
          coverage: gap
          gap: FND-MBR-STR-069
        - from: suspended
          to: active
          trigger: Staff restore a suspended membership while it is covered.
          provenance: unknown
          source: FND-MBR-STR-069
          scenario_ids: []
          coverage: gap
          gap: FND-MBR-STR-069
        - from: none
          to: future
          trigger: A first committed term begins after the requested date.
          provenance: unknown
          source: FND-MBR-STR-069
          scenario_ids: []
          coverage: gap
          gap: FND-MBR-STR-069
        - from: none
          to: pending
          trigger: A pending term is prepared for a holding with no effective term.
          provenance: unknown
          source: FND-MBR-STR-069
          scenario_ids: []
          coverage: gap
          gap: FND-MBR-STR-069
      gap: FND-MBR-STR-069
  related:
    - capability: CAP-MBR-STR-011
      scenario: ATS-MBR-STR-016-11
      provenance: proposed
  invariants:
    - id: INV-DOM-MBR-STR-005-01
      scenario_ids: []
      coverage: gap
      gap: FND-MBR-STR-069
      provenance: unknown
      source: FND-MBR-STR-069
    - id: INV-DOM-MBR-STR-005-02
      scenario_ids: []
      coverage: gap
      gap: FND-MBR-STR-069
      provenance: unknown
      source: FND-MBR-STR-069
    - id: INV-DOM-MBR-STR-005-03
      scenario_ids: []
      coverage: gap
      gap: FND-MBR-STR-069
      provenance: unknown
      source: FND-MBR-STR-069
    - id: INV-DOM-MBR-STR-005-04
      scenario_ids: []
      coverage: gap
      gap: FND-MBR-STR-069
      provenance: unknown
      source: FND-MBR-STR-069
    - id: INV-DOM-MBR-STR-005-05
      scenario_ids: []
      coverage: gap
      gap: FND-MBR-STR-069
      provenance: unknown
      source: FND-MBR-STR-069
    - id: INV-DOM-MBR-STR-005-06
      scenario_ids: []
      coverage: gap
      gap: FND-MBR-STR-069
      provenance: unknown
      source: FND-MBR-STR-069
    - id: INV-DOM-MBR-STR-005-07
      scenario_ids: []
      coverage: gap
      gap: FND-MBR-STR-069
      provenance: unknown
      source: FND-MBR-STR-069
    - id: INV-DOM-MBR-STR-005-08
      scenario_ids: []
      coverage: gap
      gap: FND-MBR-STR-069
      provenance: unknown
      source: FND-MBR-STR-069
    - id: INV-DOM-MBR-STR-005-09
      scenario_ids: []
      coverage: gap
      gap: FND-MBR-STR-069
      provenance: unknown
      source: FND-MBR-STR-069
  workflows:
    - id: WF-MBR-STR-006
      scenarios:
        - ATS-MBR-STR-016-07
        - ATS-MBR-STR-016-10
        - ATS-MBR-STR-016-11
      unproved_failure_and_concurrency: FND-MBR-STR-069
      provenance: unknown
      source: FND-MBR-STR-069
  workflow_interactions: []
rule_coverage:
  - rule: BR-CAP-MBR-STR-016-01
    scenarios:
      - ATS-MBR-STR-016-01
    gap: null
    provenance: documented
    source:
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the precedence of §2
        › puts suspended over grace
  - rule: BR-CAP-MBR-STR-016-02
    scenarios:
      - ATS-MBR-STR-016-02
    gap: null
    provenance: documented
    source:
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the effective states
        of §1 › never lets a pending term cover a date
  - rule: BR-CAP-MBR-STR-016-03
    scenarios:
      - ATS-MBR-STR-016-03
    gap: null
    provenance: documented
    source:
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the rows of §2 › is
        in grace on the last day of grace (D = E + grace_days)
  - rule: BR-CAP-MBR-STR-016-04
    scenarios:
      - ATS-MBR-STR-016-04
      - ATS-MBR-STR-016-11
    gap: null
    provenance: documented
    source:
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the rows of §2 › is
        active without benefits when the covering term’s classification confers none
      - 'services-membership:modules/configuration/db/membership-types.table.ts:membershipTypes'
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#holding status: the rows of §2 › is
        active without benefits when the covering term’s classification confers none
  - rule: BR-CAP-MBR-STR-016-05
    scenarios:
      - ATS-MBR-STR-016-05
    gap: null
    provenance: documented
    source:
      - >-
        services-membership:modules/terms/tests/unit/status.spec.ts#continuity episodes: §8 › keeps the
        run when the gap equals the allowance (starts_on = ends_on + gap + 1)
  - rule: BR-CAP-MBR-STR-016-06
    scenarios:
      - ATS-MBR-STR-016-06
    gap: null
    provenance: documented
    source:
      - >-
        services-membership:modules/terms/tests/unit/holding-cache.spec.ts#the holding cache › takes the
        join date from the first effective term, a pending or cancelled one never
  - rule: BR-CAP-MBR-STR-016-07
    scenarios:
      - ATS-MBR-STR-016-07
    gap: null
    provenance: documented
    source:
      - >-
        services-membership:modules/terms/tests/unit/sweep.spec.ts#the sweep’s boundaries › looks at the
        terms starting on D
  - rule: BR-CAP-MBR-STR-016-08
    scenarios:
      - ATS-MBR-STR-016-08
    gap: null
    provenance: documented
    source:
      - >-
        services-membership:modules/terms/tests/unit/sweep.spec.ts#the sweep’s detections › detects the
        expiry the day after the end, effective that day
  - rule: BR-CAP-MBR-STR-016-11
    scenarios:
      - ATS-MBR-STR-016-09
    gap: null
    provenance: documented
    source:
      - >-
        services-membership:modules/terms/tests/unit/columns.spec.ts#term columns (§3.2) › order the
        dates: an end, when there is one, on or after the start
  - rule: BR-CAP-MBR-STR-016-12
    scenarios:
      - ATS-MBR-STR-016-10
    gap: null
    provenance: documented
    source:
      - >-
        services-membership:modules/terms/tests/unit/define-term-engine.spec.ts#refuses the billing runs,
        naming P3
      - >-
        services-membership:modules/terms/tests/unit/define-term-engine.spec.ts#refuses the Commerce
        participant, naming P3
      - >-
        services-membership:modules/terms/tests/unit/define-term-engine.spec.ts#defineTermEngine ›
        refuses the Commerce participant, naming P3
narrative_sources:
  - section: Coverage
    provenance: documented
    source:
      - CAP-MBR-STR-016
      - FND-MBR-STR-069
  - section: Interactions With Related Capabilities
    provenance: proposed
    source:
      - ATS-MBR-STR-016-11
---

# Interpret membership status and continuity by date: Capability Test Specification

## Coverage

The coverage map distinguishes specified examples from missing proof. A covered category means an expected case is specified; executable bindings and their run results remain separate evidence. Each required rule has a proof link or an explicit coverage finding in the structured rule ledger.

| Required Rule | Scenario or Finding |
|---|---|
| `BR-CAP-MBR-STR-016-01` | `ATS-MBR-STR-016-01` |
| `BR-CAP-MBR-STR-016-02` | `ATS-MBR-STR-016-02` |
| `BR-CAP-MBR-STR-016-03` | `ATS-MBR-STR-016-03` |
| `BR-CAP-MBR-STR-016-04` | `ATS-MBR-STR-016-04`, `ATS-MBR-STR-016-11` |
| `BR-CAP-MBR-STR-016-05` | `ATS-MBR-STR-016-05` |
| `BR-CAP-MBR-STR-016-06` | `ATS-MBR-STR-016-06` |
| `BR-CAP-MBR-STR-016-07` | `ATS-MBR-STR-016-07` |
| `BR-CAP-MBR-STR-016-08` | `ATS-MBR-STR-016-08` |
| `BR-CAP-MBR-STR-016-11` | `ATS-MBR-STR-016-09` |
| `BR-CAP-MBR-STR-016-12` | `ATS-MBR-STR-016-10` |

## Interactions With Related Capabilities

Changing benefits changes current interpretation. Evaluate a covering term with benefits, disable benefits on its type and evaluate again from live settings.
