edoxen 0.7.2 → 2.1.1
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +17 -1
- data/.rubocop_todo.yml +1 -1
- data/CHANGELOG.md +246 -0
- data/README.adoc +308 -153
- data/edoxen.gemspec +10 -10
- data/lib/edoxen/action.rb +1 -1
- data/lib/edoxen/agenda.rb +4 -7
- data/lib/edoxen/agenda_item.rb +10 -3
- data/lib/edoxen/approval.rb +1 -1
- data/lib/edoxen/attendance.rb +16 -10
- data/lib/edoxen/body_vocabulary_entry.rb +24 -0
- data/lib/edoxen/body_vocabulary_host.rb +29 -0
- data/lib/edoxen/cli.rb +117 -120
- data/lib/edoxen/component_localization.rb +11 -0
- data/lib/edoxen/consideration.rb +2 -2
- data/lib/edoxen/contact.rb +24 -0
- data/lib/edoxen/contact_identifier.rb +13 -0
- data/lib/edoxen/contact_method.rb +16 -0
- data/lib/edoxen/decision.rb +69 -0
- data/lib/edoxen/decision_collection.rb +10 -0
- data/lib/edoxen/decision_date.rb +9 -0
- data/lib/edoxen/{resolution_metadata.rb → decision_metadata.rb} +5 -6
- data/lib/edoxen/decision_relation.rb +11 -0
- data/lib/edoxen/entity_ref.rb +74 -0
- data/lib/edoxen/enums.rb +117 -9
- data/lib/edoxen/error.rb +1 -1
- data/lib/edoxen/extension_attribute.rb +78 -0
- data/lib/edoxen/host_ref.rb +1 -1
- data/lib/edoxen/link_checker.rb +8 -8
- data/lib/edoxen/localization.rb +2 -2
- data/lib/edoxen/localization_host.rb +23 -0
- data/lib/edoxen/meeting.rb +63 -39
- data/lib/edoxen/meeting_collection.rb +1 -2
- data/lib/edoxen/meeting_collection_metadata.rb +3 -1
- data/lib/edoxen/meeting_component.rb +41 -0
- data/lib/edoxen/meeting_extension.rb +25 -0
- data/lib/edoxen/meeting_identifier.rb +1 -1
- data/lib/edoxen/meeting_localization.rb +6 -1
- data/lib/edoxen/meeting_series.rb +21 -0
- data/lib/edoxen/minutes.rb +2 -2
- data/lib/edoxen/minutes_section.rb +8 -11
- data/lib/edoxen/motion.rb +51 -0
- data/lib/edoxen/name.rb +29 -0
- data/lib/edoxen/officer.rb +19 -0
- data/lib/edoxen/officers_host.rb +19 -0
- data/lib/edoxen/person.rb +5 -9
- data/lib/edoxen/physical_venue.rb +15 -0
- data/lib/edoxen/recurrence.rb +27 -0
- data/lib/edoxen/recurrence_by_day.rb +10 -0
- data/lib/edoxen/reference_data.rb +35 -41
- data/lib/edoxen/schema_validator.rb +2 -3
- data/lib/edoxen/source_url.rb +3 -3
- data/lib/edoxen/structured_identifier.rb +2 -2
- data/lib/edoxen/topic.rb +37 -0
- data/lib/edoxen/topic_asset.rb +14 -0
- data/lib/edoxen/topic_document.rb +16 -0
- data/lib/edoxen/venue.rb +80 -0
- data/lib/edoxen/venue_validator.rb +56 -0
- data/lib/edoxen/version.rb +1 -1
- data/lib/edoxen/virtual_venue.rb +15 -0
- data/lib/edoxen/vote_record.rb +17 -13
- data/lib/edoxen/voting.rb +45 -0
- data/lib/edoxen/voting_counts.rb +23 -0
- data/lib/edoxen.rb +40 -13
- data/schema/edoxen.yaml +792 -145
- data/schema/meeting.yaml +600 -142
- data/sig/edoxen.rbs +581 -1
- metadata +57 -20
- data/lib/edoxen/_metadata.rb.deprecated +0 -57
- data/lib/edoxen/location.rb +0 -15
- data/lib/edoxen/resolution.rb +0 -43
- data/lib/edoxen/resolution_collection.rb +0 -10
- data/lib/edoxen/resolution_date.rb +0 -11
- data/lib/edoxen/resolution_relation.rb +0 -11
- data/lib/edoxen/resolution_set.rb +0 -17
- data/lib/edoxen/schedule_item.rb +0 -27
- data/lib/edoxen/schedule_item_localization.rb +0 -21
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0ba69e84d00cf1307fc4887da2270e2c6c8c30ffd437858aaf6afb2e1a58a1dc
|
|
4
|
+
data.tar.gz: 6e4814249a7417323e6d83dde4d4631451c6a70abdea4106c1af55caf5c5d291
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9d5453a5e99eb21be23dc0ba448cd7b44cdd91d3be947f3eb2bbb6d0c4a7cff171b4b95c1e4f477b8b194f72bff06908e88db7d0bb0bdf0163d9db3051ca3d93
|
|
7
|
+
data.tar.gz: 3dbcb645d7d6fc5e8823d553dd7bbbc740464c5a954c43038c9f5ea2680a53a347fd35b082d53c5c6579b2331d4cc9129ea56dbc5b0f1805c2c3fc737487a714
|
data/.rubocop.yml
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
inherit_from: .rubocop_todo.yml
|
|
2
2
|
|
|
3
3
|
AllCops:
|
|
4
|
-
TargetRubyVersion:
|
|
4
|
+
TargetRubyVersion: 3.1
|
|
5
|
+
NewCops: enable
|
|
5
6
|
|
|
6
7
|
Style/StringLiterals:
|
|
7
8
|
Enabled: true
|
|
@@ -13,3 +14,18 @@ Style/StringLiteralsInInterpolation:
|
|
|
13
14
|
|
|
14
15
|
Layout/LineLength:
|
|
15
16
|
Max: 120
|
|
17
|
+
|
|
18
|
+
# The LutaML parser is a self-contained state machine that lives in
|
|
19
|
+
# spec/support/ only. 101 lines for the whole module (struct types +
|
|
20
|
+
# state-machine + helpers) is acceptable; splitting would obscure the
|
|
21
|
+
# design.
|
|
22
|
+
Metrics/ModuleLength:
|
|
23
|
+
Exclude:
|
|
24
|
+
- "spec/support/lutaml_parser.rb"
|
|
25
|
+
|
|
26
|
+
# RSpec top-level describe blocks routinely run past the default
|
|
27
|
+
# threshold; the suite uses focused single-class spec files instead
|
|
28
|
+
# of splitting for size's own sake.
|
|
29
|
+
Metrics/BlockLength:
|
|
30
|
+
Exclude:
|
|
31
|
+
- "spec/**/*.rb"
|
data/.rubocop_todo.yml
CHANGED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [2.1.1] — 2026-07-06
|
|
9
|
+
|
|
10
|
+
Patch release. Bundles the v2.2 OCP refactor (Contact family), the
|
|
11
|
+
post-v2.2 audit cleanup, and the gem↔model canonical-schema sync spec.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **Contact family** (v2.2 OCP refactor): `Contact`, `Name`,
|
|
16
|
+
`ContactMethod`, `ContactIdentifier` classes plus
|
|
17
|
+
`CONTACT_METHOD_KIND` and `CONTACT_IDENTIFIER_KIND` enums. `Person`
|
|
18
|
+
now inherits from `Contact`; the hard-coded `email` / `phone` /
|
|
19
|
+
`orcid` fields are replaced by typed `contact_methods[]` and
|
|
20
|
+
`identifiers[]` collections. New channel/identifier kinds land via
|
|
21
|
+
the enum (or `other` + extensions) — no model change (OCP).
|
|
22
|
+
- **BodyVocabularyHost / LocalizationHost / OfficersHost modules.**
|
|
23
|
+
DRY the `body_vocabulary` + `canonical_type_for` lookup, the
|
|
24
|
+
`in_language` + `primary_localization` accessors, and the
|
|
25
|
+
`officers_with_role` + `chair` accessors across the classes that
|
|
26
|
+
share them.
|
|
27
|
+
- **Behavioral specs for Contact, ContactMethod, ContactIdentifier,
|
|
28
|
+
Name** — each with the typed ExtensionAttribute round-trip via
|
|
29
|
+
`it_behaves_like "extension host"`.
|
|
30
|
+
- **MECE parity spec** (`spec/edoxen/mece_parity_spec.rb`) covering
|
|
31
|
+
all four v2.1 bidirectional pairs (Motion↔Decision, Decision↔
|
|
32
|
+
Component, Decision↔Topic, Motion↔Voting). Guards the v3.0
|
|
33
|
+
stored-side removal.
|
|
34
|
+
- **Canonical-enum ≤5 architectural invariant** in
|
|
35
|
+
`body_vocabulary_spec.rb`.
|
|
36
|
+
- **Body-vocabulary metadata YAML round-trip** on both
|
|
37
|
+
`DecisionMetadata` and `MeetingCollectionMetadata`.
|
|
38
|
+
- **Cross-schema sync spec** (`spec/edoxen/schema_cross_file_sync_spec.rb`):
|
|
39
|
+
23 shared `$defs` between `schema/edoxen.yaml` and `schema/meeting.yaml`
|
|
40
|
+
enforced byte-equal. Discovery spec catches future omissions from
|
|
41
|
+
`SHARED_NAMES`.
|
|
42
|
+
- **Gem↔model canonical schema sync spec**
|
|
43
|
+
(`spec/edoxen/schema_model_canonical_sync_spec.rb`, 126 examples):
|
|
44
|
+
every `$defs` entry in the gem's mirror schemas is enforced
|
|
45
|
+
byte-equal to the model's canonical `schema/decision-collection.yaml`
|
|
46
|
+
and `schema/meeting.yaml`. Skips when the model repo isn't checked
|
|
47
|
+
out.
|
|
48
|
+
|
|
49
|
+
### Changed
|
|
50
|
+
|
|
51
|
+
- **EntityRef XOR contract enforced.** `EntityRef#valid?` now returns
|
|
52
|
+
true only when exactly one of `urn` / `identifier` / `local_ref` is
|
|
53
|
+
set (was: any number ≥1). New `#multiple_identities?` predicate
|
|
54
|
+
flags ambiguous data. The wire contract documented in
|
|
55
|
+
`edoxen-model/TODO.refactor/44-entityref-typed-cross-references.md`
|
|
56
|
+
is now truthful.
|
|
57
|
+
- **`Motion#pending?` derived from `Edoxen::Enums::MOTION_TERMINAL`.**
|
|
58
|
+
New constant partitions `MOTION_STATUS` cleanly; a coverage spec
|
|
59
|
+
asserts the union equals `MOTION_STATUS` (MECE invariant).
|
|
60
|
+
- **CLI refactored to a Profile-based dispatch.** `validate` /
|
|
61
|
+
`normalize` / `validate-meetings` / `normalize-meetings` collapse to
|
|
62
|
+
one-line delegations; option parsing and batch scaffolding share a
|
|
63
|
+
single runner.
|
|
64
|
+
- **VenueValidator dispatches on `kind`, not `is_a?`.** Wire-parsed
|
|
65
|
+
Venues (always flat `Venue`, never `PhysicalVenue`) now validate
|
|
66
|
+
correctly.
|
|
67
|
+
- **`LutamlParser.parse` refactored into five small state-handler
|
|
68
|
+
methods.** Cyclomatic and perceived complexity now within rubocop
|
|
69
|
+
limits. `LutamlEnum.values` renamed to `.items` to avoid
|
|
70
|
+
`Struct#values` / `#entries` override.
|
|
71
|
+
- **`Name#display` single-pass reject** (was: two passes).
|
|
72
|
+
- **`annexOf` / `hasAnnex` → `annex_of` / `has_annex`** across gem
|
|
73
|
+
Ruby, gem schema, model lutaml, and model schema. The camelCase
|
|
74
|
+
outliers were the only wire-form inconsistency in any enum.
|
|
75
|
+
|
|
76
|
+
### Removed
|
|
77
|
+
|
|
78
|
+
- **Dead identity `key_value` blocks** on `EntityRef` and
|
|
79
|
+
`BodyVocabularyEntry` (lutaml-model auto-emits identity maps).
|
|
80
|
+
- **`respond_to?(:to_s)`** in `EntityRef#identities_set` — replaced
|
|
81
|
+
with a `case` over `nil` / `String` / else.
|
|
82
|
+
- **Duplicate `canonical_type_for`**, `in_language` /
|
|
83
|
+
`primary_localization`, and `officers_with_role` / `chair`
|
|
84
|
+
implementations — moved to the new shared modules.
|
|
85
|
+
|
|
86
|
+
### Infrastructure
|
|
87
|
+
|
|
88
|
+
- **`.rubocop.yml` `TargetRubyVersion` 2.6 → 3.1.** `NewCops: enable`.
|
|
89
|
+
`Metrics/ModuleLength` excluded for the spec-side LutaML parser;
|
|
90
|
+
`Metrics/BlockLength` excluded for spec files generally.
|
|
91
|
+
- **`edoxen.gemspec` `required_ruby_version` 3.0 → 3.1.** Ruby 3.0
|
|
92
|
+
reached EOL March 2024. Migrated to `YAML.safe_load_file`.
|
|
93
|
+
- **`TODO.*/` added to `.gitignore`** — local planning notes never
|
|
94
|
+
committed.
|
|
95
|
+
- **`entry.country` → `entry.country_iso2`** in the `edoxen iata` CLI
|
|
96
|
+
(was calling a method that didn't exist on `Iata::Entry`).
|
|
97
|
+
|
|
98
|
+
### Test results
|
|
99
|
+
|
|
100
|
+
1339 examples, 0 failures. 0 rubocop offenses.
|
|
101
|
+
|
|
102
|
+
## [2.1.0] — 2026-07-05
|
|
103
|
+
|
|
104
|
+
Edoxen v2.1 is a backwards-compatible minor release that tightens the
|
|
105
|
+
profile mechanism and adds the LutaML↔Ruby regression net.
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
### Added
|
|
109
|
+
|
|
110
|
+
- **LutaML ↔ Ruby sync spec** (`spec/edoxen/lutaml_ruby_sync_spec.rb`):
|
|
111
|
+
walks every `class` block in `edoxen-model/models/*.lutaml` and
|
|
112
|
+
asserts the matching `Edoxen::*` Ruby class declares the same
|
|
113
|
+
attribute names + collection flags. Closes the root-cause gap from
|
|
114
|
+
the v2.0 drift audit.
|
|
115
|
+
- **LutaML enum ↔ Ruby sync** (in the same spec): walks every `enum`
|
|
116
|
+
block and asserts value-for-value equality with the matching
|
|
117
|
+
`Edoxen::Enums::*` constant.
|
|
118
|
+
- **Typed ExtensionAttribute variants**: `integer_value`, `float_value`,
|
|
119
|
+
`boolean_value`, `date_value`, `date_time_value` plus a `type`
|
|
120
|
+
discriminator. New `#typed_value` reader picks the right variant.
|
|
121
|
+
String values still use the bare `value:` wire name (v2.0 back-compat).
|
|
122
|
+
|
|
123
|
+
### Changed
|
|
124
|
+
|
|
125
|
+
- **MeetingExtension field semantics documented.** `kind` is the
|
|
126
|
+
in-profile discriminator; `ref` is the URN of an external profile
|
|
127
|
+
document. Field behavior is unchanged; the docs are now explicit.
|
|
128
|
+
- **LutaML model files** synced to match the gem after the drift audit
|
|
129
|
+
closed four real drifts (Voting.method, Agenda three drifts, missing
|
|
130
|
+
url.lutaml, vestigial subject_body.lutaml).
|
|
131
|
+
|
|
132
|
+
### Removed
|
|
133
|
+
|
|
134
|
+
- **Recursive `extensions[]` slot on MeetingExtension.** YAGNI — no
|
|
135
|
+
documented use case. Profiles needing nesting use dotted keys
|
|
136
|
+
(`vote.count`, `vote.method`) in `attributes[]`.
|
|
137
|
+
|
|
138
|
+
### Compatibility
|
|
139
|
+
|
|
140
|
+
v2.0 fixtures continue to parse and round-trip unchanged. The v2.0
|
|
141
|
+
bare `value: String` wire shape on ExtensionAttribute still works;
|
|
142
|
+
the gem routes it into the string variant with `type` defaulted to
|
|
143
|
+
`"string"`.
|
|
144
|
+
|
|
145
|
+
## [2.0.0] — 2026-07-04
|
|
146
|
+
|
|
147
|
+
Edoxen v2.0 broadens the model from a standards-body-specific Resolution
|
|
148
|
+
model to a **generic meeting, agenda, motion, voting, and decision
|
|
149
|
+
model** with profile extensions for domain-specific concepts.
|
|
150
|
+
|
|
151
|
+
### Post-launch drift closures (2026-07-04)
|
|
152
|
+
|
|
153
|
+
Per the post-v2 model↔gem drift audit (`edoxen-model/TODO.refactor/20-post-v2-gem-drift.md`):
|
|
154
|
+
|
|
155
|
+
- Added `extensions: MeetingExtension[0..*]` to `DecisionMetadata` —
|
|
156
|
+
closes the inverse drift where the gem was missing what every other
|
|
157
|
+
v2 collection-level entity already had.
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
### Breaking changes
|
|
161
|
+
|
|
162
|
+
- Renamed `Resolution` → `Decision`. `Resolution` is now a `DecisionKind` value.
|
|
163
|
+
- Renamed `ResolutionCollection` → `DecisionCollection`.
|
|
164
|
+
- Renamed `ResolutionMetadata` → `DecisionMetadata`.
|
|
165
|
+
- Renamed `ResolutionDate` → `DecisionDate`; `ResolutionDateType` → `DecisionDateType`.
|
|
166
|
+
- Renamed `ResolutionRelation` → `DecisionRelation`; `ResolutionRelationType` → `DecisionRelationType`.
|
|
167
|
+
- Renamed `ResolutionType` → `DecisionKind` (with expanded values: resolution, order, ruling, determination, recommendation, statement, finding, opinion, other).
|
|
168
|
+
- Renamed `Voting.method` → `Voting.voting_method` (avoids Ruby Object#method conflict).
|
|
169
|
+
- Removed `Meeting.virtual: Boolean`. Replaced with polymorphic `Meeting.venues: Venue[]`.
|
|
170
|
+
- Removed `Meeting.chair` and `Meeting.secretary` direct shortcuts. Replaced with `Meeting.officers: Officer[]` (role discriminates). `Meeting#chair` and `Meeting#secretary` remain as lookup helpers.
|
|
171
|
+
- Removed `Meeting.schedule: ScheduleItem[]`. Replaced with `Meeting.components: MeetingComponent[]` (flat).
|
|
172
|
+
- Removed `Meeting.host` (singular String). Use `Meeting.hosts: HostRef[]`.
|
|
173
|
+
- Removed `Meeting.year` (derivable from `date_range.start`).
|
|
174
|
+
- Renamed `Meeting.resolution_refs` → `Meeting.decisions` (inline Decision objects).
|
|
175
|
+
- Removed `AgendaItem.resolution_ref`. Use `AgendaItem.decision_ref`.
|
|
176
|
+
- Removed `Agenda.opening_session` / `Agenda.closing_session` (ScheduleItem references). These are now `MeetingComponent`s.
|
|
177
|
+
- Removed `VoteRecord.resolution_ref`. Use `VoteRecord.decision_ref` + `VoteRecord.voting_ref`.
|
|
178
|
+
- lutaml-model attribute type `:datetime` is now `:date_time` (lutaml-model 0.8+ naming).
|
|
179
|
+
|
|
180
|
+
### Added
|
|
181
|
+
|
|
182
|
+
- `Decision` base type with `kind`, `status`, and procedural fields
|
|
183
|
+
(`brought_by_motions`, `about_topics`, `made_in_component`).
|
|
184
|
+
- `Motion` entity — procedural act with state machine:
|
|
185
|
+
`introduced → seconded → debating → question_put → voting → carried/negatived/withdrawn/lapsed`.
|
|
186
|
+
- `Voting` entity — vote state machine:
|
|
187
|
+
`called → in_progress → decided | withdrawn | deferred`; `voting_method`,
|
|
188
|
+
`counts`, `casting_vote`, `vote_records`.
|
|
189
|
+
- `VotingCounts` — ayes / noes / abstentions / absent; derived `#total`,
|
|
190
|
+
`#margin`, `#tied?`.
|
|
191
|
+
- `Topic`, `TopicDocument`, `TopicAsset` — the subject of discussion.
|
|
192
|
+
Cross-meeting threading via `resumption_of`.
|
|
193
|
+
- `MeetingSeries` — parent of recurring meetings.
|
|
194
|
+
- `MeetingComponent` — flat sub-events (replaces ScheduleItem). Kinds:
|
|
195
|
+
track, session, debate, breakout, bof, keynote, opening, closing,
|
|
196
|
+
break, reception, etc.
|
|
197
|
+
- `ComponentLocalization` — per-language content for a component.
|
|
198
|
+
- `Officer` + `OfficerRole` (replaces chair/secretary shortcuts).
|
|
199
|
+
- `MeetingExtension` + `ExtensionAttribute` — profile mechanism
|
|
200
|
+
(ISO 8601-2 §15). Every core entity has an `extensions[]` slot.
|
|
201
|
+
- `Recurrence` + `RecurrenceByDay` — structured ISO 8601-2 §13
|
|
202
|
+
(queryable, not opaque RRULE).
|
|
203
|
+
- `Venue` polymorphic (kind: physical | virtual). Single flat class on
|
|
204
|
+
the wire; `kind` discriminates which fields are expected.
|
|
205
|
+
- `PhysicalVenue`, `VirtualVenue` — Ruby subclasses for type-checking
|
|
206
|
+
and helper methods.
|
|
207
|
+
- `VenueValidator` — validates Venue instances against the `unlocodes`
|
|
208
|
+
and `iata` gems; optionally auto-populates `city` / `country_code`
|
|
209
|
+
from the UN/LOCODE registry.
|
|
210
|
+
- Extended `Attendance` with `role` (AttendanceRole) and `response`
|
|
211
|
+
(AttendanceResponse, from iCalendar PARTSTAT, plain English).
|
|
212
|
+
- Extended `AgendaItem` with `topics[]` and `components[]`.
|
|
213
|
+
- Extended `Person` with `kind` and `orcid`.
|
|
214
|
+
- Extended `Meeting` with `urn`, `ordinal`, `series_ref`, `visibility`,
|
|
215
|
+
`recurrence`, `landing_url`, `registration_url`.
|
|
216
|
+
- New enums: `VenueKind`, `VirtualFeature`, `Visibility`,
|
|
217
|
+
`AttendanceRole`, `AttendanceResponse`, `ComponentKind`,
|
|
218
|
+
`DecisionKind`, `DecisionStatus`, `MotionStatus`, `VotingStatus`,
|
|
219
|
+
`VotingMethod`, `VotingOutcome`, `TopicStatus`, `OfficerRole`,
|
|
220
|
+
`RecurrenceFreq`.
|
|
221
|
+
- CLI: `edoxen iata CODE` command (parallels `edoxen unlocode`).
|
|
222
|
+
- RBS signatures (`sig/edoxen.rbs`) for every public class and method.
|
|
223
|
+
|
|
224
|
+
### Integration
|
|
225
|
+
|
|
226
|
+
- `unlocodes` gem for UN/LOCODE validation (runtime dependency).
|
|
227
|
+
- `iata` gem for IATA code validation (runtime dependency).
|
|
228
|
+
|
|
229
|
+
### References
|
|
230
|
+
|
|
231
|
+
- iCalendar (RFC 5545/7986/5546/9253) — referenced, not duplicated.
|
|
232
|
+
- ISO 8601-2 (2026) §13 for recurrence, §15 for profile mechanism.
|
|
233
|
+
|
|
234
|
+
### Migration
|
|
235
|
+
|
|
236
|
+
See the [migration guide](https://github.com/edoxen/edoxen.github.io/blob/main/docs/migration-v2.md)
|
|
237
|
+
for the full v0.x → v2.0 transformation.
|
|
238
|
+
|
|
239
|
+
## [1.0.0] — 2026-06-30
|
|
240
|
+
|
|
241
|
+
Initial public release. Standards-body-focused Resolution model with
|
|
242
|
+
Meeting + Agenda + Minutes + Attendance + VoteRecord side.
|
|
243
|
+
|
|
244
|
+
## [0.1.0] — 2025-XX-XX
|
|
245
|
+
|
|
246
|
+
Initial development release.
|