Google Cloud announced the Open Knowledge Format in June, and I read the spec the same week I was
mid-project on exactly the problem it solves. OKF names something I’ve been doing without a name
for a while: a knowledge base as a directory of markdown files with YAML frontmatter, readable by
any agent that can cat a file, shippable by anyone who can git clone a repo. Section 10 of the
spec as it stood at this article’s date, v0.1, says this almost word for word: it calls out “LLM wiki” repositories
as one of the patterns it formalizes. Section numbers here are v0.1’s; a spec this young will
renumber, so check the version before quoting a section back at anyone. That’s what my own personal knowledge base already was, built up over months across
close to twenty repositories. Reading a spec that names your own working pattern back to you,
precisely, is a different feeling than reading a spec you have to translate into what you’re
already doing.
So I converted my repos. And in doing that, I ran into the same gap you hit converting anything to
any spec: the reference implementation shows you what conformant looks like, but it doesn’t tell
you whether what you actually wrote conforms. Google’s own knowledge-catalog repo ships an
enrichment agent and an HTML visualizer. It doesn’t ship a validator. What validation logic exists
there lives inside the enrichment agent and the tests, which is a different thing from a checker
you can point at a bundle. I am not the only one who noticed: an independent implementer opened an
issue in June making the same observation and offering to contribute a portable checker upstream.
Tools have started appearing around the format rather than in it. Kiso, an open-source publishing
engine for OKF bundles, added a check command in early July that validates markdown files before
publication. That is real, and if all you need is a pre-publish gate you should use it rather than
write anything. What I wanted was narrower and reusable inside my own pipeline: the three hard
rules, checked, with nothing else in the way.
What conformance actually requires, once you read it closely
The spec is short on hard requirements, which is part of what makes it good. Three rules, total:
every non-reserved markdown file needs a parseable YAML frontmatter block, every frontmatter block
needs a non-empty type field, and the two reserved filenames (index.md and log.md) follow
their own defined structure when they’re present. Everything else is soft guidance. Missing an
optional field, using a type value nobody’s registered, a broken cross-link: none of that fails
conformance. A consumer that rejects a bundle for any of it is the one violating the spec, not the
bundle.
That permissiveness is deliberate, and it’s the right call for a format meant to formalize something people were already doing informally. But it also means “is my bundle conformant” isn’t a question you can answer by eye past a few dozen files. I wrote a validator that checks exactly those three rules, nothing more, and a converter that backfills the frontmatter a corpus is missing without ever touching what’s already there.
What building the converter actually taught me
The interesting part wasn’t the validator. It was what “idempotent, never overwrite existing metadata” turns out to require once real files stop cooperating with your assumptions.
Some of my runbooks are thin pointers to an installed skill: a title and an npx command, nothing
else to extract a description from. Auto-generating a summary from that body text produces a
summary of a shell command, which is worse than no summary. I ended up curating descriptions by
hand for anything the extractor couldn’t confidently summarize, rather than shipping a plausible-
sounding wrong one.
The real bug showed up later, converting a bigger repository with genuine internal structure. One
directory held nothing but subdirectories, no markdown file of its own, just a container. My
converter decided which folders needed a navigation index.md by checking each concept file’s
direct parent, and a folder with no concept file directly inside it never triggered that check. Its
parent’s generated index linked to it anyway, and the link went nowhere. The fix is one clause:
walk every ancestor up to the bundle root, not just the immediate parent. Finding it meant
actually converting something structurally different from my first few test repos, not just
running the same conversion again and calling it proven.
Where it landed
The validator and converter, plus the conversion procedure and everything above, are a skill now:
synthesis-okf, free and open, built on the Agent Skills standard so it installs the same way into
Claude Code, Codex, Cursor, or anything else that reads a SKILL.md. It’s part of Synthesis Skills,
the practice I’ve been building around treating AI coding agents the way you’d treat any other
engineering discipline: conventions, verification, and tooling that outlives any one session.
If you’re the one who wrote the spec (Sam, Amir), I’d genuinely like to know if the ancestor- directory case is one you’d already thought about, or if it’s new. And if anyone else is sitting on a markdown corpus wondering whether OKF is worth adopting: the answer is that the gap between “informal LLM wiki” and “conformant OKF bundle” is smaller than it looks, and now there’s a tool that tells you exactly how far you have left.
GitHub: GoogleCloudPlatform/knowledge-catalog · synthesis-okf, in the Synthesis Skills catalog