The scheduled librarian installs v0.21.0, up from v0.19.7, so it runs the current skill rather than two releases behind.
The publish job’s path check reads a concept named outside ASCII. It listed the patch’s paths with git’s default quoting, so such a path arrived C-quoted and was refused as outside the bundle. Synced from the skills repository’s template: it now lists with core.quotePath off.
An external source or definedBy is no longer flagged as dangling. Both slots are documented as taking an off-site URL, but the audit reported any untyped IRI target as missing. Nothing in this bundle tripped it - every target happens to point at a concept.
The predicate list cannot go stale again. It had drifted against the schema, missing holder, measures, memberOf and every reified relations entry; --check-refs reads the slots from the schema instead.
The scheduled librarian checks the relations it writes. Its validate step covered frontmatter shape only, leaving a fabricated target - an agent’s likeliest mistake - for the registrar gate to catch. It passes --check-refs now.
Changed
The registrar gate validates once.--check-refs rides on the existing validate step, replacing a second lokf validate run through uvx --from rust-just just.
The provenance gate reads a concept whatever its name. Synced from the skills repository’s v0.19.5 templates: both gates list paths with core.quotePath off and refuse a path git still has to quote, so a human: confirmation in a non-ASCII-named concept no longer passes unread.
The scheduled librarian installs v0.19.7, up from v0.19.2, so it runs the current skill rather than one five releases behind.
LOKF_SKILLS_REPO/LOKF_SKILLS_REF are now TRUST_LADDER_SKILLS_REPO/TRUST_LADDER_SKILLS_REF, following the skills repository’s own rename: the names said “LOKF” for a repository now called knowledge-trust-ladder. The skills keep their lokf-* names.
The family logo, .assets/knowledge-trust-ladder-logo.svg: a ladder rising out of an open book, its top rung the check mark, the rungs grey then amber then the curator’s blue. Shared byte-for-byte with the other two repositories; beside the README title, and the mark to use as the repository avatar.
Both diagrams carry the mark and the wordmark, from the same shared definition.
Changed
The diagrams no longer glare. A pure-white canvas was the brightest thing on the page, with the tinted cards sitting below it; it is now the warm #E4E1D7, so the cards read as raised.
Small grey labels are legible again: the faint ink moved from #888780 to #6E6D66, clearing 4.5:1 where it had been 3.6:1.
The skills repository is now knowledge-trust-ladder, formerly lokf-agent-skills: upstream LOKF ships its own bundled skills, and a third-party repository named after the format read as their official home.
Every link here follows it, and LOKF_SKILLS_REPO in the scheduled librarian names the new repository. The skill names, the pinned LOKF_SKILLS_REF and this plugin’s own name are unchanged; GitHub redirects the old paths either way.
A label hidden behind its own card. The curator card’s “a few at a time” was painted before the card that contains it; two labels in the plugins card came within 3px of their edges.
Both diagrams match the skills repository’s copies byte for byte.
The bundle’s log keeps the name the skills repository had on each day. The rename pass had rewritten entries written weeks before it; CHANGELOG.md was left alone, and the log is the bundle’s own record.
Retitling a pull request re-runs the release checks. The title check told the author to retitle, but the workflow listened only for the default pull-request types, so a title change fired nothing and the check stayed red whatever the author did. The trigger now names edited.
The sidecar’s scheduled-agent wrapper restores .git/config and .git/hooks/ on every exit. The copy here predated the EXIT trap, so an agent that poisoned core.hooksPath and then failed, or a cancelled job, left it for the workflow’s later steps to read.
The registrar gate reads a confirmation whole, not its by: line. Re-dating an existing human: event, moving its revision or writing it in flow style added no by: human: line and so passed the old gate unseen. The gate also refuses a human: id it cannot look up, resolves a commit-shaped revision against the tree, and now runs under a top-level permissions: {} with no checkout credential on disk.
Added
The sidecar gains the preflight, the forge-free provenance gate and the conventions parser - knowledge-preflight.sh, knowledge-provenance.sh and knowledge-conventions.py - plus .lokf/.gitattributes, keeping the bundle on LF so a Windows checkout gives CI’s verdict.
A pull request that would release is held to its release notes and its title. The plan job refuses an empty ## [Unreleased], which semantic-release itself skips on a pull-request event, and refuses a title with no releasing type, since a squash merge takes its commit subject from the title.
The pinned toolkit is lokf 0.8.0, and a malformed by, sources[].author, http_method or email is now an error, as lokf validate rejects each. stale_after accepts a datetime as well as a bare date, and the missing recommended fields setting no longer lists http_method.
npm run build-vocab reads the schema from the sidecar’s pinned toolkit, not a sibling ../lokf checkout; LOKF_SCHEMA still overrides it.
The settings merge rule moved into the pure vocab.ts (mergeSavedSettings, with vocabFromManifest for the malformed-manifest fallbacks), so the smoke test covers what sat untested in main.ts. No behaviour change.
The smoke test asserts more and characterises less. The two golden fixtures pin their warning counts, so a rule that starts or stops firing fails the build, and a drift guard catches a settings control naming a setting that does not exist.
The Known LOKF types setting is documented as the extension point for a bundle validated against a domain schema (lokf validate --schema <file>): list that schema’s classes there, since the plugin cannot read a schema outside the vault. Settings tab, README and docs/for-the-curious.md; no behaviour change.
README rewritten around how to use the plugin, as an extension of the lokf-agent-skills: the two-vault story, a four-step Quick start, Using it, the command table, Which folder is the bundle, Install and Settings. Shared material - the role table, the library metaphor, the trust ladder - now lives in the skills’ README and is linked once; no plugin change.
This repository’s own sidecar repaired by ktl-sidecar: the knowledge_bundle doorway link is now committed at the root, .lokf/justfile regains the template’s lokf-check-refs recipe, and markdownlint and lychee skip the link’s duplicate path. No plugin change.
CONTRIBUTING.md is a checklist again, with the release pipeline and the signing guide documented once in the skills repository’s docs/ and linked from here. npm run check runs build, lint and smoke test together, the settings-tab and createEl lint rules are errors rather than warnings, and CI fails an action not pinned to a commit; no plugin change.
The README says which line of defence this plugin’s work is, and points readers who work under that model at the skills’ page on the rest; no plugin change.
The registrar gate checks what lokf validate cannot: .lokf/scripts/knowledge-conventions.sh from the sidecar templates (one ISO-date log heading per day, quoted timestamps, verified as a list, open questions in the curator’s shape) and the justfile’s lokf-check-refs, on every .lokf/** pull request; no plugin change.
SECURITY.md is a policy, not a threat model: a surface table that links to the skills repository’s docs/threat-model.md instead of restating it, held to a word budget by npm run check. It now lists the plugin’s write paths as the README’s Privacy section does, where it had named only the header command; no plugin change.
“Insert the bundle’s semantic header” now asks in a vault with no bundle - make this vault the exhibition, or create a knowledge_bundle folder - instead of always nesting a folder. A two-choice modal (src/scaffold-modal.ts) suggests by what the vault holds: the root for a vault with nothing but an index.md, the folder otherwise. The palette name drops its parenthetical.
README restructured for the two-vault story. An early notice says the plugin works on the exhibition, never the workshop vault you already keep, and that it pairs with the lokf-agent-skills without needing them. Where it works replaces How this fits: three arrangements, the bundle as its own vault first, with the cost of a bundle folder inside your vault stated plainly. Host-by-host layouts moved to docs/for-the-curious.md.
This repository’s own sidecar follows the current ktl-sidecar templates: just lokf-link creates the knowledge_bundle doorway link, and the wrapper and both workflows describe the bundle’s second name as the templates do. No plugin change.
A vault with no bundle is left alone. With nothing configured, a root index.md carrying a LOKF header makes the whole vault the bundle and a top-level knowledge_bundle/ makes that the bundle, as before; a vault with neither now has no bundle - nothing scanned, no root-header warning, status bar LOKF: no bundle, commands explain instead of acting - rather than being read as one whole-vault bundle. The workshop is never mistaken for the exhibition.
Insert the bundle’s semantic header (was Insert semantic header template into root index.md): in a vault with no bundle it now creates knowledge_bundle/ and puts the header in its index.md instead of decorating the vault root.
README trimmed: the For the curious section is now docs/for-the-curious.md.
Added
Treat the vault root as the bundle (Scope, off by default): the break-glass switch that restores the old whole-vault reading for a vault whose root index.md carries no LOKF header.
Fixed
npm run lint and tsc failed on scripts/smoke-test.ts’s js-yaml import and on .github/scripts/changelog-release.mjs (outside ESLint’s project); both now pass.