---
id: ATS-MBR-MEM-018
scope: CAP-MBR-MEM-018
product_area: membership
module: memberships
revision: 2
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-membership: 5994c270e8a37a30f848e99ba5b5ee6b87c08893
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-MBR-MEM-018-01
    title: >-
      Every committed change is one attributed revision, and caches record
      nothing
    level: api
    proves:
      - BR-CAP-MBR-MEM-018-01
      - INV-DOM-MBR-MEM-006-01
    preconditions: >-
      The well-known FAA workspace fixtures, or a workspace the test builds from
      them.
    steps:
      - do: >-
          Create a membership, correct its term, change its stored status alone,
          and undo a change in the same save.
        expect: >-
          One revision for the creation with its term and affiliation, one for
          the correction, nothing for the cache or the undone change; each names
          its person then and its source.
        provenance: test
        source:
          - >-
            services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#records
            the creation as one revision of the membership, its term and
            affiliation as collections
          - >-
            services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#names
            who made each change by the name they had then, and where it came
            from
          - >-
            services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#records
            nothing for a change of the cached status alone, nor for a change
            undone in the same save
    expected: >-
      One revision for the creation with its term and affiliation, one for the
      correction, nothing for the cache or the undone change; each names its
      person then and its source.
    negative: false
    data_needs: 'FAA programs, packages, units and members from the integration seed.'
    bound_to:
      - TST-MBR-MEM-018
    provenance: test
    source: >-
      services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#records
      the creation as one revision of the membership, its term and affiliation
      as collections
    category: transition
    binding_evidence:
      - suite: TST-MBR-MEM-018
        source: >-
          services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#records
          the creation as one revision of the membership, its term and
          affiliation as collections
      - suite: TST-MBR-MEM-018
        source: >-
          services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#names
          who made each change by the name they had then, and where it came from
      - suite: TST-MBR-MEM-018
        source: >-
          services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#records
          nothing for a change of the cached status alone, nor for a change
          undone in the same save
  - id: ATS-MBR-MEM-018-02
    title: An unattributed write is refused with its business write
    level: api
    proves:
      - BR-CAP-MBR-MEM-018-02
      - INV-DOM-MBR-MEM-006-02
    preconditions: >-
      The well-known FAA workspace fixtures, or a workspace the test builds from
      them.
    steps:
      - do: Write with no source and no actor.
        expect: Refused at commit; nothing is written.
        provenance: test
        source:
          - >-
            services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#refuses
            at commit a write that names no source and no actor, and the write
            with it (a program, which has no versions)
    expected: Refused at commit; nothing is written.
    negative: true
    data_needs: 'FAA programs, packages, units and members from the integration seed.'
    bound_to:
      - TST-MBR-MEM-018
    provenance: test
    source: >-
      services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#refuses
      at commit a write that names no source and no actor, and the write with it
      (a program, which has no versions)
    category: failure
    binding_evidence:
      - suite: TST-MBR-MEM-018
        source: >-
          services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#refuses
          at commit a write that names no source and no actor, and the write
          with it (a program, which has no versions)
  - id: ATS-MBR-MEM-018-03
    title: 'The timeline pages, filters and opens section by section'
    level: api
    proves:
      - BR-CAP-MBR-MEM-018-03
    preconditions: >-
      The well-known FAA workspace fixtures, or a workspace the test builds from
      them.
    steps:
      - do: >-
          Read a busy membership's timeline by page, by operation and by person;
          open one revision; list the people.
        expect: >-
          Newest first by cursor; filters narrow it; the revision opens by
          section; each person listed once.
        provenance: test
        source:
          - >-
            services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#pages
            the timeline newest first by its sequence, the cursor continuing
            where a page ended
          - >-
            services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#filters
            the timeline by operation and by actor
          - >-
            services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#finds
            one revision of this record, and not another record’s revision by
            its id
          - >-
            services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#lists
            everyone who changed the record, once each, by their names
          - >-
            services-membership:tests/e2e/history-api.e2e.spec.ts#answers the
            three revisions newest first: the suspension, the term correction,
            the creation
    expected: >-
      Newest first by cursor; filters narrow it; the revision opens by section;
      each person listed once.
    negative: false
    data_needs: 'FAA programs, packages, units and members from the integration seed.'
    bound_to:
      - TST-MBR-MEM-018
      - TST-MBR-MEM-243
    provenance: test
    source: >-
      services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#pages
      the timeline newest first by its sequence, the cursor continuing where a
      page ended
    category: rule
    binding_evidence:
      - suite: TST-MBR-MEM-018
        source: >-
          services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#pages
          the timeline newest first by its sequence, the cursor continuing where
          a page ended
      - suite: TST-MBR-MEM-018
        source: >-
          services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#filters
          the timeline by operation and by actor
      - suite: TST-MBR-MEM-018
        source: >-
          services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#finds
          one revision of this record, and not another record’s revision by its
          id
      - suite: TST-MBR-MEM-018
        source: >-
          services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#lists
          everyone who changed the record, once each, by their names
      - suite: TST-MBR-MEM-243
        source: >-
          services-membership:tests/e2e/history-api.e2e.spec.ts#answers the
          three revisions newest first: the suspension, the term correction, the
          creation
  - id: ATS-MBR-MEM-018-04
    title: A term keeps its own history
    level: api
    proves:
      - BR-CAP-MBR-MEM-018-04
    preconditions: >-
      The well-known FAA workspace fixtures, or a workspace the test builds from
      them.
    steps:
      - do: Correct a term and read the term's history.
        expect: >-
          The correction appears on the term's timeline as on the membership's
          terms section.
        provenance: test
        source:
          - >-
            services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#records
            the same correction on the term’s own history
    expected: >-
      The correction appears on the term's timeline as on the membership's terms
      section.
    negative: false
    data_needs: 'FAA programs, packages, units and members from the integration seed.'
    bound_to:
      - TST-MBR-MEM-018
    provenance: test
    source: >-
      services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#records
      the same correction on the term’s own history
    category: invariant
    binding_evidence:
      - suite: TST-MBR-MEM-018
        source: >-
          services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#records
          the same correction on the term’s own history
  - id: ATS-MBR-MEM-018-05
    title: History needs its own key
    level: api
    proves:
      - BR-CAP-MBR-MEM-018-05
    preconditions: >-
      The well-known FAA workspace fixtures, or a workspace the test builds from
      them.
    steps:
      - do: A reader with membership-read but not history asks for history.
        expect: Refused.
        provenance: test
        source:
          - >-
            services-membership:tests/e2e/history-api.e2e.spec.ts#refuses the
            history to a reader of memberships who does not hold
            membership.memberships.history
    expected: Refused.
    negative: true
    data_needs: 'FAA programs, packages, units and members from the integration seed.'
    bound_to:
      - TST-MBR-MEM-243
    provenance: test
    source: >-
      services-membership:tests/e2e/history-api.e2e.spec.ts#refuses the history
      to a reader of memberships who does not hold
      membership.memberships.history
    category: permission
    binding_evidence:
      - suite: TST-MBR-MEM-243
        source: >-
          services-membership:tests/e2e/history-api.e2e.spec.ts#refuses the
          history to a reader of memberships who does not hold
          membership.memberships.history
  - id: ATS-MBR-MEM-018-06
    title: 'A past date is reconstructed with its units, fields, seats and contact'
    level: api
    proves:
      - BR-CAP-MBR-MEM-018-06
    preconditions: >-
      The well-known FAA workspace fixtures, or a workspace the test builds from
      them.
    steps:
      - do: >-
          Ask Jo as of a date in her term, with and without Committees' history,
          and her custom fields at the end of the date.
        expect: >-
          Her term, type, package, status, chapters with names and ancestors
          then, custom fields as recorded, seats or unavailable, and the contact
          marked captured.
        provenance: test
        source:
          - >-
            services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
            Jo’s chapters on the date with each unit’s name, parent and
            ancestors then
          - >-
            services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
            the committee seats as unavailable where Committees’ versions do not
            exist
          - >-
            services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
            the seats a committee appointment reader holds for the contact on
            the date
          - >-
            services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
            a membership custom field as it was recorded at the end of the date
          - >-
            services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
            the contact as it is now, said to be captured rather than
            reconstructed
    expected: >-
      Her term, type, package, status, chapters with names and ancestors then,
      custom fields as recorded, seats or unavailable, and the contact marked
      captured.
    negative: false
    data_needs: 'FAA programs, packages, units and members from the integration seed.'
    bound_to:
      - TST-MBR-MEM-017
    provenance: test
    source: >-
      services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
      Jo’s chapters on the date with each unit’s name, parent and ancestors then
    category: rule
    binding_evidence:
      - suite: TST-MBR-MEM-017
        source: >-
          services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
          Jo’s chapters on the date with each unit’s name, parent and ancestors
          then
      - suite: TST-MBR-MEM-017
        source: >-
          services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
          the committee seats as unavailable where Committees’ versions do not
          exist
      - suite: TST-MBR-MEM-017
        source: >-
          services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
          the seats a committee appointment reader holds for the contact on the
          date
      - suite: TST-MBR-MEM-017
        source: >-
          services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
          a membership custom field as it was recorded at the end of the date
      - suite: TST-MBR-MEM-017
        source: >-
          services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
          the contact as it is now, said to be captured rather than
          reconstructed
  - id: ATS-MBR-MEM-018-07
    title: Without an instant the past-date answer equals the live read
    level: api
    proves:
      - BR-CAP-MBR-MEM-018-07
      - INV-DOM-MBR-MEM-006-04
    preconditions: >-
      The well-known FAA workspace fixtures, or a workspace the test builds from
      them.
    steps:
      - do: Read every FAA membership as of today with no instant.
        expect: Each equals the live read.
        provenance: test
        source:
          - >-
            services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
            every FAA membership as the live read does, known now and as
            recorded now
    expected: Each equals the live read.
    negative: false
    data_needs: 'FAA programs, packages, units and members from the integration seed.'
    bound_to:
      - TST-MBR-MEM-017
    provenance: test
    source: >-
      services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
      every FAA membership as the live read does, known now and as recorded now
    category: invariant
    binding_evidence:
      - suite: TST-MBR-MEM-017
        source: >-
          services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
          every FAA membership as the live read does, known now and as recorded
          now
  - id: ATS-MBR-MEM-018-08
    title: A backdated correction shows only to readers asking after it
    level: api
    proves:
      - BR-CAP-MBR-MEM-018-08
    preconditions: >-
      The well-known FAA workspace fixtures, or a workspace the test builds from
      them.
    steps:
      - do: 'Correct a term, then ask as known before and after the correction.'
        expect: The earlier and the corrected term respectively.
        provenance: test
        source:
          - >-
            services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
            the term as it was known before the correction, with a known_at
            before it
          - >-
            services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
            the corrected term with a known_at after the correction
          - >-
            services-membership:tests/acceptance/history/MBR-ACC-0539.acceptance.ts#MBR-ACC-0539
    expected: The earlier and the corrected term respectively.
    negative: false
    data_needs: 'FAA programs, packages, units and members from the integration seed.'
    bound_to:
      - TST-MBR-MEM-017
      - TST-MBR-MEM-161
    provenance: test
    source: >-
      services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
      the term as it was known before the correction, with a known_at before it
    category: boundary
    binding_evidence:
      - suite: TST-MBR-MEM-017
        source: >-
          services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
          the term as it was known before the correction, with a known_at before
          it
      - suite: TST-MBR-MEM-017
        source: >-
          services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
          the corrected term with a known_at after the correction
      - suite: TST-MBR-MEM-161
        source: >-
          services-membership:tests/acceptance/history/MBR-ACC-0539.acceptance.ts#MBR-ACC-0539
  - id: ATS-MBR-MEM-018-09
    title: Preserve the pre-correction answer for earlier knowledge
    category: interaction
    level: api
    proves:
      - BR-CAP-MBR-MEM-003-02
      - BR-CAP-MBR-MEM-018-08
    interacts_with:
      - CAP-MBR-MEM-003
    workflows:
      - WF-MBR-MEM-003
    relies_on:
      - ATS-MBR-MEM-003-02
      - ATS-MBR-MEM-018-08
    preconditions: A committed term has recorded history.
    steps:
      - do: >-
          Correct its start, then read the same date with recording instants
          before and after the correction.
        expect: >-
          The earlier-known answer retains the first start; the later-known
          answer reflects the correction.
        provenance: proposed
        source: &ref_0
          - >-
            services-membership:modules/memberships/tests/integration/services/staff-operations.integration.spec.ts#keeps
            the old truth of a correction in the versions, recorded with the
            actor
          - >-
            services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
            the term as it was known before the correction, with a known_at
            before it
    expected: >-
      The earlier-known answer retains the first start; the later-known answer
      reflects the correction.
    negative: false
    data_needs: >-
      An isolated workspace with the specified membership, package, chapter and
      partner-port fixtures.
    bound_to: []
    provenance: proposed
    source: *ref_0
  - id: ATS-MBR-MEM-018-10
    title: Retain child history before a parental correction
    category: interaction
    level: api
    proves:
      - BR-CAP-MBR-MEM-006-07
      - BR-CAP-MBR-MEM-018-08
    interacts_with:
      - CAP-MBR-MEM-006
    workflows:
      - WF-MBR-MEM-003
    relies_on:
      - ATS-MBR-MEM-006-07
      - ATS-MBR-MEM-018-08
    preconditions: A mirrored child period and its source have committed versions.
    steps:
      - do: >-
          Correct the parent end, then reconstruct the child before and after
          the recording instant.
        expect: >-
          Earlier knowledge retains the old child end and later knowledge shows
          the contracted end.
        provenance: proposed
        source: &ref_1
          - >-
            services-membership:modules/memberships/tests/integration/services/organization-children.integration.spec.ts#re-mirrors
            the children when the parent’s end is corrected: a child never
            outlasts the parent
          - >-
            services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
            the term as it was known before the correction, with a known_at
            before it
    expected: >-
      Earlier knowledge retains the old child end and later knowledge shows the
      contracted end.
    negative: false
    data_needs: >-
      An isolated workspace with the specified membership, package, chapter and
      partner-port fixtures.
    bound_to: []
    provenance: proposed
    source: *ref_1
  - id: ATS-MBR-MEM-018-11
    title: Keep history unavailable to an officer who can read the member
    category: interaction
    level: api
    proves:
      - BR-CAP-MBR-MEM-015-08
      - BR-CAP-MBR-MEM-018-05
    interacts_with:
      - CAP-MBR-MEM-015
    workflows: []
    relies_on:
      - ATS-MBR-MEM-015-07
      - ATS-MBR-MEM-018-05
    preconditions: An officer can read a member through a unit-scoped grant.
    steps:
      - do: >-
          Read the membership, then request its history using only the officer
          grants.
        expect: >-
          The member read succeeds while the staff-only history request is
          refused.
        provenance: proposed
        source: &ref_2
          - >-
            services-membership:tests/e2e/s07-regional-officer.e2e.spec.ts#does
            not reach a staff operation: terminating Jo’s term is refused before
            the handler
          - >-
            services-membership:tests/e2e/history-api.e2e.spec.ts#refuses the
            history to a reader of memberships who does not hold
            membership.memberships.history
    expected: The member read succeeds while the staff-only history request is refused.
    negative: false
    data_needs: >-
      An isolated workspace with the specified membership, package, chapter and
      partner-port fixtures.
    bound_to: []
    provenance: proposed
    source: *ref_2
  - id: ATS-MBR-MEM-018-12
    title: Restate a snapshot using later recorded knowledge
    category: interaction
    level: api
    proves:
      - BR-CAP-MBR-MEM-018-08
      - BR-CAP-MBR-MEM-019-06
    interacts_with:
      - CAP-MBR-MEM-019
    workflows: []
    relies_on:
      - ATS-MBR-MEM-018-08
      - ATS-MBR-MEM-019-06
    preconditions: >-
      A month has a published snapshot and one membership receives a backdated
      correction.
    steps:
      - do: >-
          Reconstruct before and after the correction, rerun at the original
          instant, then restate at the later instant.
        expect: >-
          The original-instant rows reproduce; later knowledge changes only the
          corrected membership’s affected rows and counts.
        provenance: proposed
        source: &ref_3
          - >-
            services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
            the term as it was known before the correction, with a known_at
            before it
          - >-
            services-membership:modules/snapshots/tests/integration/membership-snapshot.integration.spec.ts#writes
            identical member, affiliation and count rows with the original
            known_at
    expected: >-
      The original-instant rows reproduce; later knowledge changes only the
      corrected membership’s affected rows and counts.
    negative: false
    data_needs: >-
      An isolated workspace with the specified membership, package, chapter and
      partner-port fixtures.
    bound_to: []
    provenance: proposed
    source: *ref_3
evidence:
  - >-
    services-membership at 5994c270e8a37a30f848e99ba5b5ee6b87c08893: the
    capability sources and the bound test files.
  - >-
    rhythm-v2-docs:specs/membership/memberships/design/: domain objects, state
    models and workflows reviewed for coverage.
coverage:
  rule: 'gap: FND-MBR-MEM-100'
  transition: 'gap: FND-MBR-MEM-100'
  validation: 'gap: FND-MBR-MEM-100'
  permission: 'gap: FND-MBR-MEM-100'
  edge: 'gap: FND-MBR-MEM-100'
  failure: covered
  boundary: covered
  concurrency: 'gap: FND-MBR-MEM-100'
  invariant: 'gap: FND-MBR-MEM-100'
  interaction: covered
coverage_notes:
  transition: >-
    The scenarios do not enumerate every applicable object transition; the
    finding preserves the remaining transition matrix.
  permission: >-
    The finding records named permissions without a complete positive and
    negative proof.
  invariant: >-
    Existing invariant examples do not cover every applicable domain-object
    constraint.
  interaction: >-
    Every related capability and each cross-capability workflow has an explicit
    composite scenario. Unbound composites remain proposed.
---

# See how a membership changed and what it was on any date: Capability Test Specification

## Coverage

| Rule | Scenario or Finding |
|---|---|
| `BR-CAP-MBR-MEM-018-01` | `ATS-MBR-MEM-018-01` |
| `BR-CAP-MBR-MEM-018-02` | `ATS-MBR-MEM-018-02` |
| `BR-CAP-MBR-MEM-018-03` | `ATS-MBR-MEM-018-03` |
| `BR-CAP-MBR-MEM-018-04` | `ATS-MBR-MEM-018-04` |
| `BR-CAP-MBR-MEM-018-05` | `ATS-MBR-MEM-018-05`, `ATS-MBR-MEM-018-11` |
| `BR-CAP-MBR-MEM-018-06` | `ATS-MBR-MEM-018-06` |
| `BR-CAP-MBR-MEM-018-07` | `ATS-MBR-MEM-018-07` |
| `BR-CAP-MBR-MEM-018-08` | `ATS-MBR-MEM-018-08`, `ATS-MBR-MEM-018-09`, `ATS-MBR-MEM-018-10`, `ATS-MBR-MEM-018-12` |
| `BR-CAP-MBR-MEM-018-10` | no scenario: `FND-MBR-MEM-058` |
| `BR-CAP-MBR-MEM-018-11` | no scenario: `FND-MBR-MEM-059` |

## Interactions With Related Capabilities

The interaction cases test how a shared holding, period, chapter connection or recorded change affects related work. Each case names its related capabilities and workflows in frontmatter. A composite case remains proposed until executable assertions establish every part of its expected outcome.
