---
id: STATE-CMT-MTG-008
title: Opening Status
object: DOM-CMT-MTG-005
product_area: committees
module: meetings
revision: 2
status: draft
design_intent: proposed
implementation_evidence: inconsistent
source_sha:
  services-committees: 36129c24daeaadcdb339218c38cdeaff9861359d
states:
  - name: draft
    meaning: An unpublished vacancy record available to staff.
  - name: open
    meaning: >-
      A published opening shown according to committee listing and deadline
      rules.
  - name: closed
    meaning: Staff have ended recruitment for this opening.
  - name: filled
    meaning: Enough matching started appointments have been counted to fill its places.
  - name: cancelled
    meaning: The opening is withdrawn by staff or committee dissolution.
transitions:
  - from: draft
    to: open
    trigger: Staff publish the draft.
    guard: >-
      The opening version matches and publication checks an undissolved
      committee.
    side_effects:
      - >-
        Timestamp publication, persist its event and prepare chair and
        staff-liaison notices.
    who: Staff holding opening management permission
    provenance: observed
    source: >-
      services-committees:modules/recruitment/services/persistence/openings.ts:publishOpening;
      services/openings/opening-notices.ts:noticeOpeningPublished
  - from: draft
    to: cancelled
    trigger: Staff or dissolution cancels the unpublished record.
    guard: >-
      Staff compares its version; dissolution performs a locked automatic
      cancellation.
    side_effects:
      - Retain it as cancelled without an opening-closed event.
    who: Opening staff or committee dissolution
    provenance: observed
    source: >-
      services-committees:modules/recruitment/services/persistence/openings.ts:cancelOpening
  - from: open
    to: closed
    trigger: Staff close published recruitment.
    guard: The opening version matches.
    side_effects:
      - Timestamp closure and record the closed event.
    who: Staff holding opening management permission
    provenance: observed
    source: >-
      services-committees:modules/recruitment/services/persistence/openings.ts:closeOpening
  - from: open
    to: filled
    trigger: An appointment-started delivery fills the last available place.
    guard: >-
      The appointment is an uncounted matching seat-holder and the opening is
      still open.
    side_effects:
      - >-
        Add the appointment reference, timestamp closure and record the closed
        event.
    who: Appointment-started event processing
    provenance: observed
    source: >-
      services-committees:modules/recruitment/services/openings/fill-openings.ts:fillOpeningsFor;
      services/rules/fill-rule.ts:fillOpening
  - from: open
    to: cancelled
    trigger: Staff or dissolution cancels published recruitment.
    guard: Staff compares its version; dissolution uses its own transaction.
    side_effects:
      - Timestamp closure and record the closed event.
    who: Opening staff or committee dissolution
    provenance: observed
    source: >-
      services-committees:modules/recruitment/services/openings/close-recruitment.ts:closeCommitteeRecruitment
invalid:
  - from: closed
    to: open
    why: Final recruitment statuses have no reopen operation.
  - from: draft
    to: filled
    why: Filling considers published openings only.
  - from: draft
    to: closed
    why: Unpublished recruitment is cancelled rather than closed.
concurrency: >-
  Explicit staff moves lock and version-check the opening. Intake locks open
  committee openings and stores counted appointment references before committing
  the fill.
invariants:
  - INV-DOM-CMT-MTG-005-03
  - INV-DOM-CMT-MTG-005-04
evidence:
  - >-
    services-committees at 36129c24:
    modules/recruitment/services/rules/opening-lifecycle.ts, fill-rule.ts,
    dissolved-recruitment.ts; services/persistence/openings.ts;
    services/openings/*.ts
---
# Opening Status

## The Lifecycle

```mermaid
stateDiagram-v2
  [*] --> draft
  draft --> open
  draft --> cancelled
  open --> closed
  open --> filled
  open --> cancelled
```

draft: An unpublished vacancy record available to staff.

open: A published opening shown according to committee listing and deadline rules.

closed: Staff have ended recruitment for this opening.

filled: Enough matching started appointments have been counted to fill its places.

cancelled: The opening is withdrawn by staff or committee dissolution.

## Transitions Explained

Staff publish the draft. The opening version matches and publication checks an undissolved committee. Timestamp publication, persist its event and prepare chair and staff-liaison notices.

Staff or dissolution cancels the unpublished record. Staff compares its version; dissolution performs a locked automatic cancellation. Retain it as cancelled without an opening-closed event.

Staff close published recruitment. The opening version matches. Timestamp closure and record the closed event.

An appointment-started delivery fills the last available place. The appointment is an uncounted matching seat-holder and the opening is still open. Add the appointment reference, timestamp closure and record the closed event.

Staff or dissolution cancels published recruitment. Staff compares its version; dissolution uses its own transaction. Timestamp closure and record the closed event.

## What Cannot Happen

Final recruitment statuses have no reopen operation. Filling considers published openings only. Unpublished recruitment is cancelled rather than closed. Visibility honors the deadline but ignores a future opening date. Neither the fill rule nor a scheduled closer enforces the advertised application window.

## Concurrency and Timing

Explicit staff moves lock and version-check the opening. Intake locks open committee openings and stores counted appointment references before committing the fill.
