Status: Accepted
Date: 2026-09-25 (proposed), 2026-09-25 (accepted, delivered through the eligibility-compiler plan’s Part B)
Related: ADR-A24 (backend strategy), ADR-A28 (parity gate), ADR-A29
(toolchain boundary), ADR-A71 (platform licence and SPI seam), ADR-A90
(design-time OWL backend)
Source plan: eligibility-compiler, Part B
Unit: applied-ontology-readiness (AOR-10, AOR-11)
Several checks need a DL reasoner or a rules engine, and none is available:
reasoning extra provides
owlrl, an OWL RL engine, which cannot decide them.swrlb comparison builtins.The eligibility-compiler plan (Part B) sets the constraints: no product
package depends on a reasoner or rules engine, the harness is shared across
compiler families and ecosystems, and Maven, Python tooling and mise each
keep their own dependency authority. It found Openllet to be AGPL-3.0 and
HermiT LGPL-3.0, and left the engine choice to this ADR.
platform/reasoning-testkit. Java 25, under
platform/pom.xml. Engine libraries are declared only here. The module
ships a library for Java test suites (<scope>test</scope> only) and a
shaded CLI jar for everything else.reasoning-testkit classify|satisfiable|subsumes|entails|apply-rules,
taking ontology files and a catalog (ADR-A88), writing JSON to stdout.
Python tests call it as a subprocess and skip, with a named reason, when
the jar is absent. No pyproject.toml declares a reasoner or a JVM bridge.swrlb
builtins, which HermiT does not evaluate. If verifying them is wanted,
Openllet is added as a second adapter under the same isolation. Its
AGPL-3.0 licence is compatible only because nothing links it and nothing
serves it over a network, so the guardrail in item 6 becomes load-bearing
the day it is added.mise run check:reasoning-isolation fails when any
pom.xml other than the testkit’s declares a reasoner or rules-engine
artefact, when any module depends on the testkit outside test scope, or
when any pyproject.toml declares a reasoner, a rules engine or a JVM
bridge. It has a violating fixture that must fail.mise tasks. bootstrap:reasoning-testkit builds the jar,
check:reasoning-testkit runs its self-tests.platform/reasoning-testkit is a new directory, introduced by this decision
under an existing root.eligibility-compiler Part B)consistent, satisfiable, subsumes and values (entailed pairs of an
object property).owl:imports and merges the files it is given. The OWL API
parses each file on its own, so tools/mork_compilers/src/mork_compilers/reasoning.py
passes one merged file, built from the catalog closure or the test fixtures.swrl:Imp node is anonymous.
The compilers name their rules for provenance, so the Python helper
anonymises them before calling the CLI.reasoning extra’s owlrl, a pure-Python OWL RL engine, is outside its scope.