edoxen 0.3.1 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CLAUDE.md +10 -6
  3. data/Gemfile +4 -0
  4. data/README.adoc +181 -38
  5. data/TODO.meeting-agenda/01-design-decisions.md +132 -0
  6. data/TODO.meeting-agenda/02-lutaml-canonical.md +61 -0
  7. data/TODO.meeting-agenda/03-ruby-models.md +73 -0
  8. data/TODO.meeting-agenda/04-schema.md +34 -0
  9. data/TODO.meeting-agenda/05-fixtures.md +43 -0
  10. data/TODO.meeting-agenda/06-specs.md +52 -0
  11. data/TODO.meeting-agenda/07-cli.md +55 -0
  12. data/TODO.meeting-agenda/08-docs.md +35 -0
  13. data/TODO.meeting-agenda/09-verify-and-release.md +41 -0
  14. data/TODO.meeting-agenda/10-future-enhancements.md +72 -0
  15. data/TODO.meeting-agenda/README.md +30 -0
  16. data/edoxen.gemspec +1 -0
  17. data/lib/edoxen/agenda.rb +26 -0
  18. data/lib/edoxen/agenda_item.rb +17 -0
  19. data/lib/edoxen/attendance.rb +23 -0
  20. data/lib/edoxen/cli.rb +97 -0
  21. data/lib/edoxen/date_range.rb +11 -0
  22. data/lib/edoxen/deadline.rb +10 -0
  23. data/lib/edoxen/enums.rb +31 -0
  24. data/lib/edoxen/host_ref.rb +14 -0
  25. data/lib/edoxen/link_checker.rb +85 -0
  26. data/lib/edoxen/location.rb +15 -0
  27. data/lib/edoxen/meeting.rb +82 -0
  28. data/lib/edoxen/meeting_collection.rb +26 -0
  29. data/lib/edoxen/meeting_collection_metadata.rb +11 -0
  30. data/lib/edoxen/meeting_localization.rb +15 -0
  31. data/lib/edoxen/meeting_relation.rb +12 -0
  32. data/lib/edoxen/minutes.rb +31 -0
  33. data/lib/edoxen/minutes_section.rb +27 -0
  34. data/lib/edoxen/person.rb +14 -0
  35. data/lib/edoxen/reference.rb +13 -0
  36. data/lib/edoxen/reference_data.rb +95 -0
  37. data/lib/edoxen/resolution_metadata.rb +14 -0
  38. data/lib/edoxen/schedule_item.rb +27 -0
  39. data/lib/edoxen/schedule_item_localization.rb +21 -0
  40. data/lib/edoxen/source_url.rb +6 -2
  41. data/lib/edoxen/version.rb +1 -1
  42. data/lib/edoxen/vote_record.rb +25 -0
  43. data/lib/edoxen.rb +23 -0
  44. data/schema/edoxen.yaml +11 -3
  45. data/schema/meeting.yaml +480 -0
  46. metadata +48 -2
@@ -0,0 +1,480 @@
1
+ ---
2
+ $schema: "http://json-schema.org/draft-07/schema#"
3
+ $id: "https://github.com/edoxen/edoxen/schema/meeting.yaml"
4
+ title: "Edoxen Meeting Schema"
5
+ description: |
6
+ Schema for validating Edoxen Meeting/Agenda YAML files.
7
+
8
+ Mirrors the canonical LutaML information model in
9
+ https://github.com/edoxen/edoxen-model/tree/main/models (meeting*.lutaml,
10
+ agenda*.lutaml, etc.).
11
+
12
+ The root accepts either a single Meeting or a MeetingCollection.
13
+
14
+ Enum lists in this schema are kept in lockstep with
15
+ Edoxen::Enums::* (Meeting side) by
16
+ `spec/edoxen/schema_meeting_enum_sync_spec.rb`.
17
+ type: object
18
+ oneOf:
19
+ - $ref: "#/$defs/MeetingCollection"
20
+ - $ref: "#/$defs/Meeting"
21
+
22
+ $defs:
23
+
24
+ # ====================================================================
25
+ # Reused from schema/edoxen.yaml (re-declared here so this file is
26
+ # self-contained — schema/meeting.yaml does not depend on
27
+ # schema/edoxen.yaml).
28
+ # ====================================================================
29
+
30
+ StructuredIdentifier:
31
+ type: object
32
+ description: "prefix + number identifier. A Meeting carries 1..*."
33
+ additionalProperties: false
34
+ required: [prefix, number]
35
+ properties:
36
+ prefix: { type: string }
37
+ number: { type: string }
38
+
39
+ SourceUrl:
40
+ type: object
41
+ description: "Per-language canonical source URL (PDF, page, register link)."
42
+ additionalProperties: false
43
+ required: [ref]
44
+ properties:
45
+ ref: { type: string }
46
+ format: { type: string }
47
+ language_code:
48
+ type: string
49
+ pattern: "^[a-z]{3}$"
50
+ kind:
51
+ $ref: "#/$defs/SourceUrlKind"
52
+
53
+ # ====================================================================
54
+ # Meeting-side primitive types.
55
+ # ====================================================================
56
+
57
+ DateRange:
58
+ type: object
59
+ description: "Start + end date pair for multi-day meetings."
60
+ additionalProperties: false
61
+ properties:
62
+ start:
63
+ type: string
64
+ format: date
65
+ end:
66
+ type: string
67
+ format: date
68
+
69
+ Location:
70
+ type: object
71
+ description: "Venue geography. Multi-venue meetings carry one Location per venue."
72
+ additionalProperties: false
73
+ properties:
74
+ name: { type: string }
75
+ address: { type: string }
76
+ link: { type: string }
77
+ phone: { type: string }
78
+ note: { type: string }
79
+ lat: { type: number }
80
+ lon: { type: number }
81
+
82
+ Person:
83
+ type: object
84
+ description: "Identity + role + affiliation + contact."
85
+ additionalProperties: false
86
+ properties:
87
+ name: { type: string }
88
+ role: { type: string }
89
+ affiliation: { type: string }
90
+ email: { type: string }
91
+ phone: { type: string }
92
+ orcid: { type: string }
93
+
94
+ HostRef:
95
+ type: object
96
+ description: "Typed reference to an organization that hosts or co-organizes a meeting."
97
+ additionalProperties: false
98
+ required: [ref]
99
+ properties:
100
+ ref: { type: string }
101
+ type:
102
+ $ref: "#/$defs/HostType"
103
+ role: { type: string }
104
+ contact:
105
+ $ref: "#/$defs/Person"
106
+
107
+ ScheduleItemLocalization:
108
+ type: object
109
+ description: "Per-language content for a ScheduleItem."
110
+ additionalProperties: false
111
+ required: [language_code]
112
+ properties:
113
+ language_code:
114
+ type: string
115
+ pattern: "^[a-z]{3}$"
116
+ script:
117
+ type: string
118
+ pattern: "^[A-Z][a-z]{3}$"
119
+ event: { type: string }
120
+ description: { type: string }
121
+
122
+ ScheduleItem:
123
+ type: object
124
+ description: "One entry in the meeting timetable."
125
+ additionalProperties: false
126
+ properties:
127
+ date:
128
+ type: string
129
+ format: date
130
+ time: { type: string }
131
+ event: { type: string }
132
+ description: { type: string }
133
+ room: { type: string }
134
+ localizations:
135
+ type: array
136
+ items:
137
+ $ref: "#/$defs/ScheduleItemLocalization"
138
+
139
+ Attendance:
140
+ type: object
141
+ description: "One attendance record per person at a Meeting."
142
+ additionalProperties: false
143
+ required: [person, status]
144
+ properties:
145
+ person:
146
+ $ref: "#/$defs/Person"
147
+ status:
148
+ $ref: "#/$defs/ParticipationStatus"
149
+ affiliation: { type: string }
150
+ proxy_for:
151
+ $ref: "#/$defs/Person"
152
+ notes: { type: string }
153
+
154
+ VoteRecord:
155
+ type: object
156
+ description: "One vote by one person on one resolution at one meeting."
157
+ additionalProperties: false
158
+ required: [resolution_ref, person, vote]
159
+ properties:
160
+ resolution_ref: { type: string }
161
+ person:
162
+ $ref: "#/$defs/Person"
163
+ affiliation: { type: string }
164
+ vote:
165
+ $ref: "#/$defs/VoteType"
166
+ notes: { type: string }
167
+
168
+ MinutesSection:
169
+ type: object
170
+ description: |
171
+ One section of a Meeting's minutes — typically tied to an agenda
172
+ item by its `number` field. Carries the narrative as Markdown
173
+ (the format the GLM-OCR pipeline emits) plus an optional page
174
+ range for provenance back to the source PDF.
175
+ additionalProperties: false
176
+ properties:
177
+ number: { type: string }
178
+ title: { type: string }
179
+ narrative: { type: string }
180
+ page_start: { type: integer }
181
+ page_end: { type: integer }
182
+ references:
183
+ type: array
184
+ items:
185
+ $ref: "#/$defs/Reference"
186
+
187
+ Minutes:
188
+ type: object
189
+ description: |
190
+ The narrative record of a Meeting — what was said, by whom, in
191
+ what order, with what outcome. Distinct from Agenda (the business
192
+ order drafted before the meeting) and from ResolutionCollection
193
+ (the formal decisions adopted). The Minutes are the running
194
+ record. One Minutes document per language; sections are typically
195
+ keyed by agenda-item number so consumers can join
196
+ Minutes ↔ AgendaItem ↔ Resolution.
197
+ additionalProperties: false
198
+ properties:
199
+ identifier:
200
+ type: array
201
+ items:
202
+ $ref: "#/$defs/StructuredIdentifier"
203
+ urn: { type: string }
204
+ language_code:
205
+ type: string
206
+ pattern: "^[a-z]{3}$"
207
+ script:
208
+ type: string
209
+ pattern: "^[A-Z][a-z]{3}$"
210
+ source_doc: { type: string }
211
+ source_pages: { type: string }
212
+ sections:
213
+ type: array
214
+ items:
215
+ $ref: "#/$defs/MinutesSection"
216
+
217
+ Deadline:
218
+ type: object
219
+ description: "A time-bound requirement (registration, submission, etc.)."
220
+ additionalProperties: false
221
+ required: [date]
222
+ properties:
223
+ date:
224
+ type: string
225
+ format: date
226
+ description: { type: string }
227
+
228
+ Reference:
229
+ type: object
230
+ description: "Generic document reference (used by AgendaItem.references)."
231
+ additionalProperties: false
232
+ properties:
233
+ ref: { type: string }
234
+ kind: { type: string }
235
+ title: { type: string }
236
+
237
+ # ====================================================================
238
+ # Agenda side.
239
+ # ====================================================================
240
+
241
+ AgendaItem:
242
+ type: object
243
+ description: "One entry on an Agenda."
244
+ additionalProperties: false
245
+ properties:
246
+ label: { type: string }
247
+ kind:
248
+ $ref: "#/$defs/AgendaItemKind"
249
+ title: { type: string }
250
+ description: { type: string }
251
+ references:
252
+ type: array
253
+ items:
254
+ $ref: "#/$defs/Reference"
255
+ outcome:
256
+ $ref: "#/$defs/AgendaItemOutcome"
257
+ resolution_ref:
258
+ type: string
259
+ description: "URN of the resolution this item produced."
260
+
261
+ Agenda:
262
+ type: object
263
+ description: |
264
+ The business-order document of a Meeting. Versioned independently
265
+ of the Meeting via the `status` field (draft, final, amended).
266
+ additionalProperties: false
267
+ properties:
268
+ identifier:
269
+ type: array
270
+ items:
271
+ $ref: "#/$defs/StructuredIdentifier"
272
+ status:
273
+ $ref: "#/$defs/AgendaStatus"
274
+ source_doc: { type: string }
275
+ items:
276
+ type: array
277
+ items:
278
+ $ref: "#/$defs/AgendaItem"
279
+ opening_session:
280
+ $ref: "#/$defs/ScheduleItem"
281
+ closing_session:
282
+ $ref: "#/$defs/ScheduleItem"
283
+
284
+ # ====================================================================
285
+ # Meeting side.
286
+ # ====================================================================
287
+
288
+ MeetingRelation:
289
+ type: object
290
+ description: "Directed link between two meetings."
291
+ additionalProperties: false
292
+ required: [source, destination, type]
293
+ properties:
294
+ source:
295
+ $ref: "#/$defs/StructuredIdentifier"
296
+ destination:
297
+ $ref: "#/$defs/StructuredIdentifier"
298
+ type:
299
+ $ref: "#/$defs/MeetingRelationType"
300
+
301
+ MeetingLocalization:
302
+ type: object
303
+ description: "Per-language content for a Meeting."
304
+ additionalProperties: false
305
+ required: [language_code]
306
+ properties:
307
+ language_code:
308
+ type: string
309
+ pattern: "^[a-z]{3}$"
310
+ script:
311
+ type: string
312
+ pattern: "^[A-Z][a-z]{3}$"
313
+ title: { type: string }
314
+ general_area: { type: string }
315
+ practical_info: { type: string }
316
+
317
+ Meeting:
318
+ type: object
319
+ description: "A single Meeting (event)."
320
+ additionalProperties: false
321
+ required: [identifier, type]
322
+ properties:
323
+ identifier:
324
+ type: array
325
+ minItems: 1
326
+ items:
327
+ $ref: "#/$defs/StructuredIdentifier"
328
+ urn: { type: string }
329
+ ordinal: { type: integer }
330
+ type:
331
+ $ref: "#/$defs/MeetingType"
332
+ status:
333
+ $ref: "#/$defs/MeetingStatus"
334
+ year: { type: integer }
335
+
336
+ date_range:
337
+ $ref: "#/$defs/DateRange"
338
+
339
+ committee: { type: string }
340
+ committee_group: { type: string }
341
+
342
+ venues:
343
+ type: array
344
+ items:
345
+ $ref: "#/$defs/Location"
346
+ general_area: { type: string }
347
+ city:
348
+ type: string
349
+ pattern: "^[A-Z]{2}[A-Z0-9]{3}$"
350
+ description: "UN/LOCODE of the host city (5-char: 2-letter ISO 3166-1 country + 3-char location, e.g. FRPAR, HKHKG, THCNM)."
351
+ country_code:
352
+ type: string
353
+ pattern: "^[A-Z]{2}$"
354
+ virtual: { type: boolean }
355
+
356
+ chair: { $ref: "#/$defs/Person" }
357
+ secretary: { $ref: "#/$defs/Person" }
358
+ host: { type: string }
359
+ hosts:
360
+ type: array
361
+ items:
362
+ $ref: "#/$defs/HostRef"
363
+
364
+ source_urls:
365
+ type: array
366
+ items:
367
+ $ref: "#/$defs/SourceUrl"
368
+ landing_url: { type: string }
369
+ registration_url: { type: string }
370
+
371
+ agenda:
372
+ $ref: "#/$defs/Agenda"
373
+ schedule:
374
+ type: array
375
+ items:
376
+ $ref: "#/$defs/ScheduleItem"
377
+ deadlines:
378
+ type: array
379
+ items:
380
+ $ref: "#/$defs/Deadline"
381
+ attendance:
382
+ type: array
383
+ items:
384
+ $ref: "#/$defs/Attendance"
385
+ vote_records:
386
+ type: array
387
+ items:
388
+ $ref: "#/$defs/VoteRecord"
389
+ minutes:
390
+ type: array
391
+ items:
392
+ $ref: "#/$defs/Minutes"
393
+
394
+ localizations:
395
+ type: array
396
+ items:
397
+ $ref: "#/$defs/MeetingLocalization"
398
+ relations:
399
+ type: array
400
+ items:
401
+ $ref: "#/$defs/MeetingRelation"
402
+ resolution_refs:
403
+ type: array
404
+ items: { type: string }
405
+
406
+ MeetingCollectionMetadata:
407
+ type: object
408
+ description: "Display-level metadata for a MeetingCollection."
409
+ additionalProperties: false
410
+ properties:
411
+ title: { type: string }
412
+ source: { type: string }
413
+
414
+ MeetingCollection:
415
+ type: object
416
+ description: "Top-level wrapper for many Meetings in one file."
417
+ additionalProperties: false
418
+ required: [meetings]
419
+ properties:
420
+ metadata:
421
+ $ref: "#/$defs/MeetingCollectionMetadata"
422
+ meetings:
423
+ type: array
424
+ items:
425
+ $ref: "#/$defs/Meeting"
426
+
427
+ # ====================================================================
428
+ # Enums. Each value-list must equal the matching Edoxen::Enums::*
429
+ # frozen array; spec/edoxen/schema_meeting_enum_sync_spec.rb enforces.
430
+ # ====================================================================
431
+
432
+ MeetingType:
433
+ type: string
434
+ description: "Edoxen::Enums::MEETING_TYPE."
435
+ enum: [plenary, working_group, task_group, ad_hoc, joint, conference_session]
436
+
437
+ MeetingStatus:
438
+ type: string
439
+ description: "Edoxen::Enums::MEETING_STATUS."
440
+ enum: [upcoming, completed, cancelled]
441
+
442
+ AgendaStatus:
443
+ type: string
444
+ description: "Edoxen::Enums::AGENDA_STATUS."
445
+ enum: [draft, final, amended, cancelled, superseded]
446
+
447
+ AgendaItemKind:
448
+ type: string
449
+ description: "Edoxen::Enums::AGENDA_ITEM_KIND."
450
+ enum: [numbered, unnumbered, header, opening, closing]
451
+
452
+ AgendaItemOutcome:
453
+ type: string
454
+ description: "Edoxen::Enums::AGENDA_ITEM_OUTCOME."
455
+ enum: [discussed, resolved, deferred, adopted, withdrawn]
456
+
457
+ HostType:
458
+ type: string
459
+ description: "Edoxen::Enums::HOST_TYPE."
460
+ enum: [national_body, liaison, associate, organizer]
461
+
462
+ MeetingRelationType:
463
+ type: string
464
+ description: "Edoxen::Enums::MEETING_RELATION_TYPE."
465
+ enum: [continues_from, continues_to, joint_with, supersedes, superseded_by, rescheduled_from, rescheduled_to]
466
+
467
+ SourceUrlKind:
468
+ type: string
469
+ description: "Edoxen::Enums::SOURCE_URL_KIND."
470
+ enum: [agenda_pdf, minutes_pdf, resolutions_pdf, report_pdf, register_url, landing_page]
471
+
472
+ ParticipationStatus:
473
+ type: string
474
+ description: "Edoxen::Enums::PARTICIPATION_STATUS."
475
+ enum: [present, absent, apologies, observer, excused]
476
+
477
+ VoteType:
478
+ type: string
479
+ description: "Edoxen::Enums::VOTE_TYPE."
480
+ enum: [affirmative, negative, abstain, absent, not_applicable]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: edoxen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.7.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-06-30 00:00:00.000000000 Z
11
+ date: 2026-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json_schemer
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: unlocodes
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.1'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.1'
55
69
  description: |
56
70
  Edoxen provides a Ruby library for working with resolution models, allowing
57
71
  users to create, manipulate, and serialize resolution data in a structured
@@ -73,31 +87,63 @@ files:
73
87
  - Gemfile
74
88
  - README.adoc
75
89
  - Rakefile
90
+ - TODO.meeting-agenda/01-design-decisions.md
91
+ - TODO.meeting-agenda/02-lutaml-canonical.md
92
+ - TODO.meeting-agenda/03-ruby-models.md
93
+ - TODO.meeting-agenda/04-schema.md
94
+ - TODO.meeting-agenda/05-fixtures.md
95
+ - TODO.meeting-agenda/06-specs.md
96
+ - TODO.meeting-agenda/07-cli.md
97
+ - TODO.meeting-agenda/08-docs.md
98
+ - TODO.meeting-agenda/09-verify-and-release.md
99
+ - TODO.meeting-agenda/10-future-enhancements.md
100
+ - TODO.meeting-agenda/README.md
76
101
  - edoxen.gemspec
77
102
  - exe/edoxen
78
103
  - lib/edoxen.rb
79
104
  - lib/edoxen/_metadata.rb.deprecated
80
105
  - lib/edoxen/action.rb
106
+ - lib/edoxen/agenda.rb
107
+ - lib/edoxen/agenda_item.rb
81
108
  - lib/edoxen/approval.rb
109
+ - lib/edoxen/attendance.rb
82
110
  - lib/edoxen/cli.rb
83
111
  - lib/edoxen/consideration.rb
112
+ - lib/edoxen/date_range.rb
113
+ - lib/edoxen/deadline.rb
84
114
  - lib/edoxen/enums.rb
85
115
  - lib/edoxen/error.rb
116
+ - lib/edoxen/host_ref.rb
117
+ - lib/edoxen/link_checker.rb
86
118
  - lib/edoxen/localization.rb
119
+ - lib/edoxen/location.rb
87
120
  - lib/edoxen/meeting.rb
121
+ - lib/edoxen/meeting_collection.rb
122
+ - lib/edoxen/meeting_collection_metadata.rb
88
123
  - lib/edoxen/meeting_identifier.rb
124
+ - lib/edoxen/meeting_localization.rb
125
+ - lib/edoxen/meeting_relation.rb
126
+ - lib/edoxen/minutes.rb
127
+ - lib/edoxen/minutes_section.rb
128
+ - lib/edoxen/person.rb
129
+ - lib/edoxen/reference.rb
130
+ - lib/edoxen/reference_data.rb
89
131
  - lib/edoxen/resolution.rb
90
132
  - lib/edoxen/resolution_collection.rb
91
133
  - lib/edoxen/resolution_date.rb
92
134
  - lib/edoxen/resolution_metadata.rb
93
135
  - lib/edoxen/resolution_relation.rb
94
136
  - lib/edoxen/resolution_set.rb
137
+ - lib/edoxen/schedule_item.rb
138
+ - lib/edoxen/schedule_item_localization.rb
95
139
  - lib/edoxen/schema_validator.rb
96
140
  - lib/edoxen/source_url.rb
97
141
  - lib/edoxen/structured_identifier.rb
98
142
  - lib/edoxen/url.rb
99
143
  - lib/edoxen/version.rb
144
+ - lib/edoxen/vote_record.rb
100
145
  - schema/edoxen.yaml
146
+ - schema/meeting.yaml
101
147
  - sig/edoxen.rbs
102
148
  homepage: https://github.com/metanorma/edoxen
103
149
  licenses: