Validator Engine
services/validator-engineChecked by automation only
Written 2026-10-29 by ktl-librarian (automation). Last checked 2026-10-15 by ktl-librarian (automation).
The full record
- Checks
- 2026-10-15 by
ktl-librarian(automation)
- 2026-10-15 by
- Sources
- Is part of
- About
- Related to
- Pointed to by
- KTL Registrar Plugin (depends on)
- Graph
- Open this concept in the knowledge graph
- IRI
https://w3id.org/ktl/registrar/knowledge/services/validator-engine- Licence
- CC BY 4.0
- Files
- MarkdownJSON-LDSource on GitHubHistory on GitHub
Overview
Section titled “Overview”src/validator.ts imports nothing, neither Obsidian nor a YAML parser. Callers hand in already-parsed frontmatter, and the note body when they have it, so the module runs unchanged under Obsidian and under plain Node in scripts/smoke-test.ts.
validateLokfConcept runs two layers. The LOKF semantic layer has five rule groups:
- the bundle-root semantic header and
base_iri(validateRootHeader); - the type vocabulary and type-specific fields (
validateTypeVocabulary); - typed relationships, with target-existence checking (
validateRelationships); idconsistency (validateConceptId);- the shape of the OKF v0.2 §5 trust and lifecycle fields (
validateTrustLifecycle).
The OKF v0.2 base layer is the set of okf/* rules behind the checkOkfBaseLayer setting. It checks what the LOKF schema already subsumes:
- a required
type(§11); - the
Attested Computationcontract (§10); - the reserved
index.mdandlog.mdstructure (§8 and §9); - the v0.1 to v0.2 migration hints (§13).
A vault that runs a dedicated OKF validator can turn that layer off. Credibility and trust-tier interpretation stay out of scope.
Values and types
Section titled “Values and types”The engine never assumes a frontmatter value is a string. A scalar is coerced to text for messages, and a mapping or list is named by its shape (<a mapping>, <a list>). A missing or blank type on a note that carries other LOKF fields is the error okf/type-required while the base layer is on, and an ordinary note with only tags or aliases is left alone. A list or mapping as type is a shape warning, and a coercible scalar such as type: 123 falls through to the ordinary “not in the vocabulary” warning. The type-specific field checks key on the exact class name, so a domain subclass of Metric is not held to its parent’s recommended fields.
Errors that match lokf validate
Section titled “Errors that match lokf validate”Since lokf 0.8.0, lokf validate rejects values that break the schema’s patterns, and the engine reports each as an error:
- a
generatedorverifiedactor that is nothuman:<id>,process:<id>or<producer>/<version>; - a
sources[].authorthat is not an actor string; - a
Person’semailthat is not an address; - a
Service’shttp_methodoutsideGET,POST,PUT,PATCH,DELETE,HEADandOPTIONS.
A generated block with no by and a sources entry with no resource are errors too, because OKF marks both REQUIRED. stale_after may be an ISO 8601 datetime or a bare date.
Relation fields
Section titled “Relation fields”RELATION_FIELDS names fourteen fields: isPartOf, hasPart, references, dependsOn, derivedFrom, isReplacedBy, about, sameAs, relatedTo, definedBy, source, measures, memberOf and holder. They are every slot the LOKF schema ranges over Concept apart from concepts and target, and the smoke test holds this hand-kept list to the pinned manifest, src/lokf-vocab.json. The schema declares each of them multivalued, so a bare scalar in one of them fails lokf validate, and the engine warns with the list form rather than only resolving the target. The code notes that an audit recorded in this bundle’s log.md on 2026-09-09 found that mistake in roughly half its concepts.
Paths and bundle roots
Section titled “Paths and bundle roots”excludeFolders accepts the same spellings a bundle-root folder does (a leading or trailing slash, surrounding whitespace, a ./ prefix) through the same normalizer. The base_iri authority-denylist check compares the URL’s hostname, not host, so a denylisted domain on a non-default port cannot slip past it.
implicitBundleRoots(rootIndexHasHeader, visibleBundleIndexExists, treatVaultRootAsBundle) is the pure decision behind bundle-root detection. A header wins over a knowledge_bundle folder, and the folder wins over the break-glass setting. With all three false it returns an empty list, meaning a vault with no bundle, and resolveBundleRoot then resolves every path to null.
Relation to the LOKF toolkit
Section titled “Relation to the LOKF toolkit”The engine is an independent TypeScript implementation of the rules, not a wrapper around the LOKF toolkit, and has no run-time dependency on that Python package. It runs when Obsidian scans a vault, and the Python toolkit maintains this .lokf/ sidecar.