okfctl.dev
Link graph 01Output 02Why this exists 03Documentation 04GitHub v0.4.0 ↗

OKF  /  spec-conformant authoring CLI  /  Apache-2.0

Knowledge you can move without breaking.

okfctl authors and maintains Open Knowledge Format bundles—a curated tree of Markdown nodes with a link graph, reserved index.md / log.md files, and frontmatter provenance.

curl -sSL https://okfctl.dev/install.sh | sh
Read the docs

With Homebrew: brew install cwest/tap/okfctl. With a Go toolchain: go install github.com/cwest/okfctl@v0.4.0. Or grab a prebuilt binary for darwin/linux · amd64/arm64 from releases.

pure Gono CGOno Pythonno model runtimeCGO_ENABLED=0 static build
okfctl bundle init mykb✓ conformant
mykb/
├─ index.mdreserved
├─ log.mdreserved
├─ .okfmarker
└─ concepts/
   ├─ index.mdgenerated
   └─ tannin.mdReference
--- concepts/tannin.md
type: Reference
title: Tannin
created: 2026-08-04T15:36:24Z
modified: 2026-08-04T15:36:24Z
---

The spec

OKF is a specification okfctl consumes and conforms to—it does not author it. The format is maintained by Google in GoogleCloudPlatform/knowledge-catalog. Where the spec defines behaviour, the spec wins. okfctl enforces the floor for everyone and keeps anything stricter behind an explicit opt-in overlay (--templates, §9.4), so an unknown type or a future frontmatter key never fails validate.

01

A knowledge base decays at the moment a path changes. okfctl node mv treats path as identity: it moves the file and rewrites every inbound link in the corpus, relative depth and all. Nothing dangles, and the change lands in log.md.

bundle graph4 inbound links → concepts/tannin.md
Five nodes link to the tannin node; moving it to the reference directory rewrites all four inbound links.concepts/method/reference/aging.mdoak.mdbarrel-aging.mdtasting-notes.mdtannin.md
inbound links rewrittenbefore
concepts/aging.md
# Aging
-Oak barrels add [tannin](tannin.md) over time.
method/tasting-notes.md
# Tasting notes
-Rate grip via [tannin](../concepts/tannin.md).
log.md · reserved
- 2026-08-04 — created concepts/tannin.md

Two of four rewritten files shown. Depth is recomputed per file—tannin.md and ../concepts/tannin.md both resolve to ../reference/tannin.md.

02

What it actually prints.

The command grammar below is the real okfctl command set, kept in lock-step with the binary by the command-reference drift gate. Advisory by default, gate-able on demand: validate fails on a floor violation, lint exits 0 with findings until you pass --strict.

$ okfctl bundle init mykb
Initialized OKF bundle in mykb

$ okfctl node new concepts/tannin.md --type Reference --title "Tannin" --bundle mykb
Created mykb/concepts/tannin.md

$ okfctl node list --bundle mykb
concepts/tannin.md                       Reference

$ okfctl index build mykb
Wrote 2 index.md file(s) under mykb

$ okfctl validate mykb
OK: bundle conforms to the OKF spec floor
exit 0clean cold start
03

Why this exists

Markdown knowledge bases don't rot because people stop writing. They rot because nothing enforces the structure.

01—install

One binary, no runtime underneath it.

A knowledge-base tool that needs a Python environment or a model server is a tool your CI will fight. okfctl is a single static Go binary that runs with nothing installed alongside it: go install it, or drop the binary on PATH, and it runs.

CGO_ENABLED=0 go build -o okfctl .—static, no cgo. Prebuilt for darwin and linux, amd64 and arm64.

02—integrity

Path is identity, so moving is safe.

Reorganising a corpus is the operation everyone avoids because it silently breaks links. node mv rewrites every inbound reference and recomputes relative depth per file; node rm reports the orphans it creates rather than leaving you to find them.

Moved concepts/tannin.md -> reference/tannin.md (4 inbound link(s) rewritten)

03—conformance

A floor that holds, and drift that stays advisory.

validate enforces the OKF spec floor and always fails on a violation. Everything softer—git drift between frontmatter modified and the last commit, team type-template drift, curation findings from lint—is a warning until you opt in with --strict. You choose where the gate is.

okfctl lint --strict ./bundles/knowledge—exits non-zero on any finding. Add --json for a machine path; a clean bundle emits [], never null.

04—scale

Proven against a corpus, not a fixture.

The checks were built against a live knowledge base of hundreds of nodes and thousands of internal links, which is where connectivity, staleness and cluster analysis start telling you something a grep cannot. analyze reports where a bundle is weak; lint reports where it is broken. Deliberately two commands.

okfctl graph export --format dot | dot -Tsvg > graph.svg—or okfctl serve for the interactive view.

04

Documentation

Start with concepts, then the guide for the job in front of you.okfctl <cmd> --help is authoritative and always matches the binary.

Command reference

Fifteen top-level commands. Each ships a runnable example in its --help.

okfctl bundleScaffold (init) and summarize (info) an OKF bundle.
okfctl nodeAuthor and inspect nodes: new, show, list, edit, mv, rm, refresh, promote.
okfctl indexRegenerate (build) and verify (check) the reserved per-directory index.md.
okfctl logAppend and print the reserved log.md change history.
okfctl validateCheck a bundle against the OKF spec floor; optionally overlay type-templates.
okfctl lintReport curation-health findings (orphans, broken links, coverage gaps); --strict for CI.
okfctl analyzeReport where a bundle is weak: freshness, clusters, gaps, connectivity, structure.
okfctl searchCore lexical and graph-neighborhood search—stdlib-only, no model or index.
okfctl graphExport the concept-node link graph (--format json|dot).
okfctl serveServe an interactive web visualization of the bundle graph.
okfctl templateList and show the type-templates a bundle declares.
okfctl migrateUpgrade a bundle from OKF v0.1 to v0.2—two-phase, consumer-agnostic.
okfctl registryManage named remote bundle sources—git remote for OKF bundles.
okfctl connectClone or fast-forward a remote bundle source into a local directory.
okfctl pluginDiscover and install okfctl-<name> plugins on PATH.

Start with an empty directory

curl -sSL https://okfctl.dev/install.sh | sh

Then okfctl bundle init mykb. The quickstart is eight commands long.