Build a working ontology from defence logistics data
Build an ontology from an empty Python file, inspect actual graph records and their sources, and extend a maintenance example to multiple required parts. Six chapters combine plain-language explanations with a downloadable, locally tested implementation.
The question: How do we actually create, validate and use an ontology from operational source records?
You’ll learn: Construct an ontology step by step, trace RDF facts to CSV records, validate and query them, and migrate the model to support several required parts per order.
For: Domain experts, analysts and engineers; concepts are explained before the runnable commands.
Executed teaching prototype · AI-assisted source check . This is not a human expert endorsement.
Chapter 5: Orchestrate the calculation and preserve a reviewable result
5. Orchestrate the calculation and preserve a reviewable result#
The query is one stage of the application. A reproducible run records which inputs were transformed, whether validation succeeded, what was requested, and where processing stopped. Here, orchestration is a fixed sequence of commands and artifacts. The sequence has no uncertain planning step that needs an autonomous agent.
Step 1: Run dependent stages with failure handling#
Run these commands from the extracted lab directory using the environment created in Chapter 2. PowerShell must inspect each external program's exit code so a failed stage prevents the next one from running:
.\.venv\Scripts\python.exe ontology_lab.py build
if ($LASTEXITCODE -ne 0) { throw "Build failed; stop here." }
.\.venv\Scripts\python.exe ontology_lab.py validate
if ($LASTEXITCODE -ne 0) { throw "Validation failed; inspect the report." }
.\.venv\Scripts\python.exe ontology_lab.py query --org ORG-TRAIN --order WO-204
if ($LASTEXITCODE -ne 0) { throw "Query failed; inspect the reported condition." }A successful process exit and sufficient stock are different outcomes. The command can successfully explain a shortage. An invalid graph follows the failure path. A nonempty JSON file may contain a diagnostic from a rejected stage, so inspect its status.
build performs the initial SHACL check. validate reopens and checks the generated artifacts. Before a query, load_verified() compares source, importer, query, and generated-artifact hashes with results/manifest.json. Changed inputs require an explicit rebuild.
Original process diagram for the reference implementation. Running a command again should reproduce the graph from its inputs; an external approval-and-write service is a separate extension.
Select a box to inspect its role. On a small screen, scroll the diagram sideways.Identify the exact files, schema and mapping used for this run. Mixing snapshots can produce an answer that never corresponded to any real stock state.
Read the complete diagram as text
- Read the source set: Identify the exact files, schema and mapping used for this run. Mixing snapshots can produce an answer that never corresponded to any real stock state.
- Build the graph: Create canonical objects, links and provenance. Stop on source or identity errors rather than guessing a successful result.
- Validate the graph: Inspect SHACL and integrity results. A failed validation must prevent the normal proposal path from using the failed build.
- Run the scoped query: Select the requested organization and work order, then check part, stock, allocation and inspection evidence. This is deterministic data processing.
- Expose the blockers: Six on hand minus two quarantined and three reserved leaves one. Requiring two therefore produces a shortage of one.
- Emit a review request: The artifact records the facts and blockers for a reviewer. It grants no permission and performs no live inventory change.
- Read the source set → load → Build the graph
- Build the graph → test → Validate the graph
- Validate the graph → use → Run the scoped query
- Run the scoped query → compute → Expose the blockers
- Expose the blockers → record → Emit a review request
The dependencies are concrete: declared source rows produce the graph; validation applies to that graph; a scoped query produces the explanation and local review draft. Keep these artifacts together so another engineer can reproduce the result.
Step 2: Read the implemented boundary in one place#
| Capability | Implemented and exercised here | Required for a real service |
|---|---|---|
| Data ingestion | Fixed CSV contracts, explicit aliases, typed RDF mappings | Approved connectors, feed completeness, failure ownership, and refresh policy |
| Validation | SHACL and explicit identity, unit, allocation, and freshness checks | Domain-specific acceptance coverage and trusted source verification |
| Scope | A CLI selector used by fixed, scoped queries | Verified identity, authorization, and protected data access |
| Integrity and lineage | Local hashes, source locators, and PROV records | Protected audit records and appropriately trusted ingestion |
| Review | An unsubmitted JSON draft bound to its input revision | Authenticated reviewer, approval expiry, and current-state rechecks |
| External actions | No stock reservation, purchase, or equipment release | Authorized command handling, concurrency control, receipts, and reconciliation |
| AI extraction | No model call or neural extraction stage | Candidate extraction evaluation and a review process before facts are accepted |
The local --org flag is not an access-control boundary: anyone with the downloaded files can inspect all their contents. A deployed service must derive scope from verified identity and policy. ABAC is one policy model using requester, resource, operation, and environment attributes.502 A hidden record or property must not silently become a negative business fact.
Step 3: Explain the quantity and the proposal#
The baseline's physical unit sets are disjoint: two quarantined units and three other reserved units within six on hand. The calculation therefore yields:
Available = 6 − 2 − 3 = 1
Shortage = max(0, 2 − 1) = 1The max means extra usable stock produces zero shortage. It does not justify hiding impossible negative availability. If allocations exceed stock, or the same unit appears in both excluded sets, the inputs require correction.
The query writes results/explanation.json and results/human-review-request.json. These selected review fields come from the baseline run:
{
"type": "human-review-request",
"orderId": "WO-204",
"org": "ORG-TRAIN",
"status": "UNSUBMITTED_LOCAL_DRAFT",
"shortage": 1,
"basisSchemaVersion": "1.0.0",
"basisSnapshotRevision": 1,
"requiresFreshnessAndAuthorizationRecheck": true,
"approvalImplemented": false,
"businessWritesExecuted": false
}The complete draft also includes basisInputFingerprint. It has not been delivered to a reviewer. A coordinator can inspect what was requested, which evidence revision supported it, and why another filter is needed. That is the completed output of the baseline workflow.
Step 4: Test freshness separately from structure#
A well-typed integer may still be too old to use. fixtures/scenario.json sets a fixed demonstration clock of 14 September 2026, 08:00 UTC, and a 7,200-second freshness allowance. The baseline's stock, two allocations, and inspection were observed at 07:30, giving four fresh records out of four required.
To test the boundary without editing the fixtures, run:
.\.venv\Scripts\python.exe ontology_lab.py query --org ORG-TRAIN --order WO-204 --as-of 2026-09-15T08:00:00ZInspect results/explanation.json: status becomes insufficient_evidence, while available and shortage become null. Rerun the original query to restore the baseline output. The command accepts an explicit clock for repeatable tests; it does not fetch current depot records.
A connector must distinguish observation time from ingestion time. Downloading an old spreadsheet today does not create a new stock observation. SHACL checks graph conditions; the freshness policy and physical meaning of an observation are separate responsibilities.501
Step 5: Explore changed quantities locally#
Inspect the stock calculation and proposal gates
Change the fictional PF-9 quantities and inspect why the proposal passes or stops. These controls calculate an example in your browser; they do not change an inventory system.
Available = 6 − 2 − 3 = 1. Shortage = 1.
The request is short by 1. Reviewer approval cannot remove a stock shortage.
- Quarantined: 2
- Reserved: 3
- Available: 1
The calculation assumes quarantined and reserved quantities are disjoint subsets of the on-hand count, and every quantity uses the same part, depot, unit and source snapshot. The downloadable lab also validates those source relationships.
With seven units on hand and the same two quarantined and three reserved, two remain available. That removes the quantity shortage. The exercise lets you change quantity, freshness, scope, and a simulated approval state to see which condition controls the outcome.
The controls are teaching inputs. They do not authenticate a supervisor or change inventory. The equation can be satisfied while a real maintenance process still requires other evidence or authorization.
Step 6: Define an action contract before connecting a system#
If a later pilot reserves stock, name a separate operation, for example RequestStockReservation. Agree on the following proposed contract before writing its adapter. This contract is an implementation specification, not an additional command in the download.
| Contract element | Concrete requirement |
|---|---|
| Request identity | Unique operation ID and authenticated requester; derive permitted organization server-side |
| Intended change | Exact work order, requirement line, part, unit, quantity, depot, and selected snapshot |
| Decision basis | Input fingerprint, model version, source revision, approval identity, and expiry |
| Submission checks | Current authorization, fresh evidence, approved requirement, and sufficient stock |
| Concurrent change | Compare the expected revision with current state; reject and re-evaluate on conflict |
| Result and retry | Durable operation receipt; reuse the operation ID; reconcile ambiguous downstream outcomes |
Submission conditions need both business criteria and permissions.503 Passing a quantity check alone is insufficient. If another job reserves the last unit after review, the stale proposal must not proceed with its earlier arithmetic.
An external system can succeed while a later local update fails; documented writeback behavior illustrates why these effects cannot simply be assumed to form one transaction.504 After a timeout, inspect the operation's recorded outcome before retrying. The adapter and downstream service must agree on operation identity and recovery behavior.
Checkpoint: what your workflow guarantees#
You have an ordered build, validation, and query sequence; a result tied to source revisions; and a local review draft. You can demonstrate that stale evidence withholds the calculation. You also have a concrete specification for a future action service. Chapter 6 now changes the ontology itself and proves the new requirement-line model with data, queries, and failure tests.
W3C, Shapes Constraint Language — validation against graph conditions; checked 14 September 2026. Freshness and inventory policies are explicit lab choices.
NIST, SP 800-162: Attribute Based Access Control — attributes and policy decision model; checked 14 September 2026.
Action submission criteria — configured submission conditions; checked 14 September 2026. The proposed reservation contract is this guide's design.
External writeback and webhook behavior — external success with later ontology failure remains possible; checked 14 September 2026. No webhook was configured or invoked.