Repository navigation
Releases: pwin/SemOpsManual
Release list
v2.0.3 — every tool at its current release
The October 2026 edition, re-measured on every tool at its current release. No figure moved; the versions, one count and one list of upstream drift did.
📄 SemOps-Manual-v2.0.3-A4.pdf (124 pages, A4)
📓 SemOps-Manual-v2.0.3-notebooks.zip: the three runnable notebooks, unchanged
🌐 Web edition, built from the same sources
Measured against: suite 0.25.0, extension 0.17.1, DSL 0.16.1, engine 0.3.4, HOLOS 0.26.0, tarka 0.2.1, between 13 October and 3 November 2026.
What moved
- Suite 0.24.3 → 0.25.0. It adds
--severity-policyand--stringency, which set how strict each check is at each stage of a project, applied to finished findings. Every figure the manual quotes is the same on 0.25.0. - Extension 0.16.3 → 0.17.1. It reads the same severity policies, and bundles holos-wasm-node 0.26.0. The suite's repository now locks holosdb 0.26.0 too, so Chapter 7's "the version is the same on both sides" holds again.
- tarka 0.2.0 → 0.2.1.
- The testing repository reports 166 passed, 10 skipped: one test more than the 165 first recorded, from tests it has gained since.
- Upstream drift (§14.4). The testing README's fixture count was corrected on 23 October. The same day the suite retired its
developbranch, so the manual's eleven links into it were dead. They now go tomain, and every target exists there.
evidence/
256 claims:
- 179 reproduced by 105 distinct runs, all passing;
- 123 quotations checked word for word;
- 1649 links resolving.
The runs used fresh clones of the testing repository at 31bda0d and the suite at v0.25.0. All three notebooks run with no errors on suite 0.25.0, shacl 0.3.4 and holosdb 0.26.0.
Full changelog: v2.0.2...v2.0.3
v2.0.2 — re-measured on tarka 0.2.0 and HOLOS 0.26.0
The October 2026 edition, re-measured on tarka 0.2.0 and HOLOS 0.26.0. The text changes where those releases changed it, and every check was re-run.
📄 SemOps-Manual-v2.0.2-A4.pdf (124 pages, A4)
📓 SemOps-Manual-v2.0.2-notebooks.zip: the three runnable notebooks, unchanged
🌐 Web edition, built from the same sources
Measured against: suite 0.24.3, extension 0.16.3, DSL 0.16.1, engine 0.3.4, HOLOS 0.26.0, tarka 0.2.0, between 13 October and 3 November 2026.
What moved
-
tarka 0.1.1 → 0.2.0.
runover OTTR templates reads a cell typedottr:IRIas bOTTR does, so the acme template'smailto:cells need no prefix. A row with a cell its parameter cannot take is now left out and named, and the run exits 1. The silent zero the manual recorded at 0.1.1 is gone (Ch10 §10.3, Ch14 §14.4). -
HOLOS 0.25.0 → 0.26.0.
- An in-memory store can now back up to a file.
- holosdb needs Python 3.11 or later.
- A policy denial from Python reads "access denied by policy" again.
None of it changes a figure here. The extension and the suite are still on 0.25.0, one release behind; Chapter 7 now says that 0.26.0 changes nothing a check runs, rather than claiming the same number.
evidence/
256 claims, as before:
- 179 reproduced by 105 distinct runs, all passing;
- 123 quotations checked word for word against their sources;
- 1648 links resolving.
The runs used fresh clones of the testing repository at 7deaf86 and the suite at v0.24.3. One run of C14.06 fell below its threshold: under hash seed 0, HermiT failed in 6 of 10 attempts where the claim asks for 7. Re-run, it gave 9 of 10. That is the variability C14.08 measures. All three notebooks run with no errors on suite 0.24.3, shacl 0.3.4 and holosdb 0.26.0.
Full changelog: v2.0.1...v2.0.2
v2.0.1 — the same edition, re-measured on HOLOS 0.25.0
The October 2026 edition, re-measured on the toolchain as it stands a day later. The text changes where the versions changed it, and every check was re-run.
📄 SemOps-Manual-v2.0.1-A4.pdf (124 pages, A4)
📓 SemOps-Manual-v2.0.1-notebooks.zip: the three runnable notebooks, unchanged
🌐 Web edition, built from the same sources
Measured against: suite 0.24.3, extension 0.16.3, DSL 0.16.1, engine 0.3.4, HOLOS 0.25.0, tarka 0.1.1, between 13 and 22 October 2026.
What moved
- HOLOS 0.22.0 → 0.25.0.
- 0.23.0 and 0.24.0 send every way of asking a query through one query pipeline: Python, the command line, the server, and both WebAssembly methods.
- 0.24.0 also fixes a wrong answer: a zero-length path from a joined value. For example,
VALUES ?v { 1 } ?v :p? ?vover a graph without 1 should give no rows. - 0.25.0 brings five SHACL-SPARQL fixes into its validator.
- Suite 0.24.1 → 0.24.3. No code changes. 0.24.3 publishes the suite's floor on holosdb,
>=0.24, so a fresh install cannot resolve the wrong answer above. - Extension 0.16.1 → 0.16.3. It now bundles holos-wasm-node 0.25.0, the same version the suite locks. Chapter 7's "near enough the same version" is now "the same version", and because of the one pipeline, a check is also planned alike in the editor and in CI.
What the re-run found
Two outputs changed shape. The claims for both now pass on either side of the change:
Store.validate()returns its results from holosdb 0.23.0, with one entry per result. Chapter 13's example shows them.- A policy denial's wording. From holosdb 0.23.0 to 0.25.0, a sorted query refused by
fail_closed()reads "query evaluation failed: access denied by policy". It is the same denial, under a prefix it should not have. The prefix is a HOLOS regression, fixed in its development branch for the next release. Chapter 13's table now names the error without quoting either version.
evidence/
256 claims, as before:
- 179 reproduced by 105 distinct runs, all passing;
- 65 cited;
- 12 arguments.
123 quotations are checked word for word, two more than in v2.0.0. The runs used fresh clones of the testing repository at7deaf86and the suite atv0.24.3. All three notebooks run with no errors on suite 0.24.3,shacl0.3.4 and holosdb 0.25.0.
Full changelog: v2.0.0...v2.0.1
v2.0.0 — The October 2026 toolchain, and evidence for every claim
A full revision. The manual now documents six projects at their October 2026 releases, every command in Part III was re-run against them, and a new evidence/ folder backs each checkable claim with its command, data and recorded output, so the manual can be checked rather than trusted.
📄 SemOps-Manual-v2.0.0-A4.pdf (124 pages, A4)
📓 SemOps-Manual-v2.0.0-notebooks.zip: the three runnable notebooks
🌐 Web edition, built from the same sources
Measured against: suite 0.24.1, extension and DSL 0.16.1, engine 0.3.4, HOLOS 0.22.0, tarka 0.1.1, between 13 and 21 October 2026.
Six projects, installed the way a reader would
The suite now evaluates on engines of its own: holosdb for SPARQL and shacl for SHACL. rdflib only parses, and Chapter 7 tells the STY-003 story that decided it. The manual gains:
- tarka, for TARQL, OTTR and data frames;
- HOLOS, with access policy at the index scan,
holos rules, andholos-serveras the store for every live-store example; - the TypeScript DSL;
- the testing repository, as the way the rest are kept honest.
Every install route is a PyPI or npm package, the .vsix, or a GitHub release binary.
evidence/: check it yourself
256 claims, each anchored at a passage of the manual:
| Kind | Claims | How it is checked |
|---|---|---|
| Reproduced | 179 | 105 distinct runs against the published packages and release binaries, all passing |
| Cited | 65 | A commit or a file at a fixed commit |
| Argument | 12 | Says what the judgement rests on |
Across all claims, 121 quotations are checked word for word against the sources they quote.
python verify.py re-runs everything, and an annotated copy of the manual links each claim to its evidence and back. Where a release changed what a claim should see, the claim checks the installed version and says which side of the change it ran on, so a reader on an older version can still use it.
What the checking found, and upstream fixed
Building the evidence turned up defects, and most were fixed upstream while this edition was being checked:
- HOLOS 0.21.1: validation no longer writes the shapes into the store it validates. Before, it added a copy per call, and kept it on disk.
- HOLOS 0.22.0:
holos validateexits 0, 1 or 2, so it can be a CI gate. It now defaults to the same validator asStore.validate(). - Engine 0.3.4: the
shaclcommand refuses to validate against a shapes graph with no shapes, or with-sforgotten. Before, it reportedconforms: trueand exited 0. - Suite 0.23.0:
REA-020no longer calls a consistent ontology inconsistent;--inferencereaches every engine;sketchreads each mapping with its own prefixes.
- Suite 0.24.0: six fixes, each a case where a run looked cleaner than it was. 0.24.1: a bad manifest
roleis a one-line error rather than a traceback. - DSL 0.16.1: unchecked code gets an error that names its mistake, and
build().quadsgoes to n3'sWriterwithout a cast.
The manual tells each fix with both sides kept. Chapter 14 keeps what is still open, with its mitigation.
Corrections to earlier editions
Chapter 14 lists what earlier editions had wrong. Among them:
- the
owl:equivalentClasstombstone is read in both directions; - owlready2 is a base dependency and Java is the optional part;
REA-022cannot be seen in a scoped run;- the DL reasoner's outcome follows the hash seed nine runs in ten, not every time.
evidence/EVIDENCE.md lists the corrections that writing the checks forced.
Also
- The prose brings in more of the author's own voice.
- A web edition at semantechs.co.uk, built by
tools/build-site.mjs. - The build tools now handle a CRLF checkout. On Windows, with
core.autocrlf, the build had silently dropped four diagrams. - All three notebooks re-run against suite 0.24.1, engine 0.3.4 and HOLOS 0.22.0: zero errors.
Full changelog: v1.4.0...v2.0.0
v1.4.0 — 61 checks, engine 0.2.0, and the query under review
All three toolchains moved several minor versions. Every figure re-measured rather than re-quoted.
📄 SemOps-Manual-v1.4.0-A4.pdf — 97 pages, A4
📓 SemOps-Manual-v1.4.0-notebooks.zip — the three runnable notebooks
Measured against: suite 0.14.0, engine 0.2.0, extension 0.13.4.
The registry grew from 50 checks to 61
Ten categories now, not eight. TQL-* (five checks that review the transformation query itself) and VOC-* are new; QUA, REA and DAT each gained members.
That moves every headline number in Chapter 9 without the fixture changing a line — which is now the point the chapter makes:
| Run | was | now |
|---|---|---|
| unscoped | 301 | 479 |
--exclude-imports |
9 | 27 (still exactly 4 of them false) |
--own-namespace |
5 | 23 (still all genuine) |
A registry upgrade changes your findings while your ontology sits still. Pin the suite version, and read a jump in the count as "the rules moved" before "the model got worse".
Eighteen of the 23 are QUA-009/QUA-010 firing once each on all nine Acme terms. Chapter 9 now reads that correctly: a check that fires on every term is reporting a policy you have not adopted, not nine separate mistakes.
New: the transformation query is checked (Chapter 10)
TQL-001..005 review the query rather than the graph it produces. TQL-004 repays reading twice — SPARQL's CONCAT returns a string and TARQL does not coerce it, so a ?person_IRI built by CONCAT and never wrapped in IRI() produces string literals where the model says IRIs. The data loads, the counts look right, and every join against those subjects silently finds nothing.
The stage also writes bind-facts.ttl, publishing the query's own BIND structure as a graph so it can be queried with the same tools as everything else.
Engine 0.2.0: a reorder worth a major bump
The JavaScript one-shot took (shapes, data) and now takes (data, shapes), matching every other surface. The reason is the failure it removes: a transposed call compiled the data as a shapes graph, a data graph declares no shapes, and validating against no shapes conforms — so the caller was told their graph was valid when nothing had been checked. Both one-shots now refuse a shapes graph that declares nothing. Verified both ways.
Two lessons generalise, and Chapter 11 states them as such:
- An empty rule set must not report success. Same failure as a check that matches nothing, and a filter that matches nothing. Whenever "nothing to do" and "all clear" produce the same output, the tool is unsafe exactly when it matters.
- Reordering a published signature is only safe if getting it wrong is loud.
A defect found while checking
sketch crashes on a CONSTRUCT template with no trailing . before its closing brace — which is legal SPARQL. It copies the template into the sketch.ttl it writes without a terminator, then fails parsing its own output (BadSyntax: EOF found after object). Verified minimally in both directions; the Part III fixture happens to write the dot, which is why its examples run. Recorded in Chapter 14 with the mitigation.
Also
VOC-001moved from editor-only into the shared registry, so onlyMDL-001/002/003remain extension-specific. Chapter 7 names the pattern: a check earns its way from advice into enforcement once it has proved it does not produce false positives.- Chapter 10 re-measured:
sketch35 → 38 Info,data372 → 550 unscoped, 36/37 → 54/55 scoped. - Chapter 7 gains a table of the versions this edition was measured against.
- "Vendored" removed throughout in favour of plain wording.
- All three notebooks re-verified against 0.14.0 and 0.2.0: zero errors.
Full changelog: v1.3.0...v1.4.0
v1.3.0 — Authoring checks, the manifest, and the fixture repo
Check authoring, the remote-endpoint manifest, and the fixture repository that found half the defects in the last two releases — now public and linked.
📄 SemOps-Manual-v1.3.0-A4.pdf — 92 pages, A4
📓 SemOps-Manual-v1.3.0-notebooks.zip — the three runnable notebooks
Writing your own checks (Chapter 8)
The manual showed a working SPARQL check and left the contract implicit. Now stated:
- The four properties a
CONSTRUCTmust emit —sh:resultSeverity,sh:focusNode,sh:resultMessage,sh:sourceConstraintComponent. Without the last, a finding cannot be attributed. - The SHACL half, not previously covered at all — most registry checks exist in both formulations, which is what makes
--engine native+sparqlcorroborate rather than merely combine. sh:severitygoes on the shape, never insidesh:sparql. Some processors read it there and others substituteViolation, so the same shape yields different severities under different engines. If both formulations exist they must also agree onsh:resultPathandsh:value, or one finding arrives under two dedup keys and is reported twice.- Binding several values on one result is fine and often the honest thing — they are sorted and joined. An arbitrary single pick was what made finding counts wander.
- Prove the check fires. A check that matches nothing looks exactly like a clean ontology, and the suite has shipped four of them.
The remote manifest (Chapter 13)
consistency-remote needs a manifest, and the manual showed a Python snippet without ever showing the JSON a reader actually writes. Now:
- The JSON, with a field table marking the two optional fields and the two that apply only to data graphs.
- How to discover your graph URIs — the manifest must use the store's own URIs, and a trailing-slash mismatch is the usual reason a three-way check reports nothing.
- A verified trap:
roleis not validated. A manifest saying"triplified-data"with a hyphen loads without complaint, contributes zero data bindings, and the run completes successfully having compared nothing. Same silent-zero shape as the--own-namespacenear-miss; same defence — confirm it can fail before trusting that it passed.
The fixture repository is public
consolidated-ontology-quality-suite-python-testing — thirteen deliberately broken OWL2 ontologies and a harness asserting which registry checks each must trigger. Chapter 9 §9.8 described its practice; it now links the fixtures and harness so the tables can be read against the files.
§9.8 also gained the harness's fuller design:
| Assertion | Guards against |
|---|---|
| Expected ids fired | A check silently ceasing to work |
| Forbidden ids did not fire | False positives — a check becoming over-eager |
| Severity ceiling | A finding quietly escalating |
| Optional-reasoner ids, only when it ran | A flaky optional dependency turning into a red build |
Plus two traps — test against the library rather than scraping report.html, and a non-zero exit from a deliberately-broken fixture is the fixture working — and the fact that the stage decides which checks can fire at all. REA-010/011/012 fire only from ontology, and only with --profile, so a team running checks and concluding their ontology is EL-clean has not tested that.
Output artefacts the manual had been under-reporting
A run writes rather more than report.html and full_results.csv: also summary_by_check.md, summary_by_category.md, top_offenders.md, features/, plots/ and cucumber.json — each check a scenario with Given/Then steps and a pass/fail status, which most CI systems render natively. Chapter 8 now explains the cucumber_feature/cucumber_scenario registry fields that populate it.
Also
- Install pointer moved to the extension's latest release rather than the repository tree, which carries seven older builds alongside the current one.
- All 26 external links verified HTTP 200.
Full changelog: v1.2.0...v1.3.0
v1.2.0 — Stable numbers, and testing the gate itself
Three toolchains moved, and the numbers this manual documented as unstable are now stable. Re-verified by running them.
📄 SemOps-Manual-v1.2.0-A4.pdf — 88 pages, A4
📓 SemOps-Manual-v1.2.0-notebooks.zip — the three runnable notebooks
The unscoped count no longer drifts
Five identical runs now return 301 findings every time. Earlier editions reported "close to 300" with an observed range of 289–298, traced to STR-007 returning between 12 and 21 findings on identical input.
The cause was never the check. Several registry CONSTRUCTs bind two values per result — LOG-004's two inverses, LOG-006/007's domain and range, REA-001's two disjoint classes, STR-007's subject and object — while the merge step read one via Graph.value(), an arbitrary pick, and deduplicated on it. Values are sorted and joined now, and the report shows both instead of half the finding.
The engine modes agree
Chapter 7's table was 4/5/6/6 with LOG-001 double-reported and both reporting 5 Violations against native+sparql's 2. It is now 4/5/5/5 at identical severities. Only --engine native still differs, for a stated reason: it runs the SHACL shapes only, and QUA-004 exists solely as a SPARQL check.
The severity half needed more than a number change. This manual attributed the split to a pySHACL bug, following a long comment in the suite's own source. That was half right. pySHACL does ignore sh:severity where it was written — but it was written in the wrong place, inside each nested sh:sparql block rather than on the enclosing shape, where SHACL defines it. The native engine read it there anyway. Moving it made both engines agree.
The lesson is about shape authoring, not engine choice. If your gate fails on something you declared
Warning, check wheresh:severityis attached before blaming the engine.
New: Chapter 9 §9.8 — Testing the gate itself
From the sibling fixture repository that found the defects above. Its central practice answers a question the manual had left open — how do you know the gate still works?
- Assert check identifiers, not counts. A regression then reads as "
LOG-004no longer fires" rather than "expected 85, got 83". It also survives exactly the churn above: while totals moved between 289 and 298, the set of ids never did. - Keep a clean control producing no Violation and no Warning, so findings elsewhere are attributable to seeded errors rather than background noise.
- Mark each seeded fault with an
# ERROR:comment naming its check.
The motivating case: the suite has four times shipped a check that quietly matched nothing. A check that cannot fire is worse than no check, because it looks like coverage.
The extension took the same fix — but assessed it first
Version 0.11.0 adopted the severity correction and deleted a workaround built on the assumption that a strict engine ignoring misplaced sh:severity was an engine bug. Notably it did not adopt the suite's findings on trust: it assessed each against its own stack, concluding two did not apply and one applied in a different form.
Shared artefacts need propagation with independent assessment, not synchronisation. A fix that is right for one runtime is a hypothesis about the other.
Also
DAT-001can now detect an invalidxsd:boolean— the regex branch was unreachable, because rdflib rewrites the stored lexical form of an ill-typed boolean.STR-002andSTR-007no longer disagree about external vocabularies.- Chapter 14's "gaps that have closed" now lists seven.
- All three notebooks re-verified against suite 0.6.0 and shacl 0.1.9: zero errors.
Full changelog: v1.1.1...v1.2.0
v1.1.1 — Upstream tracking: rules everywhere
All three toolchains moved, and two things this manual said one edition ago are now the opposite of true. Re-verified by running them.
📄 SemOps-Manual-v1.1.1-A4.pdf — 89 pages, A4.
The WebAssembly build now runs rules
Chapter 11 said flatly that it could not, and that on one shapes graph it returned conforms = true where the native CLI errored — "this is fine" against "I could not check this". Both fixed:
- Verified against the rebuilt 0.1.9 package:
inference="rules"fires the rule and validates the derived data, and an unrecognised mode errors rather than falling back silently to"none". - The engine's differential harness reports 0 disagreements across all 473 documents of the W3C corpus, where it previously reported one.
sh:declarewithoutsh:prefixesnow resolves, and rule compile errors are held on the rule rather than failing the whole shapes graph for callers who never asked for rules.
0.1.9 also fixes $this not being substituted into CONSTRUCT-based rules — a SPARQL rule ran for every node in the graph rather than for its focus node. If you wrote SPARQL rules against an earlier build, re-run them.
What remains is a choice, not a limitation: the VS Code extension bundles the rules-capable engine and asks for inference: "none" deliberately, so rules do not fire in the editor and its report answers a different question from CI's.
The extension swapped its SHACL engine
It replaced its JavaScript implementation with shacl-wasm-node — the same Rust engine the CLI uses natively. On its own workload: 71,237 ms → 324 ms, identical findings, and two shape files that had been crashing outright now run, so DAT-001 and EFF-002 could not fire through the SHACL path at all before.
That makes the manual's "one registry, two runtimes" argument stronger than it was: the rule that fails your build is no longer merely the same data as the rule that underlined the problem in your editor — it is the same engine evaluating it.
Still not on the Marketplace (checked: 404), so the install instructions stand.
What did not change
Re-ran the four --engine modes: unchanged at 4/5/6/6 with LOG-001 still double-reported, so Chapter 7's table needed no correction. STR-007 still drifts — five runs gave 289–298 — so Chapters 9 and 14 stand as written. Conformance is still 418/426, now with zero documents unrunnable.
Notebooks now reachable from the PDF
The print build flattened every relative link, so "notebook 2" reached paper as dead text. Links to files that live only in the repository — notebooks/, tools/, assets/ — now become absolute GitHub URLs in print, while chapter cross-references stay flattened since those point inside the same document.
Notebook 2 gains a Python-binding section, since rules are reachable that way from 0.1.8. All three re-verified against 0.1.9 with zero errors.
Full changelog: v1.1.0...v1.1.1
v1.1.0 — Rules, inference, and notebooks
A new chapter on SHACL-AF rules, three runnable notebooks, and two corrections found by reviewing the SHACL engine — run rather than read.
📄 SemOps-Manual-v1.1.0-A4.pdf — 87 pages, A4.
New: Chapter 11 — Rules and inference
The manual treated SHACL as validation only. Rules are inference, and they change what your gate sees.
- Three ways to derive a triple — transformation, RDFS closure, SHACL-AF rules — and when each is right.
- Triple rules, SPARQL rules,
sh:declare/sh:prefixes. - The four hazards that produce silence rather than an error, each reproduced from independent fixtures: a rule under
sh:propertynever fires; one pass does not close transitively; rules at equalsh:ordercannot see each other's output; negation is not monotonic under iteration. - Rules at scale, measured: 11.9s to derive and validate over 690k triples at 100k instances, 18.7s with
--iterate-rules 5, against 2.7s validate-only. - Rule accuracy proven by construction: exactly 1,000 and 100,000 inferences for the two datasets — every focus node, once, no misses or duplicates.
The significant gap it documents: the WebAssembly build has no rules at all. On a shapes graph the native engine rejects at compile time, WASM returns conforms = true with zero results. One says "I could not check this", the other says "this is fine" — so browser and editor validation is validation-only.
Corrections
--engine is not a speed switch. Measured on the same fixture, same registry, same --own-namespace:
--engine |
Findings | Severity | |
|---|---|---|---|
native |
4 | 1V / 3W | misses QUA-004, a SPARQL-only check |
sparql |
5 | 1V / 4W | the numbers this manual reports |
native+sparql |
6 | 2V / 4W | union — LOG-001 reported twice |
both |
6 | 5V / 1W | same findings, wrong severities |
Neither formulation is complete alone; the union double-reports LOG-001 with no deduplication; and the pySHACL sh:severity bug shows up as five Violations against two on identical input — which under --fail-on Violation is a red build against a green one. Chapter 7 now covers this, and Chapter 9 says why --engine sparql is pinned in every command it shows.
Named graphs are flattened. Quad syntaxes parse, then every named graph and the default graph are merged before validation — verified: a TriG file across two named graphs gives a report identical to the flattened Turtle, and there is no graph-selection option. Chapters 3 and 13 recommended per-partner named graphs without saying validation cannot be scoped to one. Both now state the limit and point at extract-then-validate.
New: notebooks
Three self-contained notebooks, each writing its own fixtures to a temp directory:
| Covers | |
|---|---|
| 1 — Validation and the gate | The unscoped gate, the flag that fixes it, and the near-miss filter that returns a confidently empty report |
| 2 — Rules and inference | Every rule form, and all four silent-failure hazards |
| 3 — Release and change | Evidence-based semver, change impact, and a repair applying itself — including the comment it mangles |
All three were verified by extracting their code cells and executing them in order: zero errors.
Verified, unchanged
418/426 W3C conformance reproduced; all 175 crate tests pass; the pySHACL benchmark reproduced at 75×/122×/114× across 1k–100k with result counts identical at every size.
Full changelog: v1.0.3...v1.1.0
v1.0.3 — Toolchain links
The manual named both toolchains but gave readers no way to get them. Now linked throughout.
📄 SemOps-Manual-v1.0.3-A4.pdf — 79 pages, A4.
Get the tools
| Toolchain | Source | Install |
|---|---|---|
| Ontology Quality Suite | GitHub | pip install ontology-quality-suite — Python 3.11+ |
| Ontology Development Suite | GitHub | .vsix from the repository — not on the Marketplace |
What changed
- The README's toolchain table links each repository, and PyPI for the Python suite.
- Chapter 7's comparison table gains Repository and Distribution rows.
- Chapter 7's install sections link source and package, note the Python 3.11+ floor, and give the actual
code --install-extensioncommand, since the extension is not on the Marketplace. - Chapter 7's ten "deeper documentation" entries are now links rather than bare filenames, as are the webapp's
README.mdandTUTORIAL.md. - The
examples/acme_robotics/fixture that every Part III command runs against is linked where it is introduced — readers can now see the deliberately-imperfect ontology the whole manual is calibrated on. - Chapter 14's Phase 1 links the extension repository at the point of the install instruction.
URLs were taken from the repositories' own git remotes and their pyproject.toml / package.json metadata rather than guessed. All 18 distinct GitHub and PyPI links verified HTTP 200. PyPI publishes 0.4.0, matching the checkout the manual was written and verified against.
Full changelog: v1.0.2...v1.0.3