Releases
0.19.4
Fixed
- An unauthenticated send-back is attributed to the session. The curator’s send-back note showed only the
human:<id>shape, so a session with noghlogin improvised a description of itself in the actor’s place, and conventions rule 4 rejected every such note at the gate. The skill now says to writeprocess:lokf-curatorthere. - The librarian template pins the current release.
LOKF_SKILLS_REFmoves fromv0.19.2tov0.19.4, the release this template ships in; check 15 failed onmainonce 0.19.4 was promoted.
Security
- The provenance gates read a concept whatever its name. Git’s default quoting C-quotes a path holding a byte above 0x7f, so the
.mdfilter in both gates dropped that concept and ahuman:confirmation inside it passed as “no new confirmations”.knowledge-registrar.yaml’sprovenancejob andknowledge-provenance.shnow list paths withcore.quotePathoff. - A path git still has to quote is refused, not skipped. A double quote, a backslash or a control character in a name is a finding with the path named; check 13 proves both outcomes.
- The registrar’s step summary strips backticks from an id that failed the login pattern, so it cannot close the code span and render as Markdown.
- The Snyk W011 finding on lokf-sidecar is answered in the
provenancejob’s comments and the threat model: the job reads pull-request metadata, and no agent runs in it.
0.19.3
Fixed
- Retitling a pull request re-runs the title check. The check that refuses a releasing pull request with a non-releasing title 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 librarian no longer points a
resourceat gitignored runtime state. A concept whoseresourcenamed an installed skill under.agents/resolved on a machine that had it and failed conventions rule 5 everywhere else, which is how it reached CI in the curator plugin. A localresourcemust be a path git tracks; the published copy, pinned to the version the host installs, is what to name instead. - The librarian template installs the current skill, not a ten-version-old one.
LOKF_SKILLS_REFpinnedv0.9.0while this repository releasedv0.19.2, so every host scaffolded from the template ran a librarian that far behind. Check 15 now holds the pin to the top released heading in the changelog, so it cannot fall behind in silence again. - The skills-pin check no longer fails every publish. Check 15 held
LOKF_SKILLS_REFto the newest released heading, but that heading is promoted on merge while its tag is created later bypublish.yml, so during the publish the only pin a host could clone is the one below it. The check now accepts either of the two newest releases.
Security
- The registrar gate opts into token scope instead of inheriting it.
knowledge-registrar.yamlhad no top-levelpermissions: {}, unlike the librarian workflow beside it, and both of its read-only jobs kept the checkout credential on disk although neither pushes. Both are now set in the template and this repository’s copy.
0.19.2
Security
- The librarian wrapper restores
.git/configand.git/hooks/on every exit. AnEXITtrap now restores them after a failing agent or a cancelled job too, so a poisonedcore.hooksPathcannot reach the workflow’s next steps. A Socket audit reported it, and the layout tests prove the fix.
0.19.1
Fixed
-
A pull request that would release must be titled to release. A squash merge takes its subject from the pull request title, and GitHub’s default title carries no type, so a typed
fix:reachedmainuntyped and released nothing. Theplanjob now refuses that combination and says how to retitle. -
The no-Python schema fallback is pinned to the toolkit’s version. It pointed at
lokf.yamlon upstreammain, which the 0.8.0 validator does not enforce. The URL now names thev0.8.0tag and moves with the floor, which also answers a skills.sh audit finding. -
A pull request that releases nothing is no longer failed for writing no release notes. The
planjob asks for notes only when one of the pull request’s own commits would release, so achore:ordocs:one, a Dependabot bump among them, passes. -
A Dependabot action bump no longer breaks the contract on its own. The bot edits
.github/workflows/and cannot see the copies underskills/lokf-sidecar/templates/github/, which check 11 holds byte-identical, so every bump failed until the template was synced by hand. The failure now names both directions instead of only “copy the template over it”, which is the wrong one in that case.
0.19.0
Added
- The registrar gate resolves a
revision. A sixth rule: a commit-shapedrevisionon an event must name a commit that holds the concept’s localresource, so the skills pin with the full hash; the validate job checks out the full history, and a shallow clone is reported rather than passed. Check 11 proves both outcomes in a throwaway repository. - Portability pages for the curator and the librarian, and the sidecar’s rewritten as a host matrix. What works, what is lost and the substitute on GitHub, GitLab, Forgejo, no forge, no git, Windows and PowerShell, macOS, synced folders and an Obsidian vault.
- Every skill declares what it needs in the Agent Skills
compatibilityfield; check 3b holds it to the spec’s 500 characters. - A forge-free provenance gate.
knowledge-provenance.shverifies each confirmation’s commit signature against the curator’s public key on file under.lokf/curators/, GPG with its subkeys or SSH, with plain git and gpg or ssh-keygen; check 13 proves each outcome with throwaway keys. - A prerequisites page gives each preflight line its plain meaning, who fixes it and what to send them, for a person who cannot act on it themselves; check 12 holds it to every line the preflight can print.
- A preflight every skill runs first.
knowledge-preflight.shprints what this machine can do, from shell and git to identity, signing, keys on file and toolkit, and ends by naming what is missing and which steps that disables; check 12 exercises it. - The sidecar lays down
.lokf/.gitattributes, keeping the bundle on LF so a Windows checkout gives CI’s verdict. - Three more conventions the gate checks: one file per
id, lowercase paths, and a closed frontmatter block with no byte order mark; check 11 proves each.
Changed
- The skills use lokf 0.9.0+’s
revision. The curator writes it on a confirmation, the librarian ongenerated, and the docent quotes it beside the date. An older toolkit leaves it out. The librarian’s tables also name a source’sexcerpt. - The sidecar’s toolkit floor is lokf 0.8.0, here and in the
lokf-sidecartemplate. The librarian’s field tables now state its constraints:sources[].authoris an actor string,http_methodis one of seven uppercase verbs, and every timestamp includingstale_afteris a datetime, a bare date meaning midnight UTC. - The curator says what it can record before offering a session, from a Ready to record line with three identity routes -
gh,glab, the signing key the forge lists - and a rule for a host with no forge. The librarian names files in lowercase and hands off on a host without git; the docent’s feedback attribution names the same routes. - Six of the conventions script’s ten checks now parse YAML for real.
knowledge-conventions.py, run throughuv run, replaces grep and awk where they missed flow-style events. The other four stay shell, and withoutuvthe script says which rules it skipped. The preflight reports a host holding one half without the other, and check 11 proves each rule.
Fixed
- The librarian’s version check names a command that exists:
uvx --from pip pip index versions lokf, sinceuv pip indexis not a subcommand. - A Windows checkout no longer blinds the conventions script. It reads files with CRLF and a byte order mark stripped, and check 11 holds a CRLF bundle to the same verdict as LF.
- A bundle reached through a link is read, not passed unread.
findnever entered a linked.lokf/knowledge, so the conventions script and the preflight saw zero files; checks 11 and 12 plant one. - The preflight reads
commit.gpgsignas git does, takingyesand1as on and nouser.signingkeyas git’s default key; all three scripts stop on one line undersh. - The gate refuses a
human:id it cannot look up. The schema acceptshuman:-x, and both the GitHub job and the forge-free script skipped such ids as unparsable, so an unsigned confirmation under one passed unseen. - The gate reads a confirmation whole, not its
by:line. Re-dating an existing event, moving itsrevision, or writing it in flow style left no addedby: human:line and passed both gates; events are now compared whole between base and head, keyed by the concept’sid, so a renamed concept keeps its confirmations and a copied one does not. Check 13 proves each. - The conventions script no longer aborts on a runner that ignores SIGPIPE. GitHub Actions starts every step that way, so an awk that closed the frontmatter pipe early turned into a
tr: write errorthatpipefailmade fatal on the first long concept; the script now reads each file whole, and the contract’s own job installsuvso the parser’s half runs there too. - A confirmation spelt with a YAML tag, anchor, alias or quoted key was invisible to both gates while
lokf validateaccepted it. Conventions rule 10 now holdsid,by,atandrevisionto spellings a line reader and a parser agree on, so thevalidatecheck fails such a concept before theprovenancecheck could miss it; check 11 proves it. - Both gates read merges,
generated, and only the frontmatter. Events are now read against every parent of a commit, fromverifiedandgeneratedand nowhere else, so a merge can no longer slip one in and an example in a body code fence no longer counts. Check 13 proves each. - A push to
mainbetween releases no longer promotes## [Unreleased]a second time. When the top released version has no tag yet,changelog-release.mjs promotefolds new entries into it by subsection instead of writing a second heading. Theplanjob also runscheckdirectly, because semantic-release skips its plugin hooks on a pull request. Check 14 proves it. publish.ymlinstallsuv, so a release can pass the contract it runs. Six conventions rules run throughuv run, and without it no release could reach the tag. The contract now names that cause in one line up front.
0.18.0
Added
- The registrar gate fails on a vanished source.
knowledge-conventions.shgains a fifth rule: aresource:that is not a URL must name a file or directory that still exists under the repository root. Check 11 proves it on a bundle that breaks it; URLs are never fetched. - Two switches in the curation policy, both off by default.
Independent re-check: <n>lists n confirmed concepts, picked by a rule the curator cannot steer, for a second person to re-check.Evidence first: yesmakes the docent quote the source before an answer resting on an unconfirmed concept.
Changed
docs/three-lines.mdis written for a governance reader. It names the IIA in full, cites its 2026 Statement of Position, places each role in a diagram, and ends with what remains open and whose it is. The model’s critics have a page of their own,docs/three-lines-critics.md.- Adopter-facing text no longer addresses “solo maintainers”. The sidecar’s automation reference and the registrar workflow’s comments describe the case - the confirming person also opens the pull request, so the gate’s evidence is their signature - and the attestation environment’s reviewers are “the people allowed to attest”.
EXAMPLES.mdis nowdocs/examples/docent.md, one page per skill’s captured sessions;docs/examples/curator.mdis a placeholder that lists what is still to capture, including a docent answer under each value ofEvidence first:.
0.17.1
Changed
SECURITY.mdis a policy, not a threat model: what executes here and what holds it, in a surface table that check 10 holds to a word budget. The shared design - hardening, thehuman:attribution gate, the prompt-injection guards - moves todocs/threat-model.md, which the sibling repositories link instead of restating; check 9 records the path.- The README is shorter, and its repository tree is now
docs/repository-layout.md. The README,docs/and the skills’ prose no longer quote how many classes and relations LOKF has; the two enumerations check 7 compares stay the only places it is counted. - Three LOKF repositories, not four. The shared pages and this bundle count
lokf-agent-skills, LOKF Registrar and LOKF Curator; a host that installs the skills is not one of them.
0.17.0
Added
validate-repository.shcheck 9: the paths sibling repositories link into. LOKF Curator and LOKF Registrar deep-link files here and their link checks follow those URLs for real, so moving one passed every check here and broke their builds; the check now fails instead, and confirms its list is complete when the siblings are cloned alongside.docs/releasing.mdanddocs/signing-commits.mdcarry the release pipeline, the repository settings it depends on, and the signing walkthrough once for all four repositories; everyCONTRIBUTING.mdlinks there instead of repeating them. Check 10 holds this repository’sCONTRIBUTING.mdto a word budget, and CI fails an action not pinned to a commit.docs/three-lines.mdmaps the cast onto the three lines of defence for readers who work under that model, and says what an auditor can check and what the evidence does not show; the README and both plugins link to it.templates/scripts/knowledge-conventions.sh, and the registrar gate runs it. It checks whatlokf validatecannot: one ISO-date log heading per day, quoted timestamps,verifiedas a list, and open questions in the curator’s shape.knowledge-registrar.yamlruns it on every.lokf/**pull request, and check 11 proves it fails on each broken rule.
Fixed
- The librarian now lints the Markdown it writes. Its rule against letting a wrapped punctuation dash start a line was advice only, and a pass tripped
MD032in a host’s lint gate anyway; the audit step now runs the host’s markdownlint config over the bundle, sincelokf validatereads a concept body as an opaque string and cannot see this class of fault at all. - One
log.mdheading per day, the bare date. A suffixed heading such as## 2026-09-14 (2)is not the ISO-date heading OKF §9 requires, and the curator plugin cannot find the day through it. The librarian and the curator now reuse the day’s heading. - The librarian’s open questions take the curator’s shape,
- YYYY-MM-DD, process:lokf-librarian: ..., so the date and actor lead and the first bullet the curator reads is the question. - The docent no longer takes a reader’s identity from
git config user.namefor a feedback entry -gh api useror nothing, the same rule the curator holds to.
0.16.1
Added
lokf-librarian/references/domain-schema.md: how to extend the vocabulary into a domain - a LinkML schema importing a pinnedlokf.yaml,--schemawired into the justfile and both workflows, both plugins’ Known LOKF types settings told, and what it leaves undone for the graph. The curator’sdomain-schemas.mdsays when; this says how. Rule 3 now reads the host’s justfile for a--schemaand counts that schema’sConceptdescendants as vocabulary.
Fixed
- Rule 3 in
lokf-librarian/SKILL.mdlisted fourteen classes, omittingRole, whileREADME.mdanddocs/for-the-curious.mdsaid fifteen. Confirmed against the raw schema and corrected; the skills now teach one number.
Changed
- The curator’s vocabulary-fit line respects a host’s domain schema. Where
.lokf/justfilevalidates with--schema <slug>.yaml,trust-fields.mdnow has the skill read that file and count itsConceptdescendants as known - the same widening as Rule 3, so the line goes quiet once a team adopts a schema instead of naming every domain class a misfit. The label reads “doesn’t fit the known vocabulary”, matching the LOKF Curator plugin. lokf-curator/references/review-session.mdstates how the curation-policy table is read: class names match ignoring spaces and plural form (“Glossary terms” isGlossaryTerm), and an unknown class binds nothing. Written down because the LOKF Curator plugin matched literally and so ignored four rows of this file’s own template.README.mdpolished, not restructured. Each role and label is said once, the plugin table maps onto the four levels of checking, and the Obsidian section moves todocs/obsidian.md.
0.16.0
Changed
- One layout on every host.
.lokf/knowledge/is always the real folder, and theknowledge_bundledoorway link beside it is created by default again (Step 2). Step 0 no longer asks what kind of host it is in; Step 6 reports whether the doorway was made and the one command if not. just lokf-linkcreates or recreates that doorway, idempotently, refusing a name already taken. Itsvisiblevariable is gone.lokf-docentgainsreferences/obsidian.md: the two-vault answer, pluslokf-sidecarnamed as the way to make a missing link. A missing link is never a feedback entry.- Shared-folder guidance consolidated into
lokf-sidecar/references/portability.md, Obsidian included: sync services carry.lokf/but drop links, so the doorway is per machine. README.mdrestructured. “Where the bundle lives” (host-agnostic) and “…and where it meets an Obsidian vault” (optional, two vaults) replace the combined section; “For the curious” moves todocs/for-the-curious.md.
Removed
- The visible layout (0.15.0) - a real
knowledge_bundle/folder inside a vault. Obsidian indexes it like any other folder, so the exhibition leaked into the workshop’s link suggestions, graph and search. Step 0’s host decision, thevisiblevariable and two layout-test cases go with it. - References to the maintainer’s private vault: the family this repository describes is the four skills and the two plugins.