---
source_sha:
  services-membership: 5994c270e8a37a30f848e99ba5b5ee6b87c08893
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
finding_evidence:
  - finding: FND-MBR-STR-001
    source:
      - 'services-membership:README.md#services-membership'
      - 'services-membership:docs/migrations/structure/README.md#The organizational structure module (P1)'
      - 'services-platform:docs/proposals/membership-architecture/12-decision-register.md (not readable in this job)'
  - finding: FND-MBR-STR-002
    source:
      - 'react-console:app/(console)/console/[tenantId]/membership/members/page.tsx'
      - 'react-console:components/membership/settings/membership-settings-page.tsx'
      - 'react-console:components/console/nav-config.ts:config-app-membership'
  - finding: FND-MBR-STR-003
    source:
      - 'react-console:lib/authz/permissions.ts:82'
      - 'services-membership:aws/membership.service.ts:MEMBERSHIP_PERMISSION_SETS'
  - finding: FND-MBR-STR-004
    source:
      - 'services-membership:modules/structure/aws/api/structure-requests.ts:unitReplaceBody'
      - 'services-membership:modules/structure/services/tree/tree-edits.ts:deactivateUnit'
      - 'react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0007'
  - finding: FND-MBR-STR-005
    source:
      - 'services-membership:modules/structure/services/tree/tree-edits.ts:mergeUnit'
      - 'react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-STR-047'
  - finding: FND-MBR-STR-006
    source:
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:recordParentChange'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:unitReferences'
      - 'react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0004'
  - finding: FND-MBR-STR-007
    source:
      - 'services-membership:modules/structure/services/persistence/organizational-unit-organizations.ts:linkOrganization'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-organizations.ts:unlinkOrganization'
      - 'react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0005'
  - finding: FND-MBR-STR-008
    source:
      - 'services-membership:modules/structure/services/persistence/organizational-unit-organizations.ts:linkOrganization'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-dues-products.ts:createDuesProduct'
      - 'services-membership:modules/structure/aws/api/structure.routes.ts:structureRoutes'
  - finding: FND-MBR-STR-009
    source:
      - 'services-membership:modules/structure/services/finance/accounting-references.ts:checkAccountingReferenceShapes'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-financial-settings.ts:setFinancialSettings'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-dues-products.ts:createDuesProduct'
  - finding: FND-MBR-STR-010
    source:
      - 'services-membership:docs/migrations/packages-as-products/README.md#What could not be done here'
  - finding: FND-MBR-STR-011
    source:
      - 'services-membership:modules/structure/services/persistence/organizational-unit-types.ts:createOrganizationalUnitType'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-organizations.ts:requireDates'
      - 'react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0001'
      - 'react-console:acceptance/membership/journeys/structure/MBR-ACC-0002.json'
      - 'react-console:acceptance/membership/journeys/structure/MBR-ACC-0036.json'
  - finding: FND-MBR-STR-012
    source:
      - 'services-membership:modules/structure/services/persistence/organizational-unit-types.ts:rowValues'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:attributeValues'
      - 'services-membership:modules/structure/services/paging.ts:pageSizeOf'
      - 'services-membership:aws/api/route-inputs.ts:pageRequestOf'
  - finding: FND-MBR-STR-013
    source:
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:programContent'
      - 'services-membership:modules/structure/aws/api/structure-requests.ts:unitTypeBody'
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0112.json'
  - finding: FND-MBR-STR-014
    source:
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:programResource'
      - 'react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-CFG-037'
      - 'react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-STR-046'
  - finding: FND-MBR-STR-015
    source:
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0113.json'
      - 'react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0082'
  - finding: FND-MBR-STR-016
    source:
      - 'services-membership:modules/configuration/services/persistence/configuration-store.ts:configurationStore'
      - 'react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-CFG-036'
  - finding: FND-MBR-STR-017
    source:
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:policySetResource'
      - 'services-membership:modules/configuration/services/persistence/membership-packages.ts:replacePackageChildren'
  - finding: FND-MBR-STR-018
    source:
      - 'services-membership:modules/memberships/services/affiliations/unit-rules.ts'
      - 'react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-CFG-019'
      - 'react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-CFG-020'
  - finding: FND-MBR-STR-019
    source:
      - 'services-membership:modules/terms/services/term-rules.ts:fixedWindowProbe'
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0100.json'
      - 'react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0087'
  - finding: FND-MBR-STR-020
    source:
      - 'services-membership:modules/terms/services/term-rules.ts'
      - 'services-membership:README.md#2026-10-18 — Final acceptance'
  - finding: FND-MBR-STR-021
    source:
      - 'services-membership:modules/terms/services/term-rules.ts:startingPoint'
      - 'react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-CFG-032'
  - finding: FND-MBR-STR-022
    source:
      - 'services-membership:modules/terms/services/term-rules.ts:fixedTermEnd'
  - finding: FND-MBR-STR-023
    source:
      - 'services-membership:modules/structure/aws/api/structure.routes.ts:structureRoutes'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:descendantsAsOf'
  - finding: FND-MBR-STR-024
    source:
      - 'services-membership:docs/migrations/structure/README.md#What could not be done as specified, and why'
  - finding: FND-MBR-STR-025
    source:
      - 'react-console:acceptance/membership/journeys/structure/MBR-ACC-0028.json'
      - 'react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0011'
      - 'react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0009'
  - finding: FND-MBR-STR-026
    source:
      - 'services-membership:docs/migrations/structure/README.md#What could not be done as specified, and why'
      - 'services-membership:modules/configuration/services/data-operations/configuration-operations.ts:configurationDataOperations'
      - 'react-console:acceptance/membership/journeys/structure/MBR-ACC-0029.json'
  - finding: FND-MBR-STR-027
    source:
      - 'services-membership:docs/migrations/structure/README.md#What could not be done as specified, and why'
      - 'react-console:acceptance/membership/journeys/structure/MBR-ACC-0027.json'
  - finding: FND-MBR-STR-028
    source:
      - 'services-membership:docs/migrations/packages-as-products/README.md#Wired on 2026-10-18 against contracts 0.4.1, and what still waits on Accounting'
      - 'services-membership:modules/structure/tests/integration/services/persistence/accounting-products.integration.spec.ts#the Accounting products port in the database › creates a product Membership owns and answers it as the reads do, at version 1'
  - finding: FND-MBR-STR-029
    source:
      - 'react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-STR-021'
      - 'react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0010'
      - 'services-membership:modules/structure/services/lifecycle/structure-participant.ts:structureParticipant'
      - 'services-membership:modules/configuration/services/shared/records.ts:translateDatabaseRefusal'
  - finding: FND-MBR-STR-030
    source:
      - 'services-membership:docs/acceptance/README.md#The landed run (2026-10-19)'
      - 'react-console:acceptance/membership/journeys/README.md'
      - 'react-console:acceptance/membership/journeys/structure/MBR-ACC-0002.json'
      - 'react-console:acceptance/membership/journeys/structure/MBR-ACC-0005.json'
      - 'react-console:acceptance/membership/journeys/structure/MBR-ACC-0008.json'
      - 'react-console:acceptance/membership/journeys/structure/MBR-ACC-0011.json'
      - 'react-console:acceptance/membership/journeys/structure/MBR-ACC-0017.json'
      - 'react-console:acceptance/membership/journeys/structure/MBR-ACC-0024.json'
      - 'react-console:acceptance/membership/journeys/structure/MBR-ACC-0028.json'
      - 'react-console:acceptance/membership/journeys/structure/MBR-ACC-0036.json'
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0087.json'
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0090.json'
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0094.json'
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0095.json'
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0096.json'
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0098.json'
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0100.json'
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0102.json'
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0103.json'
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0105.json'
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0114.json'
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0109.json (configuration revisions, memberships module)'
  - finding: FND-MBR-STR-031
    source:
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0094.json'
      - 'react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0083'
  - finding: FND-MBR-STR-032
    source:
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:statusReasonResource'
      - 'react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0089'
  - finding: FND-MBR-STR-033
    source:
      - 'services-membership:modules/structure/tests/'
      - 'services-membership:modules/terms/tests/'
      - 'services-membership:tests/e2e/'
      - 'react-console:acceptance/membership/journeys/README.md'
testing_findings:
  - id: FND-MBR-STR-054
    severity: medium
    statement: 'Define unit kinds and their permitted places: dedicated coverage remains missing for boundary, invariant. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed.'
    affects:
      - ATS-MBR-STR-001
      - CAP-MBR-STR-001
    evidence:
      - 'services-membership:modules/structure/services/persistence/organizational-unit-types.ts:createOrganizationalUnitType'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-types.ts:parentIdsOf'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-types.ts:requireKnownTypes'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-types.ts:createOrganizationalUnitType'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-types.ts:updateOrganizationalUnitType'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-types.ts:updateOrganizationalUnitType'
      - 'services-membership:modules/structure/services/tree/tree-edits.ts:validatePlacement'
      - 'services-membership:tests/e2e/structure-api.e2e.spec.ts#the structure API, end to end in process › refuses to delete a unit type in use, 409 unit_type_in_use'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-types.ts:listOrganizationalUnitTypes'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-types.ts:updateOrganizationalUnitType'
      - 'services-membership:modules/structure/aws/api/structure-requests.ts:unitTypeBody'
      - STATE-MBR-STR-002
    kind: coverage-gap
    provenance: unknown
    source:
      - 'services-membership:modules/structure/services/persistence/organizational-unit-types.ts:createOrganizationalUnitType'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-types.ts:parentIdsOf'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-types.ts:requireKnownTypes'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-types.ts:createOrganizationalUnitType'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-types.ts:updateOrganizationalUnitType'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-types.ts:updateOrganizationalUnitType'
      - 'services-membership:modules/structure/services/tree/tree-edits.ts:validatePlacement'
      - 'services-membership:tests/e2e/structure-api.e2e.spec.ts#the structure API, end to end in process › refuses to delete a unit type in use, 409 unit_type_in_use'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-types.ts:listOrganizationalUnitTypes'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-types.ts:updateOrganizationalUnitType'
      - 'services-membership:modules/structure/aws/api/structure-requests.ts:unitTypeBody'
      - STATE-MBR-STR-002
  - id: FND-MBR-STR-055
    severity: medium
    statement: 'Restructure units while preserving dated placement: dedicated coverage remains missing for transition, failure. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed.'
    affects:
      - ATS-MBR-STR-002
      - CAP-MBR-STR-002
    evidence:
      - 'services-membership:tests/e2e/structure-api.e2e.spec.ts#the structure API, end to end in process › refuses a parent of a type not allowed, 409 parent_type_not_allowed'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the refusals › refuses a move under the unit’s own descendant as a cycle'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the refusals › refuses a new child under an inactive unit'
      - 'services-membership:modules/structure/services/tree/tree-edits.ts:moveUnit'
      - 'services-membership:modules/structure/tests/unit/services/tree-edits.spec.ts#the tree edits › move › refuses a move that would put the subtree at the depth cap, before any write'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the parent history and the as-of tree › refuses a move dated before the current parent began'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:recordParentChange'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:recordParentChange'
      - 'services-membership:modules/structure/tests/unit/services/tree-edits.spec.ts#the tree edits › move › locks, validates against the current closure, changes the parent, records history, rebuilds, updates depths and checks the cap, in that order'
      - 'services-membership:modules/structure/services/tree/tree-edits.ts:moveUnit'
      - 'services-membership:modules/structure/tests/unit/services/tree-edits.spec.ts#the tree edits › move › states membership.unit.reparented with the old and the new parent and the business date'
      - 'services-membership:docs/migrations/structure/README.md#What could not be done as specified, and why'
      - 'services-membership:docs/migrations/structure/README.md#The move sequence as implemented'
      - 'services-membership:tests/e2e/s09-restructuring.e2e.spec.ts#scenario 9: organizational restructuring › rewrites no affiliation: Jo’s row is the same row, version and unit'
    kind: coverage-gap
    provenance: unknown
    source:
      - 'services-membership:tests/e2e/structure-api.e2e.spec.ts#the structure API, end to end in process › refuses a parent of a type not allowed, 409 parent_type_not_allowed'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the refusals › refuses a move under the unit’s own descendant as a cycle'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the refusals › refuses a new child under an inactive unit'
      - 'services-membership:modules/structure/services/tree/tree-edits.ts:moveUnit'
      - 'services-membership:modules/structure/tests/unit/services/tree-edits.spec.ts#the tree edits › move › refuses a move that would put the subtree at the depth cap, before any write'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the parent history and the as-of tree › refuses a move dated before the current parent began'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:recordParentChange'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:recordParentChange'
      - 'services-membership:modules/structure/tests/unit/services/tree-edits.spec.ts#the tree edits › move › locks, validates against the current closure, changes the parent, records history, rebuilds, updates depths and checks the cap, in that order'
      - 'services-membership:modules/structure/services/tree/tree-edits.ts:moveUnit'
      - 'services-membership:modules/structure/tests/unit/services/tree-edits.spec.ts#the tree edits › move › states membership.unit.reparented with the old and the new parent and the business date'
      - 'services-membership:docs/migrations/structure/README.md#What could not be done as specified, and why'
      - 'services-membership:docs/migrations/structure/README.md#The move sequence as implemented'
      - 'services-membership:tests/e2e/s09-restructuring.e2e.spec.ts#scenario 9: organizational restructuring › rewrites no affiliation: Jo’s row is the same row, version and unit'
  - id: FND-MBR-STR-056
    severity: medium
    statement: 'Combine units and continue their memberships: dedicated coverage remains missing for boundary, concurrency, invariant. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed.'
    affects:
      - ATS-MBR-STR-003
      - CAP-MBR-STR-003
    evidence:
      - 'services-membership:modules/structure/tests/unit/services/tree-edits.spec.ts#the tree edits › merge › refuses a survivor below the merged unit'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › merge › moves the children under the survivor, marks the unit merged and lists what it left'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › merge › moves the children under the survivor, marks the unit merged and lists what it left'
      - 'services-membership:docs/migrations/unit-merge/README.md#The behaviour'
      - 'services-membership:modules/structure/tests/integration/services/tree/unit-merge.integration.spec.ts#the tree edits affiliations bind › a merge an affiliation cannot follow › is refused 409 affiliations_not_movable, naming the membership and unit_minimum'
      - 'services-membership:modules/memberships/tests/integration/services/identity-unit-merge.integration.spec.ts#a unit merge moves the identity of identity-bound memberships › the merge of Macon into Atlanta › makes Atlanta the identity of Kim’s membership, at the next version'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › merge › moves the children under the survivor, marks the unit merged and lists what it left'
      - 'services-membership:modules/structure/services/tree/tree-edits.ts:mergeUnit'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:updateOrganizationalUnit'
      - 'services-membership:modules/structure/services/tree/tree-edits.ts:mergeUnit'
      - 'services-membership:modules/structure/tests/unit/services/tree-edits.spec.ts#the tree edits › merge › states membership.unit.reparented for each child that moved under the survivor, naming the merged unit'
      - 'services-membership:modules/structure/services/tree/tree-edits.ts:mergeUnit'
      - STATE-MBR-STR-001
    kind: coverage-gap
    provenance: unknown
    source:
      - 'services-membership:modules/structure/tests/unit/services/tree-edits.spec.ts#the tree edits › merge › refuses a survivor below the merged unit'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › merge › moves the children under the survivor, marks the unit merged and lists what it left'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › merge › moves the children under the survivor, marks the unit merged and lists what it left'
      - 'services-membership:docs/migrations/unit-merge/README.md#The behaviour'
      - 'services-membership:modules/structure/tests/integration/services/tree/unit-merge.integration.spec.ts#the tree edits affiliations bind › a merge an affiliation cannot follow › is refused 409 affiliations_not_movable, naming the membership and unit_minimum'
      - 'services-membership:modules/memberships/tests/integration/services/identity-unit-merge.integration.spec.ts#a unit merge moves the identity of identity-bound memberships › the merge of Macon into Atlanta › makes Atlanta the identity of Kim’s membership, at the next version'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › merge › moves the children under the survivor, marks the unit merged and lists what it left'
      - 'services-membership:modules/structure/services/tree/tree-edits.ts:mergeUnit'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:updateOrganizationalUnit'
      - 'services-membership:modules/structure/services/tree/tree-edits.ts:mergeUnit'
      - 'services-membership:modules/structure/tests/unit/services/tree-edits.spec.ts#the tree edits › merge › states membership.unit.reparented for each child that moved under the survivor, naming the merged unit'
      - 'services-membership:modules/structure/services/tree/tree-edits.ts:mergeUnit'
      - STATE-MBR-STR-001
  - id: FND-MBR-STR-057
    severity: medium
    statement: 'Close units or remove units without retained dependencies: dedicated coverage remains missing for rule, failure, boundary, concurrency. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed.'
    affects:
      - ATS-MBR-STR-004
      - CAP-MBR-STR-004
    evidence:
      - 'services-membership:modules/structure/tests/integration/services/tree/unit-merge.integration.spec.ts#the tree edits affiliations bind › delete and deactivate › deactivates it instead'
      - 'services-membership:modules/structure/services/tree/tree-edits.ts:deactivateUnit'
      - 'services-membership:modules/structure/aws/api/structure-requests.ts:unitReplaceBody'
      - 'services-membership:modules/structure/tests/integration/services/tree/unit-merge.integration.spec.ts#the tree edits affiliations bind › delete and deactivate › refuses to delete a unit a closed affiliation names, 409 unit_has_affiliations with the count'
      - 'services-membership:tests/e2e/structure-api.e2e.spec.ts#the structure API, end to end in process › refuses to delete a unit in use, 409 unit_in_use'
      - 'services-membership:tests/e2e/database-refusals.e2e.spec.ts#mistakes only the database catches, through the API › DEF-MBR-0084: a structure delete a program’s reference blocks › refuses deleting a unit a program is owned by 409 unit_in_use, and keeps it'
      - 'services-membership:modules/structure/tests/unit/services/tree-edits.spec.ts#the tree edits › delete › deletes a unit no affiliation and nothing else names'
      - STATE-MBR-STR-001
    kind: coverage-gap
    provenance: unknown
    source:
      - 'services-membership:modules/structure/tests/integration/services/tree/unit-merge.integration.spec.ts#the tree edits affiliations bind › delete and deactivate › deactivates it instead'
      - 'services-membership:modules/structure/services/tree/tree-edits.ts:deactivateUnit'
      - 'services-membership:modules/structure/aws/api/structure-requests.ts:unitReplaceBody'
      - 'services-membership:modules/structure/tests/integration/services/tree/unit-merge.integration.spec.ts#the tree edits affiliations bind › delete and deactivate › refuses to delete a unit a closed affiliation names, 409 unit_has_affiliations with the count'
      - 'services-membership:tests/e2e/structure-api.e2e.spec.ts#the structure API, end to end in process › refuses to delete a unit in use, 409 unit_in_use'
      - 'services-membership:tests/e2e/database-refusals.e2e.spec.ts#mistakes only the database catches, through the API › DEF-MBR-0084: a structure delete a program’s reference blocks › refuses deleting a unit a program is owned by 409 unit_in_use, and keeps it'
      - 'services-membership:modules/structure/tests/unit/services/tree-edits.spec.ts#the tree edits › delete › deletes a unit no affiliation and nothing else names'
      - STATE-MBR-STR-001
  - id: FND-MBR-STR-058
    severity: medium
    statement: 'Find units and inspect current or historical structure: dedicated coverage remains missing for edge, failure, concurrency, invariant. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed.'
    affects:
      - ATS-MBR-STR-005
      - CAP-MBR-STR-005
    evidence:
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the closure › answers the descendants of a unit from the closure, nearest first'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the parent history and the as-of tree › answers the descendants as of 2027-06-30 equal to the tree recorded that day'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:descendantsAsOf'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the closure › pages the tree breadth first with each unit’s parent'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:listOrganizationalUnits'
      - 'services-membership:modules/structure/aws/api/structure.routes.ts:structureRoutes'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:listParentHistory'
      - 'services-membership:modules/structure/aws/api/structure.routes.ts:structureRoutes'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the published functions › answers nothing of a tenant other than the reader’s own'
      - 'services-membership:tests/unit/metadata-registration.spec.ts#Membership’s registration manifests › reads the units’ dataset under membership.structure.read, with custom field values and the ancestors over the closure'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › row-level security › reads nothing of another tenant’s unit by id'
    kind: coverage-gap
    provenance: unknown
    source:
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the closure › answers the descendants of a unit from the closure, nearest first'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the parent history and the as-of tree › answers the descendants as of 2027-06-30 equal to the tree recorded that day'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:descendantsAsOf'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the closure › pages the tree breadth first with each unit’s parent'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:listOrganizationalUnits'
      - 'services-membership:modules/structure/aws/api/structure.routes.ts:structureRoutes'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:listParentHistory'
      - 'services-membership:modules/structure/aws/api/structure.routes.ts:structureRoutes'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the published functions › answers nothing of a tenant other than the reader’s own'
      - 'services-membership:tests/unit/metadata-registration.spec.ts#Membership’s registration manifests › reads the units’ dataset under membership.structure.read, with custom field values and the ancestors over the closure'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › row-level security › reads nothing of another tenant’s unit by id'
  - id: FND-MBR-STR-059
    severity: medium
    statement: 'Maintain a unit’s identity and local details: dedicated coverage remains missing for failure. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed.'
    affects:
      - ATS-MBR-STR-006
      - CAP-MBR-STR-006
    evidence:
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the refusals › refuses a code the tenant already has'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:updateOrganizationalUnit'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:attributeValues'
      - 'services-membership:modules/structure/db/organizational-units.table.ts:organizational_units_latitude_check'
      - 'services-membership:docs/migrations/structure/README.md#Tables and migrations'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:insertOrganizationalUnit'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:updateOrganizationalUnit'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:getOrganizationalUnit'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the versions › writes a version of the unit for its creation, its update and its move, each with the actor of its context'
      - 'services-membership:modules/structure/metadata/structure.objects.ts:organizationalUnitsObject'
    kind: coverage-gap
    provenance: unknown
    source:
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the refusals › refuses a code the tenant already has'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:updateOrganizationalUnit'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:attributeValues'
      - 'services-membership:modules/structure/db/organizational-units.table.ts:organizational_units_latitude_check'
      - 'services-membership:docs/migrations/structure/README.md#Tables and migrations'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:insertOrganizationalUnit'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:updateOrganizationalUnit'
      - 'services-membership:modules/structure/services/persistence/organizational-units.ts:getOrganizationalUnit'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the versions › writes a version of the unit for its creation, its update and its move, each with the actor of its context'
      - 'services-membership:modules/structure/metadata/structure.objects.ts:organizationalUnitsObject'
  - id: FND-MBR-STR-060
    severity: medium
    statement: 'Describe a unit’s dated relationships with organizations: dedicated coverage remains missing for failure, boundary, concurrency. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed.'
    affects:
      - ATS-MBR-STR-007
      - CAP-MBR-STR-007
    evidence:
      - 'services-membership:modules/structure/services/persistence/organizational-unit-organizations.ts:linkOrganization'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-organizations.ts:requireDates'
      - 'services-membership:tests/e2e/structure-api.e2e.spec.ts#the structure API, end to end in process › refuses a second open legal entity, 409 legal_entity_already_open'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-organizations.ts:unlinkOrganization'
      - 'services-membership:modules/structure/aws/api/structure-requests.ts:linkBody'
      - 'services-membership:tests/e2e/structure-api.e2e.spec.ts#the structure API, end to end in process › creates a relationship type with an id derived from its name'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-relationship-types.ts:createOrganizationalUnitRelationshipType'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-organizations.ts:linkOrganization'
      - 'services-membership:docs/migrations/structure/README.md#Tables and migrations'
      - 'react-console:acceptance/membership/journeys/structure/MBR-ACC-0017.json'
      - STATE-MBR-STR-003
    kind: coverage-gap
    provenance: unknown
    source:
      - 'services-membership:modules/structure/services/persistence/organizational-unit-organizations.ts:linkOrganization'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-organizations.ts:requireDates'
      - 'services-membership:tests/e2e/structure-api.e2e.spec.ts#the structure API, end to end in process › refuses a second open legal entity, 409 legal_entity_already_open'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-organizations.ts:unlinkOrganization'
      - 'services-membership:modules/structure/aws/api/structure-requests.ts:linkBody'
      - 'services-membership:tests/e2e/structure-api.e2e.spec.ts#the structure API, end to end in process › creates a relationship type with an id derived from its name'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-relationship-types.ts:createOrganizationalUnitRelationshipType'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-organizations.ts:linkOrganization'
      - 'services-membership:docs/migrations/structure/README.md#Tables and migrations'
      - 'react-console:acceptance/membership/journeys/structure/MBR-ACC-0017.json'
      - STATE-MBR-STR-003
  - id: FND-MBR-STR-061
    severity: medium
    statement: 'Connect unit dues to products and settlement choices: dedicated coverage remains missing for failure, boundary. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed.'
    affects:
      - ATS-MBR-STR-008
      - CAP-MBR-STR-008
    evidence:
      - 'services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › extends a product of type chapter_dues as a unit’s dues product, under the product’s id, with the product’s name'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-dues-products.ts:createDuesProduct'
      - 'services-membership:modules/structure/tests/unit/accounting-products.spec.ts#the Accounting products port › answers a product Accounting no longer has as its id, inactive, hidden, with no product status'
      - 'services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › re-points a unit’s dues product at another package at the version just read, 200 with the next version'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-dues-products.ts:createDuesProduct'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-financial-settings.ts:setFinancialSettings'
      - '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)'
      - 'services-membership:modules/structure/services/finance/accounting-references.ts:checkAccountingReferenceShapes'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-dues-products.ts:createDuesProduct'
    kind: coverage-gap
    provenance: unknown
    source:
      - 'services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › extends a product of type chapter_dues as a unit’s dues product, under the product’s id, with the product’s name'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-dues-products.ts:createDuesProduct'
      - 'services-membership:modules/structure/tests/unit/accounting-products.spec.ts#the Accounting products port › answers a product Accounting no longer has as its id, inactive, hidden, with no product status'
      - 'services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › re-points a unit’s dues product at another package at the version just read, 200 with the next version'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-dues-products.ts:createDuesProduct'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-financial-settings.ts:setFinancialSettings'
      - '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)'
      - 'services-membership:modules/structure/services/finance/accounting-references.ts:checkAccountingReferenceShapes'
      - 'services-membership:modules/structure/services/persistence/organizational-unit-dues-products.ts:createDuesProduct'
  - id: FND-MBR-STR-062
    severity: medium
    statement: 'Establish programs and their membership context: dedicated coverage remains missing for transition, edge, failure, concurrency, invariant. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed.'
    affects:
      - ATS-MBR-STR-009
      - CAP-MBR-STR-009
    evidence:
      - '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'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:programResource'
      - 'services-membership:modules/configuration/db/programs.table.ts:programs'
      - 'services-membership:modules/configuration/db/configuration-vocabularies.ts:NUMBER_SCOPES'
      - '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'
      - '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'
      - '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'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:programContent'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:programResource'
      - 'react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-CFG-028'
      - 'services-membership:modules/configuration/services/persistence/configuration-store.ts:configurationStore'
      - '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)'
      - STATE-MBR-STR-006
    kind: coverage-gap
    provenance: unknown
    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'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:programResource'
      - 'services-membership:modules/configuration/db/programs.table.ts:programs'
      - 'services-membership:modules/configuration/db/configuration-vocabularies.ts:NUMBER_SCOPES'
      - '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'
      - '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'
      - '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'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:programContent'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:programResource'
      - 'react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-CFG-028'
      - 'services-membership:modules/configuration/services/persistence/configuration-store.ts:configurationStore'
      - '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)'
      - STATE-MBR-STR-006
  - id: FND-MBR-STR-063
    severity: medium
    statement: 'Set a program’s affiliation requirements: dedicated coverage remains missing for rule, edge, failure, boundary, invariant. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed.'
    affects:
      - ATS-MBR-STR-010
      - CAP-MBR-STR-010
    evidence:
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:replaceProgramUnitTypesOf'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:replaceProgramUnitTypesOf'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:unitTypeProblems'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:replaceProgramUnitTypesOf'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:programUnitTypesContent'
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0096.json'
    kind: coverage-gap
    provenance: unknown
    source:
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:replaceProgramUnitTypesOf'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:replaceProgramUnitTypesOf'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:unitTypeProblems'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:replaceProgramUnitTypesOf'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:programUnitTypesContent'
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0096.json'
  - id: FND-MBR-STR-064
    severity: medium
    statement: 'Classify memberships and configure organization flow-down: dedicated coverage remains missing for rule, edge, failure, concurrency. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed.'
    affects:
      - ATS-MBR-STR-011
      - CAP-MBR-STR-011
    evidence:
      - '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 moving a type a package names to another program 400 naming program_id, and leaves it where it was'
      - 'services-membership:modules/configuration/db/membership-types.table.ts:membershipTypes'
      - '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 flow-down enabled without a target type 400 naming flowdown_type_id, and writes no type'
      - 'services-membership:modules/configuration/services/persistence/membership-types.ts:replaceFlowdownLists'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:typeContent'
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0113.json'
      - STATE-MBR-STR-006
    kind: coverage-gap
    provenance: unknown
    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 moving a type a package names to another program 400 naming program_id, and leaves it where it was'
      - 'services-membership:modules/configuration/db/membership-types.table.ts:membershipTypes'
      - '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 flow-down enabled without a target type 400 naming flowdown_type_id, and writes no type'
      - 'services-membership:modules/configuration/services/persistence/membership-types.ts:replaceFlowdownLists'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:typeContent'
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0113.json'
      - STATE-MBR-STR-006
  - id: FND-MBR-STR-065
    severity: medium
    statement: 'Offer membership through an Accounting product: dedicated coverage remains missing for rule, failure, concurrency. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed.'
    affects:
      - ATS-MBR-STR-012
      - CAP-MBR-STR-012
    evidence:
      - 'services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › refuses a package whose product Accounting does not have, 400'
      - 'services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › refuses the common fields a package no longer carries of its own (they are the product’s)'
      - 'services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › lists packages with the product’s fields and filters is_active by the product’s status'
      - 'services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › refuses a second extension of the same product: the package id is the product id'
      - '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 package of a type of another program 400 naming membership_type_id, and writes no package nor unit rule'
      - '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 package renewing into itself 400 naming renews_into_package_id'
      - 'services-membership:tests/acceptance/configuration/MBR-ACC-0115.acceptance.ts#MBR-ACC-0115: The renewal window and the reinstatement period decide what a member may buy, read live from the package: narrowing the window shuts an open renewal, widening the reinstatement period turns a rejoin back into a reinstatement, a blank period means no reinstatement at all, and the default renewal package is the one the configuration names'
      - '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 change policy set that does not exist 400 naming change_policy_set_id'
      - 'services-membership:modules/configuration/services/persistence/configuration-store.ts:configurationStore'
      - 'services-membership:modules/structure/ports/accounting-products.ts:accountingProductsFromTables'
      - 'services-membership:modules/configuration/services/persistence/membership-packages.ts:listMembershipPackages'
      - STATE-MBR-STR-006
    kind: coverage-gap
    provenance: unknown
    source:
      - 'services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › refuses a package whose product Accounting does not have, 400'
      - 'services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › refuses the common fields a package no longer carries of its own (they are the product’s)'
      - 'services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › lists packages with the product’s fields and filters is_active by the product’s status'
      - 'services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › refuses a second extension of the same product: the package id is the product id'
      - '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 package of a type of another program 400 naming membership_type_id, and writes no package nor unit rule'
      - '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 package renewing into itself 400 naming renews_into_package_id'
      - 'services-membership:tests/acceptance/configuration/MBR-ACC-0115.acceptance.ts#MBR-ACC-0115: The renewal window and the reinstatement period decide what a member may buy, read live from the package: narrowing the window shuts an open renewal, widening the reinstatement period turns a rejoin back into a reinstatement, a blank period means no reinstatement at all, and the default renewal package is the one the configuration names'
      - '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 change policy set that does not exist 400 naming change_policy_set_id'
      - 'services-membership:modules/configuration/services/persistence/configuration-store.ts:configurationStore'
      - 'services-membership:modules/structure/ports/accounting-products.ts:accountingProductsFromTables'
      - 'services-membership:modules/configuration/services/persistence/membership-packages.ts:listMembershipPackages'
      - STATE-MBR-STR-006
  - id: FND-MBR-STR-066
    severity: medium
    statement: 'Bundle grants and package-specific unit requirements: dedicated coverage remains missing for rule, failure, concurrency, invariant. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed.'
    affects:
      - ATS-MBR-STR-013
      - CAP-MBR-STR-013
    evidence:
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:packageResource'
      - '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 grant whose type is not of the granted program 400 naming grants: membership_type_id, and writes no package'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:packageResource'
      - 'services-membership:modules/configuration/services/persistence/membership-packages.ts:replacePackageChildren'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:unitRuleProblems'
      - 'services-membership:modules/memberships/services/affiliations/unit-rules.ts'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:packageResource'
      - 'react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-CFG-019'
    kind: coverage-gap
    provenance: unknown
    source:
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:packageResource'
      - '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 grant whose type is not of the granted program 400 naming grants: membership_type_id, and writes no package'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:packageResource'
      - 'services-membership:modules/configuration/services/persistence/membership-packages.ts:replacePackageChildren'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:unitRuleProblems'
      - 'services-membership:modules/memberships/services/affiliations/unit-rules.ts'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:packageResource'
      - 'react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-CFG-019'
  - id: FND-MBR-STR-067
    severity: medium
    statement: 'Record policies for future package changes: dedicated coverage remains missing for rule, transition, edge, failure, concurrency, invariant. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed.'
    affects:
      - ATS-MBR-STR-014
      - CAP-MBR-STR-014
    evidence:
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:policySetResource'
      - 'services-membership:modules/configuration/db/change-policies.table.ts:changePolicies'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:policyContent'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:policyContent'
      - 'services-membership:docs/migrations/membership-core/README.md#Tables and migrations'
      - STATE-MBR-STR-006
    kind: coverage-gap
    provenance: unknown
    source:
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:policySetResource'
      - 'services-membership:modules/configuration/db/change-policies.table.ts:changePolicies'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:policyContent'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:policyContent'
      - 'services-membership:docs/migrations/membership-core/README.md#Tables and migrations'
      - STATE-MBR-STR-006
  - id: FND-MBR-STR-068
    severity: medium
    statement: 'Determine a term’s start and end dates: dedicated coverage remains missing for transition, edge, failure, concurrency. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed.'
    affects:
      - ATS-MBR-STR-015
      - CAP-MBR-STR-015
      - BR-CAP-MBR-STR-015-09
      - BR-CAP-MBR-STR-015-13
    evidence:
      - 'services-membership:modules/terms/tests/unit/term-rules.spec.ts#term rules: what 2.0 decides › reports every problem of a rule at once'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:packageResource'
      - 'services-membership:modules/terms/tests/unit/term-rules.spec.ts#term rules: the rules of 1.0 beyond its spec cases › extends an early renewal from the current end, whatever the basis'
      - 'services-membership:modules/terms/services/term-rules.ts:startingPoint'
      - 'services-membership:modules/terms/tests/unit/term-rules.spec.ts#term rules: 1.0 calculate-expiration-date.spec.js › 1.0 lines 284-292: anniversary in years, should calculate properly for a single year › ends a purchase of 2019-04-03 at the end of the anniversary month, 2020-04-30'
      - 'services-membership:modules/terms/services/term-rules.ts:fixedWindowProbe'
      - 'services-membership:modules/terms/tests/unit/term-rules.spec.ts#term rules: 1.0 calculate-expiration-date.spec.js › 1.0 lines 70-77: calendar, a standard year, should calculate properly for April › back-dates a purchase of 2019-04-03 to 2019-01-01 and ends it 2019-12-31'
      - 'services-membership:modules/terms/tests/unit/term-rules.spec.ts#term rules: what 2.0 decides › ends a calendar period ending in February on its last day in a leap year: 2024-02-29 (decided by Andrew 2026-10-18: the real last day of the month; 1.0 added a year with Moment and ended it 2024-02-28)'
      - 'services-membership:modules/terms/tests/unit/term-rules.spec.ts#term rules: 1.0 calculate-expiration-date.spec.js › 1.0 lines 248-255: no expiration, should calculate properly › starts on 2019-04-03 and never ends'
      - 'services-membership:modules/terms/tests/unit/term-rules.spec.ts#term rules: what 2.0 decides › gives the same result twice for the same frozen inputs (1.0 turned the fixed dates into Moments in place, so a second call read other inputs)'
      - 'services-membership:modules/terms/tests/unit/isolation.spec.ts#term engine isolation › imports nothing of the repository outside modules/terms'
      - 'services-membership:modules/terms/services/term-rules.ts:fixedTermEnd'
      - 'services-membership:modules/terms/services/term-rules.ts:fixedTermEnd'
      - STATE-MBR-STR-004
    kind: coverage-gap
    provenance: unknown
    source:
      - 'services-membership:modules/terms/tests/unit/term-rules.spec.ts#term rules: what 2.0 decides › reports every problem of a rule at once'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:packageResource'
      - 'services-membership:modules/terms/tests/unit/term-rules.spec.ts#term rules: the rules of 1.0 beyond its spec cases › extends an early renewal from the current end, whatever the basis'
      - 'services-membership:modules/terms/services/term-rules.ts:startingPoint'
      - 'services-membership:modules/terms/tests/unit/term-rules.spec.ts#term rules: 1.0 calculate-expiration-date.spec.js › 1.0 lines 284-292: anniversary in years, should calculate properly for a single year › ends a purchase of 2019-04-03 at the end of the anniversary month, 2020-04-30'
      - 'services-membership:modules/terms/services/term-rules.ts:fixedWindowProbe'
      - 'services-membership:modules/terms/tests/unit/term-rules.spec.ts#term rules: 1.0 calculate-expiration-date.spec.js › 1.0 lines 70-77: calendar, a standard year, should calculate properly for April › back-dates a purchase of 2019-04-03 to 2019-01-01 and ends it 2019-12-31'
      - 'services-membership:modules/terms/tests/unit/term-rules.spec.ts#term rules: what 2.0 decides › ends a calendar period ending in February on its last day in a leap year: 2024-02-29 (decided by Andrew 2026-10-18: the real last day of the month; 1.0 added a year with Moment and ended it 2024-02-28)'
      - 'services-membership:modules/terms/tests/unit/term-rules.spec.ts#term rules: 1.0 calculate-expiration-date.spec.js › 1.0 lines 248-255: no expiration, should calculate properly › starts on 2019-04-03 and never ends'
      - 'services-membership:modules/terms/tests/unit/term-rules.spec.ts#term rules: what 2.0 decides › gives the same result twice for the same frozen inputs (1.0 turned the fixed dates into Moments in place, so a second call read other inputs)'
      - 'services-membership:modules/terms/tests/unit/isolation.spec.ts#term engine isolation › imports nothing of the repository outside modules/terms'
      - 'services-membership:modules/terms/services/term-rules.ts:fixedTermEnd'
      - 'services-membership:modules/terms/services/term-rules.ts:fixedTermEnd'
      - STATE-MBR-STR-004
  - id: FND-MBR-STR-069
    severity: medium
    statement: 'Interpret membership status and continuity by date: dedicated coverage remains missing for validation, edge, concurrency. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed.'
    affects:
      - ATS-MBR-STR-016
      - CAP-MBR-STR-016
    evidence:
      - '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'
      - STATE-MBR-STR-004
      - STATE-MBR-STR-005
    kind: coverage-gap
    provenance: unknown
    source:
      - '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'
      - STATE-MBR-STR-004
      - STATE-MBR-STR-005
  - id: FND-MBR-STR-070
    severity: medium
    statement: 'Maintain reasons for membership status actions: dedicated coverage remains missing for transition, edge, failure, boundary, concurrency, invariant. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed.'
    affects:
      - ATS-MBR-STR-017
      - CAP-MBR-STR-017
    evidence:
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:statusReasonContent'
      - 'services-membership:modules/configuration/services/persistence/membership-status-reasons.ts:requireStatusReason'
      - 'react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-CFG-022'
      - 'services-membership:modules/configuration/services/persistence/configuration-store.ts:configurationStore'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:statusReasonResource'
      - 'services-membership:modules/configuration/aws/api/configuration.routes.ts:configurationModuleRoutes'
      - STATE-MBR-STR-006
    kind: coverage-gap
    provenance: unknown
    source:
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:statusReasonContent'
      - 'services-membership:modules/configuration/services/persistence/membership-status-reasons.ts:requireStatusReason'
      - 'react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-CFG-022'
      - 'services-membership:modules/configuration/services/persistence/configuration-store.ts:configurationStore'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:statusReasonResource'
      - 'services-membership:modules/configuration/aws/api/configuration.routes.ts:configurationModuleRoutes'
      - STATE-MBR-STR-006
  - id: FND-MBR-STR-071
    severity: medium
    statement: 'Maintain configuration with consistent change safeguards: dedicated coverage remains missing for edge. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed.'
    affects:
      - ATS-MBR-STR-018
      - CAP-MBR-STR-018
    evidence:
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:createConfiguration'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:updateConfiguration'
      - 'services-membership:modules/configuration/services/persistence/configuration-store.ts:configurationStore'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:updateConfiguration'
      - 'services-membership:modules/configuration/services/persistence/configuration-store.ts:configurationStore'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:createConfiguration'
      - '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 type of a program that does not exist 400 naming program_id'
      - 'services-membership:modules/configuration/services/persistence/membership-packages.ts:listMembershipPackages'
      - 'services-membership:aws/api/route-inputs.ts:found'
      - 'services-membership:modules/configuration/services/persistence/configuration-store.ts:configurationStore'
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0122.json'
      - STATE-MBR-STR-006
    kind: coverage-gap
    provenance: unknown
    source:
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:createConfiguration'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:updateConfiguration'
      - 'services-membership:modules/configuration/services/persistence/configuration-store.ts:configurationStore'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:updateConfiguration'
      - 'services-membership:modules/configuration/services/persistence/configuration-store.ts:configurationStore'
      - 'services-membership:modules/configuration/services/configuration/configuration-records.ts:createConfiguration'
      - '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 type of a program that does not exist 400 naming program_id'
      - 'services-membership:modules/configuration/services/persistence/membership-packages.ts:listMembershipPackages'
      - 'services-membership:aws/api/route-inputs.ts:found'
      - 'services-membership:modules/configuration/services/persistence/configuration-store.ts:configurationStore'
      - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0122.json'
      - STATE-MBR-STR-006
  - id: FND-MBR-STR-072
    severity: medium
    statement: 'Authorize structure and configuration work: dedicated coverage remains missing for rule, validation, edge, failure, concurrency, invariant. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed.'
    affects:
      - ATS-MBR-STR-019
      - CAP-MBR-STR-019
    evidence:
      - '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:aws/membership.service.ts:STRUCTURE_PERMISSIONS'
      - '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'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › row-level security › shows another tenant none of the units'
      - 'services-membership:tests/unit/route-authorization.spec.ts#route authorization: every Membership operation names its permission › is allowed or evaluates only keys the published catalog defines'
      - 'react-console:lib/authz/permissions.ts:82'
    kind: coverage-gap
    provenance: unknown
    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:aws/membership.service.ts:STRUCTURE_PERMISSIONS'
      - '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'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › row-level security › shows another tenant none of the units'
      - 'services-membership:tests/unit/route-authorization.spec.ts#route authorization: every Membership operation names its permission › is allowed or evaluates only keys the published catalog defines'
      - 'react-console:lib/authz/permissions.ts:82'
  - id: FND-MBR-STR-073
    severity: medium
    statement: 'Provision, migrate and remove membership setup: dedicated coverage remains missing for rule, validation, permission, concurrency, invariant. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed.'
    affects:
      - ATS-MBR-STR-020
      - CAP-MBR-STR-020
    evidence:
      - 'services-membership:modules/structure/tests/integration/services/lifecycle/structure-participant.integration.spec.ts#the structure participant in the database › seeds the four relationship types at provisioning'
      - 'services-membership:modules/structure/tests/integration/services/lifecycle/structure-participant.integration.spec.ts#the structure participant in the database › refuses to purge a tenant Platform is not deleting, before any row is removed'
      - 'services-membership:modules/structure/tests/integration/services/lifecycle/structure-participant.integration.spec.ts#the structure participant in the database › resets the tree of a tenant being reset and keeps its unit and relationship types'
      - 'services-membership:modules/structure/services/well-known/well-known-structure.ts'
      - 'services-membership:docs/migrations/structure/README.md#Routes, permissions, metadata, data operations, lifecycle, well-known objects'
      - 'services-membership:modules/configuration/services/data-operations/configuration-operations.ts:configurationDataOperations'
      - 'services-membership:modules/configuration/services/data-operations/configuration-operations.ts:configurationDataOperations'
      - 'services-membership:modules/structure/services/lifecycle/structure-participant.ts:structureParticipant'
      - 'react-console:acceptance/membership/journeys/structure/MBR-ACC-0028.json'
      - 'services-membership:modules/structure/services/tree/tree-loads.ts:loadUnit'
    kind: coverage-gap
    provenance: unknown
    source:
      - 'services-membership:modules/structure/tests/integration/services/lifecycle/structure-participant.integration.spec.ts#the structure participant in the database › seeds the four relationship types at provisioning'
      - 'services-membership:modules/structure/tests/integration/services/lifecycle/structure-participant.integration.spec.ts#the structure participant in the database › refuses to purge a tenant Platform is not deleting, before any row is removed'
      - 'services-membership:modules/structure/tests/integration/services/lifecycle/structure-participant.integration.spec.ts#the structure participant in the database › resets the tree of a tenant being reset and keeps its unit and relationship types'
      - 'services-membership:modules/structure/services/well-known/well-known-structure.ts'
      - 'services-membership:docs/migrations/structure/README.md#Routes, permissions, metadata, data operations, lifecycle, well-known objects'
      - 'services-membership:modules/configuration/services/data-operations/configuration-operations.ts:configurationDataOperations'
      - 'services-membership:modules/configuration/services/data-operations/configuration-operations.ts:configurationDataOperations'
      - 'services-membership:modules/structure/services/lifecycle/structure-participant.ts:structureParticipant'
      - 'react-console:acceptance/membership/journeys/structure/MBR-ACC-0028.json'
      - 'services-membership:modules/structure/services/tree/tree-loads.ts:loadUnit'
  - id: FND-MBR-STR-074
    severity: medium
    statement: Two inherited unit-detail proof links identify neighboring rules rather than the behavior their scenarios exercise. Replacement-default proof now links to versioned replacement and attributed-history proof now links to retained history; welcome selection and detailed custom-value reads need their own scenarios.
    affects:
      - ATS-MBR-STR-006
      - BR-CAP-MBR-STR-006-05
      - BR-CAP-MBR-STR-006-07
      - BR-CAP-MBR-STR-006-08
      - BR-CAP-MBR-STR-006-09
    evidence:
      - 'services-membership:tests/acceptance/structure/MBR-ACC-0007.acceptance.ts'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts'
    kind: inconsistency
    provenance: test
    source:
      - 'services-membership:tests/acceptance/structure/MBR-ACC-0007.acceptance.ts'
      - 'services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts'
  - id: FND-MBR-STR-075
    severity: medium
    statement: 'The permitted console acceptance corpus contains journey definitions rather than executable Playwright suites, and the hosted Membership routes provide no structure administration workflow. Browser acceptance for this module therefore has no executable registration.'
    affects:
      - MOD-MBR-STR
      - FAS-MBR-STR-01
      - FAS-MBR-STR-02
      - FAS-MBR-STR-03
      - FAS-MBR-STR-04
      - FAS-MBR-STR-05
      - FAS-MBR-STR-06
    evidence:
      - 'react-console:acceptance/membership/journeys/README.md'
      - 'react-console:app/(console)/console/[tenantId]/membership'
      - specs/membership/structure/MODULE.md
    kind: coverage-gap
    provenance: unknown
    source:
      - 'react-console:acceptance/membership/journeys/README.md'
      - 'react-console:app/(console)/console/[tenantId]/membership'
      - specs/membership/structure/MODULE.md
  - id: FND-MBR-STR-076
    severity: medium
    statement: 'Registered executable programs and scenario specifications have different boundaries. Some suites have no verified scenario binding, some inherited bindings cover only examples of compound behavior, and newly proposed feature and interaction cases still require complete executable proof; manual acceptance programs also need explicit invocation outside the ordinary npm test tiers.'
    affects:
      - MOD-MBR-STR
      - FAS-MBR-STR-01
      - FAS-MBR-STR-02
      - FAS-MBR-STR-03
      - FAS-MBR-STR-04
      - FAS-MBR-STR-05
      - FAS-MBR-STR-06
      - TST-MBR-STR-005
      - TST-MBR-STR-020
      - TST-MBR-STR-027
      - TST-MBR-STR-030
      - TST-MBR-STR-033
      - TST-MBR-STR-034
      - TST-MBR-STR-035
      - TST-MBR-STR-036
      - TST-MBR-STR-038
      - TST-MBR-STR-040
      - TST-MBR-STR-042
      - TST-MBR-STR-043
      - TST-MBR-STR-045
      - TST-MBR-STR-048
      - TST-MBR-STR-049
      - TST-MBR-STR-050
      - TST-MBR-STR-051
      - TST-MBR-STR-052
      - TST-MBR-STR-054
      - TST-MBR-STR-058
      - TST-MBR-STR-059
      - TST-MBR-STR-061
      - TST-MBR-STR-064
      - TST-MBR-STR-065
      - TST-MBR-STR-067
      - TST-MBR-STR-070
      - TST-MBR-STR-076
      - TST-MBR-STR-083
      - TST-MBR-STR-086
      - TST-MBR-STR-093
      - TST-MBR-STR-102
    evidence:
      - 'services-membership:package.json#scripts'
      - 'services-membership:tests/acceptance/configuration/support/journey.ts'
      - 'services-membership:tests/acceptance/structure/support/journey.ts'
    kind: coverage-gap
    provenance: unknown
    source:
      - 'services-membership:package.json#scripts'
      - 'services-membership:tests/acceptance/configuration/support/journey.ts'
      - 'services-membership:tests/acceptance/structure/support/journey.ts'
---

# Organizational Structure, Configuration and Terms: Findings and Open Questions

## Findings

| id | severity | statement | affects | evidence | kind |
|---|---|---|---|---|---|
| `FND-MBR-STR-001` | medium | The external Membership decision register is unavailable in this job. Product authority is therefore limited to specific decisions reproduced in the permitted repository; the general acceptance and an approval summary do not confirm every rule. | `MOD-MBR-STR` | services-membership:README.md#services-membership; services-membership:docs/migrations/structure/README.md#The organizational structure module (P1); services-platform:docs/proposals/membership-architecture/12-decision-register.md (not readable in this job) | undocumented |
| `FND-MBR-STR-002` | low | The permitted console scope contains no structure administration screen. Its Members page and Commerce member-pricing settings do not provide this module’s setup workflows, leaving service evidence without browser workflow proof. | `MOD-MBR-STR`, `JNY-MBR-STR-001`, `JNY-MBR-STR-004` | react-console:app/(console)/console/[tenantId]/membership/members/page.tsx; react-console:components/membership/settings/membership-settings-page.tsx; react-console:components/console/nav-config.ts:config-app-membership | inconsistency |
| `FND-MBR-STR-003` | medium | The console and service use different Membership permission vocabularies. A direct match is unsupported until the product supplies and verifies the mapping used by future administration screens. | `BR-CAP-MBR-STR-019-07`, `CAP-MBR-STR-019` | react-console:lib/authz/permissions.ts:82; services-membership:aws/membership.service.ts:MEMBERSHIP_PERMISSION_SETS | inconsistency |
| `FND-MBR-STR-004` | medium | Inactive units have no reactivation operation. A detail replacement discards a submitted status, allowing the request to succeed without the attempted reopening. | `BR-CAP-MBR-STR-004-03`, `CAP-MBR-STR-004`, `OQ-MBR-STR-002` | services-membership:modules/structure/aws/api/structure-requests.ts:unitReplaceBody; services-membership:modules/structure/services/tree/tree-edits.ts:deactivateUnit; react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0007 | defect |
| `FND-MBR-STR-005` | medium | Combination leaves the source unit beneath its existing parent and retains its open parent period. Product has not settled whether a merged source should remain in the current branch. | `BR-CAP-MBR-STR-003-10`, `CAP-MBR-STR-003`, `CAP-MBR-STR-005`, `OQ-MBR-STR-001` | services-membership:modules/structure/services/tree/tree-edits.ts:mergeUnit; react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-STR-047 | undocumented |
| `FND-MBR-STR-006` | medium | A placement correction on its first effective day replaces the current history row. Earlier values survive only in versions, and deletion checks can consequently lose the source unit’s former-parent reference. | `BR-CAP-MBR-STR-002-08`, `BR-CAP-MBR-STR-004-05`, `CAP-MBR-STR-002`, `CAP-MBR-STR-004` | services-membership:modules/structure/services/persistence/organizational-units.ts:recordParentChange; services-membership:modules/structure/services/persistence/organizational-units.ts:unitReferences; react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0004 | defect |
| `FND-MBR-STR-007` | low | Repeated non-legal organization-link creation can retain duplicates with no removal operation. Repeating an unchanged ending also creates another version. | `BR-CAP-MBR-STR-007-10`, `CAP-MBR-STR-007` | services-membership:modules/structure/services/persistence/organizational-unit-organizations.ts:linkOrganization; services-membership:modules/structure/services/persistence/organizational-unit-organizations.ts:unlinkOrganization; react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0005 | defect |
| `FND-MBR-STR-008` | medium | Organization and finance writes remain available for inactive and merged units. Relationship-purpose records have no rename or retirement operation, and inactivity does not prevent their use in new links. | `BR-CAP-MBR-STR-007-07`, `BR-CAP-MBR-STR-007-08`, `BR-CAP-MBR-STR-008-09`, `CAP-MBR-STR-007`, `CAP-MBR-STR-008` | services-membership:modules/structure/services/persistence/organizational-unit-organizations.ts:linkOrganization; services-membership:modules/structure/services/persistence/organizational-unit-dues-products.ts:createDuesProduct; services-membership:modules/structure/aws/api/structure.routes.ts:structureRoutes | debt |
| `FND-MBR-STR-009` | medium | Organization, ordering-profile, default-dues and dues-package references are stored without complete existence validation. The default dues reference has no consumer, leaving configuration errors to surface outside these writes. | `BR-CAP-MBR-STR-007-05`, `BR-CAP-MBR-STR-008-05`, `BR-CAP-MBR-STR-008-07`, `BR-CAP-MBR-STR-008-08`, `CAP-MBR-STR-007`, `CAP-MBR-STR-008` | services-membership:modules/structure/services/finance/accounting-references.ts:checkAccountingReferenceShapes; services-membership:modules/structure/services/persistence/organizational-unit-financial-settings.ts:setFinancialSettings; services-membership:modules/structure/services/persistence/organizational-unit-dues-products.ts:createDuesProduct | debt |
| `FND-MBR-STR-010` | low | Membership cannot remove or deactivate a mistakenly created dues extension. Staff can change its package association or manage availability through its Accounting product. | `BR-CAP-MBR-STR-008-04`, `CAP-MBR-STR-008` | services-membership:docs/migrations/packages-as-products/README.md#What could not be done here | debt |
| `FND-MBR-STR-011` | low | Several validation refusals use codes describing missing records or already-ended links rather than malformed input. Unit-code validation also differs from configuration-kind reserved-word handling. | `BR-CAP-MBR-STR-001-01`, `BR-CAP-MBR-STR-006-01`, `BR-CAP-MBR-STR-007-01` | services-membership:modules/structure/services/persistence/organizational-unit-types.ts:createOrganizationalUnitType; services-membership:modules/structure/services/persistence/organizational-unit-organizations.ts:requireDates; react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0001; react-console:acceptance/membership/journeys/structure/MBR-ACC-0002.json; react-console:acceptance/membership/journeys/structure/MBR-ACC-0036.json | inconsistency |
| `FND-MBR-STR-012` | medium | Structure and configuration have different replacement and paging contracts. Ordinary structure omissions restore defaults, configuration omissions retain values, and oversized page requests are refused by one concern and capped by the other. | `BR-CAP-MBR-STR-001-06`, `BR-CAP-MBR-STR-006-07`, `BR-CAP-MBR-STR-005-06`, `BR-CAP-MBR-STR-018-08`, `BR-CAP-MBR-STR-018-04` | services-membership:modules/structure/services/persistence/organizational-unit-types.ts:rowValues; services-membership:modules/structure/services/persistence/organizational-units.ts:attributeValues; services-membership:modules/structure/services/paging.ts:pageSizeOf; services-membership:aws/api/route-inputs.ts:pageRequestOf | inconsistency |
| `FND-MBR-STR-013` | medium | Retained settings include unused committee, geography, welcome, grace-benefit, competing-holding, portal, suggestion and presentation choices. Policy sets likewise have no operational change consumer; storing these choices does not establish their promised experiences. | `BR-CAP-MBR-STR-001-11`, `BR-CAP-MBR-STR-006-10`, `BR-CAP-MBR-STR-009-08`, `BR-CAP-MBR-STR-009-11`, `BR-CAP-MBR-STR-010-05`, `BR-CAP-MBR-STR-011-05`, `BR-CAP-MBR-STR-014-05`, `BR-CAP-MBR-STR-017-04`, `OQ-MBR-STR-003` | services-membership:modules/configuration/services/configuration/configuration-records.ts:programContent; services-membership:modules/structure/aws/api/structure-requests.ts:unitTypeBody; react-console:acceptance/membership/journeys/configuration/MBR-ACC-0112.json | undocumented |
| `FND-MBR-STR-014` | medium | Changing a program away from affiliation binding does not remove its earlier category list or affiliations. Existing relationships also survive category retirement or disabled affiliation eligibility, leaving transition behavior for Product to settle. | `BR-CAP-MBR-STR-009-09`, `BR-CAP-MBR-STR-001-10`, `CAP-MBR-STR-009` | services-membership:modules/configuration/services/configuration/configuration-records.ts:programResource; react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-CFG-037; react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-STR-046 | undocumented |
| `FND-MBR-STR-015` | low | The recorded acceptance describes different activity checks for staff term creation and Commerce selling, including enrolment-related behavior on inactive programs. Those consumer differences require membership-module follow-up. | `BR-CAP-MBR-STR-011-06`, `BR-CAP-MBR-STR-009-10` | react-console:acceptance/membership/journeys/configuration/MBR-ACC-0113.json; react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0082 | inconsistency |
| `FND-MBR-STR-016` | low | Stored lock flags are not exposed or honored by the examined ordinary structure and configuration operations. | `BR-CAP-MBR-STR-018-10`, `CAP-MBR-STR-018` | services-membership:modules/configuration/services/persistence/configuration-store.ts:configurationStore; react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-CFG-036 | debt |
| `FND-MBR-STR-017` | low | Replacing grants or policy cases reallocates their row identities. Policy case references to types, packages and fee products are not existence-checked, although the package’s policy-set reference is checked. | `BR-CAP-MBR-STR-013-04`, `BR-CAP-MBR-STR-014-01`, `BR-CAP-MBR-STR-014-04` | services-membership:modules/configuration/services/configuration/configuration-records.ts:policySetResource; services-membership:modules/configuration/services/persistence/membership-packages.ts:replacePackageChildren | debt |
| `FND-MBR-STR-018` | low | Package requirements may introduce categories absent from program defaults. Grant configuration also omits target-program activity, owner-kind and exclusivity checks; the intended compatibility contract remains unsettled. | `BR-CAP-MBR-STR-013-06`, `BR-CAP-MBR-STR-013-08` | services-membership:modules/memberships/services/affiliations/unit-rules.ts; react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-CFG-019; react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-CFG-020 | undocumented |
| `FND-MBR-STR-019` | medium | A first purchase immediately after a fixed window closes can use the preceding window. In the documented April example this yields a June ending, demonstrating that the renewal-derived boundary adjustment also affects new members. | `BR-CAP-MBR-STR-015-06`, `CAP-MBR-STR-015`, `OQ-MBR-STR-005` | services-membership:modules/terms/services/term-rules.ts:fixedWindowProbe; react-console:acceptance/membership/journeys/configuration/MBR-ACC-0100.json; react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0087 | defect |
| `FND-MBR-STR-020` | low | The term-calculation commentary still treats the February ending as undecided, although the local acceptance record and test name reproduce Andrew’s choice of the actual last day. | `BR-CAP-MBR-STR-015-08` | services-membership:modules/terms/services/term-rules.ts; services-membership:README.md#2026-10-18 — Final acceptance | inconsistency |
| `FND-MBR-STR-021` | medium | Recorded eligibility behavior and the term engine disagree on absent reinstatement allowances, with legacy unlimited interpretation adding a migration concern. The engine itself treats absence as zero days after the end. | `BR-CAP-MBR-STR-015-04`, `CAP-MBR-STR-012`, `OQ-MBR-STR-006` | services-membership:modules/terms/services/term-rules.ts:startingPoint; react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-CFG-032 | inconsistency |
| `FND-MBR-STR-022` | low | Fixed windows may overlap and the first matching configured window decides the result without an overlap refusal. | `BR-CAP-MBR-STR-015-12` | services-membership:modules/terms/services/term-rules.ts:fixedTermEnd | undocumented |
| `FND-MBR-STR-023` | low | Unknown-reference collections return empty answers, historical placement returns current names and codes, and knowledge-time input bypasses a dedicated instant validator. Consumers need these limits stated explicitly. | `BR-CAP-MBR-STR-005-03`, `BR-CAP-MBR-STR-005-08` | services-membership:modules/structure/aws/api/structure.routes.ts:structureRoutes; services-membership:modules/structure/services/persistence/organizational-units.ts:descendantsAsOf | undocumented |
| `FND-MBR-STR-024` | low | Relocation has no repeat-request key and applies immediately. A repeated successful request becomes a current-parent refusal, and future-effective restructuring remains unavailable. | `BR-CAP-MBR-STR-002-12`, `BR-CAP-MBR-STR-002-13` | services-membership:docs/migrations/structure/README.md#What could not be done as specified, and why | debt |
| `FND-MBR-STR-025` | low | Purge preserves applied seed bookkeeping, preventing the standard relationship purposes from being restored by later provisioning. The recorded development-seed issue also describes failure to converge a unit moved beyond its fixed setup date. | `BR-CAP-MBR-STR-020-09`, `BR-CAP-MBR-STR-020-04` | react-console:acceptance/membership/journeys/structure/MBR-ACC-0028.json; react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0011; react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0009 | defect |
| `FND-MBR-STR-026` | medium | Data-job submission wiring is recorded as incomplete. Structure loads also differ from ordinary placement checks, and supported configuration loads exclude program requirements, action reasons and policy sets. | `BR-CAP-MBR-STR-020-05`, `BR-CAP-MBR-STR-020-06`, `BR-CAP-MBR-STR-020-07`, `CAP-MBR-STR-020` | services-membership:docs/migrations/structure/README.md#What could not be done as specified, and why; services-membership:modules/configuration/services/data-operations/configuration-operations.ts:configurationDataOperations; react-console:acceptance/membership/journeys/structure/MBR-ACC-0029.json | debt |
| `FND-MBR-STR-027` | low | The source record reports missing deployment registration for structure objects and datasets. The blocked acceptance case does not establish a successfully executed query. | `BR-CAP-MBR-STR-005-10` | services-membership:docs/migrations/structure/README.md#What could not be done as specified, and why; react-console:acceptance/membership/journeys/structure/MBR-ACC-0027.json | debt |
| `FND-MBR-STR-028` | low | The Accounting integration record leaves product-type registration and display order incomplete. Membership’s product-write port has an implementation and test double but no module caller. | `BR-CAP-MBR-STR-012-10`, `CAP-MBR-STR-012`, `CAP-MBR-STR-008` | services-membership:docs/migrations/packages-as-products/README.md#Wired on 2026-10-18 against contracts 0.4.1, and what still waits on Accounting; services-membership:modules/structure/tests/integration/services/persistence/accounting-products.integration.spec.ts#the Accounting products port in the database › creates a product Membership owns and answers it as the reads do, at version 1 | debt |
| `FND-MBR-STR-029` | low | The earlier acceptance catalogue is not a reliable description of every pinned behavior. Merge identity transfer, named database refusals and lifecycle admission checks have changed since parts of that inventory were recorded. | `CAP-MBR-STR-003`, `CAP-MBR-STR-004`, `CAP-MBR-STR-018`, `CAP-MBR-STR-020` | react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-STR-021; react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0010; services-membership:modules/structure/services/lifecycle/structure-participant.ts:structureParticipant; services-membership:modules/configuration/services/shared/records.ts:translateDatabaseRefusal | inconsistency |
| `FND-MBR-STR-030` | medium | Acceptance suites are executable through a manual Mocha invocation rather than an ordinary npm test tier. Their recorded earlier run includes failures and blocked cases, so the bindings identify evidence to inspect without asserting a fresh pass. | `JNY-MBR-STR-001`, `JNY-MBR-STR-002`, `JNY-MBR-STR-003`, `JNY-MBR-STR-004` | services-membership:docs/acceptance/README.md#The landed run (2026-10-19); react-console:acceptance/membership/journeys/README.md; react-console:acceptance/membership/journeys/structure/MBR-ACC-0002.json; react-console:acceptance/membership/journeys/structure/MBR-ACC-0005.json; react-console:acceptance/membership/journeys/structure/MBR-ACC-0008.json; react-console:acceptance/membership/journeys/structure/MBR-ACC-0011.json; react-console:acceptance/membership/journeys/structure/MBR-ACC-0017.json; react-console:acceptance/membership/journeys/structure/MBR-ACC-0024.json; react-console:acceptance/membership/journeys/structure/MBR-ACC-0028.json; react-console:acceptance/membership/journeys/structure/MBR-ACC-0036.json; react-console:acceptance/membership/journeys/configuration/MBR-ACC-0087.json; react-console:acceptance/membership/journeys/configuration/MBR-ACC-0090.json; react-console:acceptance/membership/journeys/configuration/MBR-ACC-0094.json; react-console:acceptance/membership/journeys/configuration/MBR-ACC-0095.json; react-console:acceptance/membership/journeys/configuration/MBR-ACC-0096.json; react-console:acceptance/membership/journeys/configuration/MBR-ACC-0098.json; react-console:acceptance/membership/journeys/configuration/MBR-ACC-0100.json; react-console:acceptance/membership/journeys/configuration/MBR-ACC-0102.json; react-console:acceptance/membership/journeys/configuration/MBR-ACC-0103.json; react-console:acceptance/membership/journeys/configuration/MBR-ACC-0105.json; react-console:acceptance/membership/journeys/configuration/MBR-ACC-0114.json; react-console:acceptance/membership/journeys/configuration/MBR-ACC-0109.json (configuration revisions, memberships module) | debt |
| `FND-MBR-STR-031` | low | The catalogue reports overlapping values between workspace and program number sequences. Product must decide whether cross-program uniqueness is required before the memberships module changes numbering. | `BR-CAP-MBR-STR-009-04` | react-console:acceptance/membership/journeys/configuration/MBR-ACC-0094.json; react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0083 | inconsistency |
| `FND-MBR-STR-032` | low | Reason use remains editable while references exist. The recorded cancellation mismatch also uses termination wording, making action explanations inconsistent. | `BR-CAP-MBR-STR-017-05`, `BR-CAP-MBR-STR-017-02` | services-membership:modules/configuration/services/configuration/configuration-records.ts:statusReasonResource; react-console:acceptance/membership/reports/defects/register.json#DEF-MBR-0089 | undocumented |
| `FND-MBR-STR-033` | medium | Some required scenarios have no bound proof of their complete behavior. The existing proposed scenarios describe needed checks, while partial examples and earlier failed or blocked acceptance cases do not establish complete proof. | `BR-CAP-MBR-STR-001-02`, `BR-CAP-MBR-STR-001-03`, `BR-CAP-MBR-STR-001-04`, `BR-CAP-MBR-STR-006-03`, `BR-CAP-MBR-STR-006-04`, `BR-CAP-MBR-STR-008-02`, `BR-CAP-MBR-STR-010-01`, `BR-CAP-MBR-STR-010-02`, `BR-CAP-MBR-STR-010-03`, `BR-CAP-MBR-STR-013-01`, `BR-CAP-MBR-STR-013-03`, `BR-CAP-MBR-STR-017-01`, `BR-CAP-MBR-STR-017-02`, `BR-CAP-MBR-STR-020-05` | services-membership:modules/structure/tests/; services-membership:modules/terms/tests/; services-membership:tests/e2e/; react-console:acceptance/membership/journeys/README.md | debt |

| `FND-MBR-STR-034` | low | The drafting brief named in the job is absent from the starting documentation commit. Its instructions cannot be independently compared with the draft in this examination. | `MOD-MBR-STR` | rhythm-v2-docs:c68c3c414ae5c67f76361d4b9b478875c0027f39:briefs/planning/membership-structure.brief.md (absent) | undocumented |
| `FND-MBR-STR-035` | medium | Bound tests provide specific examples rather than universal proof of compound statements. Manual acceptance suites and earlier execution reports need to be assessed separately from coverage bindings. | `MOD-MBR-STR` | services-membership:docs/acceptance/README.md#What `tests/acceptance` is | debt |
| `FND-MBR-STR-036` | medium | Additional refusal, calculation and cross-record-write rules now require proof. Cases without a scenario are listed in the affected-rule ledger; existing scenarios without bindings also remain open proof work. | `BR-CAP-MBR-STR-015-09`, `BR-CAP-MBR-STR-020-10`, `BR-CAP-MBR-STR-015-13`, `BR-CAP-MBR-STR-012-11`, `BR-CAP-MBR-STR-009-12`, `BR-CAP-MBR-STR-001-09`, `BR-CAP-MBR-STR-001-10`, `BR-CAP-MBR-STR-002-12`, `BR-CAP-MBR-STR-004-02`, `BR-CAP-MBR-STR-005-03`, `BR-CAP-MBR-STR-005-04`, `BR-CAP-MBR-STR-005-05`, `BR-CAP-MBR-STR-005-07`, `BR-CAP-MBR-STR-006-05`, `BR-CAP-MBR-STR-006-08`, `BR-CAP-MBR-STR-007-07`, `BR-CAP-MBR-STR-009-06`, `BR-CAP-MBR-STR-009-11`, `BR-CAP-MBR-STR-011-04`, `BR-CAP-MBR-STR-011-06`, `BR-CAP-MBR-STR-012-09`, `BR-CAP-MBR-STR-012-10`, `BR-CAP-MBR-STR-013-04`, `BR-CAP-MBR-STR-013-07`, `BR-CAP-MBR-STR-016-12`, `BR-CAP-MBR-STR-017-04`, `BR-CAP-MBR-STR-017-06`, `BR-CAP-MBR-STR-018-08`, `BR-CAP-MBR-STR-019-07`, `BR-CAP-MBR-STR-020-07`, `BR-CAP-MBR-STR-020-09` | services-membership:modules/structure/services/paging.ts:decodeCursor; services-membership:modules/terms/services/status.ts:continuousSinceOf; services-membership:modules/configuration/services/persistence/membership-packages.ts:listMembershipPackages | debt |
| `FND-MBR-STR-037` | medium | Only submitted grants receive the own-program check. Changing a package’s program while retaining grants can leave an own-program grant without revalidation, requiring a regression case and a settled compatibility policy. | `CAP-MBR-STR-013` | services-membership:modules/configuration/services/configuration/configuration-records.ts:packageResource | defect |
| `FND-MBR-STR-038` | medium | The registered source scope excludes migration SQL and the external decision register. Declarations, local migration records and integration assertions support the planning description, while complete deployed-trigger and external-decision certification remain outside this pass. | `MOD-MBR-STR`, `CAP-MBR-STR-009` | services-membership:README.md; services-membership:modules/structure/db/organizational-units.table.ts; specs/PRODUCT-AREAS.md#MOD-MBR-STR | undocumented |
| `FND-MBR-STR-039` | low | The Platform standards and architecture proposals this design must name (the Submissions publication standard, the custom-field standard, the membership architecture chapters, indexing and record history) are not readable in this job. The design cites them through the decisions and records reproduced in the Membership repository and the landed corpus. | `SVC-MBR-STR-structure`, `SVC-MBR-STR-configuration`, `SVC-MBR-STR-terms`, `ADR-MBR-STR-010` | services-platform:docs/standards/submission-compatible-operations.md (not readable in this job); services-membership:AGENTS.md#Custom Fields Are Opt-In Per Entity: R2-ARCH-001 (Andrew, 2026-10-19) | undocumented |
| `FND-MBR-STR-040` | medium | Setting up an offering saves the Accounting product and the Membership extension in two separate transactions with no compensation and no orphan detection. A refused package or dues extension leaves a product that grants no membership; deleting a package leaves its product; a package change does not recheck its product. The products port is wired, but no caller composes an atomic product-and-extension save. | `WF-MBR-STR-004`, `ADR-MBR-STR-006`, `CAP-MBR-STR-012`, `OQ-MBR-STR-009` | services-membership:modules/structure/ports/accounting-products.ts; services-membership:modules/configuration/services/configuration/configuration-records.ts:packageResource; services-membership:docs/migrations/packages-as-products/README.md#What could not be done here | debt |
| `FND-MBR-STR-041` | low | The reparent business event has no registered subscriber, so the dispatcher discards it on claim. Unit creation, deactivation, deletion and the merge itself are telemetry only, and the list of what a merge left behind exists only in that request's answer. | `WF-MBR-STR-001`, `WF-MBR-STR-002`, `ADR-MBR-STR-013`, `OQ-MBR-STR-010` | services-membership:aws/membership.change-events.ts:businessEventHandlersOf; services-membership:modules/events/services/handlers/committees-membership-events.ts; services-membership:modules/structure/services/tree/tree-edits.ts:mergeUnit | undocumented |
| `FND-MBR-STR-042` | low | The structure and configuration services call the memberships module's persistence in-process: the merge's affiliation step, the deletion's affiliation count and the requirement replacement's in-use check. The coupling is deliberate inside one transaction but makes this module's correctness depend on code it does not own. | `ADR-MBR-STR-001`, `WF-MBR-STR-002`, `WF-MBR-STR-003`, `WF-MBR-STR-005` | services-membership:modules/structure/services/tree/tree-edits.ts; services-membership:modules/configuration/services/configuration/configuration-records.ts:replaceProgramUnitTypesOf | debt |
| `FND-MBR-STR-043` | low | Structure records keep history in their own trigger-written version tables, while configuration records keep it as record revisions written by the memberships module's history streams. Two mechanisms answer the same question for one setup. | `DOM-MBR-STR-006`, `SVC-MBR-STR-configuration`, `SVC-MBR-STR-structure` | services-membership:aws/membership.change-events.ts; services-membership:modules/structure/services/lifecycle/structure-participant.ts | inconsistency |
| `FND-MBR-STR-044` | low | Replacing a program's affiliation requirements checks that no live affiliation uses a dropped unit kind without locking those affiliations, so a membership operation committing at the same moment can add one the check does not see. | `WF-MBR-STR-005`, `INV-DOM-MBR-STR-003-05`, `CAP-MBR-STR-010` | services-membership:modules/configuration/services/configuration/configuration-records.ts:replaceProgramUnitTypesOf | defect |
| `FND-MBR-STR-045` | low | The module performs no inference, but its charter does not say so in the one sentence the conventions require of a module with no Inference Operations. This is a planning correction for the charter. | `MOD-MBR-STR` | rhythm-v2-docs:specs/CONVENTIONS.md#9.8 Inference Operation (IOP); services-membership:modules/structure, modules/configuration, modules/terms (no model call) | undocumented |
| `FND-MBR-STR-046` | medium | No console or portal screen in scope administers this module's records, so no Screen Contract can be written. Future structure and configuration screens need Andrew's direction and a v0 design under the UI change approval rule. | `MOD-MBR-STR`, `FND-MBR-STR-002`, `OQ-MBR-STR-008` | react-console:app/(console)/console/[tenantId]/membership/members/page.tsx; react-console:components/membership/settings/membership-settings-page.tsx; react-console:components/console/nav-config.ts:config-app-membership | undocumented |
| `FND-MBR-STR-047` | low | A unit-kind replacement restores omitted fields to their defaults, and the default availability is active, so a replacement that omits availability silently reopens a retired kind. | `STATE-MBR-STR-002`, `ADR-MBR-STR-012`, `BR-CAP-MBR-STR-001-06` | services-membership:modules/structure/services/persistence/organizational-unit-types.ts:rowValues | defect |
| `FND-MBR-STR-048` | medium | Bulk unit loads leave the ancestry and depths stale from the first loaded unit until the producer runs the closing rebuild; nothing runs it automatically, so a failed or abandoned load leaves visibility and descendant reads working from the earlier tree until someone rebuilds. | `WF-MBR-STR-008`, `ADR-MBR-STR-016`, `FND-MBR-STR-026` | services-membership:modules/structure/services/tree/tree-loads.ts:rebuildTreeAfterLoad; services-membership:modules/data-jobs/services/operations/structure-data-operations.ts | debt |

| `FND-MBR-STR-049` | low | The requested design brief is absent from the starting corpus and fetched master. This examination uses the supplied job instructions and existing planning artifacts; the original draft brief cannot be independently checked. | `MOD-MBR-STR` | rhythm-v2-docs:briefs/design/membership-structure.brief.md (absent at starting commit and fetched origin/master) | undocumented |
| `FND-MBR-STR-050` | medium | Staff termination cancels a term not yet started and accepts an active termination reason when cancellation-reason validation fails. Commerce cancellation only looks up an optional reason: it does not require availability or matching use, and a missing reason remains empty. The planning rule requires a reason matching the action, so Product must reconcile both exceptions rather than silently broaden the rule. | `INV-DOM-MBR-STR-005-08`, `STATE-MBR-STR-004`, `BR-CAP-MBR-STR-017-02` | services-membership:modules/memberships/services/operations/staff-operations.ts:terminateTerm; services-membership:modules/commerce-participant/services/cancellation/cancellation.ts:cancel | inconsistency |
| `FND-MBR-STR-051` | medium | The examined call sites and registries do not establish telemetry exception behavior, event retry bounds, schedule redelivery, Platform lifecycle transport or whole-run serialization, or receiver-side appointment effects. These guarantees remain unknown; local transactions and enabled-handler conditions are described separately. | `WF-MBR-STR-001`, `WF-MBR-STR-002`, `WF-MBR-STR-006`, `WF-MBR-STR-007` | services-membership:modules/structure/services/tree/tree-edits.ts; services-membership:aws/membership.change-events.ts; services-membership:modules/memberships/services/sweep/status-sweep-schedule.ts; services-membership:modules/structure/services/lifecycle/structure-participant.ts; services-membership:modules/events/services/handlers/committees-membership-events.ts | undocumented |
| `FND-MBR-STR-052` | medium | The job describes the planning layer as approved, but the pinned charter, features, concepts, capabilities and journeys still declare draft status. Specific recorded decisions support confirmed design intent; this examination cannot infer approval of the remaining planning layer or authorize implementation preparation. | `MOD-MBR-STR` | rhythm-v2-docs:specs/membership/structure/MODULE.md; rhythm-v2-docs:specs/membership/structure/planning | inconsistency |

| `FND-MBR-STR-053` | low | Each module declares an additional framework health route, but the design catalogs cover only the explicit business operations and internal interfaces. The shared builder’s generated operation identifiers and access declaration are not established by the permitted source files; those three operational routes remain outside contract coverage. | `SVC-MBR-STR-structure`, `SVC-MBR-STR-configuration`, `SVC-MBR-STR-terms` | services-membership:modules/structure/aws/api/structure.routes.ts:structureRoutes; services-membership:modules/configuration/aws/api/configuration.routes.ts:configurationModuleRoutes; services-membership:aws/terms/terms.routes.ts:termsRoutes | undocumented |

| `FND-MBR-STR-054` | medium | Define unit kinds and their permitted places: dedicated coverage remains missing for boundary, invariant. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed. | `ATS-MBR-STR-001`, `CAP-MBR-STR-001` | services-membership:modules/structure/services/persistence/organizational-unit-types.ts:createOrganizationalUnitType; services-membership:modules/structure/services/persistence/organizational-unit-types.ts:parentIdsOf; services-membership:modules/structure/services/persistence/organizational-unit-types.ts:requireKnownTypes; services-membership:modules/structure/services/persistence/organizational-unit-types.ts:createOrganizationalUnitType; services-membership:modules/structure/services/persistence/organizational-unit-types.ts:updateOrganizationalUnitType; services-membership:modules/structure/services/persistence/organizational-unit-types.ts:updateOrganizationalUnitType; services-membership:modules/structure/services/tree/tree-edits.ts:validatePlacement; services-membership:tests/e2e/structure-api.e2e.spec.ts#the structure API, end to end in process › refuses to delete a unit type in use, 409 unit_type_in_use; services-membership:modules/structure/services/persistence/organizational-unit-types.ts:listOrganizationalUnitTypes; services-membership:modules/structure/services/persistence/organizational-unit-types.ts:updateOrganizationalUnitType; services-membership:modules/structure/aws/api/structure-requests.ts:unitTypeBody; STATE-MBR-STR-002 | coverage-gap |
| `FND-MBR-STR-055` | medium | Restructure units while preserving dated placement: dedicated coverage remains missing for transition, failure. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed. | `ATS-MBR-STR-002`, `CAP-MBR-STR-002` | services-membership:tests/e2e/structure-api.e2e.spec.ts#the structure API, end to end in process › refuses a parent of a type not allowed, 409 parent_type_not_allowed; services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the refusals › refuses a move under the unit’s own descendant as a cycle; services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the refusals › refuses a new child under an inactive unit; services-membership:modules/structure/services/tree/tree-edits.ts:moveUnit; services-membership:modules/structure/tests/unit/services/tree-edits.spec.ts#the tree edits › move › refuses a move that would put the subtree at the depth cap, before any write; services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the parent history and the as-of tree › refuses a move dated before the current parent began; services-membership:modules/structure/services/persistence/organizational-units.ts:recordParentChange; services-membership:modules/structure/services/persistence/organizational-units.ts:recordParentChange; services-membership:modules/structure/tests/unit/services/tree-edits.spec.ts#the tree edits › move › locks, validates against the current closure, changes the parent, records history, rebuilds, updates depths and checks the cap, in that order; services-membership:modules/structure/services/tree/tree-edits.ts:moveUnit; services-membership:modules/structure/tests/unit/services/tree-edits.spec.ts#the tree edits › move › states membership.unit.reparented with the old and the new parent and the business date; services-membership:docs/migrations/structure/README.md#What could not be done as specified, and why; services-membership:docs/migrations/structure/README.md#The move sequence as implemented; services-membership:tests/e2e/s09-restructuring.e2e.spec.ts#scenario 9: organizational restructuring › rewrites no affiliation: Jo’s row is the same row, version and unit | coverage-gap |
| `FND-MBR-STR-056` | medium | Combine units and continue their memberships: dedicated coverage remains missing for boundary, concurrency, invariant. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed. | `ATS-MBR-STR-003`, `CAP-MBR-STR-003` | services-membership:modules/structure/tests/unit/services/tree-edits.spec.ts#the tree edits › merge › refuses a survivor below the merged unit; services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › merge › moves the children under the survivor, marks the unit merged and lists what it left; services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › merge › moves the children under the survivor, marks the unit merged and lists what it left; services-membership:docs/migrations/unit-merge/README.md#The behaviour; services-membership:modules/structure/tests/integration/services/tree/unit-merge.integration.spec.ts#the tree edits affiliations bind › a merge an affiliation cannot follow › is refused 409 affiliations_not_movable, naming the membership and unit_minimum; services-membership:modules/memberships/tests/integration/services/identity-unit-merge.integration.spec.ts#a unit merge moves the identity of identity-bound memberships › the merge of Macon into Atlanta › makes Atlanta the identity of Kim’s membership, at the next version; services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › merge › moves the children under the survivor, marks the unit merged and lists what it left; services-membership:modules/structure/services/tree/tree-edits.ts:mergeUnit; services-membership:modules/structure/services/persistence/organizational-units.ts:updateOrganizationalUnit; services-membership:modules/structure/services/tree/tree-edits.ts:mergeUnit; services-membership:modules/structure/tests/unit/services/tree-edits.spec.ts#the tree edits › merge › states membership.unit.reparented for each child that moved under the survivor, naming the merged unit; services-membership:modules/structure/services/tree/tree-edits.ts:mergeUnit; STATE-MBR-STR-001 | coverage-gap |
| `FND-MBR-STR-057` | medium | Close units or remove units without retained dependencies: dedicated coverage remains missing for rule, failure, boundary, concurrency. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed. | `ATS-MBR-STR-004`, `CAP-MBR-STR-004` | services-membership:modules/structure/tests/integration/services/tree/unit-merge.integration.spec.ts#the tree edits affiliations bind › delete and deactivate › deactivates it instead; services-membership:modules/structure/services/tree/tree-edits.ts:deactivateUnit; services-membership:modules/structure/aws/api/structure-requests.ts:unitReplaceBody; services-membership:modules/structure/tests/integration/services/tree/unit-merge.integration.spec.ts#the tree edits affiliations bind › delete and deactivate › refuses to delete a unit a closed affiliation names, 409 unit_has_affiliations with the count; services-membership:tests/e2e/structure-api.e2e.spec.ts#the structure API, end to end in process › refuses to delete a unit in use, 409 unit_in_use; services-membership:tests/e2e/database-refusals.e2e.spec.ts#mistakes only the database catches, through the API › DEF-MBR-0084: a structure delete a program’s reference blocks › refuses deleting a unit a program is owned by 409 unit_in_use, and keeps it; services-membership:modules/structure/tests/unit/services/tree-edits.spec.ts#the tree edits › delete › deletes a unit no affiliation and nothing else names; STATE-MBR-STR-001 | coverage-gap |
| `FND-MBR-STR-058` | medium | Find units and inspect current or historical structure: dedicated coverage remains missing for edge, failure, concurrency, invariant. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed. | `ATS-MBR-STR-005`, `CAP-MBR-STR-005` | services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the closure › answers the descendants of a unit from the closure, nearest first; services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the parent history and the as-of tree › answers the descendants as of 2027-06-30 equal to the tree recorded that day; services-membership:modules/structure/services/persistence/organizational-units.ts:descendantsAsOf; services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the closure › pages the tree breadth first with each unit’s parent; services-membership:modules/structure/services/persistence/organizational-units.ts:listOrganizationalUnits; services-membership:modules/structure/aws/api/structure.routes.ts:structureRoutes; services-membership:modules/structure/services/persistence/organizational-units.ts:listParentHistory; services-membership:modules/structure/aws/api/structure.routes.ts:structureRoutes; services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the published functions › answers nothing of a tenant other than the reader’s own; services-membership:tests/unit/metadata-registration.spec.ts#Membership’s registration manifests › reads the units’ dataset under membership.structure.read, with custom field values and the ancestors over the closure; services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › row-level security › reads nothing of another tenant’s unit by id | coverage-gap |
| `FND-MBR-STR-059` | medium | Maintain a unit’s identity and local details: dedicated coverage remains missing for failure. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed. | `ATS-MBR-STR-006`, `CAP-MBR-STR-006` | services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the refusals › refuses a code the tenant already has; services-membership:modules/structure/services/persistence/organizational-units.ts:updateOrganizationalUnit; services-membership:modules/structure/services/persistence/organizational-units.ts:attributeValues; services-membership:modules/structure/db/organizational-units.table.ts:organizational_units_latitude_check; services-membership:docs/migrations/structure/README.md#Tables and migrations; services-membership:modules/structure/services/persistence/organizational-units.ts:insertOrganizationalUnit; services-membership:modules/structure/services/persistence/organizational-units.ts:updateOrganizationalUnit; services-membership:modules/structure/services/persistence/organizational-units.ts:getOrganizationalUnit; services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › the versions › writes a version of the unit for its creation, its update and its move, each with the actor of its context; services-membership:modules/structure/metadata/structure.objects.ts:organizationalUnitsObject | coverage-gap |
| `FND-MBR-STR-060` | medium | Describe a unit’s dated relationships with organizations: dedicated coverage remains missing for failure, boundary, concurrency. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed. | `ATS-MBR-STR-007`, `CAP-MBR-STR-007` | services-membership:modules/structure/services/persistence/organizational-unit-organizations.ts:linkOrganization; services-membership:modules/structure/services/persistence/organizational-unit-organizations.ts:requireDates; services-membership:tests/e2e/structure-api.e2e.spec.ts#the structure API, end to end in process › refuses a second open legal entity, 409 legal_entity_already_open; services-membership:modules/structure/services/persistence/organizational-unit-organizations.ts:unlinkOrganization; services-membership:modules/structure/aws/api/structure-requests.ts:linkBody; services-membership:tests/e2e/structure-api.e2e.spec.ts#the structure API, end to end in process › creates a relationship type with an id derived from its name; services-membership:modules/structure/services/persistence/organizational-unit-relationship-types.ts:createOrganizationalUnitRelationshipType; services-membership:modules/structure/services/persistence/organizational-unit-organizations.ts:linkOrganization; services-membership:docs/migrations/structure/README.md#Tables and migrations; react-console:acceptance/membership/journeys/structure/MBR-ACC-0017.json; STATE-MBR-STR-003 | coverage-gap |
| `FND-MBR-STR-061` | medium | Connect unit dues to products and settlement choices: dedicated coverage remains missing for failure, boundary. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed. | `ATS-MBR-STR-008`, `CAP-MBR-STR-008` | services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › extends a product of type chapter_dues as a unit’s dues product, under the product’s id, with the product’s name; services-membership:modules/structure/services/persistence/organizational-unit-dues-products.ts:createDuesProduct; services-membership:modules/structure/tests/unit/accounting-products.spec.ts#the Accounting products port › answers a product Accounting no longer has as its id, inactive, hidden, with no product status; services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › re-points a unit’s dues product at another package at the version just read, 200 with the next version; services-membership:modules/structure/services/persistence/organizational-unit-dues-products.ts:createDuesProduct; services-membership:modules/structure/services/persistence/organizational-unit-financial-settings.ts:setFinancialSettings; 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); services-membership:modules/structure/services/finance/accounting-references.ts:checkAccountingReferenceShapes; services-membership:modules/structure/services/persistence/organizational-unit-dues-products.ts:createDuesProduct | coverage-gap |
| `FND-MBR-STR-062` | medium | Establish programs and their membership context: dedicated coverage remains missing for transition, edge, failure, concurrency, invariant. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed. | `ATS-MBR-STR-009`, `CAP-MBR-STR-009` | 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; services-membership:modules/configuration/services/configuration/configuration-records.ts:programResource; services-membership:modules/configuration/db/programs.table.ts:programs; services-membership:modules/configuration/db/configuration-vocabularies.ts:NUMBER_SCOPES; 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; 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; 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; services-membership:modules/configuration/services/configuration/configuration-records.ts:programContent; services-membership:modules/configuration/services/configuration/configuration-records.ts:programResource; react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-CFG-028; services-membership:modules/configuration/services/persistence/configuration-store.ts:configurationStore; 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); STATE-MBR-STR-006 | coverage-gap |
| `FND-MBR-STR-063` | medium | Set a program’s affiliation requirements: dedicated coverage remains missing for rule, edge, failure, boundary, invariant. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed. | `ATS-MBR-STR-010`, `CAP-MBR-STR-010` | services-membership:modules/configuration/services/configuration/configuration-records.ts:replaceProgramUnitTypesOf; services-membership:modules/configuration/services/configuration/configuration-records.ts:replaceProgramUnitTypesOf; services-membership:modules/configuration/services/configuration/configuration-records.ts:unitTypeProblems; services-membership:modules/configuration/services/configuration/configuration-records.ts:replaceProgramUnitTypesOf; services-membership:modules/configuration/services/configuration/configuration-records.ts:programUnitTypesContent; react-console:acceptance/membership/journeys/configuration/MBR-ACC-0096.json | coverage-gap |
| `FND-MBR-STR-064` | medium | Classify memberships and configure organization flow-down: dedicated coverage remains missing for rule, edge, failure, concurrency. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed. | `ATS-MBR-STR-011`, `CAP-MBR-STR-011` | 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 moving a type a package names to another program 400 naming program_id, and leaves it where it was; services-membership:modules/configuration/db/membership-types.table.ts:membershipTypes; 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 flow-down enabled without a target type 400 naming flowdown_type_id, and writes no type; services-membership:modules/configuration/services/persistence/membership-types.ts:replaceFlowdownLists; services-membership:modules/configuration/services/configuration/configuration-records.ts:typeContent; react-console:acceptance/membership/journeys/configuration/MBR-ACC-0113.json; STATE-MBR-STR-006 | coverage-gap |
| `FND-MBR-STR-065` | medium | Offer membership through an Accounting product: dedicated coverage remains missing for rule, failure, concurrency. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed. | `ATS-MBR-STR-012`, `CAP-MBR-STR-012` | services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › refuses a package whose product Accounting does not have, 400; services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › refuses the common fields a package no longer carries of its own (they are the product’s); services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › lists packages with the product’s fields and filters is_active by the product’s status; services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › refuses a second extension of the same product: the package id is the product id; 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 package of a type of another program 400 naming membership_type_id, and writes no package nor unit rule; 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 package renewing into itself 400 naming renews_into_package_id; services-membership:tests/acceptance/configuration/MBR-ACC-0115.acceptance.ts#MBR-ACC-0115: The renewal window and the reinstatement period decide what a member may buy, read live from the package: narrowing the window shuts an open renewal, widening the reinstatement period turns a rejoin back into a reinstatement, a blank period means no reinstatement at all, and the default renewal package is the one the configuration names; 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 change policy set that does not exist 400 naming change_policy_set_id; services-membership:modules/configuration/services/persistence/configuration-store.ts:configurationStore; services-membership:modules/structure/ports/accounting-products.ts:accountingProductsFromTables; services-membership:modules/configuration/services/persistence/membership-packages.ts:listMembershipPackages; STATE-MBR-STR-006 | coverage-gap |
| `FND-MBR-STR-066` | medium | Bundle grants and package-specific unit requirements: dedicated coverage remains missing for rule, failure, concurrency, invariant. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed. | `ATS-MBR-STR-013`, `CAP-MBR-STR-013` | services-membership:modules/configuration/services/configuration/configuration-records.ts:packageResource; 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 grant whose type is not of the granted program 400 naming grants: membership_type_id, and writes no package; services-membership:modules/configuration/services/configuration/configuration-records.ts:packageResource; services-membership:modules/configuration/services/persistence/membership-packages.ts:replacePackageChildren; services-membership:modules/configuration/services/configuration/configuration-records.ts:unitRuleProblems; services-membership:modules/memberships/services/affiliations/unit-rules.ts; services-membership:modules/configuration/services/configuration/configuration-records.ts:packageResource; react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-CFG-019 | coverage-gap |
| `FND-MBR-STR-067` | medium | Record policies for future package changes: dedicated coverage remains missing for rule, transition, edge, failure, concurrency, invariant. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed. | `ATS-MBR-STR-014`, `CAP-MBR-STR-014` | services-membership:modules/configuration/services/configuration/configuration-records.ts:policySetResource; services-membership:modules/configuration/db/change-policies.table.ts:changePolicies; services-membership:modules/configuration/services/configuration/configuration-records.ts:policyContent; services-membership:modules/configuration/services/configuration/configuration-records.ts:policyContent; services-membership:docs/migrations/membership-core/README.md#Tables and migrations; STATE-MBR-STR-006 | coverage-gap |
| `FND-MBR-STR-068` | medium | Determine a term’s start and end dates: dedicated coverage remains missing for transition, edge, failure, concurrency. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed. | `ATS-MBR-STR-015`, `CAP-MBR-STR-015`, `BR-CAP-MBR-STR-015-09`, `BR-CAP-MBR-STR-015-13` | services-membership:modules/terms/tests/unit/term-rules.spec.ts#term rules: what 2.0 decides › reports every problem of a rule at once; services-membership:modules/configuration/services/configuration/configuration-records.ts:packageResource; services-membership:modules/terms/tests/unit/term-rules.spec.ts#term rules: the rules of 1.0 beyond its spec cases › extends an early renewal from the current end, whatever the basis; services-membership:modules/terms/services/term-rules.ts:startingPoint; services-membership:modules/terms/tests/unit/term-rules.spec.ts#term rules: 1.0 calculate-expiration-date.spec.js › 1.0 lines 284-292: anniversary in years, should calculate properly for a single year › ends a purchase of 2019-04-03 at the end of the anniversary month, 2020-04-30; services-membership:modules/terms/services/term-rules.ts:fixedWindowProbe; services-membership:modules/terms/tests/unit/term-rules.spec.ts#term rules: 1.0 calculate-expiration-date.spec.js › 1.0 lines 70-77: calendar, a standard year, should calculate properly for April › back-dates a purchase of 2019-04-03 to 2019-01-01 and ends it 2019-12-31; services-membership:modules/terms/tests/unit/term-rules.spec.ts#term rules: what 2.0 decides › ends a calendar period ending in February on its last day in a leap year: 2024-02-29 (decided by Andrew 2026-10-18: the real last day of the month; 1.0 added a year with Moment and ended it 2024-02-28); services-membership:modules/terms/tests/unit/term-rules.spec.ts#term rules: 1.0 calculate-expiration-date.spec.js › 1.0 lines 248-255: no expiration, should calculate properly › starts on 2019-04-03 and never ends; services-membership:modules/terms/tests/unit/term-rules.spec.ts#term rules: what 2.0 decides › gives the same result twice for the same frozen inputs (1.0 turned the fixed dates into Moments in place, so a second call read other inputs); services-membership:modules/terms/tests/unit/isolation.spec.ts#term engine isolation › imports nothing of the repository outside modules/terms; services-membership:modules/terms/services/term-rules.ts:fixedTermEnd; services-membership:modules/terms/services/term-rules.ts:fixedTermEnd; STATE-MBR-STR-004 | coverage-gap |
| `FND-MBR-STR-069` | medium | Interpret membership status and continuity by date: dedicated coverage remains missing for validation, edge, concurrency. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed. | `ATS-MBR-STR-016`, `CAP-MBR-STR-016` | 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; STATE-MBR-STR-004; STATE-MBR-STR-005 | coverage-gap |
| `FND-MBR-STR-070` | medium | Maintain reasons for membership status actions: dedicated coverage remains missing for transition, edge, failure, boundary, concurrency, invariant. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed. | `ATS-MBR-STR-017`, `CAP-MBR-STR-017` | services-membership:modules/configuration/services/configuration/configuration-records.ts:statusReasonContent; services-membership:modules/configuration/services/persistence/membership-status-reasons.ts:requireStatusReason; react-console:acceptance/membership/inventory/business-rules.json#RUL-MBR-CFG-022; services-membership:modules/configuration/services/persistence/configuration-store.ts:configurationStore; services-membership:modules/configuration/services/configuration/configuration-records.ts:statusReasonResource; services-membership:modules/configuration/aws/api/configuration.routes.ts:configurationModuleRoutes; STATE-MBR-STR-006 | coverage-gap |
| `FND-MBR-STR-071` | medium | Maintain configuration with consistent change safeguards: dedicated coverage remains missing for edge. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed. | `ATS-MBR-STR-018`, `CAP-MBR-STR-018` | services-membership:modules/configuration/services/configuration/configuration-records.ts:createConfiguration; services-membership:modules/configuration/services/configuration/configuration-records.ts:updateConfiguration; services-membership:modules/configuration/services/persistence/configuration-store.ts:configurationStore; services-membership:modules/configuration/services/configuration/configuration-records.ts:updateConfiguration; services-membership:modules/configuration/services/persistence/configuration-store.ts:configurationStore; services-membership:modules/configuration/services/configuration/configuration-records.ts:createConfiguration; 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 type of a program that does not exist 400 naming program_id; services-membership:modules/configuration/services/persistence/membership-packages.ts:listMembershipPackages; services-membership:aws/api/route-inputs.ts:found; services-membership:modules/configuration/services/persistence/configuration-store.ts:configurationStore; react-console:acceptance/membership/journeys/configuration/MBR-ACC-0122.json; STATE-MBR-STR-006 | coverage-gap |
| `FND-MBR-STR-072` | medium | Authorize structure and configuration work: dedicated coverage remains missing for rule, validation, edge, failure, concurrency, invariant. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed. | `ATS-MBR-STR-019`, `CAP-MBR-STR-019` | 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:aws/membership.service.ts:STRUCTURE_PERMISSIONS; 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; services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts#organizational units in the database › row-level security › shows another tenant none of the units; services-membership:tests/unit/route-authorization.spec.ts#route authorization: every Membership operation names its permission › is allowed or evaluates only keys the published catalog defines; react-console:lib/authz/permissions.ts:82 | coverage-gap |
| `FND-MBR-STR-073` | medium | Provision, migrate and remove membership setup: dedicated coverage remains missing for rule, validation, permission, concurrency, invariant. Existing examples do not certify every declared permission, lifecycle transition or compound rule; unbound scenarios remain proposed. | `ATS-MBR-STR-020`, `CAP-MBR-STR-020` | services-membership:modules/structure/tests/integration/services/lifecycle/structure-participant.integration.spec.ts#the structure participant in the database › seeds the four relationship types at provisioning; services-membership:modules/structure/tests/integration/services/lifecycle/structure-participant.integration.spec.ts#the structure participant in the database › refuses to purge a tenant Platform is not deleting, before any row is removed; services-membership:modules/structure/tests/integration/services/lifecycle/structure-participant.integration.spec.ts#the structure participant in the database › resets the tree of a tenant being reset and keeps its unit and relationship types; services-membership:modules/structure/services/well-known/well-known-structure.ts; services-membership:docs/migrations/structure/README.md#Routes, permissions, metadata, data operations, lifecycle, well-known objects; services-membership:modules/configuration/services/data-operations/configuration-operations.ts:configurationDataOperations; services-membership:modules/configuration/services/data-operations/configuration-operations.ts:configurationDataOperations; services-membership:modules/structure/services/lifecycle/structure-participant.ts:structureParticipant; react-console:acceptance/membership/journeys/structure/MBR-ACC-0028.json; services-membership:modules/structure/services/tree/tree-loads.ts:loadUnit | coverage-gap |
| `FND-MBR-STR-074` | medium | Two inherited unit-detail proof links identify neighboring rules rather than the behavior their scenarios exercise. Replacement-default proof now links to versioned replacement and attributed-history proof now links to retained history; welcome selection and detailed custom-value reads need their own scenarios. | `ATS-MBR-STR-006`, `BR-CAP-MBR-STR-006-05`, `BR-CAP-MBR-STR-006-07`, `BR-CAP-MBR-STR-006-08`, `BR-CAP-MBR-STR-006-09` | services-membership:tests/acceptance/structure/MBR-ACC-0007.acceptance.ts; services-membership:modules/structure/tests/integration/services/persistence/organizational-units.integration.spec.ts | inconsistency |
| `FND-MBR-STR-075` | medium | The permitted console acceptance corpus contains journey definitions rather than executable Playwright suites, and the hosted Membership routes provide no structure administration workflow. Browser acceptance for this module therefore has no executable registration. | `MOD-MBR-STR`, `FAS-MBR-STR-01`, `FAS-MBR-STR-02`, `FAS-MBR-STR-03`, `FAS-MBR-STR-04`, `FAS-MBR-STR-05`, `FAS-MBR-STR-06` | react-console:acceptance/membership/journeys/README.md; react-console:app/(console)/console/[tenantId]/membership; specs/membership/structure/MODULE.md | coverage-gap |
| `FND-MBR-STR-076` | medium | Registered executable programs and scenario specifications have different boundaries. Some suites have no verified scenario binding, some inherited bindings cover only examples of compound behavior, and newly proposed feature and interaction cases still require complete executable proof; manual acceptance programs also need explicit invocation outside the ordinary npm test tiers. | `MOD-MBR-STR`, `FAS-MBR-STR-01`, `FAS-MBR-STR-02`, `FAS-MBR-STR-03`, `FAS-MBR-STR-04`, `FAS-MBR-STR-05`, `FAS-MBR-STR-06`, `TST-MBR-STR-005`, `TST-MBR-STR-020`, `TST-MBR-STR-027`, `TST-MBR-STR-030`, `TST-MBR-STR-033`, `TST-MBR-STR-034`, `TST-MBR-STR-035`, `TST-MBR-STR-036`, `TST-MBR-STR-038`, `TST-MBR-STR-040`, `TST-MBR-STR-042`, `TST-MBR-STR-043`, `TST-MBR-STR-045`, `TST-MBR-STR-048`, `TST-MBR-STR-049`, `TST-MBR-STR-050`, `TST-MBR-STR-051`, `TST-MBR-STR-052`, `TST-MBR-STR-054`, `TST-MBR-STR-058`, `TST-MBR-STR-059`, `TST-MBR-STR-061`, `TST-MBR-STR-064`, `TST-MBR-STR-065`, `TST-MBR-STR-067`, `TST-MBR-STR-070`, `TST-MBR-STR-076`, `TST-MBR-STR-083`, `TST-MBR-STR-086`, `TST-MBR-STR-093`, `TST-MBR-STR-102` | services-membership:package.json#scripts; services-membership:tests/acceptance/configuration/support/journey.ts; services-membership:tests/acceptance/structure/support/journey.ts | coverage-gap |

## Open Questions

| id | question | why_it_matters | options | recommendation | affects |
|---|---|---|---|---|---|
| `OQ-MBR-STR-001` | How should a merged source appear in current structure? | Its members continue under the survivor while the source retains its earlier placement, creating two different views of completion. | A: close parentage and omit the source after combination. B: retain its existing placement. C: place the historical source beneath the survivor. | The product should select A so post-combination structural views reflect the surviving operation. | `CAP-MBR-STR-003`, `CAP-MBR-STR-005`, `FND-MBR-STR-005` |
| `OQ-MBR-STR-002` | Can an inactive unit reopen under its existing identity? | Recreating a reopened chapter under another code separates its future work from retained history. | A: add reopening under structure-management authority. B: require a dedicated reopening permission. C: retain permanent closure. | The product should select A and retain an attributed explanation of reopening. | `CAP-MBR-STR-004`, `FND-MBR-STR-004` |
| `OQ-MBR-STR-003` | What should happen to stored grace-benefit and competing-holding choices? | An administrator can save these choices without changing consumer behavior. | A: implement both choices. B: remove them pending a decision. C: retain them without exposing staff controls. | The product should select C until their intended effects are decided, then implement or remove them. | `CAP-MBR-STR-009`, `CAP-MBR-STR-016`, `FND-MBR-STR-013` |
| `OQ-MBR-STR-004` | Should package preparation permit an inactive backing product? | Preparation before launch can be useful, but the extension immediately appears inactive and may surprise staff. | A: permit preparation as today. B: refuse inactive products. C: permit with a visible warning. | The product should select A and display backing-product availability clearly. | `CAP-MBR-STR-012` |
| `OQ-MBR-STR-005` | Which fixed window should cover a new purchase immediately after closing? | The inherited adjustment can shorten a first-time member’s term by assigning the earlier window. | A: restrict the adjustment to continuations. B: retain it for all purchases. C: make it an offering choice. | The product should select A so fresh purchases use the window containing their purchase date. | `CAP-MBR-STR-015`, `FND-MBR-STR-019` |
| `OQ-MBR-STR-006` | Which meaning should an absent reinstatement allowance carry? | The recorded consumers and legacy interpretation disagree, making migration and eligibility unreliable. | A: disallow reinstatement. B: permit unlimited reinstatement. C: require an explicit numeric choice. | The product should select C for new offerings and translate legacy absence explicitly during migration. | `CAP-MBR-STR-012`, `CAP-MBR-STR-015`, `FND-MBR-STR-021` |
| `OQ-MBR-STR-007` | How much product authority does the final build acceptance provide? | An accepted build and individually recorded decisions have different implications for planning approval. | A: confirm every behavior explicitly demonstrated. B: confirm only recorded decision rows. C: treat the acceptance solely as delivery evidence. | The product should select B and review the remaining proposed rules before design. | `MOD-MBR-STR`, `FND-MBR-STR-001` |
| `OQ-MBR-STR-008` | Which administration screens should structure and membership configuration have? | Without screens, staff set up the association only through the API or imports, and none of the module's journeys can be proved in a browser. | A: design console screens for the tree, units, programs, types, packages and reasons, starting from a v0 design. B: keep setup API- and import-only for the pilot. C: screens for the structure only, configuration through imports. | Andrew should choose A, staged with the tree and unit screens first, because chapter administration is the most frequent setup work. | `MOD-MBR-STR`, `FND-MBR-STR-046`, `JNY-MBR-STR-001`, `JNY-MBR-STR-004` |
| `OQ-MBR-STR-009` | How should setting up an offering avoid products that grant no membership? | The two-step save leaves an Accounting product without its extension whenever the second step is refused. | A: build a Membership transaction that composes product and extension saves through the existing port. B: keep the two steps and add orphan detection with a staff view. C: have Accounting refuse to activate a membership-package product with no extension. | The product should select A; the port is available, but composing and exposing the atomic workflow still requires implementation. | `WF-MBR-STR-004`, `ADR-MBR-STR-006`, `FND-MBR-STR-040`, `CAP-MBR-STR-012` |
| `OQ-MBR-STR-010` | Which structural changes should other applications be told about? | Today only reparenting is a business event and nothing subscribes; merges and closures are invisible to Committees and reporting. | A: keep reparenting only. B: also state merges, closures and creations as business events. C: B plus tracked follow-up for what a merge leaves behind. | Select C, so a merge's leftover finance, link and committee work is visible to the people who must do it. | `ADR-MBR-STR-013`, `WF-MBR-STR-002`, `FND-MBR-STR-041`, `CAP-MBR-STR-003` |
