okf-kit
v0.19.0
Published
CLI that validates OKF v0.1 knowledge bundles for structural correctness
Maintainers
Readme
okf-kit
CLI that validates OKF v0.1 knowledge bundles for structural correctness, staleness, and citation drift.
Part of agent-dx, playbooks and tooling for teams shipping with AI agents.
Overview
okf-kit checks knowledge bundles against the Open Knowledge Format (OKF) v0.1 spec, a shape for markdown-plus-frontmatter knowledge bundles meant to be readable by both humans and agents. The check catalog was shaped by the Phase-0 OKF pilot in agent-tasks (PR #385), where a few structural mistakes (bad links, absolute paths) turned out to be easy to make and easy to catch mechanically.
It validates frontmatter shape, link resolution, staleness against git history, and citation drift (a path:N citation whose line numbers shifted under it); init scaffolds a starter bundle and docs-for answers "which docs claim this source path".
okf-kit is the producer-side check: it validates a bundle you are authoring or maintaining. Consuming a bundle at query time (loading, indexing, ranking passages for an agent) lives in codebase-oracle, a separate tool.
Key features
- 10 rules covering frontmatter shape, reserved files, link resolution, and staleness/citation drift assessed against git history; see the check catalog.
initscaffolds a starter bundle:index.md,log.md, and one template doc per concept type.docs-forreverse lookup: given one or more changed paths, which bundle docs claim them assourcesorapplies_to(a lookup-only field thatsources-freshignores).- A citation can carry an anchor (
#headingor#"text") so apath:N-Mcitation survives content moving above it; see Citation resolution. --dirty-as-nowmakes a pre-commitcheckrun report the same staleness verdict CI reports after the commit lands; see Staleness.--require-anchorsand--prose-line-referencesopt into stricter checks for a bundle whose citations are already anchored.
Install
# one-off, no install
npx okf-kit check path/to/bundle
# or install it
npm install -g okf-kitRequires Node >= 20, and git on the PATH for repo-root auto-detection and for the staleness rules, which read commit history; see the check catalog for what runs without it.
The README on the default branch can describe options that are not yet published to npm; CHANGELOG.md's [Unreleased] section lists them.
Usage
okf-kit check path/to/bundle
# explicit repo root, used for sources-shape existence checks, staleness
# checks and citation checks (see docs/check-catalog.md's "repo-root
# auto-detection" for what happens when you omit this)
okf-kit check path/to/bundle --repo-root /path/to/repo
# JSON output for tooling (format: docs/check-catalog.md's "Output")
okf-kit check path/to/bundle --json
# fail on warnings too, not just errors (STALE and FUTURE-DATED findings are warnings)
okf-kit check path/to/bundle --strict
# resolve frontmatter refs like `shipped:runbooks/r.md` into another bundle (repeatable);
# add --skip-companion-refs to report an unpassed alias as a notice instead of an error
okf-kit check path/to/bundle --companion shipped=path/to/other/bundle
# report only some rules and/or a minimum severity (the exit status counts only what is reported)
okf-kit check path/to/bundle --rule citations-resolve,links-resolve --min-severity warning
# check against a specific OKF spec version (default: detected from the bundle-root index.md
# `okf_version` frontmatter; v0.1 when that key is absent; see docs/check-catalog.md's
# "Spec version (--spec)")
okf-kit check path/to/bundle --spec v0.2check exits 0 with no errors (and, under --strict, no warnings), 1 when it finds one, and 2 on an invocation or tool error; see check catalog for the full table and Output for the text and JSON formats.
Other commands:
# scaffold docs/okf (the default target, relative to the current directory)
okf-kit init
# which docs claim src/foo.ts (or a directory it lives under) as a source?
okf-kit docs-for path/to/bundle src/foo.tsSee Scaffold a bundle and Reverse lookup for the full command reference, including flags and output formats.
Use in CI
Pin the exact version and use a full (non-shallow) checkout; CI usage explains why:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: OKF bundle check
run: npx [email protected] check path/to/bundleDocumentation
- Check catalog: all 10 rules, repo-root auto-detection, exit codes, output format.
- Scaffold a bundle (
init): generated files, placeholder sources, authoring guidance. - Reverse lookup (
docs-for): matching rules, path resolution, output formats. - Staleness (
sources-fresh): the re-stamp rule, designator-less timestamps, squash-merge interaction,--dirty-as-now,sources-fresh-future. - Citation resolution (
citations-resolve): every finding id, anchor forms, continuation and short-form citations,--require-anchors. - Prose line references: the opt-in
--prose-line-referencescheck for line numbers written outsidecitations-resolve's own grammar. - CI usage: shallow-clone caveats, the pinned-version rationale, the template's pin, and the
templates/okf-staleness.ymlwarn-only workflow template.
Development
npm install
npm run build
npm testSee ../../CONTRIBUTING.md for issue and PR conventions, and the release process (including CONTRIBUTING.md's "Releasing okf-kit" section for bumping this repo's own okf-kit@<version> pins).
Architecture
Modules under src/:
cli.ts: thecheck,docs-forandinitcommands,runCheck, and the mapping of results and errors to exit codes.bundle.ts:loadBundlewalks the bundle's*.mdfiles and parses their frontmatter (parseFrontmatter).rules/: one file per rule (sources-fresh.tsholds bothsources-freshandsources-fresh-future);rules/index.tsregisters them inallRules.report.ts:summarize, and the text (renderText) and JSON (renderJson) output ofcheck.git.ts:runGit, the git child-process wrapper, anddetectRepoRoot.util.ts: frontmattersources(string and v0.2 mapping entries)/applies_togetters,resolveRepoPath, andtimestampparsing.footnotes.ts:scanFootnotes, the[^id]reference and definition scanner shared byfootnotes-resolveandcitations-resolve.links.ts:extractMarkdownLinks, shared bylinks-resolveandno-absolute-links.companions.ts:--companionparsing (parseCompanions).docs-for.ts:runDocsForand its text and JSON output.init.tsandtemplates.ts:runInitand the scaffolded file bodies.types.ts: the shared types (Finding,Rule,BundleContext,RunGit);errors.ts:UsageError.
The diagram shows how check and docs-for share repo-root detection, bundle loading and path resolution, where the rule registry and the exit code sit, and that init (registered in cli.ts like the other two commands) stands apart: it only writes the templates.ts bodies.
flowchart TD
CHECK["check: runCheck (cli.ts)"] --> DETECT["detectRepoRoot (git.ts)<br/>when --repo-root is omitted"]
DOCSFOR["docs-for: runDocsFor<br/>(docs-for.ts)"] --> DETECT
CHECK --> COMP["parseCompanions (companions.ts)"]
CHECK --> LOAD["loadBundle (bundle.ts)"]
DOCSFOR --> LOAD
DETECT -->|"git rev-parse"| GIT["runGit (git.ts)"]
LOAD -->|"ctx"| RULES["allRules (rules/index.ts)"]
COMP -->|"ctx.companions"| RULES
RULES -->|"git (sources-fresh rules)"| GIT
RULES --> RESOLVE["resolveRepoPath (util.ts)"]
DOCSFOR -->|"sources, applies_to entries"| RESOLVE
RULES -->|"findings"| REPORT["summarize / renderText / renderJson<br/>(report.ts)"]
REPORT --> EXIT["exit 0 / 1, or 2 on an error"]
INIT["init: runInit (init.ts)<br/>+ templates.ts"]To add a rule:
- Implement
Rule(id,description,run(ctx)) insrc/rules/<id>.ts. - Register it in
allRulesinsrc/rules/index.tsand add its id totest/rules-registry.test.ts. - For an opt-in rule: add a
CheckOptionsfield and a commander option incli.tsand aBundleContextfield intypes.ts, copy the option ontoctxinrunCheck, and return[]fromrun()when it is unset. - Add a row to the check catalog and update the rule count in this README (Key features and Documentation).
License
MIT, see LICENSE at repo root.
