Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Appendix E: toolchain and reproducibility

Authors
Affiliations
Dynamical Systems Group
Humane Intelligence

This appendix says what the site and its proofs run on, so that a reader can rebuild every page and verdict on their own machine: the environment is a lockfile and the reviewer recipe is seven lines.

1What executable specification means here

The graphs are the model: the vocabulary, the sources, the rulings, the essentials, the pruned SysML rendering and the measles evaluation are Turtle files under version control, and no page states what they cannot answer by query. The scripts render every figure and table into generated/ and the explorer, and the gate regenerates them and diffs them byte for byte, so a table cannot drift from its graph. The shapes and the tests are the checks: SHACL over the record and the model graph, pytest over the prose, the citations and the wiring. The gate is the only verdict: one script, every step, one line. CI runs the same script on a fresh runner and deploys the site only when it prints PASS.

The record is a PROV bundle every item and agent is a member of, and the shapes and the record queries assume one default graph: the record, the EPO vocabulary and the model graph loaded together, since an item’s step is derived through the model and every global rule is anchored on the record its focus node belongs to. Two records in one graph do not collide. A quad store with one named graph per file answers nothing: the coverage query returns no row and the shapes find nothing to check. The explorer ships one merged file, explorer/data/all.ttl, for that reason.

2The layers

From the bottom up. The virtual environment is managed by uv: pyproject.toml declares the direct dependencies, uv.lock pins the whole resolution to versions and content hashes, and uv sync reproduces it on any machine. OpenSysML is not in that environment, on purpose: it is the modelling tool, used at authoring time for strict validation of the SysML source and its rendering to RDF, and everything downstream reads only the RDF; toolchain/get-sysml.sh fetches the pinned release as a binary and checks the tarball and the installed binary against committed digests. rdflib and pySHACL parse the graphs and run the shapes; pypdf reads the PDF sources for the quote checks. MyST, the mystmd package over Node.js, builds the site from the pages and the included fragments. nbclient re-executes the proof notebooks and compares their outputs with the committed ones. The ogc command line reads the graphs for people and AI assistants; its skill file, .claude/skills/ogc-glossary/SKILL.md, tells an assistant to ask the graph and never to answer from memory. The vendored d3 and oxigraph run Appendices A and B in the browser without the network.

The graphs are written in a small set of ontologies, none invented here beyond the specification’s own handles. PROV-O says who did what and when. EARL says what was asserted, with an outcome of passed, failed or cannot tell, which is why a determination is never a Boolean. SKOS holds the glossary. OWL and RDF Schema declare the Evaluation Process Ontology’s classes and properties. SHACL states every check. The SysML v2 vocabulary is OpenSysML’s rendering of the OMG metamodel, with a few tool facts of its own. The specification’s namespaces under w3id.org name the terms, the sources, the rulings, the essentials, the crosswalk, the derived ends of the model graph and the measles evaluation. The table below counts what each is used for.

3The Python environment

Python >=3.12 (pyproject.toml), pinned to 3.12 by .python-version so that uv sync installs the same interpreter everywhere. uv sync reproduces the environment from uv.lock (lockfile version 1, revision 3): 111 packages in all, 11 direct (3 runtime, 8 dev) and 100 transitive, every one pinned to a version and a content hash. The project og-caie-spec is installed editable and provides the ogc command.

PackageGroupConstraint (pyproject.toml)Locked (uv.lock)
rdflibruntime>=7.07.6.0
pyshaclruntime>=0.270.40.1
pypdfruntime>=6.06.17.0
pytestdev>=8.09.1.1
pyyamldev>=6.06.0.3
mystmddev>=1.31.10.1
nbclientdev>=0.100.11.0
nbformatdev>=5.105.11.1
jupyterdev>=1.01.1.1
ipykerneldev>=6.297.3.0
owlrldev>=7.6.27.6.2

4The pinned converter

SettingValueRead from
ReleaseOpenSysML v0.4.3model/model_manifest.json
Fetched fromhttps://github.com/Open-MBEE/OpenSysML/releases/download/v0.4.3toolchain/get-sysml.sh (VER=v0.4.3)
Invocation-convert ttlmodel/model_manifest.json
Digest filetoolchain/sysml-binaries.sha256, sha256 8efae36144923a29a21aa57d59286442db5ffaaa9a3773fafcc57616ade6f961model/model_manifest.json
Authoring sourcemodel/og-caie.sysml, sha256 d0764a4ea026fc29c2b8f603216679e10be00d799f853bbff28cc539c2fff735model/model_manifest.json
Term mapmodel/sysml_term_map.csv, 59 terms, sha256 6a58361b86b4a4a0a94c077efdb23a9541da988fca8735f74a4b02c6e4dd270fmodel/model_manifest.json
Canonical graphmodel/og-caie.model.ttl, 5712 triples of 18976 converted (budget 6600, headroom 888), sha256 deffb0f33dcd5d7e58de07b4a0b42f84e3ef92c9f132095b7166c4804c43e1e6model/model_manifest.json

Per platform, the digest the installed binary must hash to (toolchain/sysml-binaries.sha256) and the digest the release tarball must hash to before it is unpacked (toolchain/SHA256SUMS.pinned); toolchain/get-sysml.sh checks both on every run.

PlatformInstalled binary sha256Release tarball sha256
darwin-arm64a3298d68a08b863fba276bd6d0d72aad9947cdeb4b28103ce9b526400f8f475b0927e2e7bbf86c6b6e546d275273c529808f98b6da9c525155e8a80bba4623bf
darwin-amd64712b6c8290aea0b0395f1ea313b6a2af0754202524055733824f2064b49dfe2c95bfa593d773a5fabe99402dec8e860163d0673299ef8b038dd7c0d2e6f97350
linux-amd641fba036a16367133e6f55026f254ca4749502bb35b0c6ae0e9990961e1461d30661df51718d8506fff925d7b89d0cc119c5c1247f389f9bd9b87d6443ac4553d
linux-arm64571ab5f1bf0ba0d27732cbc1afed4d724cdc38ddd6ba7636ef67422a77648925ceba7303c9ffd391b2849b4ae4e15ec52d9ccb951e81b8dc47b7359ee07cdc96

5The ontologies and vocabularies

What the graphs are written in, counted over the committed Turtle files (vocabulary/og-caie.ttl, vocabulary/epo.ttl, vocabulary/crosswalk.ttl, vocabulary/register.ttl, vocabulary/ogm.ttl, sources/sources.ttl, rulings/adjudications.ttl, model/trace.ttl, model/og-caie.model.ttl, track/measles-evaluation.ttl, shapes/epo.shapes.ttl, shapes/model.shapes.ttl, shapes/rulings.shapes.ttl): the classes and properties of each vocabulary that the graphs actually use, and the subjects each names. The W3C vocabularies are adopted as published; the SysML namespace is OpenSysML’s rendering of the OMG SysML v2 metamodel, not a vocabulary OMG publishes at that IRI; the specification’s own namespaces resolve under w3id.org.

PrefixNamespaceWhoseWhat it does hereClasses usedProperties usedSubjectsReference
rdfhttp://www.w3.org/1999/02/22-rdf-syntax-ns#W3CRDF 1.1: typing (rdf:type) and lists030https://www.w3.org/TR/rdf11-concepts/
rdfshttp://www.w3.org/2000/01/rdf-schema#W3CRDF Schema: labels, comments, subclassing060https://www.w3.org/TR/rdf-schema/
owlhttp://www.w3.org/2002/07/owl#W3COWL 2: the EPO’s classes and properties430https://www.w3.org/TR/owl2-overview/
skoshttp://www.w3.org/2004/02/skos/core#W3CSKOS: the glossary’s concepts, labels, definitions and notes2110https://www.w3.org/TR/skos-reference/
provhttp://www.w3.org/ns/prov#W3CPROV-O: who did what and when in the record (agents, activities, entities, derivation, attribution)790https://www.w3.org/TR/prov-o/
earlhttp://www.w3.org/ns/earl#W3CEARL 1.0: assertions with an assertor, a mode, a subject, a test and an outcome (passed, failed, cantTell)270https://www.w3.org/TR/EARL10-Schema/
shhttp://www.w3.org/ns/shacl#W3CSHACL: the shapes that check the record, the model graph and the rulings, including SHACL-SPARQL constraints2180https://www.w3.org/TR/shacl/
sysmlhttps://www.omg.org/spec/SysML#OpenSysML (after the OMG SysML v2 metamodel)SysML v2 vocabulary as the OpenSysML converter renders the model: definitions, usages, ports, interfaces, actions, successions, flows26180https://www.omg.org/spec/SysML/2.0/
sysxurn:opensysml:sysml:OpenSysMLthe converter’s own facts: the ends of a connection, the source text of a statement, a prefix keyword040https://github.com/OpenMBEE/opensysml
elmturn:sysmlv2:element:OpenSysMLthe converter’s element identifiers, one per model element00647https://github.com/OpenMBEE/opensysml
exprurn:opensysml:expr:OpenSysMLthe converter’s expression identifiers (end paths, multiplicity bounds)00491https://github.com/OpenMBEE/opensysml
ogchttps://w3id.org/og-caie/this specificationthe register: citation classes and properties, shapes’ names, concerns, rulings, crosswalk rows, trace essentials652118https://w3id.org/og-caie/
termhttps://w3id.org/og-caie/terms#this specificationthe glossary’s terms0069https://w3id.org/og-caie/
srchttps://w3id.org/og-caie/sources#this specificationthe source register0079https://w3id.org/og-caie/
rulhttps://w3id.org/og-caie/rulings#this specificationconcerns and rulings00114https://w3id.org/og-caie/
epohttps://w3id.org/og-caie/epo#this specificationthe Evaluation Process Ontology’s handles: item classes, steps, layers, roles and their properties5461169https://w3id.org/og-caie/
xwhttps://w3id.org/og-caie/crosswalk#this specificationthe crosswalk rows of the front page’s bridge into the standards007https://w3id.org/og-caie/
trhttps://w3id.org/og-caie/trace#this specificationthe essentials SCI-01 to SCI-130013https://w3id.org/og-caie/
ogmhttps://w3id.org/og-caie/model#this specificationthe derived ends of the canonical model graph (resolved ports, flow ends, successions, relations)01111https://w3id.org/og-caie/
evhttps://w3id.org/og-caie/evaluation/measles#this specificationthe measles evaluation’s record, its items and agents (sheet 10-42)00127https://w3id.org/og-caie/

6The vendored browser libraries

Appendix B runs in the browser on two libraries committed under explorer/vendor/, so the explorer loads nothing from the network; Appendix A’s report draws with the same d3 file, loaded by the relative path ../explorer/vendor/d3.v7.min.js, so there is one copy. Versions and licences are as the files state them.

LibraryVersionLicenceSource or copyrightStated in
d37.9.0not stated in the fileCopyright 2010-2023 Mike Bostockexplorer/vendor/d3.v7.min.js (first line)
oxigraph (WebAssembly, web.js, web_bg.wasm)0.5.11MIT OR Apache-2.0https://github.com/oxigraph/oxigraphexplorer/vendor/oxigraph/NOTICE.md

7The gate

checks/run-checks.sh runs 10 steps, every one, in this order; a step passes when its exit code is the expected one. The only summary is the CHECKS: PASS or CHECKS: FAIL line and checks/out/report.json; each step’s full output is in checks/out/last.log. Nothing is optional and nothing fails quietly.

#StepExpected exitCommand
1toolchain: pinned sysml v0.4.3, digest-verified0bash toolchain/get-sysml.sh
2model: validate -strict (authoring view and model counterexamples)0toolchain/bin/sysml model/og-caie.sysml counterexamples/model/unwired-port.sysml counterexamples/model/expert-administers-tests.sysml counterexamples/model/missing-accountable.sysml counterexamples/model/no-obligation.sysml -validate -strict
3model graph: convert, prune, byte-identical to the committed canonical graph0uv run python scripts/prune_model.py && git diff --quiet -- model/og-caie.model.ttl model/model_manifest.json
4ogc: doctor (labels unambiguous, quotes located, record consistent)0uv run -q ogc doctor --no-cache
5drift: the consistency loop, mechanical layer (appendix letters and counts, the mutation count, stale phrases, retired words, file mentions, sheet ticks, twins, absence rows, the CI condition on held-locally quotes)0uv run python scripts/drift_check.py
6notebooks: executed by nbclient, outputs equal the committed ones, verdict NOTEBOOK: PASS0uv run python scripts/execute_notebooks.py --check
7tests: full suite0uv run pytest -q
8generated/, explorer/ and report/: regenerate byte-identically0bash checks/regen.sh (uv run python scripts/render.py && uv run python scripts/render_cli.py && uv run python scripts/render_diagrams.py && uv run python scripts/render_explorer.py && uv run python scripts/render_report.py && uv run python scripts/render_toolchain.py && uv run python scripts/render_bib.py && uv run python scripts/render_version.py) && git diff --quiet -- generated/ explorer/ report/
9site: myst build --html0uv run myst build --html
10site: the explorer and the sample report copied next to the built site0bash scripts/copy_explorer.sh

8Continuous integration

.github/workflows/deploy.yml (workflow checks-and-deploy) runs on push (branches: main), pull_request, workflow_dispatch. The checks job runs the same gate script; the deploy job needs it and runs only when github.ref == 'refs/heads/main' && github.event_name != 'pull_request'.

JobStepRuns
checksactions/checkout@v4actions/checkout@v4
checksastral-sh/setup-uv@v5astral-sh/setup-uv@v5
checksactions/setup-node@v4actions/setup-node@v4 (node-version: 20)
checkspython environmentuv sync
checksfull gatebash checks/run-checks.sh
checksgate log, for diagnosis when a step failsactions/upload-artifact@v4 (name: gate-log, path: checks/out/last.log checks/out/report.json)
checksbuild the site for PagesBASE_URL="/${REPO_NAME}" uv run myst build --html
checksthe knowledge graph explorer next to the sitebash scripts/copy_explorer.sh
checksactions/upload-pages-artifact@v3actions/upload-pages-artifact@v3 (path: _build/html)
deployactions/deploy-pages@v4actions/deploy-pages@v4

9Enforcement points

The same script gives the verdict at three points; none can be skipped by editing a page.

WhereWhat runsRead from
Before every push, in the author’s checkoutbash checks/gate-head.sh (installed with git config core.hooksPath checks/hooks)checks/hooks/pre-push
On the committed HEAD, in a detached worktree at .cache/gate-head.XXXXXX, never on the working treebash checks/run-checks.shchecks/gate-head.sh
In CI, on a fresh runner, before any deploybash checks/run-checks.sh; deploy needs checks.github/workflows/deploy.yml

10The reviewer recipe

From a git clone with git, uv and Node.js 20 or later installed. The first run needs the network for the interpreter and the wheels, the converter’s tarball and the site theme; a second run is offline. The gate takes three to four minutes on a laptop, most of it the test suite.

uv sync
bash toolchain/get-sysml.sh
bash checks/run-checks.sh
uv run -q ogc doctor
uv run myst build --html
bash scripts/copy_explorer.sh
uv run python -m http.server -d _build/html 8000

uv sync creates .venv from the lockfile. get-sysml.sh prints sysml installed+verified: sysml v0.4.3 on a first fetch and nothing when the verified binary is in place; a digest mismatch exits 1. The gate prints each step’s name and pass or FAIL, then CHECKS: PASS or CHECKS: FAIL with the commit it judged; that line is what the pre-push hook and CI require, and a failing step prints its last lines. ogc doctor ends with VERDICT: PASS with the commit it judged, after one line per check and a note per fact that is not a fault. The notebook step prints one line per notebook, fresh or STALE, then NOTEBOOK: PASS or NOTEBOOK: FAIL; the kernel’s warning about an unencrypted local transport is expected. myst build --html writes the site under _build/html; the gate copies Appendices A and B next to it, and serving that folder over http is what makes their frames and the SPARQL box work (myst start serves the pages but not the explorer). The fetch script supports macOS and Linux on x86-64 and arm64 and needs curl, tar and a sha256 tool; the site build and the notebooks need free local ports.

11The first rung

The appendices are the first rung of backup; the repository is the richer one, every graph, shape, script, test and notebook the site is rendered from, with the gate that judges them. A reader need not trust the authors: run the recipe and read the verdict.