---
id: CAP-CMT-MTG-002
title: Maintain a committee’s recurring meeting schedule
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-005
  - 'react-console acceptance journeys CMT-ACC-0217 to 0220, 0253'
source_sha:
  services-committees: 36129c24daeaadcdb339218c38cdeaff9861359d
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-committees:docs/milestones/CMTE-M3-meetings-and-minutes.md#D3'
  - 'services-committees:docs/milestones/CMTE-M3-meetings-and-minutes.md#D12'
purpose: >-
  A recurring schedule gives staff a calendar of committee meetings without entering every
  occurrence.
outcomes:
  - Regular meeting dates are generated from a shared schedule
  - Repeating calendar generation creates no duplicate occurrences
  - Schedule changes affect eligible future meetings
concepts:
  - CON-CMT-MTG-001
actors:
  - ACT-CMT-002
  - ACT-CMT-011
surfaces:
  - api
  - job
preconditions:
  - The owning committee is recorded and has not been dissolved.
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-002-01
    statement: >-
      A recurrence supports daily, weekly or monthly frequency, an interval, applicable weekdays or
      month days, a start hour with optional minutes, either a count or an end date, and excluded
      dates; unsupported combinations are rejected with an explanation.
    kind: validation
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: test
    source: >-
      services-committees:modules/meetings/tests/unit/services/recurrence-rule.spec.ts#refuses a
      yearly rule
    origin: none
    examples:
      positive: 'Meet at 19:00 on the second Tuesday each month.'
      negative: Request annual recurrence or omit the start hour.
  - id: BR-CAP-CMT-MTG-002-02
    statement: >-
      A series requires a recognised time zone, a duration from 1 through 1,440 minutes, and an end
      date on or after its first day when an end is supplied.
    kind: validation
    enforced_at:
      - api
      - service
      - database
    must_prove: true
    provenance: observed
    source: 'services-committees:modules/meetings/services/persistence/meeting-series.ts'
    origin: none
  - id: BR-CAP-CMT-MTG-002-03
    statement: >-
      An active series generates at most one meeting for each occurrence from the later of today and
      its first day through eighteen months from today, subject to its end date.
    kind: calculation
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-committees:modules/meetings/tests/integration/services/meetings.integration.spec.ts#creates
      one meeting per occurrence of the window, on the second Tuesdays
    origin: none
  - id: BR-CAP-CMT-MTG-002-04
    statement: >-
      The daily process generates occurrences for active series in active workspaces and reports
      failed series while continuing with the others.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-committees:modules/meetings/tests/integration/services/meetings-jobs-tenant.integration.spec.ts#makes
      a series’ occurrences over the 18-month window, one a week
    origin: none
  - id: BR-CAP-CMT-MTG-002-05
    statement: >-
      Changing a series updates the title, time, time zone and duration of its future draft or
      scheduled occurrences, cancels dates removed from the schedule, and preserves held or
      cancelled occurrences.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-committees:modules/meetings/tests/integration/services/meetings.integration.spec.ts#rewrites
      the future unheld occurrences to the new time
    origin: none
  - id: BR-CAP-CMT-MTG-002-06
    statement: >-
      The product should create series occurrences as drafts and call them at the committee’s lead
      time, initially thirty days before, with an option for staff to call them earlier.
    kind: policy
    enforced_at: []
    must_prove: true
    provenance: documented
    source: 'services-committees:docs/milestones/CMTE-M3-meetings-and-minutes.md#Decisions'
    origin: >-
      CMTE-M3 D3 (Andrew 2026-10-21,
      services-committees:docs/milestones/CMTE-M3-meetings-and-minutes.md#Decisions)
  - id: BR-CAP-CMT-MTG-002-07
    statement: >-
      The product should restore eligible occurrences when a paused series resumes or its end date
      is extended, after cancelling future occurrences on pause.
    kind: lifecycle
    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 1 (Andrew 2026-10-21,
      services-committees:docs/milestones/CMTE-M3-meetings-and-minutes.md#Decisions)
  - id: BR-CAP-CMT-MTG-002-08
    statement: >-
      The product should preserve meetings that staff rescheduled individually when their series
      changes.
    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 2 (Andrew 2026-10-21,
      services-committees:docs/milestones/CMTE-M3-meetings-and-minutes.md#Decisions)
  - id: BR-CAP-CMT-MTG-002-09
    statement: Creating a series for a dissolved committee is refused.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: 'services-committees:modules/meetings/services/persistence/meeting-series.ts:createSeries'
    origin: none
  - id: BR-CAP-CMT-MTG-002-10
    statement: A generated occurrence receives the series’ default physical and video meeting details.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: observed
    source: 'services-committees:modules/meetings/services/persistence/meeting-series.ts:materializeSeries'
    origin: none
  - id: BR-CAP-CMT-MTG-002-11
    statement: >-
      Staff can generate any missing occurrences in the current window without waiting for the daily
      process.
    kind: policy
    enforced_at:
      - api
    must_prove: false
    provenance: observed
    source: 'services-committees:modules/meetings/aws/api/meetings.routes.ts:materializeMeetingSeries'
    origin: none
scenarios:
  - id: SC-CAP-CMT-MTG-002-01
    given: 'A board has a monthly second-Tuesday schedule at 19:00 New York time, lasting ninety minutes'
    when: Staff save the recurring schedule
    then: Occurrences through the rolling eighteen-month window are created in scheduled status
    provenance: test
    source: >-
      services-committees:modules/meetings/tests/e2e/meetings.e2e.spec.ts#creates every occurrence
      scheduled
  - id: SC-CAP-CMT-MTG-002-02
    given: Occurrences already exist for the current generation window
    when: The same series is generated again
    then: No additional occurrence is created
    provenance: test
    source: >-
      services-committees:modules/meetings/tests/integration/services/meetings.integration.spec.ts#creates
      nothing when it runs again
edge_cases:
  - id: SC-CAP-CMT-MTG-002-03
    given: 'A Pacific-time Sunday series starts at 02:30 across the spring clock change'
    when: The calendar occurrences are generated
    then: 'The missing local hour shifts forward to 03:30; other Sundays start at 02:30'
    provenance: test
    source: >-
      react-console:acceptance/committees/playwright/journeys/meetings/CMT-ACC-0253.spec.ts#CMT-ACC-0253
constraints: []
depends_on:
  - CAP-CMT-MTG-001
related:
  - CAP-CMT-MTG-003
journeys:
  - JNY-CMT-MTG-001
open_questions: []
evidence:
  - >-
    services-committees at 36129c24: Recurring meeting generation, pause handling and local-time
    occurrence calculations.
  - >-
    react-console at baf6dae3: the meeting acceptance specifications cited by this capability and
    its acceptance set.
controls:
  - TC-IAM-006
  - 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-SEC-001
  - TC-SEC-004
  - TC-DAT-001
  - TC-DAT-002
  - TC-DAT-003
  - TC-LOG-002
  - TC-LOG-003
  - TC-LOG-004
  - TC-LOG-005
  - TC-AVL-004
  - TC-MON-001
  - TC-MON-002
  - TC-PI-001
  - TC-PI-002
  - TC-PI-003
  - TC-PI-004
  - TC-PI-005
  - TC-PRV-001
  - TC-PRV-002
---

# Maintain a committee’s recurring meeting schedule

## Purpose

A recurring calendar reduces the work of maintaining a committee’s regular meetings. Staff manage the schedule and inspect the occurrences it produces.

## How It Works

Staff enter a title, a recurrence, a time zone, a meeting duration and the first eligible date. Optional end dates and exclusions limit the calendar. Physical and video meeting details supply defaults for newly generated occurrences. Creation generates the initial calendar, while staff can request another generation without waiting for the daily process. The series remains distinct from its individual meetings. Editing it can update or cancel eligible occurrences, but does not reset completed meetings. Current generation calls every new occurrence immediately. The approved direction instead calls for drafts followed by lead-time calling. Restoring cancelled occurrences after resumption and protecting individually moved meetings are also approved directions that the current implementation does not fulfil.

## Relationships

Meeting scheduling supplies the records generated by a series. Attendance work uses the participant snapshot attached to each occurrence.
