Ontology Changelog
Changelog
Notable changes to the SOLVE-IT ontology.
[0.2.5] — 2026-08-25
solve_it_core.ttldefinessolveit-core:Citation, withcitationID,citationPlaintextandcitationBibtex. The knowledge base has published 158 citations as resources typedsolveit-core:Citationfor some time, but the ontology defined no citation term at all, so all four were being asserted into the ontology’s namespace without being defined in it.solve_it_core.ttldefinessolveit-core:objectiveIDandsolveit-core:sortOrder, both onObjective, and both used by the knowledge base on all 24 objectives.techniqueID,weaknessIDandmitigationIDwere already declared, soobjectiveIDwas the one identifier property missing.sortOrderis anxsd:integergiving the position of an objective in investigation order.solveit-core:hasReferenceis anowl:ObjectPropertywith rangesolveit-core:Citation, in place of anowl:DatatypePropertywith rangexsd:string. The knowledge base gives it an IRI on all 241 statements, which a datatype property cannot take, so the published data was not valid OWL DL. The domain is unchanged: the union of Technique, Weakness and Mitigation still matches the knowledge base exactly, at 126, 62 and 53 statements.- The examples reference citations by IRI, as
solveit-core:hasReference solveit-data:citationDFCite-1107, in place of the string"DFCite-1107". All 18 are incore_classes_examples.ttland every identifier already agreed with the knowledge base, so only the form changed. scripts/validate_kb_conformance.pychecks the generated knowledge base against the ontology, and fails if the knowledge base uses a SOLVE-IT ontology term that no ontology file defines, or gives a datatype property an IRI or an object property a literal. Run against the ontology as it stood before this release it reports all seven faults above; nothing in the repository reported any of them.- The conformance check runs in
validate-ontology.ymlandvalidate-and-build-docs.yml, and ingenerate-knowledge-base.ymlbefore that job commits, so a knowledge base using an undefined term is not published. The last of those is the one that matters: that job commits withGITHUB_TOKEN, and GitHub does not start workflow runs for pushes made with that token, so a push trigger would never have seen a knowledge base update. - The gap these checks close is that
reporting_scripts/generate_rdf_from_kb.pyin the solve-it repository mints terms through rdflibNamespaceobjects, which build an IRI by string concatenation and cannot fail, and it never reads the ontology.validate_ontology.pydoes not load the knowledge base, andvalidate_examples.pyandvalidate_example_io.pyload it only as the reference to check the examples against, so the knowledge base itself was never checked by anything.
[0.2.4] — 2026-08-25
validate-and-build-docs.ymlnow runsontospy gendocsagainst a staging directory holding only the root-levelsolve_it_*.ttlfiles, in place of the repository root.scripts/build_docs_local.shis changed to match.- ontospy recurses into subdirectories, so pointing it at the repository root
also read
solve_it_examples/. Since the UCO 1.5.0 metaclass change the examples declare techniques as classes, witha owl:Class , solveit-core:Technique, so ontospy rendered a class page for each one and listed it in the class index. Tensolveit-data:techniqueDFT-*entries were published as part of the ontology’s own vocabulary, all ten declared insolve_it_examples/core_classes_examples.ttl: DFT-1002, 1005, 1042, 1049, 1052, 1060, and 1122 to 1125. Which ten appeared depended only on which techniques that file declares. A technique the examples use without declaring it, naming it only as therdf:typeof an action instance, produced no page: DFT-1121, DFT-1182 and DFT-1183 are used that way and did not appear. - Technique entries are knowledge base data, published at
data.solveit-df.org. The ontology definessolveit-core:Technique, and the individual entries are instances of it. The examples themselves remain documented, bygenerate_examples_page.py. - The two shapes files are still read by the documentation build, so
sh:NodeShapecontinues to appear in the class index. generate_iri_redirects.pynow reads the ontology with rdflib in place of regular expressions, takes each module name from the entity’s IRI rather than by splitting its prefix, and keys entities on module and local name together rather than on local name alone. It generates 260 redirect folders, up from 226.- The 34 IRIs that gained a redirect were returning 404 on the published site.
Thirteen are
tool-profileterms and nineteen areweakness-assessmentterms: the parser tested for the three prefixessolveit-core:,solveit-analysis:andsolveit-observable:, so the two modules added since it was written were skipped in full, and neither module had any resolvable IRI. The remaining two aresolveit-observable:hasArtifactandsolveit-observable:hasFile, which collided with thesolveit-analysis:properties of the same local name. Both pairs are distinct properties with different domains,ForensicToolTagBasedReportagainstArtifactSetandFileSet, and the redirect path already separates them by module, but keying on the local name discarded one of each pair. Which one survived depended on the orderPath.globreturned the files in, so it could change between runs with no edit to the ontology. generate_iri_redirects.pyfails, and writes nothing, if an entity’s namespace has no declaredsolveit-prefix or if a redirect would point at a page that does not exist. The module name and the documentation filename come from different places: the folder path comes from the IRI, sosolveit-wa:hasEvaluationis served at/solveit/weakness-assessment/hasEvaluation, while Ontospy names the page after the declared prefix,prop-solveit-wahasevaluation.html. A redirect built from the wrong one of those is a 404 that appears only when someone dereferences the IRI.- The 226 redirects that already existed are byte-identical after the change.
- The keyword search examples in
core_classes_examples.ttldeclarehasCASEOutputClass solveit-observable:KeywordSearchResultSetfor DFT-1049, DFT-1122, DFT-1123 and DFT-1125, in place ofsolveit-observable:KeywordSearchResult. The knowledge base had been updated to the set-valued class, socheck_kb_driftinvalidate_examples.pyreported the four as drifted and the validation step failed ahead of the documentation build. DFT-1124 already declared the set. The example actions for these techniques already produce aKeywordSearchResultSet, so the declarations were the part that was behind.
[0.2.3] — 2026-08-20
validate-against-case-1.5.0.ymlnow runs automatically. It previously ran only when started by hand from the Actions tab, and had not been run since it was written on 5 August. It is now triggered by pushes tomainthat touch a TTL file, by pull requests touching the same paths, and bygenerate-knowledge-base.ymlcalling it directly.- The call from
generate-knowledge-base.ymlis made only on the runs where that job committed a rebuilt knowledge base, which is a small proportion of its hourly runs. A direct call is used in place of the push trigger because that job commits usingGITHUB_TOKEN, and GitHub does not start further workflow runs for pushes made with that token. validate-against-case-1.5.0.ymlnow confirms that the SOLVE-IT shapes are in the graph it validates against before reporting a pass. The shapes reachcase_validatebecause the two shapes files are matched by thesolve_it_*.ttlpattern used to build the merged ontology graph. Renaming a shapes file, or narrowing that pattern, would remove all 13 SOLVE-IT shapes from the graph, and every run would continue to report success. A technique that breaksTechniqueIOTermShapeis now validated first, and the job fails if it is accepted.- The merged CASE, UCO and SOLVE-IT graph used by
validate-against-case-1.5.0.ymlis cached, keyed on the CASE release tag and a hash of the local ontology files, so that a run does not check out CASE with its UCO submodule and reparse 32 files each time. validate-and-build-docs.ymlchecks out withfetch-depth: 2. The step that decides whether to bump the patch version tests whetherVERSIONchanged by runninggit diff HEAD~1, andactions/checkoutdefaults tofetch-depth: 1, soHEAD~1was not present in the runner’s clone. The command failed, and the step reported “not changed” whatever the commit contained, so a version set by hand was always overwritten by the automatic patch bump.- The 0.2.1 section is titled 0.2.1 rather than the 0.2.0 that was set in
VERSIONfor the UCO 1.5.0 metaclass change, because the fault above meant 0.2.0 was never stamped into the ontology files and never published.
[0.2.2] — 2026-08-20
hasCASEInputClassandhasCASEOutputClassno longer declarerdfs:range owl:Class. A technique’s declared input or output is usually a class, but where the technique consumes or produces a single value rather than an object it is a property, for examplecase-investigation:exhibitNumberoruco-observable:filePath. 42 of the 173 terms the knowledge base references are properties. No singlerdfs:rangeadmits both classes and properties without also admitting everything else, so the restriction is now stated in SHACL rather than in OWL.- Added
TechniqueIOTermShapetosolve_it_core_shapes.ttl. Every term named as a technique input or output must be declared anowl:Class,owl:DatatypePropertyorowl:ObjectProperty. This replaces therdfs:rangeremoved above. - Added
TechniqueIOTermConsistencyShapetosolve_it_core_shapes.ttl. A term must not be declared as more than one of those three kinds. This detects a SOLVE-IT declaration that contradicts the one CASE or UCO gives the same term, whichTechniqueIOTermShapecannot do, because that shape is satisfied by whatever declaration the knowledge base itself supplies. It only reports a violation when CASE and UCO are loaded alongside the data being validated. Run against the knowledge base as published before this change it reports 56 violations across the 42 property terms, and none against the output of the corrected generator. -
The two property names still contain the word “Class” although they now accept properties. They are expected to become
hasInputandhasOutputshortly, alongside the corresponding change in the knowledge base, so they are left unchanged here in order that the rename happens once. scripts/validate_examples.pynow requires knowledge base entities referenced in the examples to be written in thesolveit-data:namespace. An example that writes:techniqueDFT-1002against its own default prefix defines a separate entity in the examples namespace rather than referring to the catalogue entry of that name. Such a file is internally consistent and validates cleanly while describing entities that exist nowhere else, which is how the three mis-namespaced references insolve_it_examples/weakness_assessment_examples.ttlwent unnoticed.scripts/validate_examples.pynow compares the inline copies of catalogue entries held in the examples against the knowledge base. Examples restate techniques, weaknesses and mitigations so that a file can be read without opening the knowledge base, and those restatements can fall out of step with it. A value the example leaves out is accepted, because stating two of a technique’s five input classes is a partial restatement rather than a contradiction. A value the example asserts that the knowledge base does not hold is reported as an error.scripts/validate_examples.pynow followsrdfs:subClassOfwhen checking the input and output types of a performed action. A technique that declaresTimelineas its input is satisfied by aSortedTimeline, which is a subclass of it. The previous check compared the two sets of types directly and reported a mismatch in that case.
[0.2.1] — 2026-08-19
Techniquenow subclassesuco-action:Techniquerather thancase-investigation:InvestigativeAction, following the metaclass model introduced in UCO 1.5.0. A technique is a class; a performed action states which technique it implements byrdf:type, not by a property. The previous axiom sat on the metaclass and so made every catalogue entry a performed action.SolveitInvestigativeActionretained, and is now the parent of every technique class. It remains the anchor for occurrence-level properties, soappliedMitigationis unchanged — its domain is satisfied by inference.usedTechniquemarkedowl:deprecated. Retained so existing data parses.hasCASEInputClassandhasCASEOutputClasschanged from datatype properties with rangexsd:anyURIto object properties with rangeowl:Class. A class IRI held in a string literal cannot be followed by a reasoner, walked by a SPARQL property path, or checked for a typo.- All UCO and CASE imports moved from 1.4.0 to 1.5.0 across 9 files. A partial
bump does not work:
uco-action1.5.0 importsuco-core1.5.0, which would put two versionIRIs of the same ontology in one import closure. - SHACL: retired
SolveitInvestigativeActionShape, which required at least oneusedTechnique; under the metaclass model there is no violating state left to detect. AddedTechniqueShape, checking what OWL cannot express — that a technique is also declaredowl:Classand carries anrdfs:subClassOf. - Example actions migrated from
usedTechniquetordf:typeagainst the technique class, across six files. validate_examples.pynow loads the generated knowledge base (docs/data/solve-it-kb.ttl). The technique classes the examples type their actions with are defined there, not in the ontology files, so without it the examples could not be resolved against a complete schema and every domain check against an action reported a violation that was not real.- Retyped the keyword indexing example from
techniqueDFT-1126(Keyword search (live) (physical)) totechniqueDFT-1121(Index a data source for keyword searching). The action builds an index from aFileSetand anArtifactSetand produces aKeywordIndex, which is what DFT-1121 declares; it was typed as a search. - Qualified the technique and weaknesses in
weakness_assessment_examples.ttlwith thesolveit-data:prefix. They were written against the file’s default prefix, so they resolved into the examples namespace and described look-alikes rather than the catalogue entries the evaluations scored.
[0.1.10] — 2026-08-11
- Added
rowiddata property toSQLiteRecord. - Clarified comments on
fieldTypeandhasBlobContentin the SQLite module.
Versions up to 0.1.9 were reconstructed retrospectively from git history on
2026-08-11. Patch versions are assigned automatically by CI on push (see
scripts/sync_version.py), so each version is dated by the commit that stamped
it. Patch versions containing only automated rebuilds and no ontology changes
(0.0.8, 0.1.1) are omitted.
[0.1.9] — 2026-07-10
- Added
HypothesisedUserAccountto the analysis module. - README: documented that external consumers (e.g. the KB build) need updating when new module files are added.
[0.1.8] — 2026-07-02
- Added
HypothesisSetto support SOLVE-IT technique modelling.
[0.1.7] — 2026-06-25
- Added
VirtualizedDeviceandVirtualizedComputer.
[0.1.6] — 2026-06-24
- Added
VideoFileandAudioFile.
[0.1.5] — 2026-06-24
- Added
HashSet(withHashSetEntryandHashVerificationResult) plus example. - Added IDs to the timeline sorting example.
[0.1.4] — 2026-03-30
- Added sorted timeline concept (
SortedTimeline,SortedTimelineEntry) and a draft example using the SOLVE-IT timeline techniques.
[0.1.3] — 2026-03-23
- Added
TimestampOffset.
[0.1.2] — 2026-03-21
- Added
SmartHomeAppFiles.
[0.1.0] — 2026-03-20
- Renamed
PerformedTechniquetoSolveitInvestigativeAction. - Restructured weakness classification to support the new weakness formats.
- Added detail to keyword classes and added search examples.
- Improved examples and updated them to the new naming scheme.
- Added input/output class validation for examples (
validate_example_io.py).
[0.0.7] — 2026-03-17
- Added
GamingAppFiles.
[0.0.6] — 2026-03-09
- Added weakness assessment module (
solve_it_weakness_assessment.ttl) with risk scoring, plus examples. - Added application file set classes (
BrowserAppFiles,ChatAppFiles,EmailAppFiles,PhotosAppFiles, and others). - Added hypothesised event subclasses to the analysis module
(
HypothesisedWebSearch,HypothesisedCommunication, and others).
[0.0.5] — 2026-03-03
- Updated
FileSystemExtraction.
[0.0.4] — 2026-03-03
- Added mobile acquisition types:
iOSDeviceGeneratedBackup,AndroidDeviceGeneratedBackup,AppleUnifiedLogArchive,ContentQueryData.
[0.0.3] — 2026-03-03
- Docs tooling: GitHub repository link added to generated documentation pages.
[0.0.2] — 2026-03-03
- Added SQLite module (
solve_it_sqlite.ttl) with classes and examples. - Added hypothesis stub classes and
hypothesisedDateTimeproperty. - Added CASE input class support (
hasCaseInputClass). - Added
FileSetandFilteredFileSet; refinedRedactedFileSet; added aPrioritizedDeviceSetexample. - Acquisition/interface updates: added
ReadWriteDeviceInterface, reworded read-only interface; accommodated screenshots and clock offsets as acquisitions; SHACL fix forClockOffsetMeasurement. - Split forensic image containers into subclasses by contents
(
PhysicalImageContainer,LogicalImageContainer). - Added
BitstreamRandomAccessedandLiveOSDeviceInterface. - Added
BrowserCacheData. Mitigationnow subclassesInvestigativeAction.- Reworded
usedTechnique(potentially breaking). - Accommodated time ranges in
TimelineEntry. - Tooling: validation scripts run as a GitHub Action; automatic version sync.
[0.0.1] — 2026-02-20
First versioned release: added the VERSION file, version bump/sync scripts,
and documentation tidy-up. The ontology content at this point comprised the
pre-versioning development below.
Pre-versioning (2025-12-17 – 2026-02-20)
- Initial ontology structure: core classes (
Objective,Technique,Weakness,Mitigation) aligned to CASE/UCO, with observables and analysis split into separate module files. - Added
PerformedTechniquelinking performed actions to techniques and applied mitigations;Techniquechanged to subclassInvestigativeActionrather thanUcoObject. - Added tool profile module (
ToolCapabilityProfile,MitigationCapability,SolveItAwareInstrument). - Many observable classes:
Timeline/TimelineEntry,ImplicitTimingInformation,KeywordSearchResult,KeywordIndex,UnlockPattern,DecryptionKey,RedactedFileSet/RedactedArtifactSet,NetworkPacketCapture,ForensicToolTagBasedReport,ClockOffset,HTTPResponseHeader,DateTimeStamp,ApplicationFiles, screenshot acquisition types,AcquisitionRecordFile. - Added
DataAcquisitionand subclasses with acquisition error records. - Updated CASE/UCO alignment from 1.3 to 1.4.0.
- Infrastructure: GitHub Pages documentation at
ontology.solveit-df.orgwith IRI redirects; daily knowledge base RDF endpoint; MIT licence.