# Inside OKF: How the Files Actually Work

*(Part 3 of 5: Understanding OKF)*

In Part 1, we covered the shape of OKF at a high level: a folder of markdown files, each with a small metadata header. In Part 2, we made the case for why this needs to exist as a format at all, rather than just fine-tuning a model. Now let's actually open the hood. How is a real OKF file built, field by field — and why were these specific choices made instead of the obvious alternatives?

## The two-part anatomy of a concept file

Every piece of knowledge in OKF — called a **concept** — lives in one markdown file, and every one of those files splits cleanly into two parts.

```
---
type: BigQuery Table
title: Customer Orders
description: One row per completed order.
tags: [sales, orders]
---

# Schema

| Column | Type | Description |
|---|---|---|
| order_id | STRING | Unique order ID |
| customer_id | STRING | Links to the customer |
```

The block between the two `---` lines is called **frontmatter** — structured metadata a machine can read at a glance. Everything below it is just ordinary markdown — the part meant for a human (or an agent reading it like a human would) to actually read and understand.

This split matters more than it looks. A machine trying to quickly figure out "is this file relevant to what I'm looking for?" doesn't want to parse an entire document of prose — it wants to check a couple of fields and move on. A human, meanwhile, doesn't want to read a wall of key-value pairs — they want a normal document. Frontmatter lets one file serve both audiences without compromise.

## Why YAML, specifically?

This wasn't an arbitrary pick. If you compare YAML to the obvious alternative — JSON — the difference in *writability* is stark:

```yaml
# YAML
title: Customer Orders
tags: [sales, orders]
```

```json
{"title": "Customer Orders", "tags": ["sales", "orders"]}
```

Both say the same thing. But YAML has no mandatory braces, no comma-hunting, and — this is the detail people forget — **it supports comments**, which JSON flatly does not. For a format where humans and agents are expected to hand-edit these files constantly, being able to leave a `# note explaining why` matters. JSON is arguably more machine-precise. YAML is dramatically more pleasant to actually live with day to day.

There were other contenders too — TOML is a genuinely reasonable alternative, and loses mainly on momentum: YAML had already become the default for "content file with a metadata header" through tools like Jekyll and Hugo, so choosing it means inheriting a decade of existing tooling and muscle memory instead of fighting it. XML was ruled out for being too heavy and verbose for small metadata blocks. And a brand-new custom syntax was never seriously on the table — the entire point of OKF is to avoid asking anyone to learn something new.

## The one field that's actually required

Here's a detail that surprises people: almost nothing in the frontmatter is mandatory. `title`, `description`, `tags` — all optional. The *only* required field is `type`:

```
---
type: Playbook
---
Just a paragraph of text is a perfectly valid file.
```

There's no registry of allowed `type` values either — you can write `type: Metric`, `type: API Endpoint`, or something entirely your own, and any tool reading the bundle is expected to handle types it's never seen before gracefully, rather than rejecting the file. That permissiveness is a deliberate choice, not an oversight — the goal was never to impose a fixed taxonomy on how organizations think about their knowledge.

## The body doesn't have to be fancy either

Below the frontmatter, you can write whatever markdown makes sense — headings, tables, fenced code blocks, or just plain prose with no structure at all. A single paragraph explaining a playbook step is a completely valid concept body. The spec has a mild *preference* for using structure (tables for schemas, code blocks for examples) because it helps both humans skimming and agents retrieving a specific piece — but it's a recommendation, not a rule.

## Organizing the folder itself

Zooming out from a single file to the whole bundle: it's just a directory tree, and how you organize it is entirely up to you.

```
company-knowledge/
  index.md
  log.md
  payments/
    index.md
    orders.md
    refunds.md
  authorization/
    index.md
    oauth-flow.md
    api-keys.md
    log.md
```

Two filenames carry special meaning wherever they appear:

- **`index.md`** — a directory listing. Its job is to let an agent see what's in a folder without having to open every file inside it — what the spec calls *progressive disclosure*. You read one small index, decide what's relevant, and only then go open the specific concept you need.
- **`log.md`** — a running, dated change history for whatever scope it sits in. A root-level `log.md` tracks changes across the whole bundle; a `payments/log.md` tracks just that subtree.

Neither is required, and both can exist at any level of nesting, not just the root. Grouping by domain (Payments/, Authorization/) is the obvious pattern, but OKF genuinely doesn't care — group by concept type, by team ownership, by whatever makes sense for your world. The directory structure carries no required meaning of its own.

## How concepts point at each other

Concepts link to each other with completely ordinary markdown links — nothing exotic:

```markdown
Joined with [customers](/tables/customers.md) on `customer_id`.
```

There are two ways to write the path. A **bundle-root-relative** link (starting with `/`) resolves from the top of the bundle no matter where the linking file lives, and it's the recommended form specifically because it survives files getting reorganized later. A plain relative link (`./other.md`) works too, but breaks more easily if either file moves.

Here's the detail that trips people up at first: **the link itself carries no information about what kind of relationship it is.** It's not `A --[joins_with]--> B`. It's just a plain pointer, and the actual meaning — "joined," "depends on," "see also" — lives in the ordinary sentence sitting next to it. This is a deliberate trade: typed links would require everyone to agree on a fixed vocabulary of relationship types up front, which runs directly against the goal of never forcing a rigid taxonomy on anyone. Untyped links plus plain English cost you a little machine precision, but they mean writing a concept feels exactly like writing a normal wiki page — no special syntax to learn.

And broken links are explicitly fine. In a bundle that's constantly being added to — especially by agents — a link pointing at a file that doesn't exist yet usually just means "this hasn't been written yet," not "something is wrong." A conformant reader is expected to tolerate that rather than treat it as an error.

## The `references/` convention

One more pattern worth knowing, though it's a convention rather than a rule: some material isn't really a "concept" in its own right — it's supporting infrastructure that other concepts point to. Run instructions, external material, small scripts. The convention is to tuck these into a `references/` subdirectory, so it's visually obvious that `references/attesters/revenue.py` is plumbing, not a piece of documented knowledge — while still being a completely normal file that links can point to like anything else.

## What we've got so far

Put together: a bundle is a folder tree; every file in it (aside from the two reserved names) is a concept with a small YAML header and a markdown body; `index.md` and `log.md` provide navigation and history at any level; and concepts connect to each other through plain, untyped markdown links that tolerate being incomplete.

None of this, on its own, tells you whether to *trust* what's in a given file. Two concepts can look identical in structure — same frontmatter shape, same kind of body — while one was written by a person who checked it against the actual system and the other was generated by an agent thirty seconds ago and never looked at again. That distinction is invisible so far. It's exactly the problem Part 4 digs into: how OKF tracks where a piece of knowledge came from, how much to trust it, whether it's gone stale, and — for anything numeric — whether it was actually computed the sanctioned way.

---

*Next in this series: The trust layer — provenance, verification, staleness, and the clever mechanism OKF uses to stop an agent from quietly rewriting your SQL.*
