---
id: CAP-CMT-MTG-003
title: Maintain meeting participation and attendance
feature: FEAT-CMT-MTG-01
product_area: committees
module: meetings
revision: 1
status: draft
product_intent: proposed
implementation_evidence: inconsistent
supersedes:
  - 'react-console acceptance inventory CAP-CMT-MTG-006, 007'
  - 'react-console acceptance journeys CMT-ACC-0221 to 0225, 0255'
source_sha:
  services-committees: 36129c24daeaadcdb339218c38cdeaff9861359d
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-committees:docs/milestones/CMTE-M3-meetings-and-minutes.md#D4'
  - 'services-committees:docs/milestones/CMTE-M3-meetings-and-minutes.md#D5'
  - 'services-committees:docs/milestones/CMTE-M3-meetings-and-minutes.md#D12'
purpose: >-
  Staff reconcile the expected participants with the people who actually attend and preserve
  accountable corrections after closure.
outcomes:
  - Expected participants have recorded meeting roles and voting flags
  - Staff can submit attendance as one complete batch
  - Post-close changes require authorised reopening and retain an audit
concepts:
  - CON-CMT-MTG-001
actors:
  - ACT-CMT-002
  - ACT-CMT-008
surfaces:
  - api
preconditions:
  - A meeting record is available.
postconditions: []
permissions:
  - key: committees.meetings.read
    where_checked: api
    scope: tenant
  - key: committees.meetings.manage
    where_checked: api
    scope: tenant
rules:
  - id: BR-CAP-CMT-MTG-003-01
    statement: >-
      Creation copies the roster for the meeting’s local date, assigning chairs from chair
      positions, other seat-holders as members, advisers, liaisons and secretaries by participation
      kind, observers and guests as guests, and voting flags from the roster.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-committees:modules/meetings/tests/unit/services/snapshot-and-participation.spec.ts#makes
      a seat-holder in a chair position the chair
    origin: none
  - id: BR-CAP-CMT-MTG-003-02
    statement: >-
      When several roster entries describe one person, the snapshot selects a chair entry first,
      otherwise a voting entry, otherwise the first entry encountered.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: >-
      services-committees:modules/meetings/services/participants/snapshot-rule.ts:snapshotParticipants
    origin: none
  - id: BR-CAP-CMT-MTG-003-03
    statement: >-
      The product should refresh roster-derived participants until the call to order or closure,
      preserve manually added guests, proxies and corrections, and retain the resulting attendance
      record.
    kind: policy
    enforced_at: []
    must_prove: true
    provenance: documented
    source: 'services-committees:docs/milestones/CMTE-M3-meetings-and-minutes.md#Decisions'
    origin: >-
      CMTE-M3 D4 (Andrew 2026-10-21,
      services-committees:docs/milestones/CMTE-M3-meetings-and-minutes.md#Decisions)
  - id: BR-CAP-CMT-MTG-003-04
    statement: >-
      Staff can add guests, late appointees and proxies manually, but the same contact cannot be
      recorded twice for one meeting.
    kind: validation
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-committees:modules/meetings/tests/integration/services/meetings.integration.spec.ts#adds
      a guest with no appointment, non-voting
    origin: none
  - id: BR-CAP-CMT-MTG-003-05
    statement: >-
      A proxy must identify an appointment already represented among that meeting’s participants,
      and a non-proxy cannot identify a represented appointment.
    kind: validation
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-committees:modules/meetings/tests/integration/services/meetings.integration.spec.ts#refuses
      a proxy for an appointment that is not at the meeting
    origin: none
  - id: BR-CAP-CMT-MTG-003-06
    statement: >-
      Proxy participation is accepted when no decision-rule document exists or when that document
      does not explicitly forbid proxies.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-committees:modules/meetings/tests/integration/services/meetings.integration.spec.ts#adds
      a proxy for an appointment of the meeting when the committee has no rules
    origin: none
  - id: BR-CAP-CMT-MTG-003-07
    statement: >-
      The product should require explicit committee permission for proxies, record representation
      against the absent member, preserve the holder’s own role and presence, and prevent multiple
      proxies for one member.
    kind: policy
    enforced_at: []
    must_prove: true
    provenance: documented
    source: 'services-committees:docs/milestones/CMTE-M3-meetings-and-minutes.md#Decisions'
    origin: >-
      CMTE-M3 D5 (Andrew 2026-10-21,
      services-committees:docs/milestones/CMTE-M3-meetings-and-minutes.md#Decisions)
  - id: BR-CAP-CMT-MTG-003-08
    statement: >-
      An API attendance batch contains one through 1,000 entries with distinct participant
      identities, and any invalid entry rolls back the complete batch.
    kind: validation
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: test
    source: >-
      services-committees:modules/meetings/tests/integration/services/meetings.integration.spec.ts#records
      attendance for every participant in one write
    origin: none
  - id: BR-CAP-CMT-MTG-003-09
    statement: A recorded departure cannot precede the corresponding arrival when both are supplied.
    kind: validation
    enforced_at:
      - database
    must_prove: true
    provenance: observed
    source: >-
      services-committees:modules/meetings/db/meeting-participants.table.ts:meeting_participants_presence_check
    origin: none
  - id: BR-CAP-CMT-MTG-003-10
    statement: >-
      Held-meeting participant and attendance edits require explicit reopening by a meeting manager,
      with each successful edit appended to an audit protected from application updates and
      deletion.
    kind: invariant
    enforced_at:
      - api
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-committees:modules/meetings/tests/integration/services/minutes.integration.spec.ts#refuses
      attendance after the close without reopen
    origin: none
  - id: BR-CAP-CMT-MTG-003-11
    statement: >-
      The product should require a reason for a post-close attendance correction and display that
      reason in the meeting history.
    kind: policy
    enforced_at: []
    must_prove: true
    provenance: documented
    source: >-
      services-committees:docs/milestones/plans/CMTE-M3-plan.md#D12. Smaller rules to approve as a
      group
    origin: >-
      CMTE-M3 D12 item 8 (Andrew 2026-10-21,
      services-committees:docs/milestones/CMTE-M3-meetings-and-minutes.md#Decisions)
  - id: BR-CAP-CMT-MTG-003-12
    statement: Participant edits are refused for cancelled meetings even when reopening is requested.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-committees:modules/meetings/tests/unit/services/minutes-rule.spec.ts#refuses every
      edit of a cancelled meeting, reopened or not
    origin: none
  - id: BR-CAP-CMT-MTG-003-13
    statement: The participant’s video attendance stores each provider event once despite repeat delivery.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-committees:modules/meetings/tests/integration/services/meetings.integration.spec.ts#records
      a joined event on the participant once, however often it is delivered
    origin: none
  - id: BR-CAP-CMT-MTG-003-14
    statement: >-
      The product should let staff remove an accidentally added participant before the meeting is
      called to order.
    kind: policy
    enforced_at: []
    must_prove: true
    provenance: documented
    source: >-
      services-committees:docs/milestones/plans/CMTE-M3-plan.md#D12. Smaller rules to approve as a
      group
    origin: >-
      CMTE-M3 D12 item 6 (Andrew 2026-10-21,
      services-committees:docs/milestones/CMTE-M3-meetings-and-minutes.md#Decisions)
  - id: BR-CAP-CMT-MTG-003-15
    statement: >-
      Updating a participant requires the current saved version, while contact and appointment
      identities cannot be changed through that update.
    kind: validation
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: observed
    source: >-
      services-committees:modules/meetings/services/persistence/meeting-participants.ts:updateParticipant
    origin: none
  - id: BR-CAP-CMT-MTG-003-16
    statement: >-
      Manual participant creation checks that a supplied appointment exists, but does not verify
      that it belongs to the supplied contact or committee, and does not validate the contact
      against CRM.
    kind: validation
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: observed
    source: >-
      services-committees:modules/meetings/services/persistence/meeting-participants.ts:addParticipant
    origin: none
scenarios:
  - id: SC-CAP-CMT-MTG-003-01
    given: The roster gains a director after the meeting’s participant snapshot was created
    when: Staff retrieve the meeting participants
    then: The later appointment is absent from the snapshot unless staff add the person explicitly
    provenance: test
    source: >-
      services-committees:modules/meetings/tests/integration/services/meetings.integration.spec.ts#never
      re-snapshots: a later appointment does not join the meeting
edge_cases: []
constraints: []
depends_on:
  - CAP-CMT-MTG-001
related:
  - CAP-CMT-MTG-011
  - CAP-CMT-MTG-020
journeys:
  - JNY-CMT-MTG-001
open_questions: []
evidence:
  - >-
    services-committees at 36129c24: Roster snapshots, manually supplied participants, presence
    intervals and reopening audits.
  - >-
    react-console at baf6dae3: the meeting acceptance specifications cited by this capability and
    its acceptance set.
controls:
  - TC-AZ-001
  - TC-AZ-002
  - TC-AZ-003
  - TC-AZ-004
  - TC-AZ-006
  - TC-TEN-001
  - TC-TEN-002
  - TC-TEN-003
  - TC-TEN-004
  - TC-SEC-001
  - TC-SEC-004
  - TC-DAT-001
  - TC-DAT-002
  - TC-DAT-003
  - TC-LOG-001
  - TC-LOG-002
  - TC-LOG-003
  - TC-LOG-004
  - TC-LOG-005
  - TC-PI-001
  - TC-PI-003
  - TC-PI-005
  - TC-PRV-001
  - TC-PRV-002
---

# Maintain meeting participation and attendance

## Purpose

Attendance distinguishes an expected participant from someone who actually takes part. Staff retain that distinction when making later corrections.

## How It Works

A meeting begins with a date-specific roster snapshot. Staff inspect the resulting roles and voting flags, then add people who were not included. A guest, a later appointee and a proxy each need an explicit participant record. Staff can adjust roles, invitation responses, attendance, presence times and notes using the saved participant version. Contact and appointment identity stay fixed during an update. Attendance can be submitted for several participants together, with failed entries leaving the batch unchanged. Video attendance is retained separately from staff-entered attendance. Closing a meeting restricts further participant writes to authorised, audited reopening. Cancellation prevents those writes altogether. Automatic roster refresh, the approved proxy model, removal of mistaken additions and visible correction reasons remain directions for future implementation. Manual additions currently accept some mismatched references, so an accepted record does not establish a verified contact-to-appointment relationship.

## Relationships

Scheduling establishes the meeting and initial snapshot. Quorum assessment consumes attendance, while member participation supplies invitation responses.
