Suma: utility for the STEP Unified Model-driven Architecture
Purpose
SUMA, the "STEP Unified Model-Based Standards Architecture", is a authoring and publication system developed for the management of EXPRESS schemas and its documentation.
This utility is used by the ISO 10303 collection to build the following artifacts:
-
the STEP Resource Library (SRL)
Features
-
EXPRESS schema management for STEP and other schema collections
-
Document collection building and compilation
-
Referential closure validation over the whole corpus
-
EXPRESS links validation and extraction
-
Schema listing file generation
-
OWL/Turtle projection with structural validation
-
Typed change manifests, changelogs, and dependency impact analysis
-
Glossarist terminology and hierarchical registers with edition metadata
-
Dereferenceable URN artifacts (canonical JSON + static HTML)
-
Incremental, parallel, and cached corpus builds
-
Reproducible outputs with verifiable, optionally signed provenance
-
Integration with the Metanorma ecosystem
Installation
$ gem install sumaUsage: CLI
General
# Defaults to `suma help`
$ suma
Commands:
suma build METANORMA_SITE_MANIFEST # Build collection from site manifest
suma check_svg_quality [PATH] # Check SVG quality
suma compare TRIAL_SCHEMA REFERENCE_SCHEMA # Compare schemas; typed changes, impact
suma convert-jsdai XML_FILE IMAGE_FILE OUTPUT_DIR # Convert JSDAI XML and image files to SVG and EXP
suma export *FILES -o OUTPUT # Export EXPRESS schemas or project them to OWL
suma extract-terms SCHEMA_MANIFEST_FILE GLOSSARIST_OUTPUT_PATH # Extract entity concepts to Glossarist v3
suma ingest-translations CONCEPTS_DIR TRANSLATIONS_FILE [-o OUT] # Overlay translated content onto extracted concepts
suma generate-register SCHEMA_MANIFEST_FILE OUTPUT_PATH # Generate hierarchical register.yaml
suma generate-schemas METANORMA_MANIFEST_FILE SCHEMA_MANIFEST_FILE # Generate a schema manifest from a site manifest
suma reformat EXPRESS_FILE_PATH # Reformat EXPRESS files
suma resolve [URN] --manifest=MANIFEST -o OUTPUT # Emit canonical JSON + HTML for URNs
suma package-gcr CONCEPTS_DIR --register=REGISTER -o OUTPUT # Package concepts into a .gcr archive
suma serve DIRECTORY # Serve resolved artifacts (Accept negotiation)
suma validate SUBCOMMAND ...ARGS # Validate express documentsBuild command
The build command processes a Metanorma site manifest and generates the specified output.
$ suma build METANORMA_SITE_MANIFEST [options]Parameters:
METANORMA_SITE_MANIFEST-
This is the path to the Metanorma site manifest, typically
metanorma.yml.
Options:
--[no-]compile-
Compile or skip compilation of collection (default: true)
-
--schemas-all-path=PATH,-s PATH -
Generate file that contains all schemas in the collection
--[no-]staged-
Memory-bounded build: compile each member in its own process, then reinflate
--[no-]incremental-
Re-render only changed schemas and their transitive dependents
--state-file=PATH-
Incremental build state file (default:
plain_schemas/.suma-build-state.json) --jobs=N-
Concurrent schema export workers (document compilation stays sequential; default: 1)
--provenance=PATH-
Write a provenance manifest (sha256 of inputs/outputs + toolchain versions)
--sign=METHOD-
Sign the provenance manifest:
minisignorsigstore --sign-key=PATH-
Signing key; minisign requires it, sigstore signs keylessly when omitted
The generated schemas-*.yaml file name is derived from the input file name
with the word metanorma replaced with schemas.
Repeated builds reuse work and are reproducible: a schema document is rendered
again only when its adoc, schema config, schema source, or the rendering
toolchain changed, and the collection render is skipped entirely when no site
input changed (state: _site/.suma-site-build.json). Metanorma’s random
manifest identifiers and per-document type markers are canonicalized, so two
identical builds produce byte-identical output. A provenance manifest covers
schema_docs, plain_schemas, and _site, and verification reports files
that appeared under those roots without being recorded (build metadata such as
the site state file is excluded explicitly).
Top-level schema documents render with live cross-reference links: every
schema.entity and entity.attribute reference Expressir emits becomes an
in-page link, and suma validate anchors verifies that no link is dead.
$ bundle exec suma build metanorma-test.yml$ bundle exec suma build metanorma-srl.yml$ bundle exec suma build --no-compile metanorma-srl.yml
# => generates schemas-srl.ymlAll documents need to have a schemas.yaml in their document root that lists
out which schemas the document includes.
Reformat command
The reformat command provides utilities for reformatting EXPRESS files.
$ suma reformat EXPRESS_FILE_PATH [options]Parameters:
EXPRESS_FILE_PATH-
Path to an EXPRESS file or a folder containing EXPRESS files
Options:
-
--[no-]recursive,-r -
Select EXPRESS files recursively based on the specified folder path (default: false)
$ bundle exec suma reformat `pwd` -rThis command:
-
Loads the EXPRESS files specified in the
EXPRESS_FILE_PATH -
Reformats and saves the loaded EXPRESS files
Validate command
General
The validate command groups various validation utilities for EXPRESS documents.
$ suma validate SUBCOMMAND [options]Subcommands:
links-
Validate EXPRESS links
closure-
Validate referential closure over the whole corpus
Links subcommand
The links subcommand extracts and validates EXPRESS links without creating intermediate files.
$ suma validate links SCHEMAS_FILE DOCUMENTS_PATH [OUTPUT_FILE]Parameters:
SCHEMAS_FILE-
Path to the schemas file (default: "schemas-srl.yml")
DOCUMENTS_PATH-
Path to the documents directory (default: "documents")
OUTPUT_FILE-
Path to write validation results (default: "validation_results.txt")
$ bundle exec suma validate links schemas-srl.yml documents validation_results.txtThis command:
-
Loads the schemas specified in the
SCHEMAS_FILE -
Searches for EXPRESS links in all AsciiDoc files in the
DOCUMENTS_PATH -
Validates these links against the loaded schemas
-
Writes validation results to the
OUTPUT_FILE -
Provides progress bars to track schema loading and link validation
Closure subcommand
The closure subcommand extracts every EXPRESS-internal reference (attribute
domains, SELECT and aggregate branches, where-rule expressions, subtype
constraints, supertype/subtype lists, rule applies-to, and USE/REFERENCE
interfaces) and resolves it against the corpus graph. It exits non-zero when
any reference does not resolve, which makes it usable as a CI gate
(rake closure runs it on the fixture corpus).
$ suma validate closure SCHEMAS_MANIFEST [DOCUMENTS_PATH] [--format terminal|json|yaml]When DOCUMENTS_PATH is given, documentation-layer link failures are merged
into the same report.
Anchors subcommand
The anchors subcommand checks rendered schema documents for dead links:
every Expressir cross-reference (…,
…) emitted in a compiled doc_*.adoc must have a
matching anchor in its rendered doc_*.html, and every in-page href must
point at an existing id. It exits non-zero on violations.
$ suma validate anchors SCHEMA_DOCS_PATHGenerate schemas command
The suma generate-schemas command generates an EXPRESS schema manifest file
containing all schemas of documents referenced in the Metanorma manifest file,
recursively.
$ suma generate-schemas METANORMA_MANIFEST_FILE SCHEMA_MANIFEST_FILE [options]Parameters:
METANORMA_MANIFEST_FILE-
Path to the Metanorma manifest file (e.g.: "metanorma-smrl-all.yml")
Options:
-
--exclude_path,-e -
Exclude schemas by pattern (e.g.
*_lf.exp)
$ bundle exec suma generate-schemas metanorma-smrl-all.yml schemas-smrl-all.yml
# => generates schemas-smrl-all.yml*_lf.exp
$ bundle exec suma generate-schemas metanorma-smrl-all.yml schemas-smrl-all.yml -e *_lf.exp
# => generates schemas-smrl-all.yml without schemas with names like *_lf.expAll documents need to have a schemas.yaml in their document root that lists
out which schemas the document includes.
Extract terms command
The "extract terms" command is implemented for ISO 10303-2, and could also be used for other EXPRESS schema collections that require term extraction for glossary or dictionary applications.
The suma extract-terms command extracts terms from EXPRESS schemas and
generates a Glossarist v3 dataset in the output directory. This command processes
various types of STEP schemas and creates standardized terminology datasets
suitable for glossary and dictionary applications.
$ suma extract-terms SCHEMA_MANIFEST_FILE GLOSSARIST_OUTPUT_PATH [options]Parameters:
SCHEMA_MANIFEST_FILE-
Path to the schema manifest file that lists all schemas to process (e.g., "schemas-smrl-all.yml")
GLOSSARIST_OUTPUT_PATH-
Path to the output directory where the Glossarist v3 dataset will be generated
Options:
-
--language_code,-l -
Language code for the Glossarist dataset (default: "eng")
--edition=N-
Owning edition recorded on each concept
--language-codes=a,b-
Additional linked localization languages (the primary language is always included)
Supported schema types
The command supports extraction from the following EXPRESS schema types:
-
ARM (application reference model) - application module schemas ending with
_arm -
MIM (module implementation model) - application module schemas ending with
_mim -
Resource schemas - General resource schemas
-
BOM (business object model) - business object model schemas ending with
_bom
|
Note
|
The "Long Form" EXPRESS schemas (ending with _lf) should be excluded
from the manifest file as they do not contain definitions of ENTITY objects.
|
Extracted concepts
The command extracts ENTITY objects from EXPRESS schemas, with the following
information:
-
a unique identifier in form of
{schema_name}.{entity_name}(whereentity_nameis a slug derived from theENTITYname); -
a generated definition depending on the schema type and entity type;
-
a "Note to entry" from its first coherent textual element described in Annotated EXPRESS;
-
source information including: schema name and schema version;
-
domain in the pattern of:
{domain_type}: {schema_name}, wheredomain_typeis one ofapplication module,resource, orbusiness object model.
Output format
The command generates a Glossarist v3 compliant dataset with:
-
concept/directory containing concept definition files in YAML -
localized_concept/directory containing localized concept files in YAML
$ bundle exec suma extract-terms schemas-smrl-all.yml glossarist_output
# => generates glossarist_output/concept/*.yaml and
# glossarist_output/localized_concept/*.yaml$ bundle exec suma extract-terms schemas-activity-modules.yml terms_output
# => processes only schemas listed in the manifest fileIngest translations command
The suma ingest-translations command overlays translated content onto
extracted concepts. A translations file is a YAML sequence of
localized-concept documents, each keyed by concept id (or localized
UUID) and carrying the fields to apply:
- concept_id: example_schema.part
data:
language_code: fra
terms:
- designation: pièce
type: expression
normative_status: preferred
definition:
- content: "Composant d'un assemblage."Every field the entry provides replaces that localization’s field; every
field it omits keeps the source-language content (a language absent from
the extracted concepts is created with the same stable UUID convention
the linked localizations use). Updated concepts are written in place, or
to --output when given.
$ suma ingest-translations CONCEPTS_DIR TRANSLATIONS_FILE [-o OUTPUT_DIR]Generate register command
The suma generate-register command reads an EXPRESS schema manifest and
emits a Glossarist v3 register.yaml with hierarchical sections. The
output is used by the concept browser to render a navigable sidebar of
sections and to resolve concept cross-references.
$ suma generate-register SCHEMA_MANIFEST_FILE OUTPUT_PATH -u URN --id ID --ref REFParameters:
SCHEMA_MANIFEST_FILE-
Path to the schema manifest (e.g., "schemas-smrl-part-2.yml")
OUTPUT_PATH-
Directory where
register.yamlwill be written
Options:
-
--urn,-u -
Base URN prefix for the dataset (e.g.
urn:iso:std:iso:10303:-2:ed-2:en:tech:*). The wildcard is stripped for the base URN and kept inurnAliases. Required. --year=N-
Edition year recorded on the register
--supersedes=URN-
URN/ref of the superseded edition
--edition=N-
Edition number, tagged as
edition:N; every register also carries adataset:<id>tag so sibling editions can be grouped.
The URN is fully configurable — every component can be changed to match the dataset being exported. The general structure is:
urn:iso:std:iso:<part>:ed-<edition>:<lang>:tech:*
For example, to export edition 3 in French:
--urn urn:iso:std:iso:10303:-2:ed-3:fr:tech:*
The current ISO 10303-2 SMRL data is edition 2; use ed-2 unless you are
re-publishing an earlier edition.
--id-
Dataset identifier (e.g.
iso10303-2-express). Required. --ref-
Human-readable dataset reference label (e.g.
ISO 10303-2 EXPRESS Concepts). Required. -
--language_code,-l -
Language code for section names (default: "eng")
The generated register contains two top-level groups:
-
Resources — integrated resource schemas (path contains
schemas/resources/) -
Application Modules — ARM and MIM schemas (path contains
schemas/modules/)
Each schema gets a human-readable name via the SchemaNaming module
(e.g. topology_schema → "Resource: Topology", Activity_method_assignment_mim → "Module: Activity Method Assignment (MIM)"). Acronyms (AIC, AEC, BREP, 2D, 3D) are preserved; function words (as, of, the) are lowercased per ISO title-case convention.
Convert JSDAI image outputs to SVG and Annotated EXPRESS
The suma convert-jsdai command converts JSDAI EXPRESS-G diagram outputs
(XML + image file) into SVG and Annotated EXPRESS formats suitable for
Metanorma documentation.
JSDAI (Java Step Data Access Interface) Java tool is used by ISO/TC 184/SC 4 to create EXPRESS-G diagrams.
JSDAI generates two files for each diagram:
-
a raster image file (GIF or JPEG)
-
an XML file containing image metadata and clickable area definitions
This command converts these inputs into:
-
an SVG file that embeds the raster image as Base64 with clickable rectangular areas
-
an Annotated EXPRESS file with a Metanorma
svgmapblock for easy copy-paste
$ suma convert-jsdai XML_FILE IMAGE_FILE OUTPUT_DIRWhere:
XML_FILE-
Path to the JSDAI XML file (e.g., "action_schemaexpg1.xml")
IMAGE_FILE-
Path to the raster image file (GIF or JPEG format)
OUTPUT_DIR-
Path to the output directory where SVG and EXP files will be generated
$ bundle exec suma convert-jsdai \
documents/resources/action_schema/action_schemaexpg1.xml \
documents/resources/action_schema/action_schemaexpg1.gif \
output/
# => generates:
# output/action_schemaexpg1.svg
# output/action_schemaexpg1.expThis command:
-
Parses the JSDAI XML file to extract image metadata and clickable area definitions
-
Reads the raster image file and converts it to base64 format
-
Generates an SVG file with:
-
The embedded base64-encoded image
-
Clickable rectangular areas (
<a>and<rect>elements) corresponding to the XML definitions -
Proper viewBox dimensions matching the source image
-
-
Generates an Annotated EXPRESS file containing:
-
A Metanorma
svgmapblock with numbered cross-references -
Proper anchor IDs for document integration
-
Cross-reference targets extracted from the XML href attributes
-
The generated SVG and EXP files work together through a numbered mapping system:
-
In the SVG file, each clickable area is assigned a sequential number:
<a href="1"><rect .../></a> <a href="2"><rect .../></a> <a href="3"><rect .../></a>
-
In the EXPRESS file, the
svgmapblock maps these numbers to targets which are either EXPRESS or AsciiDoc anchors.Example 4. Resource schema diagram with SVG and Annotated EXPRESS cross-references(*"action_schema.__expressg" [[action_schema_expg1]] [.svgmap] ==== image::action_schemaexpg1.svg[] * <<express:basic_attribute_schema>>; 1 * <<express:action_schema>>; 2 * <<express:support_resource_schema>>; 3 ==== *)Example 5. Module schema diagram with SVG and Annotated EXPRESS cross-references(*"Activity_mim.__expressg" [[Activity_mim_expg1]] [.svgmap] ==== image::mimexpg1.svg[] * <<Activity_mim_expg2>>; 1 * <<express:action_schema>>; 2 * <<Activity_method_mim_expg1>>; 3 * <<express:basic_attribute_schema>>; 4 * <<express:management_resources_schema>>; 5 ==== *) -
When rendered in Metanorma, clicking on "area 1" in the SVG, will navigate to the
express:basic_attribute_schemaanchor, "area 2" toexpress:action_schema, and so on.
The mapping is derived from the original JSDAI XML file, where each <img.area>
element contains:
-
coordsattribute -
converted to SVG
<rect>dimensions -
hrefattribute -
converted to EXPRESS cross-reference target in the
svgmapblock - Sequential position
-
assigned as the numbered href in both SVG and
svgmaplist
Export schemas command
General
The suma export command exports EXPRESS schemas from manifest files and/or
standalone EXPRESS files to a specified output directory.
This command is useful for extracting plain or annotated EXPRESS schemas for distribution or further processing.
$ suma export -o OUTPUT_DIR FILE1 [FILE2 FILE3 ...]Parameters:
FILE1 [FILE2 FILE3 …]-
One or more files to export. Each file can be:
- An EXPRESS schema manifest file (
.yml,.yaml) -
schemas listed in the manifest will be exported
- An standalone EXPRESS file (
.exp) -
the schema will be exported directly
- An EXPRESS schema manifest file (
Options:
-
--output=PATH,-o PATH -
(required) Output directory path
--[no-]annotations-
Include annotations (remarks/comments) in exported schemas (default: false)
--[no-]zip-
Create ZIP archive of exported schemas (default: false)
--profile=PROFILE-
Schema profile:
iso10303(default) orgeneric --publication=SCHEMA_ID-
Export an AP publication bundle: the lead schema plus its transitive USE-FROM/REFERENCE closure
--format=FORMAT-
Output format:
express(default) orowl --[no-]corpus-
OWL only: emit one corpus ontology importing every schema ontology
--urn=URN-
OWL only: base URN for IRIs, before the
:techcomponent
Behavior
The command exports schemas based on the input file types:
For EXPRESS schema manifest files:
-
Schemas are exported while preserving the directory structure from the manifest file paths
-
Schemas under
resources/are exported toOUTPUT/resources/ -
Schemas under
modules/are exported toOUTPUT/modules/ -
Other categories (
business_object_models/,core_model/) follow the same pattern
For standalone EXPRESS files:
-
Schemas are exported directly to the output directory root
-
Output filename format:
{schema_id}.exp
By default, schemas are exported without annotations (plain EXPRESS). Use the
--annotations flag to include remarks and comments.
The --zip flag creates a ZIP archive in addition to the directory output,
named OUTPUT.zip.
$ bundle exec suma export -o express-files schemas-srl.yml
# => generates express-files/ directory with plain EXPRESS schemas$ bundle exec suma export -o express-files geometry_schema.exp
# => generates express-files/geometry_schema.exp$ bundle exec suma export -o express-files schema1.exp schema2.exp schema3.exp
# => generates express-files/{schema1,schema2,schema3}.exp$ bundle exec suma export -o express-files schemas-srl.yml additional-schemas.yml
# => exports schemas from both manifest files$ bundle exec suma export -o express-files schemas-srl.yml geometry_schema.exp
# => exports schemas from manifest with directory structure
# plus geometry_schema.exp at the root$ bundle exec suma export -o express-files --annotations schemas-srl.yml
# => generates express-files/ directory with annotated EXPRESS schemas$ bundle exec suma export -o express-files --zip schemas-srl.yml
# => generates both:
# - express-files/ directory
# - express-files.zip archive$ bundle exec suma export -o express-files \
--annotations \
--zip \
schemas-srl.yml geometry_schema.exp
# => generates annotated schemas in both directory and ZIP formatOutput structure
The exported directory structure depends on the input file types:
express-files/
├── geometry_schema.exp # standalone EXPRESS file (at root)
├── topology_schema.exp # standalone EXPRESS file (at root)
├── resources/ # from manifest files
│ ├── action_schema/
│ │ └── action_schema.exp
│ └── ...
├── modules/ # from manifest files
│ ├── activity/
│ │ ├── arm.exp
│ │ └── mim.exp
│ └── ...
├── business_object_models/ # from manifest files
│ └── ...
└── core_model/ # from manifest files
└── ...Schema profiles and AP publications
Suma works with any schema collection. Suma::SchemaProfile declares how
schema identifiers and paths map to types, how identifiers become display
names, and the ordered register categories. Registered profiles:
iso10303-
Default; STEP conventions including
/applications/classifying as an application protocol generic-
No STEP conventions (one category for every schema)
ifc-
buildingSMART IFC editions: one standalone schema per edition (
ifc4,ifc4x3, …), edition names preserved uppercase (IFC4,IFC4X3), Ifc-prefixed declarations, oneOther Schemasregister category
An AP publication is a lead schema bundled with the module and resource
schemas it USEs. --publication SCHEMA_ID computes the transitive
USE-FROM/REFERENCE closure and writes the bundle flat under
OUTPUT/<lead_id>/. In the register, application protocols are grouped under
a per-publication parent section.
OWL projection
suma export --format owl projects a parsed corpus into OWL/Turtle:
-
entities become
owl:Class;SUBTYPE OFbecomesrdfs:subClassOf -
SELECT types become
owl:unionOf; enumerations becomeowl:oneOfnamed individuals -
simple type aliases become
rdfs:Datatype -
explicit, derived, and inverse attributes become object/datatype properties attached through named
owl:Restrictionnodes, with cardinality from optionality and aggregate bounds -
WHERE, DERIVE, and INVERSE clauses are preserved as annotated constraints
IRIs derive from the corpus URN scheme (<base>:tech:<schema>.<element>).
Per-schema ontologies declare owl:imports for their USE-FROM/REFERENCE
targets, and --corpus adds a corpus ontology importing every schema. The
projection is validated before writing (materialization, property
declarations, orphan classes, dangling superclasses, superclass cycles), and
contains no blank nodes, so it is deterministic and golden-comparable.
$ suma export --format owl --urn urn:iso:std:iso:10303:-2:ed-2:en \
-o OUTPUT schemas.yaml
$ suma export --format owl --corpus --urn urn:iso:std:iso:10303:-2:ed-2:en \
-o OUTPUT schemas.yamlPackage concepts for the Vocabulary Browser
The package-gcr command bundles extracted concepts into a GCR
(Glossarist Concept Repository) archive — the sealed distribution format
consumed by the Glossarist Vocabulary Browser:
$ suma package-gcr CONCEPTS_DIR --register register.yaml \
--shortname my-dataset --version 1.0.0 \
--title "My Dataset" --description "Concepts from my corpus" \
-o OUTThe archive contains metadata.yaml (identity, statistics), the original
register.yaml, and concepts/ in the browser’s canonical flat format
(termid, term, one block per language). Both a versioned
({shortname}-{version}.gcr) and an unversioned ({shortname}.gcr)
archive are written. Pass --created-at to pin the package timestamp for
byte-reproducible archives. Point the browser’s datasets.yml at the
published archive (or at the concepts directory in development via
localPath).
Serve resolved artifacts
suma serve serves a resolve --all artifact tree at its URN-derived
paths, returning JSON or HTML according to the request’s Accept
header:
$ suma serve OUT --port 2113
$ curl -H "Accept: application/json" \
http://localhost:2113/urn/iso/std/iso/10303/-2/ed-2/en/tech/action_schema.actionProduction hosting maps the same paths statically; no application server is required.
Resolve URNs command
The resolve command turns URNs into static, dereferenceable artifacts: a
canonical JSON document (sorted keys) and an HTML page per URN, written under
a path derived from the URN itself. It resolves:
-
tech:schema, declared-element, and attribute (OWL property) URNs from a schema manifest -
term:concept URNs from Glossarist concept documents -
the dataset URN from
register.yaml
$ suma resolve URN --manifest SCHEMAS_YAML [--concepts DIR] [--register register.yaml] -o OUT
$ suma resolve --all --manifest SCHEMAS_YAML [--concepts DIR] [--register register.yaml] -o OUT--all also writes index.html, linking every artifact. No server is
required.
Compare schemas command
General
The suma compare command compares two EXPRESS schemas using eengine and
generates an EXPRESS Changes YAML file tracking the differences.
This command is essential for managing schema evolution across versions, particularly when working with multiple git branches of the same repository.
$ suma compare TRIAL_SCHEMA REFERENCE_SCHEMA --version VERSION [options]Parameters:
TRIAL_SCHEMA-
Path to the new/trial EXPRESS schema file
REFERENCE_SCHEMA-
Path to the old/reference EXPRESS schema file
Options:
-
--version=VERSION,-v VERSION -
(required) Version number for this change version
-
--output=PATH,-o PATH -
Output Change YAML file path (default:
{schema}.changes.yamlin trial schema directory) --mode=MODE-
Schema comparison mode:
resourceormodule(default:resource) --trial-stepmod=PATH-
Override auto-detected trial repository root
--reference-stepmod=PATH-
Override auto-detected reference repository root
--verbose-
Enable verbose output
--typed-output=PATH-
Write a typed change manifest (lutaml-model records with classification)
--[no-]changelog-
Render a markdown changelog alongside the change manifest
--[no-]impact-
Report affected schemas and AP publications using the corpus graph
--manifest=SCHEMAS_YAML-
Schema manifest used for impact analysis
Typical workflow
The compare command is designed for a two-repository workflow where you have different branches checked out:
# 1. Check out old version at /path/to/repo-old
# 2. Check out new version at /path/to/repo-new
# 3. Compare schemas:
$ suma compare \
/path/to/repo-new/schemas/resources/action_schema/action_schema.exp \
/path/to/repo-old/schemas/resources/action_schema/action_schema.exp \
--version 2Behavior
The command:
-
Auto-detects git repository roots from schema file paths
-
Uses detected roots as stepmod paths for eengine
-
Generates or updates
.changes.yamlfile in the trial schema directory -
Replaces existing change version if the version already exists
-
Adds new change version if the version is different
Requirements
This command requires eengine to be installed:
$ suma compare \
~/iso-10303-new/schemas/resources/support_resource_schema/support_resource_schema.exp \
~/iso-10303-old/schemas/resources/support_resource_schema/support_resource_schema.exp \
--version 2
# => generates or updates support_resource_schema.changes.yaml$ suma compare schema_new.exp schema_old.exp --version 2 --verbose
# Shows: eengine version, detected repo roots, XML generation, etc.$ suma compare schema_new.exp schema_old.exp \
--version 2 \
--output /path/to/custom.changes.yaml$ suma compare schema_new.exp schema_old.exp \
--version 2 \
--trial-stepmod ~/repo-new \
--reference-stepmod ~/repo-oldGenerated Change YAML format
The command generates EXPRESS Changes YAML files in the ISO 10303 format:
---
schema: support_resource_schema
versions:
- version: '2'
description: 'TYPE text: Underlying Type changed'
modifications:
- type: TYPE
name: textFor complete format documentation, see the EXPRESS Changes specification.
Expressir command
General
The suma expressir command provides access to all Expressir commands for
working with EXPRESS schemas. This includes documentation coverage analysis,
schema formatting, validation, and other EXPRESS-related operations.
Expressir is a comprehensive toolkit for EXPRESS schema processing that Suma integrates to provide additional functionality beyond Suma’s core features.
$ suma expressir SUBCOMMAND ...ARGS [options]Available subcommands:
coverage-
Check documentation coverage of EXPRESS schemas
format-
Pretty print EXPRESS schemas
clean-
Strip remarks and prettify EXPRESS schemas
validate-
Validate EXPRESS schemas
benchmark-
Benchmark schema loading performance
version-
Display expressir version
Coverage subcommand
The coverage subcommand analyzes EXPRESS schemas to determine documentation
coverage, reporting how many EXPRESS objects (entities, constants, functions,
types, etc.) have been documented with Annotated EXPRESS.
This addresses the need to measure and improve documentation quality in EXPRESS schema collections.
$ suma expressir coverage PATH [PATH...] [options]Parameters:
PATH-
One or more paths to analyze. Each path can be:
-
An EXPRESS schema manifest file (
.yml,.yaml) -
A single EXPRESS file (
.exp) -
A directory containing EXPRESS files
-
Options:
--format=FORMAT-
Output format:
text(default),json, oryaml --output=FILE-
Output file path for JSON/YAML formats (defaults to
coverage_report.jsonorcoverage_report.yaml) --exclude=TYPES-
Comma-separated list of EXPRESS entity types to exclude from coverage analysis (e.g.,
TYPE,CONSTANT,TYPE:SELECT) --ignore-files=FILE-
Path to YAML file containing array of file patterns to ignore from overall coverage calculation
$ suma expressir coverage schemas-srl.yml$ suma expressir coverage schemas-srl.yml --format=json --output=coverage.json$ suma expressir coverage schemas/ --exclude=TYPE:ENUMERATION,PARAMETER$ suma expressir coverage schemas-srl.yml additional-schemas.ymlThe coverage report includes:
-
Overall coverage statistics (total entities, documented entities, percentage)
-
Per-file coverage details
-
Per-directory coverage summaries
-
List of undocumented entities by type and name
Format subcommand
The format subcommand pretty-prints EXPRESS schemas.
$ suma expressir format PATHParameters:
PATH-
Path to the EXPRESS schema file to format
$ suma expressir format schema.expClean subcommand
The clean subcommand strips remarks and prettifies EXPRESS schemas.
$ suma expressir clean PATH [options]Parameters:
PATH-
Path to the EXPRESS schema file to clean
Options:
--output=FILE-
Output file path (defaults to stdout)
$ suma expressir clean schema.exp --output=cleaned_schema.expValidate subcommand
The validate subcommand validates EXPRESS schemas for syntactic correctness.
$ suma expressir validate PATH [PATH...]Parameters:
PATH-
One or more paths to EXPRESS schema files or directories to validate
$ suma expressir validate schema.exp
$ suma expressir validate schemas/Additional information
For complete documentation of all Expressir commands and options, see the Expressir documentation.
Check SVG quality command
General
The check_svg_quality command validates SVG files for conformance and quality
using the svg_conform library. It supports
both batch directory scanning and single file analysis.
By default, it uses the metanorma profile which allows raster images
(PNG, JPEG) and other features specific to Metanorma documentation.
$ suma check_svg_quality [PATH] [options]Parameters:
PATH-
Path to directory containing SVG files or a single SVG file. Defaults to
schemasdirectory.
Batch directory scanning
When given a directory, it scans all SVG files and produces a quality report sorted by error count (most problematic files first).
$ suma check_svg_quality ../iso-10303/schemas🔍 Scanning 3878 SVG files...
╔══════════════════════════════════════════════════════════════════════════════╗
║ 🔍 SVG Quality Report Sorted by error count (most first) ║
╚══════════════════════════════════════════════════════════════════════════════╝
📊 OVERVIEW
● Total Files : 3878
● Valid : 3845 ✅
● Invalid : 33 ❌
...
💥 CRITICAL QUALITY (2 files)
✗ 0/100 813 errors schemas/resources/action_schema/action_schemaexpg2.svg
✗ 25/100 156 errors schemas/modules/activity/mimexpg1.svg
Single file analysis
When given a path to a single SVG file, it shows detailed error breakdown grouped by requirement type.
$ suma check_svg_quality schemas/resources/action_schema/action_schemaexpg2.svg📄 SVG Quality Report: schemas/resources/action_schema/action_schemaexpg2.svg
Valid: NO ❌
Errors: 813
📋 Error Details
style (56 occurrences)
- Style property 'enable-background' removed
- Style property 'overflow' removed
...
allowed_elements (109 occurrences)
- The element 'image' is not allowed as a child of 'svg'
...
color_restrictions (108 occurrences)
- Color 'rgb(33, 128, 255)' in style property 'fill' is not allowed
...
Options:
--profile=PROFILE-
Validation profile to use (default:
metanorma). Other options:svg_1_2_rfc,svg_1_2_rfc_with_rdf,base,lucid_fix --sort=MODE-
Sort order:
errors(most errors first, default) orquality(lowest quality scores first) --format=FORMAT-
Output format:
terminal(default),json, oryaml -
--output=PATH,-o PATH -
Write output to file instead of stdout
--min_errors=N-
Filter to show only files with at least N errors
--limit=N-
Limit output to top N files
--progress-
Show progress during batch scanning
--summary-only-
Show only summary, not individual file details
$ suma check_svg_quality schemas/ --profile svg_1_2_rfc$ suma check_svg_quality schemas/ --format json --output quality_report.json$ suma check_svg_quality schemas/ --min_errors 100Usage: Ruby
General
Suma can be used programmatically in your Ruby applications. The following examples demonstrate common usage patterns.
Building collections
require 'suma'
# Build a collection with default settings
Suma::Processor.new(
metanorma_yaml_path: "metanorma-srl.yml",
schemas_all_path: "schemas-srl.yml",
compile: true,
output_directory: "_site"
).run
# Generate schema listing without compilation
Suma::Processor.new(
metanorma_yaml_path: "metanorma-srl.yml",
schemas_all_path: "schemas-srl.yml",
compile: false
).runWorking with schema manifests
Schema manifests are loaded via Expressir::SchemaManifest:
require 'suma'
schemas_file_path = "schemas-srl.yml"
schemas_config = Expressir::SchemaManifest.from_file(schemas_file_path)
# Access schema information
schemas_config.schemas.each do |schema|
puts "Schema ID: #{schema.id}"
puts "Schema path: #{schema.path}"
endExtracting terms
require 'suma'
Suma::TermExtractor.new(
"schemas-smrl-part-2.yml",
"glossarist_output",
urn: "urn:iso:std:iso:10303:-2:ed-2:en:tech:*",
).callGenerating a register.yaml
require 'suma'
Suma::RegisterManifestGenerator.new(
"schemas-smrl-part-2.yml",
"register_output",
urn: "urn:iso:std:iso:10303:-2:ed-2:en:tech:*",
id: "iso10303-2-express",
ref: "ISO 10303-2 EXPRESS Concepts",
).generateArchitecture
Suma’s domain is split into MECE concerns:
-
Data models (pure):
CollectionManifest,ExpressSchema -
Value objects (pure):
SchemaCategory,Urn -
Services (single concern):
ManifestTraverser,SchemaDiscovery,SchemaCompiler,SchemaExporter,SchemaIndex,LinkValidator,SchemaComparer,SchemaManifestGenerator,TermExtractor,RegisterManifestGenerator,Processor -
Renderers (pure, composable):
SchemaTemplate::Plain,SchemaTemplate::Document
Key invariants:
-
The classifier
ExpressSchema::Type.classify(id:, path:)is the single source of truth for schema type.SchemaCategory,SchemaNaming,SchemaExporter, andRegisterManifestGeneratorall derive from it. -
Urnowns URN semantics (wildcard stripping, base/alias split, leaf composition). -
CollectionManifestis a pure data model; tree walking lives inManifestTraverser, schema I/O lives inSchemaDiscovery. -
SchemaCompilerorchestrates one Metanorma compilation; the adoc body is injected via aSchemaTemplate::*renderer.
Code-style rules enforced throughout lib/suma/:
-
Ruby
autoloadonly — norequire_relative -
No
sendto call private methods -
No
instance_variable_set/instance_variable_get -
No
respond_to?for type checking -
Utils.logwrites to$stderr; debug level gated bySUMA_DEBUG
Copyright and license
Copyright Ribose. BSD 2-clause license.
Development and benchmarks
The default gate is rake (specs, RuboCop, referential closure).
$ rake benchmarkrake benchmark builds a synthetic 1,000-schema corpus and asserts wall-time
and peak-RSS budgets; the same benchmark runs nightly in CI. Schema export can
run in parallel with build --jobs N, while Metanorma document compilation
stays sequential and composes with staged process isolation.