01must proveConfirmed | Staff creation requires a program, owner category, matching owner reference, a reason between 1 and 500 characters and an initial term, and refuses an inactive program or an owner category that the program excludes. ✓ A coordinator records a complimentary Regular term for a person in the national program and explains the board’s decision.✗ An organization cannot join a program restricted to individual owners; creation returns a validation refusal. no proof recorded yet | validation | api, service | observed |
02must proveConfirmed | An owner cannot receive another principal membership in the same program and identity unit; the refusal directs staff to extend the existing membership with a term. no proof recorded yet | invariant | service, database | observed |
03must proveConfirmed | Identity-bound programs require a unit of their configured identity type, while programs without that binding refuse an identity unit. origin: D-02 (services-membership:README.md, architecture decisions approved 2026-10-17) no proof recorded yet | validation | service, database | observed |
04must proveConfirmed | The chosen type must be active within the program, any package must be active and belong to that type, and a term without a package requires explicit starting and ending dates. no proof recorded yet | validation | service | observed |
05must proveConfirmed | Where dates are omitted, the package rule calculates the period from the supplied effective date or the workspace business date; an explicit start without an end uses that rule to calculate the end. no proof recorded yet | calculation | service | observed |
06must proveConfirmed | The service rejects overlap with effective or pending terms and identifies the conflict, while the database exclusion independently rejects overlap between effective terms and does not cover pending terms. no proof recorded yet | invariant | service, database | test |
07must proveConfirmed | An owner cannot have overlapping effective or pending periods in different programs belonging to the same exclusivity group. no proof recorded yet | policy | service | test |
08must proveConfirmed | Creation allocates the membership number using the workspace sequence, program sequence or owner’s CRM number selected by the program, refusing CRM numbering when the owner has no number. origin: D-41 (services-membership:modules/memberships/services/membership-numbers.ts header) no proof recorded yet | calculation | service | test |
09must proveConfirmed | The enrolment event retains the creation reason, and the original join date uses the first effective term’s start unless staff supply a date that is recorded as their choice. no proof recorded yet | lifecycle | service | observed |
10must proveConfirmed | Imports match records by identity or producer source key and load configuration before memberships before terms; inserts record an imported event, all term writes refresh status, and neither grants nor flow-down children are generated. no proof recorded yet | policy | service | observed |
11must proveConfirmed | Prevalidation identifies malformed import fields before writing, and an overlapping imported term is classified as a conflict for that item. no proof recorded yet | validation | service | test |
12must proveConfirmed | The product should validate imported owners, programs, types and packages as staff creation does and prevent an upsert from changing a term belonging to another membership. no proof recorded yet | validation | service | unknown |
13must proveConfirmed | The product should support staff and import entry of customer-defined membership values under the declared custom-field contract. origin: R2-ARCH-001 (services-membership:AGENTS.md, Andrew 2026-10-19) no proof recorded yet | policy | service | unknown |
14Confirmed | Staff creation sets renewal, drop, directory and auto-renew choices without offering later staff edits to those choices, the join date or owner, although import upserts can replace these values. | lifecycle | service | observed |