KNOWLEDGE GRAPHS FOR AI AGENTS
Track 3 Β· Narrative Knowledge

M06 β€” The Open Knowledge Format Specification

⏱ ~60 min πŸ“‹ Prerequisites: M00–M05 Intermediate
Module 7 of 14

Learning Objectives

  • Explain what the Open Knowledge Format (OKF) standardizes β€” and, just as importantly, everything it deliberately does not include.
  • Author a valid OKF concept file from scratch: YAML frontmatter with the one required field, a Markdown body, and cross-links.
  • Describe the role of the two reserved filenames, index.md and log.md, and how progressive disclosure works as a token-budget control.
  • State the conformance leniency rules and argue both sides of the trade-off they create.
  • Read a bundle programmatically in about three lines of Python or Node.js.

Bridge: From Structure to Narrative

In Track 2 you built and queried structural graphs: tree-sitter parsed the orderflow code, Graphify clustered it into communities, and you could answer "who calls decode_jwt?" deterministically. That graph knows everything about what the code is. It knows nothing about what your team knows.

Consider a question the structural graph cannot answer: "What is the canonical definition of Weekly Active Users?" The AST can find the function weekly_active_users(), but it cannot tell you that this function is the attested source of truth, that the exclusion of internal testers was a deliberate policy decision from a 2026 data-governance review, or that the old definition in a stale doc is wrong. That knowledge lives in people's heads, in wikis, in Slack threads β€” scattered, unversioned, and invisible to agents.

This module introduces the format designed to fix exactly that: a way to write down curated, canonical knowledge so that both humans and agents can read it deterministically. Track 3 is about the narrative layer.

What OKF Is (and Isn't)

BEFORE: Before USB-C, every device had its own connector. Your iPhone needed Lightning, your Android needed Micro-USB, your laptop needed a barrel jack, your camera needed Mini-USB. Every vendor invented a plug, and every plug needed its own cable, charger, and adapter.

PAIN: The pain wasn't any single cable β€” it was the multiplication. Every new device meant another cable to buy, carry, and lose. Knowledge inside companies works the same way today: one team keeps definitions in Confluence, another in a metadata catalog, another in code comments, another in a senior engineer's memory. Every new AI agent needs a custom adapter for each source, rebuilt from scratch, every time.

MAPPING: OKF is the USB-C of organizational knowledge β€” one analyst called it exactly that: "the USB-C cable of AI knowledge β€” a universal connector that anyone can produce and anyone can consume, without proprietary SDKs, APIs, or lock-in." It doesn't replace what's in the sources; it standardizes the shape knowledge takes so any agent can plug in and read it, natively, with no translation layer.

The Open Knowledge Format (OKF) is a vendor-neutral specificationA written standard describing exactly what a valid artifact looks like, so independent tools can produce and consume it interchangeably. A spec is a contract, not software. for representing curated knowledge as a directory of plain MarkdownThe lightweight plain-text formatting language used in READMEs everywhere: # for headings, [text](url) for links, | pipes | for tables. Renders natively on GitHub. files, each carrying a small YAML frontmatterA block of key: value metadata at the very top of a Markdown file, fenced by two lines containing only ---. YAML is the human-friendly config syntax used by tools like GitHub Actions. block. It is not a database, not a model, not a cloud service, and not an SDK. It is a wire format: rules about file shape, nothing more.

Three consequences follow from "format, not platform," and each one matters in practice. First, there is nothing to install. The spec's own FAQ puts it memorably: "If you can cat a file, you can read OKF; if you can git clone a repo, you can ship it." Second, the knowledge is Git-native: version-controlled, auditable through pull requests, diffable line by line. When your company's definition of "Revenue" changes, the change has an author, a timestamp, a review trail. Third, it is human-and-agent readableat the same time: the same file renders beautifully on GitHub for a person and parses in three lines for an agent. Compare that to a vector index, which is meaningful to exactly one embedding model and opaque to everyone else.

It's worth pausing on what OKF deliberately leaves out, because the omissions are the design. There is no built-in search engine β€” no indexing, no ranking, no query language. There is no schema registry β€” nobody validates that your type values are drawn from an approved list. There is no sync mechanism β€” the spec has no opinion on how bundles get created or stay current (that's Module 8's entire subject). Prior enterprise metadata standards demanded schema registries, validation servers, and vendor SDKs before you could write a single entry; OKF's bet is that minimalism is what makes a standard adoptable at all.

βœ… Why It Matters

Recall M02's churn-rate disaster: a RAG pipeline blended a 2023 slide deck, an outdated wiki, and a Slack argument into a confidently wrong SQL query that shipped for three weeks. The root cause wasn't retrieval quality β€” it was that the truth was never written down in one canonical, versioned place. A folder of well-formed Markdown fixes that in a way no similarity search ever can: for canonical facts, 90% semantic similarity is a failure; 100% exactness is non-negotiable.

⚠️ Common Misconceptions

"OKF is Google's new database product." β€” No. It's an open specification published on GitHub. There is no service to sign up for, no billing account, no runtime. Google's own Knowledge Catalog can serve OKF bundles, but the format works identically in a bare Git repo.

"OKF replaces RAG." β€” No. OKF has no search of its own; past the size a person or agent can browse by following index files, something still has to index it β€” often the same retrieval machinery RAG already provides. The honest framing: "RAG, pointed at something worth retrieving from." Curated Markdown with explicit links is far better material to index than a PDF chopped into arbitrary chunks. Module 10 builds the full hybrid picture.

"It's just documentation β€” we already have a wiki." β€” The difference is contract and consumer. A wiki has no format guarantees, so agents can't parse it reliably; and human wikis rot because upkeep is boring. OKF gives agents a guaranteed shape AND assumes agents do the boring upkeep (M08).

Lineage & Release: How a One-Page Spec Happened

On June 12–13, 2026, Google Cloud's Sam McVeety and Amir Hormati published OKF v0.1 through the GoogleCloudPlatform/knowledge-catalog repository. Their announcement framed it plainly: "a vendor-neutral, agent- and human-friendly standard for representing the metadata, context, and curated knowledge that modern AI systems need." The problem it targets is what the Google Cloud blog calls the context-assembly problem: table schemas, metric definitions, JOIN paths, and incident guides live scattered across catalogs, wikis, code comments, and experienced employees' memories β€” so every new agent rebuilds the same context from scratch.

Google is explicit about the intellectual lineage. In April 2026, Andrej Karpathy published the LLM WikiKarpathy's April 2026 thought experiment: instead of a model re-searching raw documents on every query, let it build and maintain a living, cross-linked Markdown wiki as durable external memory. idea: an LLM should maintain a compiled, cross-linked Markdown wiki as durable external memory β€” the way source code is compiled once and reused rather than re-parsed on every read. His framing for why this works stuck with a lot of engineers, and Google's materials quote the spirit of it directly: "LLMs don't get bored, don't forget to update a cross-reference, and can touch 15 files in one pass. The bookkeeping that causes humans to abandon personal wikis is exactly what LLMs are good at."

OKF didn't invent a substrate, either. The AGENTS.md convention had already spread across tens of thousands of open-source projects; developers were already wiring Obsidian-style vaults straight into coding agents. As one analysis put it: OKF standardizes the substrate that already won β€” Markdown, frontmatter, and Git. The full v0.1 conformance spec fits on a single page: three conformance rules, total. That minimalism is not a gap to be filled later. It is the entire design philosophy β€” "the spec defines the interoperability surface, not the content model."

And it shipped with proof it scales past a toy: Google published reference sample bundles (a GA4 e-commerce bundle, Stack Overflow, Bitcoin) plus a BigQuery metadata-extraction agent. The GA4 demo bundle is 17 Markdown files β€” indexes, references, datasets, tables β€” demonstrating that this restraint holds up on something real.

Bundle Anatomy: Directories, Concepts, and Paths as Identity

A bundle is a directory of Markdown files. A concept is one file representing exactly one unit of knowledge β€” a table, a metric, a service, a runbook, an API endpoint. The file's path is its identity: analytics/metrics/weekly_active_users.md is the concept's ID. There is no separate ID system to keep in sync with file locations β€” the filesystem itself is the index.

Path-as-identity sounds like a small decision, but it kills an entire class of maintenance bugs. Every system that assigns synthetic IDs (UUIDs in a catalog, page IDs in a wiki) eventually faces drift between the ID registry and reality: the page moved, the record was cloned, the pointer dangles. When the path is the ID, moving a file is renaming a concept β€” visible in Git, reviewable in a PR, greppable everywhere it's referenced. One thing to update, one place to see it.

Here is what a real bundle looks like β€” an internal "company brain" with knowledge compiled into hyper-focused, singular concepts:

BUNDLE_TREE β€” a knowledge bundle assembles
Static view: a bundle directory tree. The root index.md is the entry point; each subdirectory holds one index.md plus singular concept files (service_mesh.md, customers.md, active_users.md). Directory paths define each concept's identity.

Notice the granularity. There is no misc_notes.md dumping ground. Information is compiled into hyper-focused, singular concepts: one file per API contract, one per financial metric, one per database table. That granularity is what makes progressive disclosure (next section) work β€” an agent can load exactly the concept a task needs, and nothing else.

Frontmatter: One Required Field

Every concept file follows a strict but minimal design: a YAML frontmatter block on top, a free-form Markdown body underneath. Of the recommended frontmatter fields, exactly one is required: type. Everything else β€” title, description, resource, tags, timestamp β€” is optional. As the spec's authors put it: "OKF requires exactly one thing of every concept: a type field."

Watch a canonical concept file come apart into its pieces:

FRONTMATTER_ANATOMY β€” dissecting a concept file
Static view: a concept file has two parts. Top: YAML frontmatter between --- fences (type β€” the only required field β€” plus optional title, description, resource, tags, timestamp). Bottom: a free-form Markdown body (here: a schema table and a Joins section) whose relative links to other concept files act as graph edges.

Why does the frontmatter matter operationally? Because it gives the LLM structured, high-level context before it reads the body. An agent scanning a directory can filter on type: metric or tags: [billing] using explicit metadata rather than fuzzy semantics β€” a cheap, deterministic pre-filter that costs a few dozen tokens per file instead of the whole file.

Here's a second canonical example β€” the one this course keeps returning to. This is a real business-metric concept, the kind whose absence caused M02's churn disaster:

analytics/metrics/weekly_active_users.md
---
type: metric
id: analytics/metrics/active_users
title: Weekly Active Users (WAU)
owner: data-eng@company.com
updated_at: 2026-06-15
citations:
  - source: "https://github.com/internal-org/dbt/models/wau.sql"
---

# Weekly Active Users (WAU)

The total unique count of user IDs who have triggered at least one core
backend API transaction within a rolling 7-day window.

## Computation Rules
We explicitly exclude internal QA and test accounts:
`WHERE user_id NOT IN (SELECT user_id FROM staging.internal_testers)`

## Related Components
- See [[analytics/tables/customers]] for primary user dimension mappings.
- See [[analytics/tables/billing]] to correlate usage with subscription cycles.

Three details deserve attention. First, the frontmatter includes fields beyond the recommended set (owner, citations) β€” perfectly legal, because consumers must tolerate unknown keys (next section). Second, the body carries the actual, audited SQL exclusion rule β€” not a description of where to find it. When an agent needs to compute WAU, it extracts the absolute logic and follows the explicit link to the customers table concept for current join keys. It generates a correct query on the first attempt, citing the exact file, its update time, and its owner. Third β€” and this is a spec subtlety worth teaching precisely β€” the id field here is redundant with the path by design: the path is the identity; the field is a convenience mirror some producers include.

πŸ”Ž What Just Happened?

You've now seen both canonical concept shapes: a data asset (the Orders table: schema + joins) and a business definition (WAU: rules + exclusions + links). Same skeleton β€” type plus optional metadata, then a structured body with relative links. In M07 you'll see the third shape: a service concept describing code, which is where this course lives.

The Reserved Filenames: index.md and log.md

Two filenames have reserved meanings in every bundle, and they give the format its structure without adding a single required field.

index.md β€” the progressive disclosure lever

index.md is a directory listing at any level of the bundle β€” the entry point an agent reads before touching anything else. Progressive disclosureA consumption pattern: start at the root index, follow links only as deep as the task requires, and load only the concept files actually needed β€” instead of loading the entire bundle into context. means the agent walks the hierarchy one level at a time, loading only what the task needs.

This is a genuine token-budget control, not a convenience file. An orchestrating agent reads index.md, decides which concept files a given subtask actually needs, and loads those β€” nobody pulls a thousand-file bundle into context for a change that touches one service. Watch the difference:

PROGRESSIVE_DISCLOSURE β€” index-first vs bundle-dump
Static comparison: an index-first agent reads the root index (~200 tokens), one branch index (~250), then exactly one concept (~850) β€” about 1,300 tokens total. A bundle-dump agent loads every concept file and fills its entire context budget before reasoning starts. Progressive disclosure only pays off if the orchestrator is actually built to read the index first.

One production tip carries more weight than any other here: keep index entries to a title and a one-line description pulled straight from each concept's frontmatter. An index bloated with detail defeats the point of having one β€” it becomes just another big file the agent must wade through.

log.md β€” what the bundle knows, over time

log.md is a chronological, date-grouped record of changes to what the bundle knows β€” deliberately distinct from git log, which records what changed in the files. These are different questions. A service's code can change without its documented responsibilities changing (a refactor), and its documented responsibilities can change without a single code line moving (a policy decision). "What changed in this file" and "what changed in our understanding of this system" need separate answers, and log.md lets an agent β€” or a person β€” answer the second one directly instead of inferring it from commit archaeology.

Conformance Leniency: The Trade-Off at the Heart of the Spec

The v0.1 conformance rules are deliberately, radically lenient. A conformant consumer must not reject a bundle for:

  • missing optional fields,
  • unrecognized type values (there is no type registry β€” type is producer-defined),
  • unknown frontmatter keys,
  • or even broken links.

Why design it this way? Because strictness kills adoption. Every failed validation is a reason for a team to give up on the format; every required registry is infrastructure someone must stand up before writing entry one. Leniency means a team can start with a single file, today, and be conformant. That is why OKF spread in weeks while stricter predecessors β€” the schema-registry, validation-server kind β€” spent years stalled.

But the same leniency creates the risk this course spends Module 11 on: silent degradation. A bundle full of dangling links, drifted type names ("API Endpoint" here, "Endpoint" there, "Route" somewhere else), and stale timestamps is still technically conformant. Nothing errors. Nothing warns. The spec will never save you from a rotting bundle β€” only your own lintAn automated checker that enforces rules stricter than the format requires β€” e.g., "every concept must have a description" or "no dangling links." The okf CLI ships 13 built-in lint rules (M07). rules and review discipline can. Remember the asymmetry: the spec is lenient so that adoption is easy; your pipeline must be strict so that trust is possible.

⚠️ Common Misconceptions

"If it passes the spec, it's a good bundle." β€” Spec-conformant and trustworthy are different properties. A bundle can pass conformance and still be an unlinked, out-of-date mess. Lint is "the only thing standing between technically conformant and actually useful."

"Broken links will show up as errors somewhere." β€” By spec, consumers must tolerate broken links. No error will ever fire unless you write the check yourself.

Code Walkthrough: Reading a Bundle Programmatically

The entire consumption story fits in a few lines β€” that's the point of standardizing on boring substrates. Let's read the WAU concept, then write the validation check every pipeline needs. Chunk 1 β€” load and inspect. WHAT: parse one concept into metadata + body. WHY: this is the exact operation an agent's tool layer performs before deciding whether the concept is relevant. GOTCHA: a file with no frontmatter loads fine with empty metadata β€” reading never throws just because metadata is missing, which is why validation must be explicit.

read_concept.py Β· pip install python-frontmatter
import frontmatter  # pip install python-frontmatter

concept = frontmatter.load("analytics/metrics/weekly_active_users.md")
print(concept["type"])        # "metric"
print(concept["title"])       # "Weekly Active Users (WAU)"
print(concept.content[:200])  # the markdown body: rules, links, everything
read_concept.mjs Β· npm install gray-matter
import fs from "node:fs";
import matter from "gray-matter";  // npm install gray-matter

const raw = fs.readFileSync("analytics/metrics/weekly_active_users.md", "utf8");
const concept = matter(raw);
console.log(concept.data.type);        // "metric"
console.log(concept.data.title);       // "Weekly Active Users (WAU)"
console.log(concept.content.slice(0, 200)); // the markdown body

Chunk 2 β€” validate. WHAT: enforce the one hard rule (type present) across a bundle, in CI. WHY: leniency means nothing else will ever catch a malformed concept; this tiny gate is the seed of the lint discipline M07 and M11 grow into. GOTCHA: catch parse errors too β€” a mangled YAML fence is worse than a missing field, because it can silently swallow the whole header.

validate_bundle.py
import sys
from pathlib import Path
import frontmatter

def validate_bundle(root: Path) -> int:
    errors = 0
    for path in sorted(root.rglob("*.md")):
        if path.name in {"index.md", "log.md"}:   # reserved files: no type needed
            continue
        try:
            post = frontmatter.load(path)
        except Exception as exc:       # mangled YAML is an error, not a shrug
            print(f"ERROR {path}: unparseable frontmatter ({exc})")
            errors += 1
            continue
        if not post.metadata.get("type"):
            print(f"ERROR {path}: missing required field 'type'")
            errors += 1
    print(f"{errors} error(s)")
    return 1 if errors else 0

if __name__ == "__main__":
    raise SystemExit(validate_bundle(Path(sys.argv[1])))
validate_bundle.mjs
import fs from "node:fs";
import path from "node:path";
import matter from "gray-matter";

function walk(dir) {
  return fs.readdirSync(dir, { withFileTypes: true }).flatMap((e) =>
    e.isDirectory() ? walk(path.join(dir, e.name))
      : e.name.endsWith(".md") ? [path.join(dir, e.name)] : []);
}

let errors = 0;
for (const file of walk(process.argv[2])) {
  const base = path.basename(file);
  if (base === "index.md" || base === "log.md") continue;
  try {
    const { data } = matter(fs.readFileSync(file, "utf8"));
    if (!data.type) { console.error(`ERROR ${file}: missing required field 'type'`); errors++; }
  } catch (exc) {
    console.error(`ERROR ${file}: unparseable frontmatter (${exc.message})`); errors++;
  }
}
console.log(`${errors} error(s)`);
process.exit(errors ? 1 : 0);
βœ… What Just Happened?

You read a concept in three effective lines and wrote the seed of a lint gate in thirty. No SDK, no schema registry, no service. That's the whole consumption stack β€” and it's also why "format, not platform" is a feature: your validation code will still run unchanged if you switch clouds, agents, or LLM vendors tomorrow.

Hands-On Exercise: Author Your First Concepts

πŸ“‚ Get the files: labs/M06-okf-authoring on GitHub β€” or clone the whole course once: git clone https://github.com/varasrinivas/knowledge-graph-course.git

What you'll build: two valid OKF concepts for orderflow β€” the WAU metric and the orders_fact table β€” plus the frontmatter validator, in labs/M06-okf-authoring/. Time: 25–35 min. Files: two .md concepts and validate.py.

  1. Step 1 β€” Study the shape. Open starter/knowledge/analytics/metrics/weekly_active_users.md. The frontmatter is stubbed; only type is required, but your lint will warn on missing recommended fields.
    βœ… Checkpoint

    You can name all five recommended optional fields without looking. (title, description, resource, tags, timestamp.)

  2. Step 2 β€” Complete the two concepts. WAU: 7-day rolling window over completed orders, explicit tester exclusions, resource: pointing at services/orders/metrics.py, cross-link to [orders_fact](../tables/orders_fact.md). orders_fact: schema table, Joins section, link back to the metric.
  3. Step 3 β€” Write the validator. Complete starter/validate.py per the walkthrough above: hard-fail on missing type, warn on missing recommended fields.
  4. Step 4 β€” Verify. Run:
    terminal
    cd labs/M06-okf-authoring/starter
    python validate.py knowledge
    Expected output: 2 concepts valid, 0 errors.
    βœ… Checkpoint

    Now break it on purpose: delete type: from one file and re-run. You must get a non-zero exit and the offending path. If the validator still passes, you're reproducing the spec's leniency instead of guarding against it.

Troubleshooting: a YAML ScannerError usually means your --- fences aren't alone on their lines; a validator that passes empty files means you forgot that frontmatter.load returns empty metadata rather than raising. Stretch goal: add a dangling-link check β€” every relative .md link must resolve inside the bundle.

πŸ” Context Engineering Lens

In context-engineering terms (sibling course M03B), index.md is static-first ordering plus the select decision: a stable pre-flight read that lets the agent choose which concept files enter context at all. M03B's caching rule β€” "same content in the wrong order can cost 6x more" β€” is exactly why the bundle's entry point never changes shape while its leaves do. Progressive disclosure is the select lever with a filesystem for a UI. Full mapping in M02B.

Knowledge Check

1. Which frontmatter field is REQUIRED by the OKF v0.1 spec?

title
type
type and timestamp
id, type, and title

2. In OKF, what serves as a concept's unique identity?

A UUID assigned by the Knowledge Catalog
The file's path within the bundle
The required id frontmatter field
A hash of the file's contents

3. What distinguishes log.md from git log?

log.md is machine-readable; git log is for humans
log.md records changes to what the bundle KNOWS; git log records changes to the files
Nothing β€” log.md is a cached copy of git log
log.md is required; git log is optional

4. A conformant OKF consumer encounters a bundle with broken links and unrecognized type values. What must it do?

Reject the bundle with a validation error
Auto-repair the links and normalize the types
Accept the bundle β€” leniency is required by the spec
Accept unknown types but reject broken links

5. Which capability does OKF explicitly NOT provide?

Human readability on GitHub
Git-based version control of knowledge
A built-in search/retrieval engine
Cross-links between concept files

6. Why is an OKF bundle better raw material for retrieval than a folder of PDFs?

Markdown compresses better, so more fits in context
Concepts are singular and pre-organized with explicit links β€” the retriever fetches organized truth instead of making sense of chaos
The spec requires embedding vectors in frontmatter
PDFs cannot be chunked at all

Module Summary

The specv0.1, published Jun 12–13 2026 by Google Cloud (McVeety & Hormati) via GoogleCloudPlatform/knowledge-catalog. One page, three conformance rules. Formalizes Karpathy's LLM Wiki + AGENTS.md + Obsidian patterns.
The unitBundle = directory. Concept = one file = one piece of knowledge. Path IS the identity. YAML frontmatter: one required field (type), five recommended (title, description, resource, tags, timestamp).
Reserved filesindex.md = progressive disclosure = a token-budget control. log.md = history of what the bundle knows (β‰  git log).
The trade-offConsumers must tolerate missing fields, unknown types, broken links. Adoptable AND silently degradable β€” your lint, not the spec, guards trust.
Links = edgesRelative Markdown links turn folders into a deterministic knowledge graph. Untyped, so curated β€” Track 2's AST edges stay the verified layer.
Format, not platformcat to read, git clone to ship. Three lines of Python (python-frontmatter) or Node (gray-matter) to parse.

What we built: orderflow's first two concepts β€” the WAU metric with its attested exclusion rule, and the orders_fact table β€” plus the validator that will grow into M07's lint gate.

Next module preview: Google's reference use case is BigQuery tables. M07 makes the pivot that matters for this course: the same concept shape, aimed at code β€” services, dependencies, responsibilities β€” and the okf CLI with its 13 lint rules.

References

  • Google Cloud: Introducing the Open Knowledge Format β€” cloud.google.com/blog/products/data-analytics (June 2026)
  • OKF Specification v0.1 β€” github.com/GoogleCloudPlatform/knowledge-catalog (okf/SPEC.md)
  • OKF FAQ β€” okf.md/faq
  • Karpathy, A. β€” LLM Wiki / knowledge-compiler pattern (April 2026)
  • Course corpus: "Beyond RAG: How Google's OKF is Replacing the Vector Database"; "Did Google Just Kill RAG?"; "Standardizing Agent Memory"; "Your Vector DB is Shredding Context"