BS 0:2006 Meeting Minutes

BS 0:2006 is the British Standard A standard for standards — the meta-standard that governs how BSI technical committees operate. Its §7.6 specifies the structure of committee meeting minutes, including two concepts that every standards body tracks but few models capture natively: statements (who said what) and declarations (conflicts of interest and IPR positions).

Edoxen 1.0 promotes these from a BSI-specific concern to first-class core entities, because ISO, IEC, BIPM, IETF, and every other standards body needs the same tracking. The BS 0 provenance is kept in the documentation so adopters can trace the lineage.

What’s new

Three new core entities, plus field changes on Meeting, Topic, and MinutesSection:

Entity / change What it captures Reference
Statement A remark by one or more members. Three kinds: statement, comment, standpoint. Statement →
Declaration A formal declaration. Two kinds: conflict_of_interest, ipr. Declaration →
DateTimeRange A start + end pair with sub-day precision. DateTimeRange →
Meeting changes dateRange renamed scheduledDateRange; new occurredDateRange; new declarations[]. below
Topic changes New statements[] (standing) + declarations[] (standing). Topic →
MinutesSection changes New statements[] (per-meeting) + topic_ref (URN back-link). Minutes →

Statement

A Statement is one remark made by one or more meeting members. The kind discriminator separates three BS 0:2006 types: statement (general remark), comment (sub-type), and standpoint (a member’s position on the topic).

Statements attach at two levels:

  • MinutesSection.statements[]per-meeting: what was said this time, in this meeting, on this agenda item.
  • Topic.statements[]standing: a position that travels with the topic across meetings.

Declaration

A Declaration is a formal declaration by one or more members. The kind discriminator covers conflict_of_interest and ipr. IPR declarations carry typed EntityRef slots (ipr_subject_ref, ipr_target_ref) that the schema validates.

Declarations attach at two levels:

  • Meeting.declarations[]per-meeting: declarations made at this sitting.
  • Topic.declarations[]standing: a declaration that travels with the topic.

DateTimeRange

A DateTimeRange is a start + end pair with sub-day precision — parallel to DateRange (day granularity). The two are intentionally separate types so the granularity is visible at the type level.

Meeting time fields

The BS 0 integration renames Meeting.dateRange to scheduledDateRange and adds occurredDateRange:

Field Type Precision Description
scheduled_date_range DateRange Day When the meeting was planned to happen.
occurred_date_range DateTimeRange Sub-day When the meeting actually ran (e.g. 09:00–11:30).

This separation matters when a meeting is scheduled for a full day but only runs three hours, or when a meeting overruns its planned window.

Example: bilingual committee minutes with BS 0 concepts

This is the bs0-sample.yaml fixture from the gem — a BSI TC/1 sitting with bilingual statements, declarations (CoI + IPR), and scheduled-vs-occurred date ranges:

identifier:
  - prefix: BSI
    number: "TC/1/2026/03"
urn: urn:edoxen:meeting:bsi:tc1-2026-03
type: committee
status: completed
title:
  - spelling: eng
    value: BSI TC/1 — March 2026 sitting
  - spelling: fra
    value: BSI TC/1 — séance de mars 2026
scheduled_date_range:
  start: 2026-03-12
  end: 2026-03-12
occurred_date_range:
  start: 2026-03-12T09:00:00+00:00
  end: 2026-03-12T11:45:00+00:00
declarations:
  - kind: conflict_of_interest
    description:
      - spelling: eng
        value: Mr Smith declares a conflict of interest on agenda item 5.2.
      - spelling: fra
        value: M. Smith déclare un conflit d'intérêts sur le point 5.2.
    party:
      - name:
          - spelling: eng
            value:
              formatted: Mr John Smith
  - kind: ipr
    description:
      - spelling: eng
        value: Ms Doe declares a patent on the technology described in clause 7.
    party:
      - name:
          - spelling: eng
            value:
              formatted: Ms Jane Doe
    ipr_subject_ref:
      urn: urn:edoxen:ipr-subject:iso-patent-policy:2024
    ipr_target_ref:
      identifier:
        prefix: ISO
        number: "8601-1:2019"
minutes:
  - identifier:
      - prefix: BSI
        number: "TC/1/2026/03/min"
    spelling: eng
    sections:
      - number: "5.2"
        title:
          - spelling: eng
            value: Patent clause discussion
        narrative:
          - spelling: eng
            value: |
              The committee discussed the patent clause in detail.
        statements:
          - kind: standpoint
            description:
              - spelling: eng
                value: Ms Doe supports the clause as drafted.
            party:
              - name:
                  - spelling: eng
                    value:
                      formatted: Ms Jane Doe
          - kind: comment
            description:
              - spelling: eng
                value: Mr Smith requested his dissent be recorded.
            party:
              - name:
                  - spelling: eng
                    value:
                      formatted: Mr John Smith
        topic_ref: urn:edoxen:topic:bsi:tc1-patent-clause

When to use BS 0 concepts

If your domain tracks… Use…
Who said what during a meeting MinutesSection.statements[]
A committee’s long-held position on a subject Topic.statements[] with kind: standpoint
Conflicts of interest Meeting.declarations[] with kind: conflict_of_interest
IPR positions (patents, copyright) Meeting.declarations[] with kind: ipr + ipr_subject_ref / ipr_target_ref
Actual meeting times (not just scheduled dates) Meeting.occurred_date_range

API usage

Ruby (gem)

require 'edoxen'

collection = Edoxen::MeetingCollection.from_yaml(File.read('meeting.yaml'))
meeting = collection.meetings.first

# Scheduled vs occurred times
scheduled = meeting.scheduled_date_range  # => DateRange (day precision)
occurred  = meeting.occurred_date_range   # => DateTimeRange (sub-day)

# Declarations on the meeting
meeting.declarations.each do |decl|
  kind = decl.kind  # => "conflict_of_interest" or "ipr"
  desc = decl.description.find { |l| l.spelling == "eng" }&.value
  puts "[#{kind}] #{desc}"

  if decl.kind == "ipr"
    puts "  subject: #{decl.ipr_subject_ref.urn}"
    puts "  target:  #{decl.ipr_target_ref.identifier.first.number}"
  end
end

# Statements in a minutes section
meeting.minutes.first.sections.each do |section|
  section.statements.each do |stmt|
    kind = stmt.kind  # => "statement", "comment", or "standpoint"
    text = stmt.description.find { |l| l.spelling == "eng" }&.value
    who  = stmt.party.map { |p| p.name.first.value.formatted }.join(", ")
    puts "  [#{kind}] #{who}: #{text}"
  end
end

TypeScript / JavaScript (@edoxen/edoxen)

import { validateMeetings } from '@edoxen/edoxen'
import yaml from 'js-yaml'
import fs from 'node:fs'

const doc = yaml.load(fs.readFileSync('meeting.yaml', 'utf-8'))
const result = await validateMeetings(doc)

if (result.valid) {
  const meeting = doc.meetings[0]

  // Scheduled vs occurred
  console.log('scheduled:', meeting.scheduled_date_range)
  console.log('occurred:', meeting.occurred_date_range)

  // Declarations
  for (const decl of meeting.declarations ?? []) {
    console.log(`[${decl.kind}]`, decl.description[0]?.value)
    if (decl.kind === 'ipr') {
      console.log('  subject:', decl.ipr_subject_ref?.urn)
      console.log('  target:', decl.ipr_target_ref?.identifier?.[0]?.number)
    }
  }

  // Statements in minutes sections
  for (const section of meeting.minutes?.[0]?.sections ?? []) {
    for (const stmt of section.statements ?? []) {
      const who = stmt.party?.map(p => p.name?.[0]?.value?.formatted).join(', ')
      console.log(`  [${stmt.kind}] ${who}: ${stmt.description?.[0]?.value}`)
    }
  }
}

See also

  • Statement — reference for the Statement entity
  • Declaration — reference for the Declaration entity
  • DateTimeRange — reference for the DateTimeRange entity
  • Minutes — the narrative record, now with per-section statements
  • Topic — the subject of discussion, now with standing statements + declarations
  • Meeting Collection — the parent entity
  • Schema — the JSON Schema that enforces these types