KTL Curator plugin
services/ktl-curator-pluginChecked by automation only
still a draft
Written 2026-10-15 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
- Has part
- Derived from
- Pointed to by
- Curator side panel (is part of)
- Edits engine (is part of)
- In-editor aids (is part of)
- No network access, no telemetry (about)
- Settings tab (is part of)
- Trust engine (is part of)
- Why KTL Curator exists (about)
- Graph
- Open this concept in the knowledge graph
- IRI
https://w3id.org/ktl/curator/knowledge/services/ktl-curator-plugin- Licence
- CC BY 4.0
- Files
- MarkdownJSON-LDSource on GitHubHistory on GitHub
Overview
Section titled “Overview”KtlCuratorPlugin (src/main.ts) is the Obsidian-facing orchestrator. It holds no rule logic of its own: every trust label comes from trust-engine, and every write from edits-engine. It is responsible for:
-
Resolving configured bundle roots (
bundleRoots()), and re-scanning onmetadataCache“changed” andvault“delete”/“rename” events, debounced 300ms. With no roots configured, the privateimplicitRoots()reads the rootindex.md’s frontmatter and whetherknowledge_bundle/index.mdexists. It then defers the actual decision tobundle.ts’s pureimplicitBundleRoots(rootHasHeader, visibleIndexExists, treatVaultRootAsBundle). An absent root is explained only after checking Obsidian’s live index, so a dot-folder root another plugin exposes is read like any other. -
No bundle, by design.
implicitBundleRootsreturns an empty list, not the whole vault, when all three of these hold:- the root
index.mdhas no LOKF header; - there is no top-level
knowledge_bundle/index.md; - the break-glass
treatVaultRootAsBundlesetting is off.
So an ordinary notes vault is left alone rather than misread as one giant bundle.
hasNoBundle()reports that state.noBundleNotice()explains it wherever a command or the status bar would otherwise act on a bundle that isn’t there, and points at KTL Registrar’s header command, thektl-sidecarskill, or the break-glass setting. - the root
-
Reading each candidate concept’s frontmatter and headings through
metadataCache.getFileCache(a scan that reads no note content), building oneTrustRecordper concept, and computing the ranked queue and health counts per bundle root. -
Prompting once, through a modal, for the curator id (
ensureCuratorId): a slug validated against^[a-z0-9][a-z0-9-]*$, and refused if it contains@. -
The five verdict methods (
confirm,sendBack,corrected,retire,later), each writing throughapp.fileManager.processFrontMatterand the body andlog.mdthrough the atomicapp.vault.process, and upserting the day’s**Curation**line in the bundle’slog.md. -
The mtime guard on “Wrong - I corrected it”.
recordCardOpened(file)notes the file’smtimewhen its review card opens.hasReviewedCard(file)keeps the verb disabled until the card has been open at least once this session.hasChangedSinceCardOpened(file)is true when themtimehas changed since. When it has not, the card asks “The note hasn’t changed - did you mean Confirm?” before it records the correction. -
Six commands: Open curator panel, Create curation policy, Record something missing, Review the next concept in the queue, Review the active note, and Look up a LOKF field. A ribbon icon and a status-bar item also open the panel, and the ribbon carries the
ktl-trust-ladder-checkicon thatcurator-view.tsdraws. -
The type vocabulary (added 2026-09-14):
CuratorSettings.knownTypes, defaulting to the manifest’sKNOWN_LOKF_TYPES, is handed to everybuildTrustRecordcall and topolicyOverridesFor’sparseCurationPolicyTable. A vocabulary-fit entry’s message now reads “not one of the known vocabulary classes”. -
The settings themselves are not this module’s.
src/settings-model.ts(import-free, added 2026-09-14) holds theCuratorSettingsshape,DEFAULT_SETTINGSandmergeSavedSettings.mergeSavedSettingsputs saved values over the defaults. It refreshes aknownTypeslist still at the pre-schemaHARDCODED_LOKF_TYPESto the manifest’s, and preserves an edited one, the same rule asktl-registrar’s.loadSettingsis one call and an assignment.main.tsre-exports the type and the defaults. The rule moved so the smoke test could cover it. That is the boundary this plugin draws generally: logic worth testing leavesmain.tsrather than being tested through it.