Project

edoxen

0.0
The project is in a healthy, maintained state
Edoxen provides a Ruby library for working with resolution models, allowing users to create, manipulate, and serialize resolution data in a structured format. It is built on top of the lutaml-model serialization framework, which provides a flexible and extensible way to define data models and serialize them to YAML or JSON formats.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Runtime

 Project Readme

Edoxen

GitHub Stars GitHub Forks License Build Status RubyGems Version

Purpose

Edoxen is a set of information models used for representing resolution and decision information. They are designed to provide a structured way to model formal resolutions, including their metadata, actions, considerations, and approvals.

The edoxen gem provides a Ruby library for working with these models, allowing users to create, manipulate, and serialize resolution data in a structured format. It is built on top of the lutaml-model serialization framework, which provides a flexible and extensible way to define data models and serialize them to YAML or JSON formats.

This library is particularly useful for standards organizations, committees, and governance bodies that need to maintain structured records of their decision-making processes.

Origin

"Edoxen" is how all resolutions of Ancient Athens started.

"It was the opinion of…​ (the people and city that…​)"

The word "edoxen" originates from the Ancient Greek word edokeō (ἔδοξεν), meaning "it was the opinion of" or "it seemed good to". This term was used in the context of formal resolutions and decisions made by the Athenian assembly, reflecting the collective will and judgment of the citizens.

Features

  • Classes for modeling resolutions, actions, considerations, and approvals

  • Support for resolution collections with rich metadata

  • Structured date handling with semantic meaning (meeting, decision, effective dates)

  • YAML and JSON serialization with round-trip compatibility

  • Structured identifiers and meeting information

  • Resolution relationships and dependencies

  • Integration with the lutaml-model serialization framework

  • Comprehensive YAML schema for validation

  • Command-line interface for validation and processing

  • Real-world compatibility with real-world resolutions (e.g., ISO/TCs, CIPM)

Installation

Add this line to your application’s Gemfile:

gem 'edoxen'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install edoxen

Command Line Interface

The edoxen command provides utilities for working with resolution data files.

Available Commands

Get help on available commands:

$ edoxen help
Commands:
  edoxen help [COMMAND]               # Describe available commands or one specific command
  edoxen normalize YAML_FILE_PATTERN  # Normalize YAML files using Edoxen schema
  edoxen validate YAML_FILE_PATTERN   # Validate YAML files against Edoxen schema

Validation

Validate resolution data files against the Edoxen schema:

# Validate a single file
$ edoxen validate resolutions.yaml

# Validate multiple files
$ edoxen validate file1.yaml file2.yaml file3.yaml

# Validate files using patterns
$ edoxen validate "*.yaml"
$ edoxen validate "resolutions/*.yml"

# Example output
🔍 Validating 3 file(s)...
  resolutions.yaml... ✅ VALID
  file1.yaml... ✅ VALID
  file2.yaml... ❌ INVALID
    - Line 15: Invalid action type 'invalid_type'

📊 Validation Summary:
  Valid files: 2
  Invalid files: 1
  Success rate: 66.7%

Get detailed help for the validate command:

$ edoxen help validate
Usage:
  edoxen validate YAML_FILE_PATTERN

Description:
  Validate YAML files against the Edoxen schema. Supports file patterns and multiple files.

Examples:
  edoxen validate resolutions.yaml
  edoxen validate *.yaml
  edoxen validate "data/*.yml"

Normalization

Normalize YAML files to ensure they conform to the Edoxen schema format.

This command loads the YAML files, parses them through the Edoxen models, and outputs clean, properly formatted YAML.

# Normalize files to a specific output directory
$ edoxen normalize resolutions.yaml --output /path/to/output

# Normalize multiple files
$ edoxen normalize "*.yaml" --output normalized/

# Normalize files in place (overwrites original files)
$ edoxen normalize resolutions.yaml --inplace

# Example output
🔄 Normalizing 2 file(s)...
  resolutions.yaml... ✅ NORMALIZED → /path/to/output/resolutions.yaml
  meeting-notes.yaml... ✅ NORMALIZED → /path/to/output/meeting-notes.yaml

📊 Normalization Summary:
  Successful: 2
  Failed: 0
  Success rate: 100.0%
  Output directory: /path/to/output

Get detailed help for the normalize command:

$ edoxen help normalize
Usage:
  edoxen normalize YAML_FILE_PATTERN

Options:
  [--output=OUTPUT]                              # Output directory for normalized files
  [--inplace], [--no-inplace], [--skip-inplace]  # Modify files in place (no backup)

Description:
  Normalize YAML files using Edoxen schema. This ensures consistent formatting
  and structure according to the Edoxen data models.

Examples:
  edoxen normalize resolutions.yaml --output clean/
  edoxen normalize "*.yaml" --inplace
  edoxen normalize "data/*.yml" --output normalized/

Common use cases

Validating resolution collections

# Validate all YAML files in a directory
$ edoxen validate "resolutions/*.yaml"

# Validate specific meeting files
$ edoxen validate "plenary-*.yaml" "ballots-*.yaml"

Cleaning up legacy data

# Normalize legacy files to new schema format
$ edoxen normalize "legacy/*.yaml" --output clean/

# Update files in place after backup
$ cp -r data/ data-backup/
$ edoxen normalize "data/*.yaml" --inplace

Batch processing

# Validate and normalize in sequence
$ edoxen validate "input/*.yaml" && edoxen normalize "input/*.yaml" --output output/

Usage

Parsing resolution data

From YAML

metadata:
  title: "Resolutions of the 42nd plenary meeting of ISO/TC 154"
  dates:
    - kind: meeting
      start: 2024-01-15
      end: 2024-01-17
  source: "ISO/TC 154 Secretariat"
  urls:
    - href: "https://example.com/meeting"
      title: "Meeting Information"

resolutions:
  - identifier: "2024-01"
    title: "Adoption of new standard"
    category: "Technical resolutions"
    dates:
      - kind: decision
        start: 2024-01-16
    subject: "ISO/TC 154"

    considerations:
      - type: "having"
        message: "reviewed the technical specifications"

    actions:
      - type: "resolves"
        dates:
          - kind: effective
            start: 2024-01-16
        message: "to adopt ISO 12345 as a new standard"

    approvals:
      - type: "affirmative"
        degree: "unanimous"
        message: "UNANIMOUS"
require 'edoxen'

# Parse from YAML string
yaml_content = File.read('resolutions.yaml')
resolution_set = Edoxen::ResolutionSet.from_yaml(yaml_content)

# Access metadata
puts "Title: #{resolution_set.metadata.title}"
puts "Meeting dates: #{resolution_set.metadata.dates.first.start} to #{resolution_set.metadata.dates.first.end}"
puts "Source: #{resolution_set.metadata.source}"

# Access resolutions
resolution_set.resolutions.each do |resolution|
  puts "Resolution: #{resolution.identifier} - #{resolution.title}"
  puts "Category: #{resolution.category}"
  puts "Subject: #{resolution.subject}"

  # Access structured dates
  resolution.dates.each do |date|
    puts "  #{date.kind.capitalize} date: #{date.start}"
  end

  # Access considerations
  resolution.considerations.each do |consideration|
    puts "  Consideration (#{consideration.type}): #{consideration.message}"
  end

  # Access actions
  resolution.actions.each do |action|
    puts "  Action (#{action.type}): #{action.message}"
    action.dates.each do |date|
      puts "    #{date.kind.capitalize} date: #{date.start}"
    end
  end

  # Access approvals
  resolution.approvals.each do |approval|
    puts "  Approval: #{approval.type} (#{approval.degree})"
  end
end

From JSON

require 'edoxen'

# Parse from JSON string
json_content = File.read('resolutions.json')
resolution_set = Edoxen::ResolutionSet.from_json(json_content)

# Access data (same as with YAML)

Creating resolution data

Basic resolution

require 'edoxen'

# Create structured dates
meeting_date = Edoxen::ResolutionDate.new(
  kind: "meeting",
  start: Date.new(2024, 1, 15),
  end: Date.new(2024, 1, 17)
)

decision_date = Edoxen::ResolutionDate.new(
  kind: "decision",
  start: Date.new(2024, 1, 16)
)

effective_date = Edoxen::ResolutionDate.new(
  kind: "effective",
  start: Date.new(2024, 1, 16)
)

# Create metadata
metadata = Edoxen::Metadata.new(
  title: "Resolutions of the 42nd plenary meeting of ISO/TC 154",
  dates: [meeting_date],
  source: "ISO/TC 154 Secretariat",
  urls: [
    Edoxen::Url.new(
      href: "https://example.com/meeting",
      title: "Meeting Information"
    )
  ]
)

# Create a resolution
resolution = Edoxen::Resolution.new(
  identifier: "2024-01",
  title: "Adoption of new standard",
  category: "Technical resolutions",
  subject: "ISO/TC 154",
  dates: [decision_date]
)

# Add considerations
consideration = Edoxen::Consideration.new(
  type: "having",
  message: "reviewed the technical specifications"
)
resolution.considerations = [consideration]

# Add actions
action = Edoxen::Action.new(
  type: "resolves",
  dates: [effective_date],
  message: "to adopt ISO 12345 as a new standard"
)
resolution.actions = [action]

# Add approvals
approval = Edoxen::Approval.new(
  type: "affirmative",
  degree: "unanimous",
  message: "UNANIMOUS"
)
resolution.approvals = [approval]

# Create resolution set
resolution_set = Edoxen::ResolutionSet.new(
  metadata: metadata,
  resolutions: [resolution]
)

Multiple action types

# Actions can have multiple types
action = Edoxen::Action.new(
  type: ["resolves", "requests"],
  dates: [effective_date],
  message: "to adopt the standard and request implementation guidance"
)

Serializing resolution data

To YAML

# Serialize to YAML
yaml_content = resolution_set.to_yaml
File.write('resolutions.yaml', yaml_content)

To JSON

# Serialize to JSON
json_content = resolution_set.to_json
File.write('resolutions.json', json_content)

Data model

The Edoxen gem provides the following models:

                ┌─────────────────────────┐
                │     ResolutionSet       │
                │                         │
                │ ◊metadata               │
                │ ◊resolutions            │
                └───────────┬─────────────┘
                            │ 1..*
            ┌───────────────┴────────────────┐
┌───────────▼─────────────┐     ┌────────────▼───────────┐
│       Resolution        │     │       Metadata         │
│                         │     │                        │
│ •identifier             │     │ •title                 │
│ •title                  │     │ ◊dates                 │
│ •category               │     │ •source                │
│ •subject                │     │ ◊urls                  │
│ ◊dates                  │     └────────────────────────┘
│ ◊considerations         │
│ ◊actions                │
│ ◊approvals              │
└────────────┬────────────┘
             ├────────────────────┬────────────────────┐
             │ 1..*               │ 1..*               │ 1..*
    ┌────────▼────────┐  ┌────────▼────────┐  ┌────────▼────────┐
    │  Consideration  │  │     Action      │  │    Approval     │
    │                 │  │                 │  │                 │
    │ •type           │  │ •type           │  │ •type           │
    │ •message        │  │ •message        │  │ •degree         │
    │ •date_effective │  │ •subject        │  │ •message        │
    └─────────────────┘  └─────────────────┘  └─────────────────┘

ResolutionSet

The main container for resolution collections with metadata.

metadata

A Metadata object containing collection information

resolutions

A collection of Resolution objects

Metadata

Contains metadata about the resolution collection.

title

The collection title as a string

dates

A collection of ResolutionDate objects for meeting dates

source

The source organization as a string

urls

A collection of Url objects for reference links

ResolutionDate

Represents structured date information with semantic meaning.

kind

The type of date as a string

start

The start date as a Date object

end

The end date as a Date object (optional, for date ranges)

Url

Represents a URL reference with optional title.

href

The URL as a string

title

The link title as a string (optional)

Resolution

Represents a single formal resolution.

identifier

The resolution identifier as a string

title

The resolution title as a string

category

The resolution category as a string (optional)

subject

The subject body as a string (optional)

dates

A collection of ResolutionDate objects

considerations

A collection of Consideration objects

actions

A collection of Action objects

approvals

A collection of Approval objects

Action

Represents actions taken within a resolution.

type

The action type(s). Can be a string or array of strings

dates

A collection of ResolutionDate objects

message

The action description as a string

subject

The action subject as a string (optional)

Consideration

Represents considerations that lead to a resolution.

type

The consideration type as a string

message

The consideration description as a string

date_effective

The effective date as a Date object (optional)

Approval

Represents approval information for a resolution.

type

The approval type as a string

degree

The degree of approval as a string (optional)

message

The approval message as a string (optional)

Copyright Ribose.

License

The gem is available as open source under the terms of the 2-Clause BSD License.